我一直在研究从样本列表中播放声音的方法,我找到了一些可以做到这一点的模块。
我使用 AudioLazy 模块使用以下脚本播放声音:
from audiolazy import AudioIO
sound = Somelist
with AudioIO(True) as player:
player.play(sound, rate=44100)
此代码的问题在于它会停止整个应用程序,直到声音停止播放,我无法同时播放多个声音。
我的程序是交互式的,所以我想要的是能够同时播放多个声音,所以例如我可以运行这个播放5秒声音的脚本然后在第二个2我可以播放5秒再次响起。
我不希望整个节目停止播放声音。
答案 0 :(得分:3)
这是使用pydub的更简单的解决方案。
使用overlay
模块的AudioSegment
功能,您可以非常轻松superimpose
多个音频互相播放。
这是一个组合三个音频文件的工作代码。使用相同的概念,您可以将多个音频相互组合。
有关overlay
函数here
pydub
也支持多种音频格式。
from pydub import AudioSegment
from pydub.playback import play
audio1 = AudioSegment.from_file("chunk1.wav") #your first audio file
audio2 = AudioSegment.from_file("chunk2.wav") #your second audio file
audio3 = AudioSegment.from_file("chunk3.wav") #your third audio file
mixed = audio1.overlay(audio2) #combine , superimpose audio files
mixed1 = mixed.overlay(audio3) #Further combine , superimpose audio files
#If you need to save mixed file
mixed1.export("mixed.wav", format='wav') #export mixed audio file
play(mixed1) #play mixed audio file
以下是根据我们的讨论进行的更新。
首先我们创建44KHz信号并保存到sound.wav
下一步读取波形文件并将信号保存到文本文件
然后创建三种输入信号变体来测试叠加
原始信号有dtype int16
然后我们创建三个音频片段
然后如上所述混合/叠加。
wav
信号数据存储在test.txt
使用修改后的代码
import numpy as np
from scipy.io.wavfile import read
from pydub import AudioSegment
from pydub.playback import play
import wave, struct, math
#Create 44KHz signal and save to 'sound.wav'
sampleRate = 44100.0 # hertz
duration = 1.0 # seconds
frequency = 440.0 # hertz
wavef = wave.open('sound.wav','w')
wavef.setnchannels(1) # mono
wavef.setsampwidth(2)
wavef.setframerate(sampleRate)
for i in range(int(duration * sampleRate)):
value = int(32767.0*math.cos(frequency*math.pi*float(i)/float(sampleRate)))
data = struct.pack('<h', value)
wavef.writeframesraw( data )
wavef.writeframes('')
wavef.close()
#Read wave file and save signal to text file
rate, signal = read("sound.wav")
np.savetxt('test.txt', signal, delimiter=',') # X is an array
#load wav data from text file
wavedata1 = np.loadtxt("test.txt", comments="#", delimiter=",", unpack=False, dtype=np.int16)
#Create variation of signal
wavedata2 = np.loadtxt("test.txt", comments="#", delimiter=",", unpack=False, dtype=np.int32)
#Create variation of signal
wavedata3 = np.loadtxt("test.txt", comments="#", delimiter=",", unpack=False, dtype=np.float16)
#create first audio segment
audio_segment1 = AudioSegment(
wavedata1.tobytes(),
frame_rate=rate,
sample_width=2,
channels=1
)
#create second audio segment
audio_segment2 = AudioSegment(
wavedata2.tobytes(),
frame_rate=rate,
sample_width=2,
channels=1
)
#create third audio segment
audio_segment3 = AudioSegment(
wavedata3.tobytes(),
frame_rate=rate,
sample_width=2,
channels=1
)
# Play audio (requires ffplay, or pyaudio):
play(audio_segment1)
play(audio_segment2)
play(audio_segment3)
#Mix three audio segments
mixed1 = audio_segment1.overlay(audio_segment2) #combine , superimpose audio files
mixed2 = mixed1.overlay(audio_segment3) #Further combine , superimpose audio files
#If you need to save mixed file
mixed2.export("mixed.wav", format='wav') #export mixed audio file
play(mixed2) #play mixed audio file
答案 1 :(得分:2)
我建议使用Pyaudio来执行此操作。
import pyaudio
import wave
sound1 = wave.open("/path/to/sound1", 'rb')
sound2 = wave.open("/path/to/sound2", 'rb')
def callback(in_data, frame_count, time_info, status):
data1 = sound1.readframes(frame_count)
data2 = sound2.readframes(frame_count)
decodeddata1 = numpy.fromstring(data1, numpy.int16)
decodeddata2 = numpy.fromstring(data2, numpy.int16)
newdata = (decodeddata1 * 0.5 + decodeddata2* 0.5).astype(numpy.int16)
return (newdata.tostring(), pyaudio.paContinue)
答案 2 :(得分:1)
使用多个线程可以解决您的问题:
import threading
from audiolazy import AudioIO
sound = Somelist
with AudioIO(True) as player:
t = threading.Thread(target=player.play, args=(sound,), kwargs={'rate':44100})
t.start()