This minimum reproducible example:
#!/usr/bin/env python3
from contextlib import contextmanager
import pyaudio
from matplotlib import pyplot as plt
RATE = 44_100
def init_plot():
fig, ax1 = plt.subplots(ncols=1)
broad_line, = ax1.loglog([], [])
def plot():
x = [0]*32
broad_line.set_xdata(x)
broad_line.set_ydata(x)
print('Drawing...')
# Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
fig.canvas.draw()
print('Done.')
return plot
def audio_cb(plot):
def cb(*args):
try:
plot()
flag = pyaudio.paContinue
except RuntimeError as e:
print(e)
flag = pyaudio.paComplete
out_data = None
return out_data, flag
return cb
@contextmanager
def init_audio(n_frames: int, cb):
audio = pyaudio.PyAudio()
stream = audio.open(
input=True,
rate=RATE,
channels=1,
format=pyaudio.paFloat32,
frames_per_buffer=n_frames,
stream_callback=cb,
)
try:
yield
finally:
stream.close()
audio.terminate()
def main():
n_frames = 32768
plot = init_plot()
with init_audio(n_frames, audio_cb(plot)):
plt.show(block=True)
main()
crashes where indicated, every single time. It kills Python itself. The stacktrace from gdb
is
#0 0x00007fffc3371ce5 in Tk_GetImageMasterData () from /usr/lib/libtk8.6.so
#1 0x00007fffc337d2dd in Tk_FindPhoto () from /usr/lib/libtk8.6.so
#2 0x00007fffc2909966 in mpl_tk_blit (self=<optimized out>, args=<optimized out>) at src/_tkagg.cpp:64
#3 0x000055555577020d in cfunction_call (func=0x7fffc2b30e00, args=<optimized out>, kwargs=<optimized out>)
at Objects/methodobject.c:546
#4 0x00005555555c5d50 in _PyObject_MakeTpCall (tstate=0x7fff98023060, callable=0x7fffc2b30e00,
args=<optimized out>, nargs=<optimized out>, keywords=0x0) at Objects/call.c:191
...
#37 0x00007fffe2b13674 in _stream_callback_cfunction (input=0x555556beea30, output=0x0, frameCount=32768, timeInfo=<optimized out>, statusFlags=<optimized out>, userData=<optimized out>) at src/_portaudiomodule.c:1302
#38 0x00007fffdfd8cdc8 in ?? () from /usr/lib/libportaudio.so.2
#39 0x00007fffdfd8ea51 in ?? () from /usr/lib/libportaudio.so.2
#40 0x00007fffdfd9646b in ?? () from /usr/lib/libportaudio.so.2
#41 0x00007ffff7f453e9 in start_thread () from /usr/lib/libpthread.so.0
#42 0x00007ffff7d22293 in clone () from /usr/lib/libc.so.6
Should I basically give up on attempting to call into matplotlib
from a PortAudio callback? If so, how best could I pass audio data from the callback to a rendering thread?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…