If you are trying to get clean sound from a Raspberry Pi Model B, the direct answer is to bypass the onboard 3.5mm jack entirely and use an I2S DAC breakout board like the Adafruit MAX98357A (Product ID: 3006).

Let’s clear up the naming first: in 2026, "Model B" practically refers to the Raspberry Pi 4 Model B. The original 2012 Model B is obsolete, and the newer Pi 5 dropped the 3.5mm jack altogether. The Pi 4 Model B’s onboard 3.5mm audio is driven by PWM (Pulse Width Modulation), not a true DAC. This results in a notoriously high noise floor, a 60Hz hum, and terrible signal-to-noise ratio (SNR) that ruins both music playback and embedded voice-assistant projects. To get true 16-bit/24-bit digital-to-analog conversion with zero USB latency overhead, you need to route the I2S (Inter-IC Sound) bus directly from the Pi’s GPIO header to a dedicated DAC chip.

The Raspberry Pi Model B Audio Output Decision Matrix

Before soldering, you need to choose your audio routing path. Here is the decision framework for embedded Pi audio, terminating in the optimal hardware pick for custom builds.

Audio Method Hardware Example Noise Floor / SNR CPU / Bus Overhead Best Use Case
Onboard 3.5mm (PWM) Pi 4 Model B native jack Poor (~60dB SNR, high hum) High (PWM uses CPU cycles) Basic system beeps only
USB Audio Dongle Apple USB-C to 3.5mm adapter Good (~95dB SNR) Medium (USB polling latency) Desktop media centers
I2S DAC HAT HiFiBerry DAC+ Standard Excellent (~110dB SNR) Low (Direct hardware bus) Audiophile / Line-out
I2S DAC Breakout (PICK) Adafruit MAX98357A (PID 3006) Great (~101dB SNR, 3.2W Amp) Low (Direct hardware bus) Embedded DIY, robotics, portable speakers
The Concrete Pick: For embedded projects where you are wiring your own speakers or building a custom enclosure, the Adafruit MAX98357A I2S Breakout is the definitive choice. It combines a high-quality 24-bit I2S DAC with a 3.2W Class-D amplifier on a single board, costing around $7.95. It eliminates the need for a separate amp board and avoids the mechanical bulk of a full HAT.

Parts List & Hardware Pin Mapping

This guide targets the Raspberry Pi 4 Model B (4GB or 8GB variant) running Raspberry Pi OS (64-bit, Bookworm or newer). The pinout also applies directly to the Raspberry Pi 5.

Bill of Materials

  • Microcontroller: Raspberry Pi 4 Model B (4GB+ recommended for DSP tasks)
  • DAC/Amp: Adafruit MAX98357A I2S Breakout Board (PID 3006)
  • Speaker: 4Ω or 8Ω passive speaker (3W max rating)
  • Wiring: 5x female-to-female jumper wires (silicone stranded preferred)

GPIO Pin Mapping Table (BCM Numbering)

The I2S protocol requires three shared signal lines plus power and ground. Ensure your Pi is powered off and unplugged before wiring.

MAX98357A Pin Pi 4 Model B GPIO (BCM) Pi 40-Pin Header Physical Pin Function Description
VIN 5V Power Pin 2 or 4 Power supply (3.5V - 5.5V acceptable)
GND Ground Pin 6 Common ground reference
BCLK GPIO 18 (PCM_CLK) Pin 12 Bit Clock (synchronizes data bits)
LRC GPIO 19 (PCM_FS) Pin 35 Left/Right Clock (Word Select)
DIN GPIO 21 (PCM_DOUT) Pin 40 Serial Audio Data In
Bench Tip: Gain and Shutdown Pins
The MAX98357A has two extra pads: GAIN and SD. Leave the SD (Shutdown) pad unconnected; the internal pull-up keeps the amp enabled. Solder the GAIN pad to GND to set the amplifier to 9dB (safest for small desktop speakers). Leaving it floating defaults to 15dB, which can clip and distort smaller 4Ω drivers.

Software Setup & ALSA Configuration

