rosenfranz
Posts: 17
Joined: Sun Oct 26, 2014 11:19 am

PyAudio Issue - record mic. input while button is pressed

Sat Aug 13, 2016 8:57 am

Hey there folks,

I'd really appreciate some help on this one.
So I have a pushbutton hooked up to the GPIOs of my Pi2 Model B, in order to record Mic-Input from an USB Audiostick (https://amzn.com/B0027EMHM6) for as long as the button is pushed.
Works fine on the first run but Python alsways kicks me out as soon as I try it a second time (the script is a loop. button pushed > start recording > button released > finish recording & create wav file > button pushed > start recording > and so on).

so here's my script:

Code: Select all

#!/usr/bin/python
import RPi.GPIO as GPIO

import pyaudio
import wave
import time
 
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 512
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "rec41000.wav"
 
p = pyaudio.PyAudio()

#audio_info = p.get_device_info_by_index(0)
#print (audio_info)
 
#GPIO pin setup for button
ledPin = 18
buttonPin = 23

#set up GPIO using BCM numbering
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

#enable LED and button (button with pull-up)
GPIO.setup(ledPin, GPIO.OUT)
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

#set LED to OFF
GPIO.output(ledPin, GPIO.LOW)

while(True):

	print "waiting for button event"

	#wait for button to be pressed
	time.sleep(0.2)
	GPIO.wait_for_edge(buttonPin, GPIO.FALLING)

	while True:
		try:
                    frames = []
                    stream = p.open(format = FORMAT,
                                            channels = CHANNELS, 
                                            rate = RATE, 
                                            input = True,
                                            frames_per_buffer = CHUNK)
            
                    print "* recording"
                    #turn on LED ring when recording starts
                    GPIO.output(ledPin, GPIO.HIGH)
            
                    #record as long as button held down
                    while GPIO.input(buttonPin) == 0:
                        data = stream.read(CHUNK)
                        frames.append(data)
            
                        break
            
                except IOError:
                        printer.println(textWrapped('- Aufnahmefehler. Starte neu, Moment bitte. -', 32))

	# button released
	print "* done"
	GPIO.output(ledPin, GPIO.LOW)

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

	#make wave file from recorded data stream
	wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
	wf.setnchannels(CHANNELS)
	wf.setsampwidth(p.get_sample_size(FORMAT))
	wf.setframerate(RATE)
	wf.writeframes(b''.join(frames))
	wf.close()      
and this is what I get in the shell (the alsa and jack server notifications are normal and can be ignored):

pi@bcfpi:~/bcfnikki $ python record5sec.py
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
waiting for button event
* recording
* done
-- the main loop restarts here --
waiting for button event
Traceback (most recent call last):
File "record5sec.py", line 55, in <module>
frames_per_buffer = CHUNK)
File "/usr/local/lib/python2.7/dist-packages/pyaudio.py", line 750, in open
stream = Stream(self, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/pyaudio.py", line 441, in __init__
self._stream = pa.open(**arguments)
IOError: [Errno -9996] Invalid input device (no default output device)


My Pi is running with Raspbian GNU/Linux 8 (jessie). As I didn't get the latest version of PyAudio with 'sudo pip install pyaudio' right away (quit with error message) I had to do this to get the 0.2.9 Package installed: sudo apt-get install portaudio19-dev python-all-dev python3-all-dev && sudo pip install pyaudio

Any ideas what might be the problem, here? Any help is much appreciated.
Last edited by rosenfranz on Sat Aug 13, 2016 2:31 pm, edited 2 times in total.

User avatar
davef21370
Posts: 897
Joined: Fri Sep 21, 2012 4:13 pm
Location: Earth But Not Grounded

Re: PyAudio Issue - record mic. input while button is presse

Sat Aug 13, 2016 9:31 am

Don't know, but from the docs "To keep the stream active, the main thread must not terminate, e.g., by sleeping (5).".
Maybe don't use p.terminate() until you're ready to quit and create a new WAV file for each button push while remaining in the main loop.

Dave.
Apple say... Monkey do !!

rosenfranz
Posts: 17
Joined: Sun Oct 26, 2014 11:19 am

Re: PyAudio Issue - record mic. input while button is presse

Sat Aug 13, 2016 9:50 am

Thanks for your response, dave.
Actually I took this process directly from a test record script that is included in the PyAudio library: 'record.py', here it is:

Code: Select all

"""
PyAudio example: Record a few seconds of audio and save to a WAVE
file.
"""

import pyaudio
import wave
import sys

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

if sys.platform == 'darwin':
    CHANNELS = 1

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

print("* recording")

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    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(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
This script works fine so maybe my script architecture is the problem? Anyone, please feel free to post corrections/alternate approaches! I'm not that experienced with Python/PyAudio...

rosenfranz
Posts: 17
Joined: Sun Oct 26, 2014 11:19 am

Re: PyAudio Issue - record mic. input while button is presse

Sun Aug 14, 2016 12:20 pm

Hey there!

I was able to solve this myself. As so often it was only a super stupid error in the script:
I created the PyAudio object outside of my main loop. So it works fine one time but when finishing the recording process the pyaudio object is being terminated WITHIN the main loop. So of course no pyaudio object can be found in the second run as I initiated it outside the loop.

doh...

pierreee1
Posts: 3
Joined: Wed Jul 31, 2019 6:18 am

Re: PyAudio Issue - record mic. input while button is pressed

Thu Aug 01, 2019 2:49 am

Hello, I'm trying to do the same thing so I ran the code you posted above but it doesn't recognize the button being released. Is it possible for you to post the final code?

Pierre

Return to “Python”