python - 在Python中随机开始播放多个循环音轨?

标签 python audio raspberry-pi pyaudio pydub

我有一个保存为 .wav 文件的各种长度的声音样本列表。我想播放第一个样本并让它永远循环。在事件或状态更改后的某个时间点,我希望第二个样本开始与第一个样本一起播放。两个样本都会永远循环。

在下一次事件之后,第三个 sample 将被添加到混合物中。所有三个样本都会永远循环。所有 sample 都将继续如此。

我已成功同时播放多个轨道,但无法将新轨道添加到之前循环的轨道中。我尝试过 PyAudio 和 PyDub。

有没有办法获得连续循环流并添加额外的轨道?我有点卡住了。先感谢您。

from pydub import AudioSegment
from pydub.playback import play

audio1 = AudioSegment.from_file("zipper.wav") 
audio2 = AudioSegment.from_file("jar.wav") 
audio3 = AudioSegment.from_file("dribble.wav") 

mixed = audio1.overlay(audio2)          
mixed1  = mixed.overlay(audio3)

mixed1.export("mixed.wav", format='wav')

play(mixed1)   

编辑 #1

随着不断的实验,pydub 似乎是一个阻塞函数,所以我将无法使用它,因为我将把这种音频混合与 OpenCV 和 LED 光矩阵的热像仪分析结合起来。

不知道该去哪里。

编辑#2 我在这个 link 找到了一些非阻塞的 pyaudio 代码。它允许我无限循环地播放一个 .wav 文件。我尝试添加第二个玩家,但出现错误。

非阻塞循环代码.wav

import os
import time
import wave
import threading
import sys

# PyAudio Library
import pyaudio

class WavePlayerLoop(threading.Thread) :
  """
  A simple class based on PyAudio to play wave loop.
  It's a threading class. You can play audio while your application
  continues to do its stuff. :)
  """

  CHUNK = 1024

  def __init__(self,filepath,loop=True) :
    """
    Initialize `WavePlayerLoop` class.
    PARAM:
        -- filepath (String) : File Path to wave file.
        -- loop (boolean)    : True if you want loop playback. 
                               False otherwise.
    """
    super(WavePlayerLoop, self).__init__()
    self.filepath = os.path.abspath(filepath)
    self.loop = loop

  def run(self):
    # Open Wave File and start play!
    wf = wave.open(self.filepath, 'rb')
    player = pyaudio.PyAudio()

    # Open Output Stream (basen on PyAudio tutorial)
    stream = player.open(format = player.get_format_from_width(wf.getsampwidth()),
        channels = wf.getnchannels(),
        rate = wf.getframerate(),
        output = True)

    # PLAYBACK LOOP
    data = wf.readframes(self.CHUNK)
    while self.loop :
      stream.write(data)
      data = wf.readframes(self.CHUNK)
      if data == b'' : # If file is over then rewind.
        wf.rewind()
        data = wf.readframes(self.CHUNK)

    stream.close()
    player.terminate()


  def play(self) :
    """
    Just another name for self.start()
    """
    self.start()

  def stop(self) :
    """
    Stop playback. 
    """
    self.loop = False


player = WavePlayerLoop("zipper.wav", loop=True)
player.play()

此外,如果我将函数调用放在 while true: 循环中,则什么也不会发生。不知道为什么。

 # Main program logic follows:
    try:

        while True:
            player = WavePlayerLoop("zipper.wav", loop=True)
            player.play()
    except KeyboardInterrupt:
        player.terminate()

最佳答案

经过深入研究和多次尝试,我找到了一种使用 pygame 模块来做到这一点的方法。我最初没有研究这个模块,因为我认为它仅限于 8 个同时发出的声音。这只是默认设置。

pygame.mixer.set_num_channels(26)

我将 channel 数更改为 26。

import pygame
import time

pygame.mixer.init()
pygame.init()

pygame.mixer.set_num_channels(26)

sound1 = pygame.mixer.Sound("sound1.ogg")
sound2 = pygame.mixer.Sound("sound2.ogg")

sound1.play(loops = -1)
time.sleep (2)

sound2.play(loop = -1)

关于python - 在Python中随机开始播放多个循环音轨?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55235070/

相关文章:

mysql - 无法使用 Coda 2 连接到 MySQL 数据库

camera - YUV 缓冲区末尾的额外字节 - RaspberryPi

iphone - 多个音频文件同时iPhone

c# - 如何可视化声音?

algorithm - 如何让波形渲染更有趣?

Python 目标系统

python - 使用python更新标签中的图像

python - 在不使用 ITERTOOLS 的情况下在 bool 列表的 python 中创建组合/排列

python - SWIG 如何在可从 Python 调用的结构中创建 typedef 函数指针

python - Gunicorn 20 未能在 'app.server' 中找到应用程序对象 'index'