WM8960 Audio Codec: High Quality Sound on Raspberry Pi
The WM8960 audio codec by Cirrus Logic is a professional-grade stereo audio chip delivering 24-bit/48kHz audio performance on Raspberry Pi. Unlike the built-in 3.5mm jack (which uses PWM with audible hiss), the WM8960 provides true I2S digital audio with SNR exceeding 98dB — studio-quality sound in a tiny package. This guide covers WM8960 integration with Raspberry Pi for projects ranging from DIY smart speakers to professional audio streaming devices.
WM8960 Specifications Overview
The WM8960 is a full-duplex stereo codec combining both ADC (recording) and DAC (playback) in a single chip. Key specifications that make it ideal for Raspberry Pi audio projects:
- Digital Interface: I2S (data), I2C (control/configuration)
- Audio Resolution: 16/20/24/32-bit depth
- Sample Rates: 8kHz to 48kHz
- Playback SNR: 98dB (Line Out), 96dB (Headphone)
- Recording SNR: 94dB (Line In)
- Outputs: 40mW headphone amp + differential speaker output (1W)
- Inputs: Stereo differential mic input + stereo line input
- Supply voltage: 2.5V – 3.6V
- India module price: ₹400-700 (WM8960-equipped HAT/breakout)
Popular WM8960 modules for Raspberry Pi include the Waveshare WM8960 Audio HAT and various breakout boards. In India, these are available through Robu.in, Electronicscomp.com, and Amazon.in.
Hardware Setup and Wiring
The WM8960 connects via two interfaces simultaneously: I2S for audio data and I2C for codec configuration. Most WM8960 HATs plug directly onto the 40-pin GPIO header. For breakout boards, manual wiring is required.
# WM8960 Breakout Board → Raspberry Pi 4 GPIO
# I2S Connections (Audio Data):
# WM8960 BCLK → Pi GPIO 18 (PCM_CLK, Pin 12)
# WM8960 DACLRC → Pi GPIO 19 (PCM_FS, Pin 35) [LR Clock]
# WM8960 DACDAT → Pi GPIO 21 (PCM_DOUT, Pin 40) [Data to codec]
# WM8960 ADCDAT → Pi GPIO 20 (PCM_DIN, Pin 38) [Data from codec]
#
# I2C Connections (Configuration):
# WM8960 SCL → Pi GPIO 3 (SCL, Pin 5)
# WM8960 SDA → Pi GPIO 2 (SDA, Pin 3)
#
# Power:
# WM8960 VDD → Pi 3.3V (Pin 1 or 17)
# WM8960 GND → Pi GND (Pin 6 or any ground)
#
# Audio Output:
# WM8960 HP_L, HP_R → 3.5mm stereo jack (headphone)
# WM8960 SPK+, SPK- → 8Ω speaker (mono, 1W)
Raspberry Pi Configuration
Setting up the WM8960 requires kernel overlay configuration, ALSA driver installation, and optionally PulseAudio or PipeWire setup for desktop audio.
# Step 1: Enable I2C and I2S in raspi-config
sudo raspi-config
# → Interface Options → I2C → Enable
# → Interface Options → I2S → Enable (if available)
# Step 2: Edit /boot/config.txt
sudo nano /boot/config.txt
# Add these lines:
# dtparam=i2c_arm=on
# dtparam=i2s=on
# dtoverlay=wm8960-soundcard
# Step 3: Install WM8960 driver (Waveshare method)
git clone https://github.com/waveshare/WM8960-Audio-HAT
cd WM8960-Audio-HAT
sudo ./install.sh
sudo reboot
# Step 4: Verify ALSA sees the device
aplay -l
# Should show: WM8960-Audio-HAT
arecord -l
# Should show WM8960 capture device
# Step 5: Set default audio device in .asoundrc
cat > ~/.asoundrc << 'EOF'
pcm.!default {
type asym
playback.pcm "playback"
capture.pcm "capture"
}
pcm.playback {
type plug
slave.pcm "hw:1,0" # WM8960 device number
}
pcm.capture {
type plug
slave.pcm "hw:1,0"
}
EOF
Testing Audio Playback and Recording
# Test playback: Play a WAV file
aplay -D plughw:1,0 /usr/share/sounds/alsa/Front_Center.wav
# Test recording: Record 5 seconds of audio
arecord -D plughw:1,0 -f S16_LE -r 44100 -c 2 -d 5 test_recording.wav
# Playback the recording to verify
aplay -D plughw:1,0 test_recording.wav
# Adjust volume via ALSA mixer
alsamixer -c 1
# Press F4 for capture controls, F3 for playback
# Use arrow keys to adjust levels
# Set headphone volume to 80% via command line
amixer -c 1 sset 'Headphone' 80%
amixer -c 1 sset 'Speaker' 70%
amixer -c 1 sset 'Capture' 90%
Recommended Product
INMP441 MEMS Microphone for ESP32/Raspberry Pi
High-precision I2S MEMS microphone — pairs perfectly with WM8960 for stereo capture setups. Superior to electret mics for voice recognition applications.
Category: Audio & Sound Modules
Python Audio Programming
Python’s PyAudio library provides real-time audio I/O on the WM8960. This enables building voice recorders, audio processing pipelines, and audio streaming applications.
#!/usr/bin/env python3
# WM8960 Audio Recording and Playback with Python
# Install: pip3 install pyaudio wave
import pyaudio
import wave
import struct
import math
import numpy as np
# WM8960 Audio Parameters
SAMPLE_RATE = 44100
CHANNELS = 2
FORMAT = pyaudio.paInt16
CHUNK = 1024
DEVICE_INDEX = 1 # Check with find_devices() first
def find_wm8960_device():
"""Find WM8960 device index in PyAudio"""
p = pyaudio.PyAudio()
for i in range(p.get_device_count()):
dev = p.get_device_info_by_index(i)
if 'WM8960' in dev['name'] or 'wm8960' in dev['name'].lower():
print(f"Found WM8960 at index {i}: {dev['name']}")
return i
p.terminate()
return 1 # Default to device 1
def record_audio(filename, duration_seconds):
"""Record audio from WM8960 microphone input"""
p = pyaudio.PyAudio()
stream = p.open(
format=FORMAT,
channels=CHANNELS,
rate=SAMPLE_RATE,
input=True,
input_device_index=DEVICE_INDEX,
frames_per_buffer=CHUNK
)
print(f"Recording {duration_seconds}s of audio...")
frames = []
for _ in range(0, int(SAMPLE_RATE / CHUNK * duration_seconds)):
data = stream.read(CHUNK, exception_on_overflow=False)
frames.append(data)
stream.stop_stream()
stream.close()
p.terminate()
# Save to WAV file
wf = wave.open(filename, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(SAMPLE_RATE)
wf.writeframes(b''.join(frames))
wf.close()
print(f"Saved to {filename}")
def get_rms_level(data):
"""Calculate RMS audio level for VU meter"""
count = len(data) // 2
shorts = struct.unpack("%dh" % count, data)
sum_squares = sum(s**2 for s in shorts)
rms = math.sqrt(sum_squares / count)
return 20 * math.log10(max(rms, 1) / 32768) # dBFS
def live_vu_meter():
"""Real-time VU meter display"""
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, channels=1, rate=SAMPLE_RATE,
input=True, frames_per_buffer=CHUNK,
input_device_index=DEVICE_INDEX)
print("Live VU Meter (Ctrl+C to stop):")
try:
while True:
data = stream.read(CHUNK, exception_on_overflow=False)
db = get_rms_level(data)
# Visual bar: -60dB to 0dB
bar_len = int(max(0, 60 + db))
bar = '=' * bar_len
color = 'RED' if db > -6 else 'YELLOW' if db > -18 else 'GREEN'
print(f"r[{bar:<60}] {db:+.1f}dBFS ({color})", end='')
except KeyboardInterrupt:
pass
stream.close()
p.terminate()
if __name__ == '__main__':
record_audio('/tmp/test.wav', 5)
DIY Smart Speaker Project
Combine WM8960 with Raspberry Pi Zero 2W to build a compact smart speaker with offline voice recognition using Vosk or PocketSphinx:
#!/usr/bin/env python3
# Offline Voice Command Recognition with WM8960 + Raspberry Pi
# Install: pip3 install vosk pyaudio
# Download model: https://alphacephei.com/vosk/models (vosk-model-small-en-in for Indian English)
from vosk import Model, KaldiRecognizer
import pyaudio
import json
MODEL_PATH = "/home/pi/vosk-model-small-en-in-0.4"
def voice_command_listener():
model = Model(MODEL_PATH)
recognizer = KaldiRecognizer(model, 16000)
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1,
rate=16000, input=True, frames_per_buffer=4000,
input_device_index=1) # WM8960
print("Listening for voice commands (Indian English)...")
while True:
data = stream.read(4000, exception_on_overflow=False)
if recognizer.AcceptWaveform(data):
result = json.loads(recognizer.Result())
text = result.get('text', '')
if text:
print(f"Heard: {text}")
process_command(text)
def process_command(text):
text = text.lower()
if 'lights on' in text: print("→ Turning lights ON")
elif 'lights off' in text: print("→ Turning lights OFF")
elif 'play music' in text: print("→ Starting music playback")
elif 'stop' in text: print("→ Stopping")
voice_command_listener()
Recommended Product
AI Thinker ESP32-A1S WiFi+BT Audio Development Board
Built-in audio codec with ESP32 — an excellent alternative to WM8960+Raspberry Pi for standalone smart speaker and audio streaming projects.
Category: Audio & Sound Modules
WM8960 vs Other Audio Codecs
| Codec | SNR | Sample Rate | Built-in Amp | India Price |
|---|---|---|---|---|
| WM8960 | 98dB | 8-48kHz | 40mW HP + 1W SPK | ₹400-700 |
| PCM5102 | 106dB | 8-384kHz | No (DAC only) | ₹250-450 |
| MAX98357 | 77dB | 8-96kHz | 3W Class D | ₹150-300 |
| ES8388 | 90dB | 8-96kHz | No | ₹300-500 |
The WM8960 wins for all-in-one designs needing both input and output with built-in headphone/speaker amplification. For pure playback with maximum dynamic range, PCM5102 is superior but requires an external amplifier.
Recommended Product
Analog Sound Sensor Microphone Module
Budget alternative for audio input testing on Arduino-based projects when WM8960 codec-level performance is not required.
Category: Audio & Sound Modules
Frequently Asked Questions
Q: Does WM8960 work with Raspberry Pi Zero?
A: Yes, WM8960 works with all Raspberry Pi models including Zero/Zero 2W. The Pi Zero’s 40-pin GPIO header supports I2S. The Waveshare WM8960 HAT fits all standard GPIO headers. Processing power for audio streaming is sufficient even on Pi Zero 2W.
Q: Can I use WM8960 with Raspberry Pi 5?
A: Yes, but the device tree overlay may need updates. As of 2025, community-maintained overlays support Pi 5. Check the WM8960-Audio-HAT GitHub repository for the latest compatibility patches. Pi 5’s I2S implementation differs slightly from Pi 4.
Q: Why does my WM8960 recording sound distorted?
A: Common causes: (1) Gain set too high in alsamixer — reduce Capture gain to 60-70%, (2) Clipping on loud sounds — check for overload LEDs on module, (3) Sample rate mismatch between application and ALSA config, (4) Ground loop between Pi power supply and audio output — use filtered supply.
Q: What sample rate should I use for voice recognition?
A: Most voice recognition engines (Vosk, PocketSphinx, Google STT) use 16kHz mono audio. Record at 16kHz single channel for voice input to minimize CPU load on Pi Zero. For music, use 44.1kHz or 48kHz stereo.
Q: Can WM8960 do simultaneous playback and recording (full duplex)?
A: Yes — this is one of WM8960’s key advantages. It supports full-duplex operation at any supported sample rate, enabling applications like voice conferencing, karaoke (vocals over backing track), and active noise cancellation prototypes.
Add comment