Phase 1: Audio Processing & Streaming · 50 min · Python · PyAudio · pydub
Digital Audio Basics: Sample Rate, Bit Depth, and Channels
Before you stream audio, you must understand what audio is at the sample level.
Hiring signal: Digital audio manipulation is the first coding round in streaming audio interviews at Deepgram and ElevenLabs.
What you will learn
- Read and write WAV files with Python's wave module and pydub
- Manipulate sample rate, bit depth, and channels programmatically
- Visualize audio waveforms and spectrograms with matplotlib
- Understand the relationship between sample rate, bit depth, and audio quality
The Problem
Every voice agent pipeline starts with audio I/O. You need to read audio from telephony (8kHz μ-law), convert it to the format ASR expects (16kHz PCM), process it, and write TTS output (24kHz PCM). If you can't reliably read, write, and inspect audio files, nothing downstream works.
This lesson builds the audio I/O muscle: read WAV files, understand their properties, generate test audio, and visualize what's inside.
The Concept
The WAV File Format
WAV is the standard uncompressed audio format. It's a RIFF container with a header followed by raw PCM samples:
RIFF Header (12 bytes)
- "RIFF" (4 bytes)
- File size - 8 (4 bytes)
- "WAVE" (4 bytes)
fmt Chunk (24+ bytes)
- "fmt " (4 bytes)
- Chunk size (4 bytes)
- Audio format: 1=PCM, 7=μ-law (2 bytes)
- Num channels (2 bytes)
- Sample rate (4 bytes)
- Byte rate (4 bytes)
- Block align (2 bytes)
- Bits per sample (2 bytes)
data Chunk
- "data" (4 bytes)
- Data size (4 bytes)
- Raw audio samples
A WAV file has sample_rate=16000, bits_per_sample=16, channels=1. What is the byte rate?
16000 × 16 = 256000 bytes/sec
Reading WAV Files with Python
import wave
import numpy as np
def read_wav(filepath):
with wave.open(filepath, 'rb') as wf:
sample_rate = wf.getframerate()
channels = wf.getnchannels()
sample_width = wf.getsampwidth()
n_frames = wf.getnframes()
raw_data = wf.readframes(n_frames)
# Convert bytes to numpy array
if sample_width == 2: # 16-bit
audio = np.frombuffer(raw_data, dtype=np.int16)
elif sample_width == 1: # 8-bit
audio = np.frombuffer(raw_data, dtype=np.uint8)
elif sample_width == 4: # 32-bit
audio = np.frombuffer(raw_data, dtype=np.int32)
if channels > 1:
audio = audio.reshape(-1, channels)
return audio, sample_rate, channels, sample_width
Writing WAV Files
def write_wav(filepath, audio, sample_rate, bit_depth=16):
with wave.open(filepath, 'wb') as wf:
wf.setnchannels(1)
wf.setsampwidth(bit_depth // 8)
wf.setframerate(sample_rate)
wf.writeframes(audio.tobytes())
Visualizing Audio
Unlock the full lesson
You've read the first 2 sections. The rest of this lesson covers Build It, Use It, Ship It, Evaluation, Key Terms, Common Pitfalls, Interview Framing — plus a hands-on lab, quiz, and project artifact.
Create a free account to unlock Phase 0 and Phase 1 of every course — no credit card.
Browse all courses · View pricing · DeVenture Academy