I am trying to use PyAudio to process real-time data from a microphone. I have followed the examples on the PyAudio Documentation and this blog post. When I use stream.is_active() without a callback, I have no error and everything works fine, but if I use a callback I get the following "SystemError: new style getargs format but argument is not a tuple"
I have looked at the question Where is the error? “SystemError: new style getargs format but argument is not a tuple”, however, this doesn't translate to my problem. I will explain the things I tried below my code:
FORMAT = pyaudio.paInt32
CHANNELS = 2
RATE = 44100
CHUNK = 1024
def callback(in_data, frame_count, time_info, flag):
print('Hi')
audio = pyaudio.PyAudio()
# start Recording
stream = audio.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True,
frames_per_buffer=CHUNK,stream_callback = callback)
stream.start_stream()
while stream.is_active():
time.sleep(0.1)
print('1')
stream.stop_stream()
stream.close()
audio.terminate()
I have determined that that the error is any time I add stream_callback = callback
. If I remove this, I do not get the error. The exact code in my callback does not seem to affect the error as I get it when I just include the statement above (my whole code calculates the time delay between the two channels though). My callback parameters are defined directly from the documentation. I am not really sure what else to try as I'm not directly doing anything in the callback.
As the example you linked says:
In callback mode, PyAudio will call a specified callback function (2) whenever it needs new audio data (to play) and/or when there is new (recorded) audio data available. Note that PyAudio calls the callback function in a separate thread. The function has the following signature
callback(<input_data>, <frame_count>, <time_info>, <status_flag>)
and must return a tuple containingframe_count
frames of audio data and a flag signifying whether there are more frames to play/record.
But your callback function doesn't do that:
def callback(in_data, frame_count, time_info, flag):
print('Hi')
This has no return
statement at all, so it just returns None
.
Compare it to the quoted example, which returns a buffer and a flag. That's what you need to do.
The reason you're getting the specific error you are, rather than something more understandable, is that, somewhere under the covers, PyAudio is parsing your return value by using a C API function that takes a Python tuple, without doing any explicit error handling. Which is not ideal, because the error message is harder to read when you have no idea what it means…