2

我必须同时录制 3 个麦克风,并且它们之间的延迟尽可能短。这将允许我计算麦克风之间声音的TDOA,以便我可以精确定位源位置。

但是,我不断收到 PulseAudio 引发的输入溢出错误,这使得数据无法使用,因为麦克风捕获的该块中的帧被丢弃。

到目前为止,我已经尝试通过更改块大小来解决这个问题,甚至在某一时刻将其设置为我的速率的 2 倍。最初我使用的是PyAudio,但我的代码的当前版本运行sounddevice

为了同时开始所有三个录制,我一直在使用多处理,每个进程都包含自己的输入流,但即使在一个进程中运行所有 3 个流也会导致溢出。

我也尝试过在有或没有回调的情况下运行流,但这没有任何区别。与将数据写入内存或直接写入磁盘相同。

CHUNK = 48000*2 #Chunk sizes varied from 5 up to 96000, both didn't work
RATE = 48000
CHANNELS = 1
FILE_NAME = 'recording'

def recorder(start, mic_num, file_name):
    running = False
    q = Queue()
    file = sf.SoundFile(f'./recordings/{file_name}_{mic_num}.wav', mode = 'w', samplerate = RATE, channels = CHANNELS)
    print('Created', mic_num) 

    def mic_processor(data, frames, time, status):
        if(status):
            #RIP recording :/
            print(status) #Only status ever thrown is input overflow
            global running
            running = False
            sys.exit()
        q.put(data)

    while not running:
        if(datetime.datetime.now() >= start):
            stream = sd.InputStream(samplerate = RATE, blocksize = CHUNK, device = mic_num, channels = CHANNELS, callback = mic_processor)
            stream.start()
            print('Microphone', mic_num, 'recording')
            running = True
    while running:
        try:
            file.write(q.get())
        except KeyboardInterrupt:
            stream.stop()
            file.flush()
            file.close()
            running = False

if __name__ == '__main__':
    start = datetime.timedelta(seconds=5)+datetime.datetime.now()

    p1 = Process(target = recorder, args = (start, 2, FILE_NAME))
    p2 = Process(target = recorder, args = (start, 3, FILE_NAME))
    p3 = Process(target = recorder, args = (start, 4, FILE_NAME))

    p1.start()
    p2.start()
    p3.start()

    while True:
        try:
            time.sleep(0.0001)
            if not p1.is_alive() or not p2.is_alive() or not p3.is_alive():
                print('Something went wrong with one of the processes, gotta exit :/')
                p1.terminate()
                p2.terminate()
                p3.terminate()
                sys.exit()
        except KeyboardInterrupt:
            print('Writing to file')
            time.sleep(0.5)
            while p1.is_alive() or p2.is_alive() or p3.is_alive():
                time.sleep(0.1)
            break

理想情况下,我希望不再有输入溢出,但此时我完全不知道如何防止它们。我是否应该切换到 ALSA 而不是 PulseAudio?

我真的很感激我能得到的任何帮助:)

4

0 回答 0