libsamplerate_sys/
lib.rs

1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4
5include!("bindings.rs");
6
7impl Default for SRC_DATA {
8    fn default() -> Self {
9        unsafe { std::mem::zeroed() }
10    }
11}
12
13#[cfg(test)]
14#[macro_use]
15extern crate all_asserts;
16
17#[cfg(test)]
18mod tests {
19    use super::*;
20
21    #[test]
22    fn simple_sample_rate_conversion() {
23        unsafe {
24            let from = 44100;
25            let to = 48000;
26            let ratio = to as f64 / from as f64;
27
28            // Setup sample data and storage.
29            let freq = ::std::f32::consts::PI * 880f32 / from as f32;
30            let mut input: Vec<f32> = (0..from).map(|i| (freq * i as f32).sin()).collect();
31            let mut resampled = vec![0f32; to];
32            let mut output = vec![0f32; from];
33
34            // Convert from 44100Hz to 48000Hz.
35            let mut src_pass_1 = SRC_DATA {
36                data_in: input.as_mut_ptr(),
37                data_out: resampled.as_mut_ptr(),
38                input_frames: (input.len() as i32).into(),
39                output_frames: (resampled.len() as i32).into(),
40                src_ratio: ratio,
41                ..Default::default()
42            };
43            let err = src_simple(&mut src_pass_1 as *mut SRC_DATA, SRC_SINC_BEST_QUALITY as i32, 1);
44            assert_eq!(err, 0);
45            assert_eq!(src_pass_1.output_frames_gen, src_pass_1.output_frames);
46            assert_eq!(src_pass_1.input_frames_used, src_pass_1.input_frames);
47
48            // Convert from 48000Hz to 44100Hz.
49            let mut src_pass_2 = SRC_DATA {
50                data_in: resampled.as_mut_ptr(),
51                data_out: output.as_mut_ptr(),
52                input_frames: (resampled.len() as i32).into(),
53                output_frames: (output.len() as i32).into(),
54                src_ratio: 1f64/ratio,
55                ..Default::default()
56            };
57            let err = src_simple(&mut src_pass_2 as *mut SRC_DATA, SRC_SINC_BEST_QUALITY as i32, 1);
58            assert_eq!(err, 0);
59            assert_eq!(src_pass_2.output_frames_gen, src_pass_2.output_frames);
60            assert_eq!(src_pass_2.input_frames_used, src_pass_2.input_frames);
61
62            // Expect the difference between all input frames and all output frames to be less than
63            // an epsilon.
64            let error = input.iter().zip(output).fold(0f32, |max, (input, output)| max.max((input - output).abs()));
65            assert_lt!(error, 0.002);
66        }
67    }
68
69    #[test]
70    fn complex_sample_rate_conversion() {
71        unsafe {
72            let from = 44100;
73            let to = 44100;
74            let ratio = to as f64 / from as f64;
75
76            // Setup sample data and storage.
77            let freq = ::std::f32::consts::PI * 880f32 / from as f32;
78            let mut input: Vec<f32> = (0..from).map(|i| (freq * i as f32).sin()).collect();
79            let mut resampled = vec![0f32; to];
80            let mut output = vec![0f32; from];
81
82            // Create the samplerate converter.
83            let mut error = 0i32;
84            let converter: *mut SRC_STATE = src_new(SRC_SINC_BEST_QUALITY as i32, 1, &mut error as *mut i32);
85
86            assert_eq!(error, 0);
87
88            // Initial input configuration.
89            let slices: usize = 10;
90
91            let mut src = SRC_DATA {
92                src_ratio: ratio,
93                input_frames: (input.len() as i32 / slices as i32).into(),
94                output_frames: (resampled.len() as i32 / slices as i32).into(),
95                ..Default::default()
96            };
97
98            // Convert the input data in slices.
99            let mut out_pos = 0;
100            for i in 0..slices+1 {
101                if i == (slices - 1) {
102                    src.end_of_input = 1;
103                }
104                if i == slices {
105                    src.input_frames = 0;
106                } else {
107                    src.data_in = input[i * from / slices..].as_mut_ptr();
108                }
109
110                src.data_out = resampled[out_pos..].as_mut_ptr();
111
112                let err = src_process(converter, &mut src as *mut SRC_DATA);
113                assert_eq!(err, 0);
114                assert_eq!(src.input_frames_used, src.input_frames);
115                out_pos += src.output_frames_gen as usize;
116            }
117            assert_eq!(out_pos, resampled.len());
118
119            // Delete the converter.
120            src_delete(converter);
121
122            // Convert back from 48000Hz to 44100Hz.
123            let mut src_reverse = SRC_DATA {
124                data_in: resampled.as_mut_ptr(),
125                data_out: output.as_mut_ptr(),
126                input_frames: (resampled.len() as i32).into(),
127                output_frames: (output.len() as i32).into(),
128                src_ratio: 1f64/ratio,
129                ..Default::default()
130            };
131            let err = src_simple(&mut src_reverse as *mut SRC_DATA, SRC_SINC_BEST_QUALITY as i32, 1);
132
133            assert_eq!(err, 0);
134            assert_eq!(src_reverse.output_frames_gen, src_reverse.output_frames);
135            assert_eq!(src_reverse.input_frames_used, src_reverse.input_frames);
136
137            // Expect the difference between all input frames and all output frames to be less than
138            // an epsilon.
139            let error = input.iter().zip(output).fold(0f32, |max, (input, output)| max.max((input - output).abs()));
140            assert_lt!(error, 0.002);
141        }
142    }
143}