我必须同时录制 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?
我真的很感激我能得到的任何帮助:)