feat(disc): read CD-DA off a real drive, measured before it was written
New crate `qbz-disc`: table of contents and raw audio sectors through the
kernel's own cdrom ioctls. No libcdio — not because libcdio is worse (it is
better at RIPPING than this will ever be) but because this path PLAYS a clean
disc, and for that the kernel interface is enough while a native library would
have to be built into Flatpak, Snap and AppImage. Both need the same --device
permission in a sandbox; only one needs the library shipped.
Every claim below was measured on the owner's USB drive with Tool — Fear
Inoculum BEFORE a line of this crate existed, so the design answers evidence
rather than the other way round:
- the TOC reads back 7 audio tracks, lead-out at LSN 356568, and the track
lengths match the record exactly (10:21, 11:52, 12:44, 13:37, 10:05, 4:48,
15:44 — 79:11 total);
- CDROMREADAUDIO over 20 frames from LSN 4000 returned 47 040 bytes, 99 %
non-zero samples, peak 14559: real audio, not silence;
- the drive hands back LITTLE-endian samples. Neighbouring-sample deltas
average 73.5 read as LE against 20 971 read as BE, a 285x margin, so the
bytes go straight into a little-endian WAV with no swap. That is one
drive, so `looks_byte_swapped` keeps the test available as a diagnostic
instead of an article of faith;
- the disc's MCN is all zeros, which is why identity is a digest over the
track table and not the catalogue number.
What this is NOT is accurate extraction: no overlap synchronisation, no cache
modelling, no jitter verification. On a clean disc that is fine for playback,
and an unreadable sector surfaces as an ERROR rather than a hole full of
zeros — silence that pretends to be audio is the one outcome a bit-perfect
player must never produce.
`/dev/sr0` is nowhere in the code: drives are enumerated, because a box can
have several and /dev/cdrom is a symlink that may point at any of them. Data
tracks of a mixed-mode disc are skipped by their control bits.
`CdRef` is the typed reference (`cdda:/dev/sr0#285735+70833`) with ONE parser,
not prefix tests copied around — the scattered version is a known failure mode
here and cost a whole session on 2026-08-20.
11 tests, several asserting against that real table of contents.
cc
This commit is contained in:
6 files changed
+801
No files matched your search
Generated
+11
@@ -6369,6 +6369,15 @@ dependencies = [
|
||||
"qbz-models",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qbz-disc"
|
||||
version = "2.0.2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qbz-dsd"
|
||||
version = "2.0.2"
|
||||
@@ -6670,6 +6679,7 @@ dependencies = [
|
||||
"qbz-core",
|
||||
"qbz-credentials",
|
||||
"qbz-dac-wizard-core",
|
||||
"qbz-disc",
|
||||
"qbz-external-reco",
|
||||
"qbz-i18n",
|
||||
"qbz-integrations",
|
||||
@@ -6760,6 +6770,7 @@ version = "2.0.2"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"log",
|
||||
"qbz-disc",
|
||||
"qbz-jellyfin",
|
||||
"qbz-library",
|
||||
"qbz-media-cache",
|
||||
|
||||
Reference in new issue
Block a user