У меня есть список звуковых образцов различной длины, сохраненных в виде файлов .wav. Я хочу сыграть семпл кулака и сделать его зацикленным навсегда. Как некоторый момент времени после события или изменения состояния, я хочу, чтобы 2-й семпл начал играть с первого семпла. Тогда оба сэмпла будут зациклены навсегда.
После следующего события третий образец будет добавлен в микс. Все три сэмпла будут зациклены навсегда. Это будет продолжаться для всех образцов.
Я успешно воспроизвел несколько дорожек одновременно, но не смог добавить новую дорожку к ранее записанной дорожке. Я пытался с 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 и светодиодной матрицы света.
Не уверен, куда идти отсюда.
Редактировать # 2
По этой ссылке я нашел некоторый неблокирующий код 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()
Кроме того, если я поместил вызов функции в некоторое время true: loop, то ничего не произойдет. Не знаю почему.
# Main program logic follows:
try:
while True:
player = WavePlayerLoop("zipper.wav", loop=True)
player.play()
except KeyboardInterrupt:
player.terminate()