我正在尝试创建一个允许我输出 WAVE 文件的低级 Stream,同时在同一音频设备上记录输入。我的音频设备已设置,以便输出 WAVE 文件将通过输出播放,这将通过一个系统运行,然后转到设备上的输入。使用 python-sounddevice 中的便捷函数 playrec() 可以完整记录输入中看到的内容,但是使用较低级别的 Stream() 函数的代码,录制开始较晚,并且音频的最后一点是没有记录。我想使用较低级别的 Stream() 函数的原因是测试与 playrec() 相比,我是否可以减少该系统的整体延迟。我尝试更改块大小和缓冲区大小无济于事。
def callback(indata, outdata, frames, time, status):
assert frames == args.blocksize
qr.put(indata.copy())
rec_file.write(qr.get())
if status.output_underflow:
print('Output underflow: increase blocksize?', file=sys.stderr)
raise sd.CallbackAbort
assert not status
try:
data = q.get_nowait()
except queue.Empty:
print('Buffer is empty: increase buffersize?', file=sys.stderr)
raise sd.CallbackAbort
if data.size < outdata.size:
outdata[:len(data),0] = data
outdata[len(data):] = 0
raise sd.CallbackStop
else:
outdata[:,0] = data
try:
with sf.SoundFile(args.filename) as f:
#queue for recording input
qr = queue.Queue(maxsize=args.buffersize)
#queue for output WAVE file
q = queue.Queue(maxsize=args.buffersize)
event = threading.Event()
for _ in range(args.buffersize):
data = f.read(frames=args.blocksize, dtype='float32')
if data.size == 0:
break
q.put_nowait(data) # Pre-fill queue
stream = sd.Stream(
samplerate=f.samplerate, blocksize=args.blocksize,
dtype='float32', callback=callback, finished_callback=event.set,
latency='low')
with sf.SoundFile('output'+str(itr)+'.wav', mode='x', samplerate=f.samplerate,
channels=1) as rec_file:
with stream:
timeout = args.blocksize * args.buffersize / f.samplerate
while data.size != 0:
data = f.read(args.blocksize, dtype='float32')
q.put(data, timeout=timeout)
event.wait() # Wait until playback is finished