0

我正在使用 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()

我的第一次尝试是关闭finished_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)。在这部分我不能有任何阻碍,因为这是我更新我的情节的地方。有没有办法在它已经打开后更改流的采样率,或者有另一种方法来完成我想要做的事情?

4

1 回答 1

0

首先,如果您有不同采样率的文件,您应该考虑重新采样(又名采样率转换)。这是通常用来解决您的问题的方法。

其次,PortAudio(模块背后的 C 库sounddevice)不支持更改现有流的采样率。如果您真的需要,还有其他音频框架理论上支持该功能(例如 JACK)。

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

你不应该关闭 中的流finished_callback,事实上你不应该从sounddevice那里的模块调用任何函数。

update_plot回调中创建流可能不是一个好主意,因为当变量超出范围时它会被销毁(这种情况发生得非常快,因为函数通常很短)。

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

于 2018-10-04T14:29:01.637 回答