Skip to content

ADR-0054: Audio subsystem — WM8960 stereo codec, 2″ full-range speaker, canonical headphone jack

The prior KN-86 audio chain was a MAX98357A mono I2S DAC + class-D amplifier driving a 28 mm round driver, 8 Ω, 2 W, mono. YM2149 PSG synthesis runs on the Pi Pico 2 coprocessor (per ADR-0017); the Pico streams 16-bit PCM to the MAX98357A over I2S. The MAX98357A is strap-pin configured — gain and channel are set by hardware straps, so the chip needs no I²C register configuration.

A 3.5 mm switched TRS headphone jack existed only in the bench plan and was explicitly marked non-canonical pending Josh’s sign-off (the “Spec reconciliation” caveat in device/hardware/audio.md). The parent canonical-spec.md Canonical Hardware Specification did not carry it.

Two things motivated a rethink now:

  1. Better on-device sound. A 28 mm, 2 W driver is small and thin-sounding. A larger full-range driver gives the built-in speaker meaningfully more body and SPL headroom in a handheld the size of a Pelican 1170.
  2. A real stereo path on headphones. The realistic default for a portable deck is screen-on / sound-off — audio is a layer, not a requirement (cf. the DEPTHCHARGE de-hype, merged: DEPTHCHARGE no longer requires stereo-by-ear). But when an operator does plug in headphones, a codec that drives both a speaker amp and a stereo headphone amp gives a proper stereo image off one chip, and promotes the headphone jack from bench-only to a committed product surface.
  • Built-in audio stays mono — one internal speaker. Two drivers ~10 cm apart in a handheld give almost no stereo image, so on-device stereo is not worth the space.
  • The Pico owns the audio path (I2S out per ADR-0017). Any new codec-config duty (I²C) should stay on the coprocessor so the whole audio chain lives on one MCU, unless bring-up finds a reason to move it to the Pi.
  • The 18650 pack is the dominant space claim in the Pelican interior (ADR-0038); a deeper speaker must not fight it.

Replace the MAX98357A + 28 mm 8 Ω 2 W mono speaker with a WM8960 stereo codec driving one Gikfun 2″ (≈50 mm) full-range 4 Ω 5 W driver for built-in mono audio, plus a canonical 3.5 mm switched stereo headphone jack off the codec’s headphone-amp output.

Concrete commitments:

  1. Speaker: one Gikfun 2″ (≈50 mm) full-range driver, 4 Ω, 5 W, single (mono built-in). Sourced as the Amazon Gikfun EK1949 pack of 2 — the device uses one; the second is a spare. Built-in audio remains mono (one driver).
  2. Codec/amp: WM8960 stereo codec. One chip provides a stereo DAC + a ~1 W class-D speaker amplifier + a stereo headphone amplifier. It is fed I2S by the Pico 2 (same I2S source as before). Unlike the strap-pin MAX98357A, the WM8960 requires I²C register configuration. The I²C master (Pi vs Pico) and the codec’s I²C address are finalized at bring-up; the expectation is that the Pico owns the I²C link to keep the whole audio path on the coprocessor, but this ADR does not hard-commit the master.
  3. Headphone jack: canonical. The 3.5 mm switched TRS jack — previously bench-only and non-canonical — is now canonical, wired stereo off the WM8960’s headphone-amp output. The built-in speaker auto-cuts when a plug is inserted (switched-jack normally-closed contact and/or the codec’s jack-detect — the exact mechanism is finalized at bring-up).
  4. The audio path is stereo-capable: mono sum to the built-in speaker, stereo to the headphone jack. (Optional per-voice PSG panning / ABC-ACB “Turbosound”-style stereo on the Pico mixer is possible but deferred — not required by any launch cart; see Consequences.)

Option A: 2× MAX98357A driving two speakers for on-device stereo

Section titled “Option A: 2× MAX98357A driving two speakers for on-device stereo”

Keep the MAX98357A family, add a second amp + second driver, get stereo on the built-in speakers.

Rejected because: two drivers ~10 cm apart in a handheld produce almost no perceptible stereo image, and the 2″ driver is ~25 mm deep — a second one doubles a space claim that already fights the 18650 pack (ADR-0038). The cost (board area, BOM, mechanical volume) buys a stereo effect the operator cannot hear at handheld distance.

Option B: Keep the MAX98357A for the speaker + a separate dedicated stereo DAC/headphone-amp for the jack

Section titled “Option B: Keep the MAX98357A for the speaker + a separate dedicated stereo DAC/headphone-amp for the jack”

Retain the strap-pin MAX98357A for the built-in speaker, add a second dedicated stereo DAC + headphone amplifier just for the jack.

Rejected because: two chips and more board area to deliver what one codec delivers. The single-chip WM8960 (speaker amp + stereo headphone amp + stereo DAC) wins on integration even though its speaker amp is lower-power than the MAX98357A’s.

Option C: TAS5805M / TAS5825M stereo I²S DSP amplifier

Section titled “Option C: TAS5805M / TAS5825M stereo I²S DSP amplifier”

A modern stereo class-D I²S amp with onboard DSP.

Rejected because: these parts are 20–30 W into a hungry PVDD rail — massive overkill for a 2″ full-range driver in a battery handheld, and they still don’t integrate the headphone-amp path the codec gives for free.

One chip = stereo DAC + ~1 W class-D speaker amp + stereo headphone amp, fed I2S by the Pico, configured over I²C.

Chosen because: it collapses the built-in speaker amp and the stereo headphone path into a single part, gives a genuine stereo image where stereo is actually audible (headphones), and keeps the audio chain on the existing Pico I2S source. The accepted cost is a lower speaker-amp ceiling (~1 W vs the MAX98357A’s ~3.2 W) and a new I²C config duty — both acceptable for a handheld (see below).


