Phase 1: Audio Processing & Streaming · 45 min · Python · scipy · libsamplerate
Audio Resampling and Format Conversion
Resampling is where audio quality lives or dies. Get it wrong and your ASR accuracy drops 20%.
Hiring signal: Resampling quality directly impacts ASR accuracy — a measurable engineering decision.
What you will learn
- Resample audio between sample rates without introducing artifacts
- Use scipy.signal.resample and libsamplerate for high-quality resampling
- Build the μ-law 8kHz → PCM 16kHz/24kHz conversion pipeline
- Handle edge cases: clipping, aliasing, DC offset
The Problem
Telephony audio arrives at 8kHz. ASR needs 16kHz. TTS outputs 24kHz. WebRTC wants 48kHz. Every transition requires resampling — and bad resampling introduces artifacts that degrade ASR accuracy and audio quality.
The most common resampling bug: aliasing. When downsampling without a low-pass filter, high frequencies fold back into the audible range as artifacts. The audio sounds "metallic" or "underwater."
The Concept
Why Resampling Is Needed
The Nyquist Theorem and Aliasing
The Nyquist theorem states: to represent a frequency f, you need a sample rate of at least 2f. If you downsample from 48kHz to 16kHz without filtering, frequencies above 8kHz (the new Nyquist) will alias — fold back into the 0-8kHz range as false frequencies.
You're downsampling from 48kHz to 8kHz. What happens to a 10kHz tone in the audio?
It stays at 10kHz
Upsampling vs Downsampling
| Direction | Risk | Solution |
|---|
| Upsampling (8kHz → 16kHz) | No aliasing (more room) | Interpolation (linear, sinc) |
| Downsampling (48kHz → 16kHz) | Aliasing | Low-pass filter + decimation |
Resampling Methods
| Method | Quality | Speed | Use Case |
|---|
| Linear interpolation | Fair | Fast | Quick prototyping |
scipy.signal.resample | Good | Medium | General purpose (FFT-based) |
scipy.signal.resample_poly | Good | Fast | Polyphase filtering |
| libsamplerate (secret rabbit) | Excellent | Fast | Production quality |
| SoX resampling | Excellent | Medium | Offline processing |
Anti-Aliasing Filter
Before downsampling, apply a low-pass filter at the target Nyquist frequency:
from scipy.signal import resample_poly, butter, sosfilt
def resample_with_antialias(audio, from_rate, to_rate):
if from_rate == to_rate:
return audio
if to_rate < from_rate:
# Downsampling: apply anti-aliasing filter
cutoff = to_rate / 2 # New Nyquist
sos = butter(10, cutoff / (from_rate / 2), output='sos')
audio = sosfilt(sos, audio.astype(np.float32))
# Use polyphase resampling
from scipy.signal import resample_poly
gcd = np.gcd(from_rate, to_rate)
up = to_rate // gcd
down = from_rate // gcd
return resample_poly(audio, up, down).astype(np.int16)
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