如何更新声音设备的采样率?

时间:2018-10-03 16:19:44

标签: python python-2.7 python-sounddevice

我正在使用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),新流之后没有任何阻塞。在本节中,我没有任何阻碍,因为这是我要更新情节的地方。在流已经打开之后,是否可以更改它的采样率?是否有另一种方法可以完成我正在尝试做的事情?

1 个答案:

答案 0 :(得分:0)

首先,如果文件的采样率不同,则应考虑重新采样(也就是采样率转换)。这通常是解决您的问题的方法。

第二,PortAudio(sounddevice模块后面的C库)不支持更改现有流的采样率。如果您确实需要,理论上还有其他音频框架(例如JACK)也支持。

第三,如果您确实需要具有不同采样率的流,则当然可以关闭一个流,然后打开另一个具有不同采样率的流。在某些平台上,您甚至可以同时具有多个流(可能具有不同的设置)。

您不应在finished_callback中关闭流,实际上您不应在其中的sounddevice模块中调用任何函数。

update_plot回调中创建流可能不是一个好主意,因为当变量超出范围时,流将被破坏(由于该函数通常很短,所以发生得很快)。

您可能应该创建一个单独的线程来进行绘图,并处理主线程中音频流的停止和重新启动(反之亦然)。