Add pluggable AudioSectorReader file backing (1.0)#58
Conversation
Reconstructs the pluggable file/image backing from the pre-1.0 `file-based-backend` branch on top of main's unified read API, since a literal rebase would collide with main's independently-built data-track support. - backend.rs: AudioSectorReader trait, `read_track` free fn, and TrackReadError, with the CdReader impl now reading via `read_sector_range(.., &ReadOptions::default())`. - Expose the support surface the seam needs: free `create_wav` and a public `lba_to_msf` (for building a Toc from image metadata). - examples: file_backend (dependency-free backing) and save_data_track (detect -> read cooked -> save .iso -> mount). - docs/consuming-cd-da-reader.md: downstream-consumer guide covering the options model, sector formats, detection, the data-track workflow, Mode 1 vs Mode 2, file backing, and a pre-1.0 -> 1.0 migration table. - README: data-track and file-image sections. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The data-track example read the entire track into a Vec before writing — a full data track can be hundreds of MB. Switch it to the streaming API (open_track_stream_with_options) so cooked/raw chunks are written as they arrive and peak memory is one ~64 KB chunk regardless of track size. Both the ISO (Mode1Cooked) and Mode 2 branches now share one stream_track_to_file helper with a progress line, which also showcases that reading and streaming run over the same options/read path. Docs updated to recommend streaming for large images. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First release carrying the breaking 1.0 API (SectorReadFormat, per-read ReadOptions, detect_track_format) plus the AudioSectorReader file backing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@danifunker hey, thanks for the PR. I looked over it but I am a bit confused on how is it supposed to be used. In the description you mentioned the BIN/CUE and network. So is it intended to turn CUE + PCM data into individual files? But if you have that, wouldn't you have tracks as actual tracks and not just PCM data? And if you have a CD image, wouldn't it be easier to mount it into a virtual drive? |
|
Thanks for review it so quickly! I may read like a format-conversion feature, but it's really just an abstraction seam - it parses/converts nothing and pulls in no image-format deps. I am hoping for a native rust-only solution for my projects. AudioSectorReader is a one-method trait: read_audio_sectors(start_lba, count) -> Vec of raw 2352-byte sectors. BIN/CUE, CHD, and "network" were just examples of backings a user could implement - not formats the crate reads. The value is reusing everything above the raw read (track-boundary math incl. the CD-Extra trailing-gap rule, plus create_wav), which is currently welded to the SCSI path. CdReader now implements the trait too, so drive- and file-backed code share one read_track. To answer your questions:
I've already implemented this in one of my cross-platform projects which helps users identify what discs they may be looking at, and provides a way to "listen to the track" in the case users are familiar with the music (think vintage video-game CDs, or older OSTs/Anime CDs). |
|
Alright, I am going to review it properly tomorrow! We definitely don't want to bundle the 1.0 update with this PR, I update all releases as a separate PR/commit |
|
Sounds fair! I thought you may have overlooked that a bit. Do you want me to revert that part of the PR? |
Summary
Adds a hardware-independent seam for reading CD-DA tracks from a file/image
(CHD, BIN/CUE, in-memory, network, …) reusing the crate's existing TOC/track
machinery, with no image-format dependencies pulled into the crate. Also bumps
to
1.0.0, the first release carrying the breaking 1.0 API already onmain.This is the
file-based-backendwork rebuilt on top of the 1.0 API rather thangit-rebased:
mainand that branch had independently built data-track support, soa literal rebase would have collided and dragged back the older implementation.
Only the genuinely-unique file backing is ported here.
Public API additions
AudioSectorReadertrait — implementread_audio_sectors(start_lba, count)forany backing that yields raw CD-DA sectors (2352 B, 16-bit signed LE, stereo).
read_track(&src, &toc, n) -> Result<Vec<u8>, TrackReadError<E>>— thefile/image counterpart to
CdReader::read_track;TrackReadErrorkeeps a badtrack request (
Toc) separate from a backing failure (Backend(E)).create_wav(Vec<u8>)and publiclba_to_msf(u32)— the support surface abacking needs (WAV wrapping without naming
CdReader; building aTocfromimage metadata).
CdReaderitself implementsAudioSectorReadeked code share the genericread_track` path.No changes to existing drive behavior.
Examples
examples/file_backend.rs— dependency-free ihe seamwithout a decoder).
examples/save_data_track.rs— detect a data itcooked to a mountable
.iso(bounded memory),t command;Mode 2 falls back to saving complete raw secto
Docs
docs/consuming-cd-da-reader.md— downstream-del,sector formats,
detect_track_format, the dats Mode 2,file backing, and a pre-1.0 → 1.0 migration ta
Verification
cargo fmt --check,cargo clippy --all-targets -- -D warnings, andcargo test(49 unit + 6 doctests) all pass.fnd (validRIFF…WAVE, correct sizes). The drive-dependent examples (save_data_track,read_data_track`) are compit pathneeds a physical mixed-mode disc.
Note for reviewers
The
1.0.0bump rides along with this feature. If you'd rather tag the releaseindependently, land the version commit (`885335ed keep
this PR purely additive — or just squash-merge.