Skip to content

WavAmpster Station Package Format

packaging tool, the runtime player, or a cart that ships its own stations.

Status: v1 (GWP-599 / GWP-676). Concretizes the approved WavAmpster design (deleted 2026-07-29; recover from git history).


A station is a background music playlist for the deck: an ordered set of tracks the operator tunes in the WavAmpster player, which then play in the background while they use the rest of the deck. WavAmpster plays real PCM audio (the deck’s PCM lineage), never PSG chiptune — see music.md for the separate PSG ambient-music system.

A station is a directory, not a binary container:

<station-id>/
station.knst ; the playlist manifest (this format)
01-neon-rain.pcm ; one raw-PCM file per track, playback order
02-cold-transit.pcm
03-static-bloom.pcm

This is deliberately the design’s “one playlist manifest + its rendered PCM files.” The same directory layout is the single format shared by all three station sources (below), so nothing needs a bespoke packer to read a station — the runtime open()s the manifest and streams the .pcm files directly, the way the deck already treats raw PCM assets.

Every track .pcm file is raw, headerless PCM:

PropertyValue
Encodingsigned 16-bit little-endian (S16LE)
Channelsmono (1)
Sample rate44 100 Hz
Containernone — raw samples, no WAV/RIFF header
Extension.pcm

Sample count is filesize / 2. This matches the emulator’s SDL output device exactly (S16 / 44 100 / mono), so the runtime mixes station samples straight into the audio buffer with no resampling — all decode and resampling happen once, at build time, in the sdk/ tool. It also matches the deck’s canonical “44.1 kHz mono PCM” audio (see the Canonical Hardware Specification in the umbrella CLAUDE.md; do not restate rates here).

Note on “bark-matched.” The design calls the format “bark-matched.” The .pcm files under runtime/assets/barks/ are actually 8 kHz / 8-bit and currently dormant (no runtime PCM path consumed them). Stations are the first live PCM path on the deck; they target the 16-bit / 44.1 kHz output format, not the legacy bark rate. Do not conflate the two.

station.knst is a small, line-oriented UTF-8 text file. It is trivial to emit (the Rust tool) and trivial to parse (a ~40-line C reader in the runtime) — neither side needs a TOML/JSON dependency.

# KN-86 WavAmpster station manifest
version: 1
id: idleware-nightshift
name: NIGHTSHIFT
format: pcm-s16le-44100-mono
track: 01-neon-rain.pcm | Neon Rain | 213402
track: 02-cold-transit.pcm | Cold Transit | 187015
track: 03-static-bloom.pcm | Static Bloom | 240900
  • One directive per line. Leading/trailing whitespace is ignored.
  • A line whose first non-space character is # is a comment. Blank lines are ignored.
  • A directive is key: value. The key is lowercase; whitespace around the : is trimmed.
KeyReqMeaning
versionyesManifest schema version. 1 today. A reader MUST reject a version it does not understand.
idyesStable station identifier, [a-z0-9-]+. The selector for (station-tune id). Unique among discovered stations.
nameyesOperator-facing display name (short; UPPERCASE by house convention for the amber grid).
formatyesAudio format token. v1 supports exactly pcm-s16le-44100-mono. A reader MUST reject an unknown token (forward-safety).

Unknown header keys are ignored (forward-compatibility). Unknown format values are a hard error — the file is claiming an audio layout the reader can’t stream.

Each track: line is one track. Manifest order is playback order (not filename order — the NN- filename prefix is a convenience, not authoritative). The value is three pipe-delimited fields, each trimmed:

track: <pcm-file> | <title> | <duration-ms>
FieldMeaning
<pcm-file>Track filename, relative to the station directory. No path separators; must exist.
<title>Operator-facing track title (from the source file’s ID3 tag, else its filename stem).
<duration-ms>Integer track length in ms (samples * 1000 / 44100). Informational — the player derives exact length from the file size; a reader may treat it as a hint.

At least one track: row is required. A station with zero tracks is invalid.

All three use the identical directory + manifest format:

  1. Built-in stations ship in the system image under runtime/assets/stations/<station-id>/. The host scans that directory at boot; every subdirectory containing a valid station.knst is one station.
  2. Cart-contributed stations — a cart may carry a stations/<id>/ subtree. Discovered by the same scan when the cart is mounted; the format is identical, so a cart station is a first-class station with no special-casing.
  3. Future broadcast / signal sources tie in as just another station source — no format change.

The knamp tool in sdk/knamp/ (GWP-677) is the reference producer: a folder of .mp3 / .wav → decode → downmix to mono → resample to 44 100 Hz → quantize to S16LE → NN-<slug>.pcm per track + an emitted station.knst. Titles come from ID3 tags, falling back to the filename stem; tracks are ordered by source filename. Hand-authoring a station (drop raw .pcm files + write the manifest) is equally valid.

Terminal window
knamp build ~/Music/kn86-stations/idleware-vol1 runtime/assets/stations/idleware-vol1

All decode happens here, on a workstation. The deck ships no decoder and streams the rendered PCM only. To install stations on a real device, use the stations Ansible role (hosts/device/tools/sd-provision/converge/stations.yml), which runs this tool on the control node and pushes the result.

Streaming, literally. The runtime reads a track through a fixed 256 KB ring rather than loading it whole, so a track costs the same memory whether it runs one minute or ten (ADR-0060). Two consequences for authoring: track length is unbounded by device RAM, and the .pcm file must stay readable for the whole time it plays, because a station directory is opened lazily rather than slurped at tune time.

version: 1 is the initial schema. Additive header keys are backward-compatible (readers ignore unknown keys). A breaking change (new required key, new format token, changed track-row shape) bumps version and readers gate on it.

  • WavAmpster design (deleted 2026-07-29; recover from git history) — the approved brief.
  • music.md — the separate PSG-only ambient music system (chiptune, not PCM).
  • clip-system.md — the other pre-rendered asset primitive (terminal animation).
  • Canonical Hardware Specification (umbrella canonical-spec.md) — the deck’s audio + display source of truth.

Assigned by Josh in the kn86-inspo workbench. Full map: cart-inspiration-map.md.

SourceCategory
4TRKmusic app
AetherTunemusic app
PulseDeckmusic app
asakmusic app
audiummusic app
cliampmusic app
valveFMmusic app
wavesmusic app
cmusterminal app