Skip to main content

read_speed/
read_speed.rs

1/// Reads the first audio track repeatedly at different requested speeds and reports the
2/// elapsed time for each read.
3use std::time::Instant;
4
5use cd_da_reader::{CdReader, ReadOptions, ReadSpeed};
6
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8    let reader = CdReader::open_default()?;
9    let toc = reader.read_toc()?;
10
11    let first_audio = toc
12        .tracks
13        .iter()
14        .find(|track| track.is_audio)
15        .ok_or("no audio tracks found")?;
16
17    // Keep "unchanged" immediately after 1x so it tests whether the previous speed
18    // request remains in effect when no new speed command is sent.
19    let speed_tests = [
20        ("1x", ReadSpeed::CustomMultiplier(1)),
21        ("unchanged (after 1x)", ReadSpeed::Unchanged),
22        ("10x", ReadSpeed::CustomMultiplier(10)),
23        ("30x", ReadSpeed::CustomMultiplier(30)),
24        ("optimal", ReadSpeed::Optimal),
25    ];
26
27    println!(
28        "Reading audio track {} {} times\n",
29        first_audio.number,
30        speed_tests.len()
31    );
32
33    let mut timings = Vec::with_capacity(speed_tests.len());
34
35    for (label, read_speed) in speed_tests {
36        let options = ReadOptions::default().with_read_speed(read_speed);
37
38        println!("Reading at {label}...");
39        let started = Instant::now();
40        let data = reader.read_track_with_options(&toc, first_audio.number, &options)?;
41        let elapsed = started.elapsed();
42
43        println!(
44            "Read {} bytes in {:.3} seconds\n",
45            data.len(),
46            elapsed.as_secs_f64()
47        );
48        timings.push((label, elapsed));
49    }
50
51    println!("Timing summary:");
52    for (label, elapsed) in timings {
53        println!("  {label:<22} {:>10.3} seconds", elapsed.as_secs_f64());
54    }
55
56    Ok(())
57}