pyaudio seems to randomly halt input. - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: pyaudio seems to randomly halt input. (/thread-41475.html) |
pyaudio seems to randomly halt input. - elpidiovaldez5 - Jan-22-2024 I am trying to use ReSpeaker 4 mic array v2.0. It appears to work perfectly using: arecord -D plughw:1,0 -f S16_LE -c2 -r16000 test.wav aplay test.wav I am now trying to record speech using python 3.8.10 and pyaudio 0.2.11 I used the code supplied in the ReSpeaker documentation, but that blocked and could not be exited with ctrl-c or ctrl-d. I modified the code to print the number of each chunk of data read. That made the code work....mostly. It normally runs to completion and save the audio file, but sometimes it halts on a random chunk, requiring the process to be killed. I would appreciate a solution to this problem that enables speech to be recorded reliably, without a print statement (hopefully without changing the versions I use - because that will introduce a lot of knock-on bugs). The code (including the 'print' statement that I added is: import pyaudio import wave RESPEAKER_RATE = 16000 RESPEAKER_CHANNELS = 1 # change base on firmwares, 1_channel_firmware.bin as 1 or 6_channels_firmware.bin as 6 RESPEAKER_WIDTH = 2 # run getDeviceInfo.py to get index RESPEAKER_INDEX = 16 # refer to input device id CHUNK = 1024 RECORD_SECONDS = 5 WAVE_OUTPUT_FILENAME = "output.wav" p = pyaudio.PyAudio() stream = p.open( rate=RESPEAKER_RATE, format=p.get_format_from_width(RESPEAKER_WIDTH), channels=RESPEAKER_CHANNELS, input=True, input_device_index=RESPEAKER_INDEX,) print("* recording") frames = [] for i in range(0, int(RESPEAKER_RATE / CHUNK * RECORD_SECONDS)): print("Reading {}\n".format(i)) #I added this line! data = stream.read(CHUNK) frames.append(data) print("* done recording") stream.stop_stream() stream.close() p.terminate() wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(RESPEAKER_CHANNELS) wf.setsampwidth(p.get_sample_size(p.get_format_from_width(RESPEAKER_WIDTH))) wf.setframerate(RESPEAKER_RATE) wf.writeframes(b''.join(frames)) wf.close() RE: pyaudio seems to randomly halt input. - plonkarchivist - Jan-22-2024 The issue you are facing might be related to the Ctrl-C not working as expected when using PyAudio. This is a common problem with some audio libraries in Python. One approach to handle this is to set up a signal handler to catch the interrupt signal and then gracefully close the audio stream. Here is a modified version of your code using the signal module to handle Ctrl-C: geometry dash meltdown import pyaudio import wave import signal import sys RESPEAKER_RATE = 16000 RESPEAKER_CHANNELS = 1 RESPEAKER_WIDTH = 2 RESPEAKER_INDEX = 16 CHUNK = 1024 RECORD_SECONDS = 5 WAVE_OUTPUT_FILENAME = "output.wav" p = pyaudio.PyAudio() def signal_handler(sig, frame): print('Ctrl+C pressed, exiting...') stream.stop_stream() stream.close() p.terminate() sys.exit(0) signal.signal(signal.SIGINT, signal_handler) stream = p.open( rate=RESPEAKER_RATE, format=p.get_format_from_width(RESPEAKER_WIDTH), channels=RESPEAKER_CHANNELS, input=True, input_device_index=RESPEAKER_INDEX, ) print("* recording") frames = [] try: for i in range(0, int(RESPEAKER_RATE / CHUNK * RECORD_SECONDS)): print("Reading {}\n".format(i)) data = stream.read(CHUNK) frames.append(data) except KeyboardInterrupt: pass # Ctrl+C was pressed print("* done recording") stream.stop_stream() stream.close() p.terminate() wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(RESPEAKER_CHANNELS) wf.setsampwidth(p.get_sample_size(p.get_format_from_width(RESPEAKER_WIDTH))) wf.setframerate(RESPEAKER_RATE) wf.writeframes(b''.join(frames)) wf.close() RE: pyaudio seems to randomly halt input. - elpidiovaldez5 - Jan-22-2024 Thanks for the tip, but I have fixed the problem - after spending about 9 hours on it (the whole night!). It turns out that I needed to update the firmware on the ReSpeaker card. That was not my first thought, because the original firmware plainly worked using arecord and aplay. Then at one point arecord STOPPED working - I have no explanation for this, but installing firmware from github got arecord working again AND fixed the problem using pyaudio. For anyone in the same situation: git clone https://github.com/respeaker/usb_4_mic_array.git cd usb_4_mic_array sudo python3 dfu.py --download 1_channel_firmware.bin |