我正在使用sd.Stream来同时输出声音和从麦克风录制。我需要能够同时获取输入和输出以进行实时音频处理,这就是为什么我使用Stream的原因。如果我正在使用使用相同采样率的所有文件,则可以正常工作。如果我有一些音频文件没有相同的采样率,则需要能够更改Stream使用的采样率。
try:
stream = sd.Stream(device=(args.input_device, args.output_device),
samplerate=args.samplerate, blocksize=args.blocksize,
dtype='float32', latency=(0, 0),
channels=len(args.channels), callback=callback, finished_callback=finished_callback)
with stream:
ani = FuncAnimation(fig, update_plot, interval=args.interval, blit=False, init_func=plot_init)
plt.show()
我的第一次尝试是在finish_callback中关闭流:
def finished_callback():
global stream
print "just closed"
stream.close()
,然后在update_plot中重新打开流:
if stream.closed and callback.fs_mismatch:
args.samplerate = callback.new_fs
callback.fs_mismatch = 0
stream = sd.Stream(device=(args.input_device, args.output_device),
samplerate=args.samplerate, blocksize=args.blocksize,
dtype='float32', latency=(0, 0),
channels=len(args.channels), callback=callback, finished_callback=finished_callback)
print "stopped stream and fs mismatch!\n"
重新打开流似乎根本没有任何作用。我相信这样做的原因是,像我以前使用的那样(plt.show),新流之后没有任何阻塞。在本节中,我没有任何阻碍,因为这是我要更新情节的地方。在流已经打开之后,是否可以更改它的采样率?是否有另一种方法可以完成我正在尝试做的事情?
答案 0 :(得分:0)
首先,如果文件的采样率不同,则应考虑重新采样(也就是采样率转换)。这通常是解决您的问题的方法。
第二,PortAudio(sounddevice
模块后面的C库)不支持更改现有流的采样率。如果您确实需要,理论上还有其他音频框架(例如JACK)也支持。
第三,如果您确实需要具有不同采样率的流,则当然可以关闭一个流,然后打开另一个具有不同采样率的流。在某些平台上,您甚至可以同时具有多个流(可能具有不同的设置)。
您不应在finished_callback
中关闭流,实际上您不应在其中的sounddevice
模块中调用任何函数。
在update_plot
回调中创建流可能不是一个好主意,因为当变量超出范围时,流将被破坏(由于该函数通常很短,所以发生得很快)。>
您可能应该创建一个单独的线程来进行绘图,并处理主线程中音频流的停止和重新启动(反之亦然)。