Raspberry Pi OS uses ALSA (Advanced Linux Sound Architecture) under the hood. To make the kernel recognize the I2S breakout, you must load the correct device tree overlay.

  1. Edit the boot configuration file. In modern Raspberry Pi OS (Bookworm and later), the config file moved to /boot/firmware/. Open it with nano:
    sudo nano /boot/firmware/config.txt
  2. Enable the I2S bus and load the overlay. Add or uncomment these lines at the bottom of the file:
    dtparam=i2s=on
    dtoverlay=max98357a
    Note: If you are using a generic I2S DAC without a specific overlay, use dtoverlay=hifiberry-dac instead. See the official Raspberry Pi Device Tree Documentation for a full list of audio overlays.
  3. Reboot the Pi to apply the device tree changes:
    sudo reboot
  4. Verify ALSA sees the hardware. Run aplay -l. You should see card 0: max98357a or card 0: sndrpihifiberry listed.
  5. Install Python audio dependencies. We will use sounddevice (a PortAudio wrapper) and scipy for WAV parsing:
    sudo apt update
    sudo apt install libportaudio2 python3-scipy
    pip3 install sounddevice numpy

Complete Python Audio Playback Code

This script targets the Raspberry Pi 4 Model B. It dynamically queries ALSA for the I2S device, plays a WAV file if provided, and falls back to generating a 440Hz sine wave test tone if the file is missing. This guarantees you can verify your wiring without hunting for audio assets.

import numpy as np
import sounddevice as sd
import scipy.io.wavfile as wav
import sys
import os

# --- Configuration & Pin/Device Definitions ---
TARGET_DEVICE_KEYWORD = "max98357a"  # Fallback: "hifiberry" or "sndrpi"
SAMPLE_RATE = 44100
DEFAULT_WAV_FILE = "test_audio.wav"

def find_i2s_device():
    """Queries ALSA/PortAudio to find the I2S DAC index."""
    devices = sd.query_devices()
    for i, dev in enumerate(devices):
        if TARGET_DEVICE_KEYWORD in dev['name'].lower() and dev['max_output_channels'] > 0:
            return i
    # Fallback: Look for generic I2S/HifiBerry names
    for i, dev in enumerate(devices):
        if ('hifiberry' in dev['name'].lower() or 'sndrpi' in dev['name'].lower()) and dev['max_output_channels'] > 0:
            return i
    return None

def generate_sine_wave(freq=440.0, duration=3.0, sr=SAMPLE_RATE):
    """Generates a fallback test tone if no WAV file is present."""
    t = np.linspace(0, duration, int(sr * duration), False)
    # Generate stereo sine wave (MAX98357A is mono, but ALSA often expects stereo streams)
    wave = np.sin(2 * np.pi * freq * t)
    return np.column_stack((wave, wave)) * 0.5  # 50% volume to protect speakers

def main():
    device_idx = find_i2s_device()
    if device_idx is None:
        print("[FATAL] Could not find I2S audio device in ALSA.")
        print("Run 'aplay -l' to verify the dtoverlay loaded correctly.")
        sys.exit(1)

    print(f"[INFO] Targeting Audio Device {device_idx}: {sd.query_devices(device_idx)['name']}")

    audio_data = None
    sr = SAMPLE_RATE

    # Attempt to load WAV file, fallback to sine wave
    if os.path.exists(DEFAULT_WAV_FILE):
        print(f"[INFO] Loading {DEFAULT_WAV_FILE}...")
        sr, audio_data = wav.read(DEFAULT_WAV_FILE)
        if audio_data.ndim == 1:
            audio_data = np.column_stack((audio_data, audio_data)) # Mono to Stereo
    else:
        print(f"[WARN] {DEFAULT_WAV_FILE} not found. Generating 440Hz test tone.")
        audio_data = generate_sine_wave()

    # Normalize data to float32 [-1.0, 1.0] for PortAudio
    if audio_data.dtype != np.float32:
        max_val = np.iinfo(audio_data.dtype).max if np.issubdtype(audio_data.dtype, np.integer) else 1.0
        audio_data = (audio_data / max_val).astype(np.float32)

    try:
        print("[INFO] Starting audio stream...")
        sd.play(audio_data, samplerate=sr, device=device_idx, blocking=True)
        print("[INFO] Playback complete.")
    except sd.PortAudioError as e:
        print(f"[ERROR] PortAudio failed: {e}")
        print("Check if another process (like PulseAudio/PipeWire) is hogging the ALSA device.")
        sys.exit(2)
    except Exception as e:
        print(f"[ERROR] Unexpected failure: {e}")
        sys.exit(3)

