Audio
Spec hygiene (canonical-spec.md rule 1). This document does not restate canonical values (sample rate, register count, speaker spec). Those live in the Canonical Hardware Specification. Any value inline is a bug — fix it.
The KN-86’s audio chain produces YM2149 PSG-style synthesis (3 tone channels + noise + envelope generator, 14-register Yamaha programming model — software emulation, not original silicon) at 44.1 kHz mono PCM, output through a WM8960 stereo codec (stereo DAC + class-D speaker amp + stereo headphone amp on one chip) into a single mono full-range speaker, with a switched 3.5 mm TRS jack for stereo headphones. The path is stereo-capable — mono sum to the built-in speaker, stereo to the headphone jack (per ADR-0054).
For canonical chip family, channel count, register count, sample rate, and speaker spec, see Canonical Hardware Specification — Audio + Speaker rows.
Signal chain
Section titled “Signal chain”nOSh (Pi) --UART PSG_REG_WRITE--> Pi Pico 2 firmware | | YM2149 emulator | (full register state + | envelope + LFSR noise) | I2S (PIO + DMA, 44.1 kHz PCM) + I²C (register config) | v WM8960 stereo codec (stereo DAC + ~1 W class-D speaker amp + stereo headphone amp; I²C-configured) | speaker amp out | headphone amp out (stereo) +-------------+-------------+ | | v v Gikfun 2" 4 Ω 5 W speaker 3.5 mm TRS jack (switched, stereo) (mono, built-in) | ^ plug inserted? -- yes --> headphones | | +----------- no ------------+ (speaker auto-cuts on plug insert)YM2149 PSG (Pico 2 firmware)
Section titled “YM2149 PSG (Pico 2 firmware)”Per ADR-0017, PSG synthesis runs as firmware on the Pi Pico 2, not as a userspace process on the Pi:
- Pico maintains the full YM2149 register state (14 registers, envelope generator, LFSR noise).
- Pi sends register-write commands over UART (
PSG_REG_WRITE,PSG_BULK_WRITE,PSG_RESET— seesoftware/api-reference/grammars/coprocessor-protocol.md). - Pico applies them and continues generating samples at 44.1 kHz.
- Output to the WM8960 codec via PIO-driven I2S + DMA.
Why Pico-side, not Pi-side. The argument for Pi-side was “an A53 @ 1 GHz is overkill for a 1 MHz logic chip’s worth of synthesis.” The argument for Pico-side won: synthesis cost isn’t the issue — output cadence is. A 44.1 kHz I2S sample stream cannot underrun. Once Pi rendering pressure rises (Clip playback, algorithmic art, large bitmap blits), the audio thread loses scheduling slots and underruns become the failure mode. Dedicated silicon eliminates the failure mode by construction.
In the desktop emulator, PSG synthesis stays in the runtime (runtime/src/psg.c) and routes through the in-process coproc.c stub — same FFI surface, no real Pico.
WM8960 (stereo codec: DAC + speaker amp + headphone amp)
Section titled “WM8960 (stereo codec: DAC + speaker amp + headphone amp)”WM8960 stereo codec breakout. One chip integrates a stereo DAC, a ~1 W class-D speaker amplifier, and a stereo headphone amplifier (per ADR-0054). It is fed I2S by the Pico 2 (same source as the prior MAX98357A) and, unlike the strap-pin MAX98357A, requires I²C register configuration at init. Its speaker amp is ~1 W — lower than the MAX98357A’s ~3.2 W ceiling — an accepted trade for a handheld where built-in audio is a layer, not a headline (ADR-0054); the 2″ 4 Ω full-range driver partly offsets the lower amp power.
| Signal | From | Notes |
|---|---|---|
| BCLK | Pico 2 GPIO (TBD at F2 firmware bring-up) | I2S bit clock. |
| LRCLK / WS | Pico 2 GPIO (TBD at F2 firmware bring-up) | I2S word select / left-right clock. |
| DIN | Pico 2 GPIO (TBD at F2 firmware bring-up) | I2S serial data. |
| SDA | I²C master (TBD at bring-up — Pico expected) | I²C data for codec register config. Master (Pi vs Pico) + codec address finalized at bring-up (ADR-0054). |
| SCL | I²C master (TBD at bring-up — Pico expected) | I²C clock for codec register config. |
| VIN | 5 V rail (shared with Pi VIN) | See power.md. |
| GND | Common ground | Common ground domain with Pi + Pico. |
The pre-ADR-0017 wiring (Pi GPIO I2S pins + hifiberry-dac device-tree overlay) is superseded. Pi-side audio device-tree overlay is no longer required — the Pi does not generate audio. Specific Pico I2S GPIOs and the I²C master/address are finalised at bring-up — TBD, will live with the Pico 2 coprocessor firmware under hosts/device/firmware/ in the kn-86 monorepo. The expectation is that the Pico owns the I²C link so the whole audio path stays on the coprocessor, but the master is not hard-committed (ADR-0054).
The GWP-619 OLED 8080 bench harness was selected to keep an I2S route available for the codec bring-up. Before soldering the codec, freeze the Pico firmware pin map (I2S plus I²C) and keep BCLK / LRCLK / DIN outside the OLED data/control set.
Speaker and jack
Section titled “Speaker and jack”- Speaker — Gikfun 2″ (≈50 mm) full-range driver, 4 Ω, 5 W. Mono (one driver — built-in audio is mono). Mounts in a base-panel pocket behind a small grille cutout (see
enclosure.md). Sourced as a pack of 2 (Gikfun EK1949); the device uses one, the second is a spare. - 3.5 mm TRS PCB-mount jack — switched, stereo, canonical. Wired stereo off the WM8960’s headphone-amp output (canonical per ADR-0054). The built-in speaker auto-cuts on plug insert — via the jack’s switched normally-closed contact and/or the codec’s jack-detect (exact mechanism finalized at bring-up). The speaker amp feeds the driver; the headphone amp feeds the jack; both are on the one WM8960.
A 3.5 mm TRRS PCB-mount 4-pole jack (BOM line 16) handles linked-play between two decks — separate from the headphone jack.
Latency budget
Section titled “Latency budget”End-to-end audio latency (nOSh-issued PSG register write → audible tone): target <30 ms (ADR-0017 Known Unknown #5; software/api-reference/grammars/coprocessor-protocol.md §7).
Dominated by:
- UART transit at 1 Mbps — hundreds of µs.
- Pico command processing — tens of µs.
- I2S output buffer depth — configurable; 5–20 ms typical.
Bring-up at Stage 1c measures real round-trip and either confirms the budget or escalates.
Audio current draw is part of the post-coprocessor envelope on the main 5 V rail (Pi + Pico + WM8960 all draw from it). See power.md for the full envelope and CLAUDE.md Battery row for the runtime band. The WM8960’s class-D speaker amp is efficient — typical draw scales with output volume; quiet output is single-digit mA. WM8960 draw differs from the prior MAX98357A and is re-measured at bring-up per ADR-0054.
Mechanical
Section titled “Mechanical”The WM8960 codec breakout mounts on the interior plate near the speaker. The speaker mounts in a base-panel pocket; the TRS and TRRS jacks are panel-mount through cutouts in the base panel. The 2″ driver is deeper (~25 mm) than the prior 28 mm driver — its seat and clearance against the 18650 pack are confirmed at bring-up (ADR-0054). See enclosure.md.
Bring-up
Section titled “Bring-up”Stage 2 in build-specification.md §4. Run Stage 1c first (coprocessor.md) — the Pico must be alive before audio can be brought up against its I2S output.
- Solder the WM8960 codec breakout to the Pico 2 I2S pins (BCLK / LRCLK / DIN) and the I²C control pins (SDA / SCL) plus 5 V (shared 5V rail) and GND. Specific Pico I2S GPIOs and the I²C master/address are finalised at bring-up (Pico expected to own I²C).
- Configure the WM8960 over I²C at init (register setup) — this step is new versus the strap-pin MAX98357A. Lock the I²C master and codec address.
- Wire the Gikfun 2″ speaker to the codec’s speaker-amp output and the 3.5 mm TRS jack (stereo) to the headphone-amp output. Confirm the speaker auto-cuts on plug insert (switched-jack contact and/or codec jack-detect).
- Test-play a YM2149 reference pattern: nOSh issues
PSG_REG_WRITEframes over UART to set up channel A with a steady tone (e.g. 440 Hz square), thenPSG_RESETto silence. Validate clean audio on the speaker, clean stereo on headphones, and clean silence on reset.
PCM voice bark
Section titled “PCM voice bark”A separate non-PSG path — short PCM sound clips for distinct moments — is documented at software/runtime/pcm-voice-bark.md. PCM voice bark shares the WM8960 output stage but bypasses the YM2149 emulator on the Pico (PCM samples DMA’d straight to I2S).
Sourcing
Section titled “Sourcing”BOM lines in sourcing-guide.md:
- 13 — WM8960 stereo codec breakout, 1× (~$10). Waveshare / generic (Adafruit does not stock a WM8960 breakout — Waveshare’s WM8960 audio HAT/board or a generic WM8960 breakout is the common source; characterise before committing).
- 14 — Gikfun 2″ (≈50 mm) full-range speaker, 4 Ω, 5 W, qty 1 (+1 spare from the pack of 2 — Gikfun EK1949, Amazon).
- 15 — 3.5 mm TRS PCB-mount switched stereo jack, 2× ($1 ea). Adafruit / Amazon.
- 16 — 3.5 mm TRRS PCB-mount 4-pole jack (linked-play), 1× ($1). Adafruit.
See also
Section titled “See also”coprocessor.md— Pico 2 hosts the PSG firmware.software/api-reference/grammars/coprocessor-protocol.md— UART frame layouts forPSG_*commands.software/runtime/pcm-voice-bark.md— non-PSG PCM voice clip path.build-specification.md§4 Stage 2 — bring-up checklist.