Master PyAudio — the cross-platform Python library for recording, playing, and processing audio. This comprehensive guide covers everything from installation and first steps to advanced real-time streams, AI voice assistants, and performance tuning.
PyAudio is the most popular Python library for cross-platform audio input and output. It gives you low-level control over your sound hardware, making it essential for voice assistants, music applications, telephony, and real-time audio processing. Whether you're a beginner building your first voice recorder or an expert developing a low-latency audio engine, PyAudio has you covered.
PyAudio provides Python bindings for PortAudio, the cross-platform audio I/O library. It allows you to:
It's the foundation for many Python audio tools, including speech recognition, music generation, and acoustic analysis.
| Feature | Description |
|---|---|
| Cross‑platform | Windows, macOS, Linux |
| Low‑latency streaming | Callback and blocking I/O |
| Device enumeration | List all input/output devices |
| Multiple formats | paInt16, paFloat32, paInt24, etc. |
| Multi‑channel | Mono, stereo, surround |
| Full‑duplex | Record and play simultaneously |
pip install pyaudiopip install pyaudioIf you encounter errors, try installing from a pre‑built wheel or use conda install pyaudio.
sudo apt-get install portaudio19-dev python3-pyaudiobrew install portaudio
pip install pyaudioCFLAGS="-I/opt/homebrew/include" LDFLAGS="-L/opt/homebrew/lib" pip install pyaudioRun the following script to check your PyAudio setup:
import pyaudio
p = pyaudio.PyAudio()
print("PyAudio version:", pyaudio.__version__)
print("Device count:", p.get_device_count())
for i in range(p.get_device_count()):
info = p.get_device_info_by_index(i)
print(f"{i}: {info['name']}")
p.terminate()
Expected output: A list of audio devices, including your microphone and speakers.
This example records 3 seconds of audio and plays it back immediately.
import pyaudio
import wave
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 3
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE,
input=True, frames_per_buffer=CHUNK)
print("Recording...")
frames = []
for _ in range(int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("Playing back...")
stream.stop_stream(); stream.close()
play_stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, output=True)
play_stream.write(b''.join(frames))
play_stream.stop_stream(); play_stream.close()
p.terminate()
Use stream.read() to capture audio data. The example below saves the recording to a WAV file.
import pyaudio, wave
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=44100,
input=True, frames_per_buffer=1024)
frames = []
for _ in range(0, int(44100 / 1024 * 5)):
frames.append(stream.read(1024))
stream.stop_stream(); stream.close(); p.terminate()
wf = wave.open("recording.wav", 'wb')
wf.setnchannels(1)
wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))
wf.setframerate(44100)
wf.writeframes(b''.join(frames))
wf.close()
Common mistake: Forgetting to set the correct sample width. Use p.get_sample_size(FORMAT).
To play a WAV file, read it with the wave module and write chunks to the output stream.
import pyaudio, wave
wf = wave.open("recording.wav", 'rb')
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(), rate=wf.getframerate(), output=True)
data = wf.readframes(1024)
while data:
stream.write(data)
data = wf.readframes(1024)
stream.close(); p.terminate(); wf.close()
WAV is the most common format for PyAudio. Use the built‑in wave module to read and write WAV files. For advanced features like metadata extraction or format conversion, use scipy.io.wavfile or soundfile.
To select a specific microphone, use input_device_index. List all devices with get_device_info_by_index().
import pyaudio
p = pyaudio.PyAudio()
for i in range(p.get_device_count()):
info = p.get_device_info_by_index(i)
if info['maxInputChannels'] > 0:
print(f"Input device {i}: {info['name']}")
Use output_device_index to choose a speaker. Most systems use the default output device.
PyAudio supports a callback mode for non‑blocking, low‑latency processing. The callback function is called whenever new audio data is available.
import pyaudio, numpy as np
def callback(in_data, frame_count, time_info, status):
audio = np.frombuffer(in_data, dtype=np.int16)
processed = (audio * 0.5).astype(np.int16) # volume reduction
return (processed.tobytes(), pyaudio.paContinue)
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=44100,
input=True, output=True, stream_callback=callback)
stream.start_stream()
while stream.is_active():
pass
stream.close(); p.terminate()
Always manage streams properly: open(), start_stream(), stop_stream(), and close(). Use try/finally blocks to ensure cleanup.
Key parameters when opening a stream:
Buffer size (frames_per_buffer) determines the latency and CPU usage. Smaller buffers = lower latency but higher risk of underruns. A typical value is 1024 or 512.
Sample rate is the number of samples per second. Common rates: 8000 Hz (telephony), 44100 Hz (CD quality), 48000 Hz (video), 96000 Hz (high resolution).
Channels refer to the number of audio tracks. Mono = 1 channel, Stereo = 2 channels, Surround = 6 or more.
| Format | Description |
|---|---|
| paInt16 | 16‑bit signed integer (most common) |
| paInt24 | 24‑bit signed integer |
| paFloat32 | 32‑bit floating point (good for DSP) |
| paInt8 | 8‑bit signed integer |
Combine PyAudio with speech_recognition and pyttsx3 to create a simple voice assistant.
import speech_recognition as sr
import pyttsx3
recognizer = sr.Recognizer()
engine = pyttsx3.init()
with sr.Microphone() as source:
print("Listening...")
audio = recognizer.listen(source)
try:
text = recognizer.recognize_google(audio)
print(f"You said: {text}")
engine.say("You said " + text)
engine.runAndWait()
except sr.UnknownValueError:
print("Could not understand")
Build a full-featured voice recorder with start/stop, pause, and save options using PyAudio and Tkinter.
Display real-time waveform or volume levels using Matplotlib. Use the callback to update the plot.
Advantages:
Limitations:
| Library | Pros | Cons |
|---|---|---|
| PyAudio | Low-level control, cross-platform, mature | Complex API |
| sounddevice | NumPy-friendly, simpler API | Less control over buffers |
| pygame.mixer | Easy playback for games | Limited recording, less flexible |
| playsound | One‑line playback | No recording, no streaming |
PyAudio is used for cross-platform audio input/output, including recording, playback, and real‑time processing.
Yes, PyAudio is open-source under the MIT license.
pip install pyaudio (see installation section for platform-specific steps).
Yes, using full‑duplex streams with the callback API.
PyAudio is lower‑level; sounddevice offers a higher‑level, NumPy‑centric API.
Use input_device_index parameter after enumerating devices.
44100 Hz for general use, 16000 Hz for speech recognition.
It's the number of frames per chunk; smaller values reduce latency.
No, only PCM formats. Use additional libraries like pydub for MP3.
Check that your microphone is not in use by another application.
Yes, by using threads or the callback API.
Depends on your hardware, but typically 192 kHz.
Process the audio data inside the callback or after recording.
Yes, it's used in many production applications.
Not directly; you need a loopback driver or virtual audio cable.
Use get_device_info_by_index().
Device unavailable, buffer underflow, format mismatch.
Use smaller buffer sizes and the callback API.
Yes, the callback API is designed for real‑time processing.
Check the official PyAudio documentation and GitHub repository.
PyAudio is the Swiss Army knife for audio in Python. From simple voice recorders to professional DAWs and AI voice assistants, it provides the foundation for any audio project. With the knowledge from this tutorial, you're ready to build robust, cross-platform audio applications.
stream.read() and stream.write() for blocking I/O.Build a Tkinter app with buttons for Start Recording, Stop, and Playback. Use PyAudio for recording and playback, and save the final recording as a WAV file.
Create a real‑time voice changer that applies pitch shifting and reverb effects to microphone input. Use PyAudio's callback API and NumPy for DSP. Add a GUI to control effect parameters.
2026 LegalCodx — Comprehensive PyAudio Tutorial