Skip to main content

decode_to_file/
decode_to_file.rs

1//! Decode an APE file to a WAV file or raw PCM.
2//!
3//! Usage: cargo run --release --example decode_to_file -- <input.ape> <output.wav>
4//!        cargo run --release --example decode_to_file -- --raw <input.ape> <output.pcm>
5
6use std::fs::File;
7use std::io::{BufReader, Write};
8
9fn main() {
10    let args: Vec<String> = std::env::args().collect();
11
12    let (raw_mode, input, output) = if args.len() == 4 && args[1] == "--raw" {
13        (true, &args[2], &args[3])
14    } else if args.len() == 3 {
15        (false, &args[1], &args[2])
16    } else {
17        eprintln!("Usage: decode_to_file [--raw] <input.ape> <output>");
18        std::process::exit(1);
19    };
20
21    let file = File::open(input).expect("failed to open input file");
22    let mut decoder =
23        ape_decoder::ApeDecoder::new(BufReader::new(file)).expect("failed to parse APE");
24
25    {
26        let info = decoder.info();
27        eprintln!(
28            "{}Hz, {} ch, {}-bit, {} samples ({} ms)",
29            info.sample_rate,
30            info.channels,
31            info.bits_per_sample,
32            info.total_samples,
33            info.duration_ms,
34        );
35    }
36
37    let pcm = decoder.decode_all().expect("failed to decode");
38    eprintln!("Decoded {} bytes of PCM", pcm.len());
39
40    let mut out = File::create(output).expect("failed to create output file");
41
42    if !raw_mode {
43        // Write WAV header: prefer stored header from the APE file, fall back to generated
44        let header = decoder
45            .wav_header_data()
46            .map(|h| h.to_vec())
47            .unwrap_or_else(|| decoder.info().generate_wav_header());
48        out.write_all(&header).expect("failed to write WAV header");
49    }
50
51    out.write_all(&pcm).expect("failed to write PCM data");
52    eprintln!("Wrote {}", output);
53}