Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

pyaudio (Part 2)

00:00 Now it’s time to take a look at recording sound using pyaudio. Like before, you can expect this to use quite a few more lines of code than python-sounddevice. Let’s jump into the editor and get started. First, go ahead and make your imports, so we want pyaudio and also wave.

00:18 Now it’s time to set some attributes. chunk, like before, will be 1024. The sample_format is going to equal pyaudio.paInt16, which just sets it to 16 bits per sample. For channels, you’re going to want 2 to get a stereo. And set the sample rate.

00:45 Like the other examples, this will be 44100 samples per second. Do a duration, so set seconds = 3. And then a filename, which like before, make this 'output.wav'.

01:02 And I’ve gone and deleted the output.wav from the previous example. All right. So now you want to make that PortAudio interface, so set p = pyaudio.PyAudio(), and so that we know that we’re recording, you can just print out something like 'Recording...'.

01:21 Since pyaudio works by writing to that stream, you’re going to need to create the stream object. So do a p.open(), and you’ll want to set the format=sample_format.

01:36 channels=channels. The rate is your sample rate, so fs. The frames_per_buffer is going to equal the chunk.

01:50 And now this time, you’ll set input=True, and this is what will tell pyaudio that we’re going to be recording. Now that you have that, go ahead and make an empty list called frames to collect the data frames that will be recorded.

02:05 You’re going to want to store data in those chunks for three seconds, and you can do this with a for loop. So, for i in range(), and you want to start at 0 and then make an integer from the sample rate divided by the chunk times seconds.

02:24 And you’re going to make a chunk of data, which you’ll set equal to the stream, and you’ll read all of the samples in that chunk.

02:36 Once you have that, take your frames list and append that data frame. When that loop is finished, you’ll no longer be recording. At this point, you can take your stream and you can stop the stream.

02:52 You can also close the stream. And, like before, you’re going to want to terminate that interface to PortAudio. So now everything related to the recording is completed, so you can print out 'Finished recording...', and you’re left with that list of data frames.

03:11 To save this, you want to make a new file object. So wave.open(), pass in the filename, and this time you’re going to be writing to it.

03:21 And then you’ll want to set those attributes that you defined earlier, so .setnchannels() is going to equal channels, the .setsampwidth() (set the sample width) is going to be p.get_sample_size(), and then you’ll pass in that sample_format. And then set the frame rate,

03:48 which will just be that sample rate from earlier.

03:54 And then now you can actually write the data to it, so you’ll do .writeframes()

04:01 and you’ll make a byte string, which you’ll then just join all of the data from that frames list. And close the file. So, you can see from writing to the file that we’re doing things kind of backwards from playing audio. Now instead of getting these attributes from the file itself, you’re setting these attributes. All right, let’s see if it works!

04:23 So let’s save this and try it out.

04:28 This is recording with pyaudio. Okay. No errors, seemed like it worked, and there was an output here. Like before, let’s comment out all of this stuff,

04:43 and then do a from playsound import playsound. And then let’s do playsound('output.wav') to see if it really worked.

04:58 “This is recording with pyaudio.” It worked! Now you have two solid ways to record audio in your projects. Both of these produced WAV files, however, so if you want to make MP3s or use other audio formats, you’ll want to be able to convert them.

05:13 The next section will cover how to do these conversions.

juliettetworsey on Feb. 17, 2020

Hi Joe,

Thank you for this awesome course! I am really enjoying it.

I am encountering an issue when trying to record with pyaudio (and with python-sounddevice). I get this error when trying to run the script to record:

Python[35377:161495] Error loading /Library/Audio/Plug-Ins/HAL/Digidesign CoreAudio.plugin/Contents/MacOS/Digidesign CoreAudio: dlopen(/Library/Audio/Plug-Ins/HAL/Digidesign CoreAudio.plugin/Contents/MacOS/Digidesign CoreAudio, 262): no suitable image found. Did find: /Library/Audio/Plug-Ins/HAL/Digidesign CoreAudio.plugin/Contents/MacOS/Digidesign CoreAudio: no matching architecture in universal wrapper

I am on a macOS Mojave v10.14.6.

What could be the problem?

Thanks in advance for any advice:-)

Juliette

Joe Tatusko RP Team on March 2, 2020

Hi Juliette! How are you running your script? It seems like most of the CoreAudio and macOS issues I can find online aren’t necessarily related to Python, but to privacy permissions.

If you try running the script from a regular Terminal session does it prompt you to allow access to the microphone?

juliettetworsey on March 4, 2020

Hi Joe,

I am attempting to run the scripts from my iTerm terminal with:

python3 python_record_sounddevice.py

python3 python_record_pyaudio.py

I am not getting any prompt to allow microphone access. I suppose that this is due to some baked in settings/permissions macOS Mojave v10.14.6, but I can’t be sure.

I checked my preferences to make sure that iTerm has access to my microphone, but that doesn’t seem to make a difference.

I was unable to find a workaround when searching online.

I also noticed some other strange bug/behavior:

Even though I have loaded all of these modules (and have created a pipfile), when I try to run any of the scripts I am now getting an error (EX) ModuleNotFoundError: No module named 'playsound':

pipenv shell
pipenv install playsound
pipenv install PyObjC
pipenv install simpleaudio
pipenv install numpy
pipenv install soundfile
pipenv install sounddevice
pipenv install pydub simpleaudio
brew install ffmpeg
pipenv install ffmpeg-python

pipenv install pyaudio`//ERROR: Failed building wheel for pyaudio

brew update
brew install portaudio
brew link --overwrite portaudio

pipenv install pyaudio//2nd attempt initially succeeded 

pipenv install scipy

…hmmmm....not sure what to do, but I am going to attempt to start from scratch from within a Docker container and see if I get a different result.

Let me know if you have any ideas/thoughts on what could be wrong.

Thanks for getting back to me:-)

juliettetworsey on March 4, 2020

PS. For the sake of clarity…

Initially I was able to run the scripts to play back audio (just not record), but now (as mentioned above) my iTerm (in addition to the other issue initially mentioned) is no longer finding the modules…hope that makes sense.

Become a Member to join the conversation.