flac/
lib.rs

1#![allow(unused_imports)]
2mod flac;
3
4/// * The flac encoder. The `FlacEncoder` is a wrapper for the `FlacEncoderUnmovable` what prevents the structure moves.
5pub use crate::flac::{FlacEncoderUnmovable, FlacEncoder};
6
7/// * The flac decoder. The `FlacDecoder` is a wrapper for the `FlacDecoderUnmovable` what prevents the structure moves.
8pub use crate::flac::{FlacDecoderUnmovable, FlacDecoder};
9
10/// * The codec options for FLAC
11pub mod options {
12    pub use crate::flac::{FlacAudioForm, SamplesInfo};
13    pub use crate::flac::{FlacCompression, FlacEncoderParams};
14}
15
16/// * The objects for you to implement your closure, some is closures' params, some is the return value that your closure should return.
17pub mod closure_objects {
18    pub use crate::flac::SamplesInfo;
19    pub use crate::flac::{FlacReadStatus, FlacInternalDecoderError};
20}
21
22/// The errors of this library
23pub mod errors {
24    pub use crate::flac::FlacError;
25    pub use crate::flac::{FlacEncoderError, FlacDecoderError};
26    pub use crate::flac::{FlacEncoderErrorCode, FlacDecoderErrorCode};
27    pub use crate::flac::{FlacEncoderInitError, FlacDecoderInitError};
28    pub use crate::flac::{FlacEncoderInitErrorCode, FlacDecoderInitErrorCode};
29}
30
31#[test]
32fn test() {
33    use std::{io::{self, Read, Write, Seek, SeekFrom, BufReader, BufWriter}, cmp::Ordering, fs::File};
34
35    // Open the FLAC file for decoding using the `BufReader`
36    type ReaderType = BufReader<File>;
37    let mut reader: ReaderType = BufReader::new(File::open("test.flac").unwrap());
38
39    // Retrieve the file length
40    let length = {
41        reader.seek(SeekFrom::End(0)).unwrap();
42        let ret = reader.stream_position().unwrap();
43        reader.seek(SeekFrom::Start(0)).unwrap();
44        ret
45    };
46
47    // Open the FLAC file for encoding using the `BufWriter`
48    type WriterType = BufWriter<File>;
49    let mut writer: WriterType = BufWriter::new(File::create("output.flac").unwrap());
50
51    // Prepare to get the samples
52    let mut pcm_frames = Vec::<Vec<i16>>::new();
53
54    // There is an encoder to save samples to another FLAC file
55    // But currently we don't know the source FLAC file spec (channels, sample rate, etc.)
56    // So we just guess it.
57    // Let's create the encoder now
58    let mut encoder = FlacEncoder::new(
59        &mut writer,
60        // on_write
61        Box::new(|writer: &mut WriterType, data: &[u8]| -> Result<(), io::Error> {
62            writer.write_all(data)
63        }),
64        // on_seek
65        Box::new(|writer: &mut WriterType, position: u64| -> Result<(), io::Error> {
66            writer.seek(SeekFrom::Start(position))?;
67            Ok(())
68        }),
69        // on_tell
70        Box::new(|writer: &mut WriterType| -> Result<u64, io::Error> {
71            writer.stream_position()
72        }),
73        &FlacEncoderParams {
74            verify_decoded: false,
75            compression: FlacCompression::Level8,
76            channels: 2,
77            sample_rate: 44100,
78            bits_per_sample: 16,
79            total_samples_estimate: 0
80        }
81    ).unwrap();
82    encoder.initialize().unwrap();
83
84    // Create a decoder to decode the test file.
85    let mut decoder = FlacDecoder::new(
86        &mut reader,
87        // on_read
88        Box::new(|reader: &mut ReaderType, data: &mut [u8]| -> (usize, FlacReadStatus) {
89            let to_read = data.len();
90            match reader.read(data) {
91                Ok(size) => {
92                    match size.cmp(&to_read) {
93                        Ordering::Equal => (size, FlacReadStatus::GoOn),
94                        Ordering::Less => (size, FlacReadStatus::Eof),
95                        Ordering::Greater => panic!("`reader.read()` returns a size greater than the desired size."),
96                    }
97                },
98                Err(e) => {
99                    eprintln!("on_read(): {:?}", e);
100                    (0, FlacReadStatus::Abort)
101                }
102            }
103        }),
104        // on_seek
105        Box::new(|reader: &mut ReaderType, position: u64| -> Result<(), io::Error> {
106            reader.seek(SeekFrom::Start(position))?;
107            Ok(())
108        }),
109        // on_tell
110        Box::new(|reader: &mut ReaderType| -> Result<u64, io::Error> {
111            reader.stream_position()
112        }),
113        // on_length
114        Box::new(|_reader: &mut ReaderType| -> Result<u64, io::Error>{
115            Ok(length)
116        }),
117        // on_eof
118        Box::new(|reader: &mut ReaderType| -> bool {
119            reader.stream_position().unwrap() >= length
120        }),
121        // on_write
122        Box::new(|samples: &[Vec<i32>], sample_info: &SamplesInfo| -> Result<(), io::Error>{
123            if sample_info.bits_per_sample != 16 {
124                panic!("The test function only tests 16-bit per sample FLAC files.")
125            }
126            let pcm_converted: Vec<Vec<i16>> = samples.iter().map(|frame: &Vec<i32>|{
127                frame.into_iter().map(|x32|{*x32 as i16}).collect()
128            }).collect();
129            pcm_frames.extend(pcm_converted);
130
131            // The encoder wants the `i32` for samples to be encoded so we convert the PCM samples back to `i32` format for the encoder.
132            let i32pcm: Vec::<Vec<i32>> = pcm_frames.iter().map(|frame: &Vec<i16>|{
133                frame.into_iter().map(|x16|{*x16 as i32}).collect()
134            }).collect();
135            encoder.write_frames(&i32pcm).unwrap();
136            pcm_frames.clear();
137
138            Ok(())
139        }),
140        // on_error
141        Box::new(|error: FlacInternalDecoderError| {
142            panic!("{error}");
143        }),
144        true, // md5_checking
145        false, // scale_to_i32_range
146        FlacAudioForm::FrameArray
147    ).unwrap();
148
149    decoder.decode_all().unwrap();
150    decoder.finalize();
151    encoder.finalize();
152}
153