if __name__ == "__main__":
    main()

Debugging: "ALSA: Couldn't open audio device" & Other Failures

When working with ALSA and I2S on the Pi, things will break. Here are the first three things to check when audio fails, followed by a breakdown of specific error strings.

The First Three Checks

  1. Verify the Device Tree Overlay: Run vcdbg log msg 2>&1 | grep dt or simply aplay -l. If the MAX98357A doesn't show up as a sound card, your config.txt syntax is wrong, or you edited the wrong file (remember, it's /boot/firmware/config.txt on modern OS).
  2. Check BCLK/LRCLK Swap: If your code runs without errors but you hear only harsh white noise or static, you have almost certainly swapped the BCLK (GPIO 18) and LRCLK (GPIO 19) wires. The DAC is misinterpreting the clock timing.
  3. Kill Audio Daemons: Raspberry Pi OS runs PipeWire or PulseAudio by default, which can lock the ALSA hardware device. Run systemctl --user stop pipewire pulseaudio before running raw Python ALSA scripts.

Exact Error Strings & Ranked Causes

Exact Error String Ranked Causes (Most Likely First) Fix
sounddevice.PortAudioError: Error opening OutputStream: Invalid device [PaErrorCode -9996] 1. Device index not found.
2. dtoverlay missing in config.txt.
3. Targeting an input-only device.
Run python3 -m sounddevice to print all devices. Update the TARGET_DEVICE_KEYWORD in the script to match the exact string ALSA reports.
ALSA lib pcm_dmix.c:1032:(snd_pcm_dmix_open) unable to open slave 1. PipeWire/PulseAudio has exclusive lock.
2. Another script is actively playing audio.
Stop the audio daemon (systemctl --user stop pipewire) or configure PortAudio to use the plug ALSA device instead of hw.
ValueError: could not broadcast input array from shape (X,) into shape (Y,) 1. WAV file is mono, but PortAudio is trying to map it to a 2-channel (stereo) I2S stream. The provided code handles this via np.column_stack, but if writing your own, ensure you duplicate mono arrays into a 2D stereo matrix before passing to sd.play().

Extending and Simplifying the Build

Once you have clean I2S audio output, you will inevitably want to tweak the system. Here is how to scale the project up or down based on your final application.

How to Extend (Scale Up)

  • Add Hardware Volume Control: The MAX98357A lacks a digital volume register; it only has hardware gain pads. To add software volume control without eating CPU cycles in Python, insert an ALSA softvol plugin in your ~/.asoundrc file. This creates a virtual mixer control that ALSA handles at the kernel level before passing bits to the I2S bus.
  • Integrate a DSP: If you are building a smart speaker or room-correction system, route the I2S output through an ADAU1701 SigmaDSP chip before the amplifier. This allows you to apply EQ, crossovers, and limiters in hardware.
  • Add I2S Input (Microphone): To make this a two-way voice assistant, wire an INMP441 MEMS microphone to the I2S input pins (GPIO 19/20) and use the dtoverlay=googlevoicehat-soundcard overlay, which supports simultaneous I2S playback and capture.

How to Simplify (Scale Down)

If wiring five GPIO pins and debugging ALSA device tree overlays feels like overkill for a simple kiosk or notification speaker, abandon I2S and use a USB Audio Adapter. A $10 generic CM108-based USB sound card will show up as a standard USB audio class device. It requires zero config.txt edits, works instantly with PipeWire, and bypasses the Pi's noisy onboard PWM circuitry entirely. However, you sacrifice the ultra-low latency and hardware synchronization that I2S provides for robotics and DSP applications.

For any embedded project requiring reliable, low-latency, and noise-free audio on the Raspberry Pi 4 Model B, the I2S route via the MAX98357A remains the undisputed benchmark. Wire it correctly, verify your device tree overlays, and let the hardware bus do the heavy lifting.