feat: CD-DA (Red Book) audio → WAV extraction for console-family ports #279
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "refs/pull/279/head"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds Red Book CD-DA (audio-track) → WAV extraction for the console-family
ports, closing the last per-port audio gap in Phase 3. The console editions
(Sega CD, Mac JP, FM-Towns, PC-9821) ship their soundtrack as raw CD audio
tracks — headerless 44.1 kHz / 16-bit / stereo PCM — rather than in
graphics.dat. Conversion is a passthrough (reinterpret the bytes asinterleaved
i16in the correct byte order and wrap in a WAV header); the onenon-trivial part is sample byte order, which is auto-detected.
What landed
dm2-wav—pcm16_stereo_to_wavconvenience (mirrors the existing monohelpers; the streaming stereo writer already existed for the OPL3 render).
dm2-music::cdda— new module:ByteOrder { Le, Be },to_wav(raw, order)(trims any partial trailing frame, delegates todm2-wav), and adetect_byte_order/byte_order_statsheuristic. The heuristic comparesthe lag-1 absolute-difference energy of both interpretations over a bounded
probe window — real audio is far smoother sample-to-sample than its
byte-swapped noise — and picks the lower one (ties/degenerate input →
Le).dm2-cli—dm2 convert --cdda [--byte-order auto|le|be] [--all] [--jobs N]. Raw CD-DA is headerless (no magic to sniff), so it takes anexplicit
--cddapath that bypasses the format-detection dispatch. Singlefile, or
--allover a directory oftrack*.binin parallel.for the detector on synthetic signals; skip-on-missing fixture + CLI
integration tests over the staged audio.
music.md(converter + byte-order handling, impl-order item #9flipped to done),
sega-cd-us.md/mac-jp-cd.md(audio-track sections andextraction recipes), and
ROADMAP.md(Phase 3 status).Byte order — determined empirically
Byte order is a property of how a rip was extracted, not of the port. Running
the detector against the staged fixtures shows all four ports are
little-endian (FM-Towns, PC-9821, Sega CD US, Mac JP), each with a decisive
230×–367× energy margin. Notably the Sega CD US Redump
.bin(split withbchunk, no-s) is standard LE — not the classic Sega/Redump byte-swapcase — so auto-detect defaults to LE and
--byte-orderremains the escapehatch for any future rip that is swapped.
Scope / non-goals
Deliberately out of scope for this pass: routing integration (the
console-family
CD.DATmusic_id→ audio-track mapping is empirical and notencoded in any shipped file — still an open question), in-tool CHD/cue
splitting (the tool takes already-split per-track
.bin), and lossy output.The audio-track
.binfixtures are gitignored (large, copyrighted), so thefixture-gated tests skip cleanly where they are absent.