The WM8960’s speaker amplifier is ~1 W, quieter than the MAX98357A’s ~3.2 W into 8 Ω. This is the honest cost of the codec choice. It is acceptable because (1) the realistic default for the deck is screen-on / sound-off — built-in audio is a layer, not a headline feature; (2) the larger 2″ 4 Ω full-range driver is more efficient and fuller-sounding than the old 28 mm 8 Ω driver, which partly offsets the lower amp power; and (3) the win the codec buys — a real stereo headphone path from a single chip — is where audio quality actually matters for a solo operator. Against Options A/B/C, WM8960 is the only one-chip path to both a built-in speaker amp and a stereo headphone amp, and it reuses the existing Pico I2S source. The new I²C config step is a few lines of init and ~2 Pico pins; trivial against the integration it buys.


  • One chip does speaker + stereo headphones. Stereo DAC + class-D speaker amp + stereo headphone amp in a single WM8960 — fewer parts than a MAX98357A-plus-separate-headphone-amp split.
  • Real stereo where it’s audible. The headphone jack is stereo off the codec’s dedicated headphone amp — a proper image for a solo operator, versus a meaningless on-device stereo pair.
  • Bigger, fuller built-in speaker. The 2″ full-range 4 Ω driver has more body and SPL headroom than the 28 mm 8 Ω driver.
  • Headphone jack is now canonical. The bench-only, non-canonical jack becomes a committed product surface — the audio.md “Spec reconciliation” caveat is retired.
  • Audio chain stays on the Pico. Same I2S source; the codec is fed by the same coprocessor path (ADR-0017).
  • Lower speaker-amp power. WM8960’s speaker amp is ~1 W vs the MAX98357A’s ~3.2 W — quieter built-in audio. Accepted for a handheld where sound is a layer.
  • New I²C config duty. The WM8960 must be configured over I²C at init (register setup), where the MAX98357A needed none. This adds an I²C master duty (~2 pins) — expected on the Pico. coprocessor-firmware.md’s “No I²C config required” statement becomes false and is corrected.
  • Pico pin budget grows slightly. The Pico gains an I²C master (~2 pins) for codec config on top of the I2S output pins. The pin budget is still fine, but the Pico pin map (I2S + I²C) must be frozen before soldering.
  • Mechanical re-check. The 2″ / ~25 mm-deep driver is larger and deeper than the 28 mm driver — its seat in the base-panel speaker pocket and its clearance against the 18650 pack are confirmed at bring-up (enclosure.md).
  • Electrical load change. 4 Ω (was 8 Ω) matches the codec/amp; higher current per watt, but low absolute in this envelope.
  • Stereo-capable path, panning deferred. The path is now stereo-capable (mono sum to speaker, stereo to headphones). Per-voice PSG panning / ABC-ACB “Turbosound”-style stereo on the Pico mixer is a deferred possibility, not specified here and not required by any launch cart.
  • Freeze the Pico pin map (I2S + I²C) before hard-soldering the codec.
  • Re-measure amp draw for the power envelope (ADR-0038) — WM8960 draw differs from the MAX98357A.

Documentation Updates (REQUIRED — part of the decision, not aspirational)

Section titled “Documentation Updates (REQUIRED — part of the decision, not aspirational)”

Per canonical-spec.md Spec Hygiene Rule 3, this ADR lands with every dependent doc updated in the same PR:


Bring-up validations, tracked against the audio stage of device/hardware/build-specification.md §4:

  1. Codec I²C bring-up. Confirm the WM8960 configures over I²C from the chosen master (Pico expected); lock the I²C master and address.
  2. Speaker fit + clearance. Confirm the Gikfun 2″ (~25 mm deep) driver seats in the base-panel speaker pocket and clears the 18650 pack (enclosure.md).
  3. Headphone output. Validate stereo output off the WM8960 headphone amp into the 3.5 mm jack.
  4. Speaker auto-cut on insert. Confirm the built-in speaker mutes when a plug is inserted (switched-jack contact and/or codec jack-detect — lock the mechanism).
  5. Freeze the Pico pin map (I2S + I²C) before hard-soldering the codec.
  6. Re-measure amp draw for the power envelope (ADR-0038) — WM8960 draw differs from the MAX98357A; populate the power-idle.md measured-draw rows.

The prior audio chain was a strap-pin MAX98357A mono amp driving a small 28 mm speaker, with a headphone jack that only ever lived in the bench plan. Two realizations moved us: a portable deck’s honest default is screen-on / sound-off, so audio is a layer rather than a headline — but when an operator plugs in headphones, they deserve real stereo, and on-device stereo across two drivers 10 cm apart is inaudible. A single WM8960 codec resolves both: it drives a bigger 2″ full-range built-in speaker (mono, where mono is all you’d hear anyway) and a stereo headphone amp off the same chip, fed by the same Pico I2S source. The costs are honest — the codec’s speaker amp is quieter than the MAX98357A’s, and unlike the strap-pin part it needs I²C configuration (a new ~2-pin duty, expected on the Pico) — and both are fine for a handheld. The headphone jack graduates from bench-only to canonical, stereo, with the speaker auto-cutting on insert. Per-voice PSG panning across the stereo field is now possible on the Pico mixer, but no launch cart needs it, so it stays deferred. Future readers should take three things: built-in audio is deliberately mono and modest; the stereo win is on headphones, from one chip; and the WM8960’s I²C-config requirement is the one genuinely new firmware duty this change introduces.