Skip to main content

custom_retry/
custom_retry.rs

1/// Reads the first audio track with an aggressive retry configuration
2/// suitable for scratched or damaged discs.
3/// By default, it already retries multiple times with smaller number
4/// of sectors, so this usually should not be necessary, but you can see
5/// here that you can tweak details.
6mod common;
7
8use std::time::Duration;
9
10use cd_da_reader::{CdReader, ReadOptions, RetryConfig, create_wav};
11
12fn main() -> Result<(), Box<dyn std::error::Error>> {
13    let output_dir = common::fresh_output_dir("custom_retry")?;
14    let reader = CdReader::open_default()?;
15    let toc = reader.read_toc()?;
16
17    let first_audio = toc
18        .tracks
19        .iter()
20        .find(|t| t.is_audio)
21        .ok_or("no audio tracks found")?;
22
23    // More attempts, longer backoff, and sector reduction down to 1
24    // for maximum resilience on scratched media.
25    let retry = RetryConfig::default()
26        .with_max_attempts(8)
27        .with_initial_backoff(Duration::from_millis(50))
28        .with_max_backoff(Duration::from_secs(1))
29        .with_chunk_reduction(true)
30        .with_min_sectors_per_read(1);
31    let options = ReadOptions::default().with_retry(retry);
32
33    println!(
34        "Reading track {} with aggressive retry...",
35        first_audio.number
36    );
37    let data = reader.read_track_with_options(&toc, first_audio.number, &options)?;
38
39    let wav = create_wav(data);
40    let output_path = output_dir.join(format!("track{:02}.wav", first_audio.number));
41    std::fs::write(&output_path, wav)?;
42    println!("Saved {}", output_path.display());
43
44    Ok(())
45}