Pyaudio обратный вызов вызывается только один раз - PullRequest
0 голосов
/ 30 сентября 2019

Я пытаюсь использовать pyaudio с опцией обратного вызова, и я хочу получить данные вместо чтения из файла. Когда я использую опцию обратного вызова, она вызывается только один раз.

Есть другой вопрос с той же проблемой, но у него нет ответа. Я сделал минимальный воспроизводимый пример. Код работает, когда используется блокировка.

import time
import numpy as np
import scipy.signal
import sounddevice as sd
import pyaudio

sample_rate=44100
max_amp =  2**(15)-1
f0 = 500
duration = 1
f1 = 3000

x = np.arange(0, duration, 1/sample_rate)
y_float = max_amp*scipy.signal.chirp(x, f0, duration, f1)
y = y_float.astype(np.int16)
data = y.tostring()

def create_data_generator(data):
    periodsize = 1000
    for i in range(int(len(data)/(periodsize))):
        chunk = data[periodsize*i:periodsize*(i+1)]
        yield chunk

data_generator = create_data_generator(data)

def callback(in_data, frame_count, time_info, status):
    data = next(data_generator)
    return (data, pyaudio.paContinue)

# -------- blocking------------------
# periodsize = 1000
# p = pyaudio.PyAudio()
# stream = p.open(format=pyaudio.paInt16,
#         channels=1,
#         rate=sample_rate,
#         output=True)

# start = time.time()
# for i in range(int(len(data)/(periodsize))):
#     chunk, status = callback(0, 0, 0, 0)
#     stream.write(chunk)

# time.sleep(duration-(time.time()-start))

# stream.stop_stream()
# stream.close()
# p.terminate()

# -------- callback ------------------
periodsize = 1000
p = pyaudio.PyAudio()

stream = p.open(format=pyaudio.paInt16,
        channels=1,
        rate=sample_rate,
        output=True, 
        stream_callback=callback)

# start the stream (4)
stream.start_stream()

# wait for stream to finish (5)
while stream.is_active():
    time.sleep(0.1)

# stop stream (6)
stream.stop_stream()
stream.close()

# close PyAudio (7)
p.terminate()
...