Я пытаюсь разбить аудиофайл на заданное количество NumPy блоков и поместить их в ОЗУ для воспроизведения, как и play_a_very_long_sound_file . К сожалению, мне не хватает знаний о массивах NumPy и аудиофайлах в целом. Как только этот код заработает, я хотел бы добавить процесс записи в функцию обратного вызова. С кодом, который у меня есть в настоящее время, я получаю:
ValueError: не удалось преобразовать строку в float: ''
, что происходит во втором 'if 'в функции обратного вызова. Я пытаюсь добавить нули в конец блока исходящих данных, но не знаю, как go об этом.
Еще одна любопытная вещь: я получаю только массив numpy, возвращенный из soundfile.read (), который обычно возвращает массив numpy и частоту дискретизации. Но я предполагаю, что это вызвано тем, что я разбил его на кадры. Любая помощь приветствуется!
def callback(outdata, frames, time, status):
assert frames == args.blocksize
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 len(data) < len(outdata):
outdata[:len(data),0] = data
outdata[len(data):,0] = b'\x00' * (len(outdata) - len(data))
raise sd.CallbackStop
else:
outdata[:,0] = data
try:
with sf.SoundFile(args.filename) as f:
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.OutputStream(
samplerate=f.samplerate, blocksize=args.blocksize,
device=args.device, channels=f.channels, dtype='float32',
callback=callback, finished_callback=event.set)
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