samplerate_rs/
samplerate.rs1use crate::converter_type::ConverterType;
2use crate::error::{Error, ErrorCode};
3use libsamplerate::*;
4use std::clone::Clone;
5
6pub struct Samplerate {
26 ptr: *mut SRC_STATE,
27 from_rate: u32,
28 to_rate: u32,
29}
30
31impl Samplerate {
32 pub fn new(
34 converter_type: ConverterType,
35 from_rate: u32,
36 to_rate: u32,
37 channels: usize,
38 ) -> Result<Samplerate, Error> {
39 let ratio = to_rate as f64 / from_rate as f64;
41 if unsafe { src_is_valid_ratio(ratio) } == 0 {
42 return Err(Error::from_code(ErrorCode::BadSrcRatio));
43 }
44 let mut error_int = 0i32;
46 let ptr: *mut SRC_STATE = unsafe {
47 src_new(
48 converter_type as i32,
49 channels as i32,
50 &mut error_int as *mut i32,
51 )
52 };
53 match ErrorCode::from_int(error_int) {
54 ErrorCode::NoError => Ok(Samplerate {
55 ptr,
56 from_rate,
57 to_rate,
58 }),
59 _ => Err(Error::from_int(error_int)),
60 }
61 }
62
63 pub fn reset(&mut self) -> Result<(), Error> {
65 let error_code = ErrorCode::from_int(unsafe { src_reset(self.ptr) });
66 match error_code {
67 ErrorCode::NoError => Ok(()),
68 _ => Err(Error::from_code(error_code)),
69 }
70 }
71
72 pub fn from_rate(&self) -> u32 {
74 self.from_rate
75 }
76
77 pub fn to_rate(&self) -> u32 {
79 self.to_rate
80 }
81
82 pub fn set_from_rate(&mut self, from_rate: u32) {
84 self.from_rate = from_rate;
85 }
86
87 pub fn set_to_rate(&mut self, to_rate: u32) {
89 self.to_rate = to_rate;
90 }
91
92 pub fn ratio(&self) -> f64 {
94 self.to_rate as f64 / self.from_rate as f64
95 }
96
97 pub fn channels(&self) -> Result<usize, Error> {
99 let channels = unsafe { src_get_channels(self.ptr) };
100 if channels >= 0 {
101 Ok(channels as usize)
102 } else {
103 Err(Error::from_int(channels))
104 }
105 }
106
107 fn _process(
108 &self,
109 input: &[f32],
110 output_len: usize,
111 end_of_input: bool,
112 ) -> Result<Vec<f32>, Error> {
113 let channels = self.channels()?;
114 let mut output = vec![0f32; output_len];
115 let mut src = SRC_DATA {
116 data_in: input.as_ptr(),
117 data_out: output.as_mut_ptr(),
118 input_frames: (input.len() as i32 / channels as i32).into(),
119 output_frames: (output_len as i32 / channels as i32).into(),
120 src_ratio: self.ratio(),
121 end_of_input: if end_of_input { 1 } else { 0 },
122 input_frames_used: 0,
123 output_frames_gen: 0,
124 };
125 let error_int = unsafe { src_process(self.ptr, &mut src as *mut SRC_DATA) };
126 match ErrorCode::from_int(error_int) {
127 ErrorCode::NoError => Ok(output[..src.output_frames_gen as usize * channels].into()),
128 _ => Err(Error::from_int(error_int)),
129 }
130 }
131
132 pub fn process(&self, input: &[f32]) -> Result<Vec<f32>, Error> {
136 let channels = self.channels()?;
137 self._process(
138 input,
139 (self.ratio() * input.len() as f64) as usize + channels,
140 false,
141 )
142 }
143
144 pub fn process_last(&self, input: &[f32]) -> Result<Vec<f32>, Error> {
148 let channels = self.channels()?;
149 let output_len = (self.ratio() * input.len() as f64) as usize + channels;
150 match self._process(input, output_len, true) {
151 Ok(mut output) => {
152 loop {
153 match self._process(&[0f32; 0], output_len, true) {
154 Ok(output_last) => {
155 if output_last.len() < 1 {
156 break;
157 } else {
158 output.extend(output_last);
159 }
160 }
161 Err(err) => return Err(err),
162 }
163 }
164 Ok(output)
165 }
166 Err(err) => Err(err),
167 }
168 }
169}
170
171impl Drop for Samplerate {
172 fn drop(&mut self) {
173 unsafe { src_delete(self.ptr) };
174 }
175}
176
177impl Clone for Samplerate {
178 fn clone(&self) -> Samplerate {
180 let mut error_int = 0i32;
181 let ptr: *mut SRC_STATE = unsafe { src_clone(self.ptr, &mut error_int as *mut i32) };
182 let error_code = ErrorCode::from_int(error_int);
183 if error_code != ErrorCode::NoError {
184 panic!(
185 "Error when cloning Samplerate struct: {}",
186 error_code.description()
187 );
188 }
189 Samplerate {
190 ptr,
191 from_rate: self.from_rate,
192 to_rate: self.to_rate,
193 }
194 }
195}
196
197#[cfg(test)]
198mod tests {
199 use super::*;
200 use std::usize;
201
202 #[test]
203 fn samplerate_new_channels_error() {
204 match Samplerate::new(ConverterType::Linear, 44100, 48000, usize::MAX) {
205 Ok(_) => assert!(false),
206 Err(error) => assert_eq!(error, Error::from_code(ErrorCode::BadChannelCount)),
207 };
208 }
209
210 #[test]
211 fn samplerate_new_channels_correct() {
212 let converter = Samplerate::new(ConverterType::Linear, 44100, 48000, 4).unwrap();
213 assert_eq!(converter.channels().unwrap(), 4);
214 }
215
216 #[test]
217 fn samplerate_clone() {
218 let converter = Samplerate::new(ConverterType::Linear, 44100, 48000, 4).unwrap();
219 let cloned = converter.clone();
220 assert_eq!(cloned.channels().unwrap(), 4);
221 }
222
223 #[test]
224 fn samplerate_conversion() {
225 let freq = std::f32::consts::PI * 880f32 / 44100f32;
227 let input: Vec<f32> = (0..44100).map(|i| (freq * i as f32).sin()).collect();
228
229 let mut converter =
231 Samplerate::new(ConverterType::SincBestQuality, 44100, 48000, 1).unwrap();
232
233 let mut resampled = vec![0f32; 0];
235 let chunk_size = 4410; for i in 0..input.len() / chunk_size {
237 resampled.extend(if i < (input.len() / chunk_size - 1) {
238 converter
239 .process(&input[i * chunk_size..(i + 1) * chunk_size])
240 .unwrap()
241 } else {
242 converter
243 .process_last(&input[i * chunk_size..(i + 1) * chunk_size])
244 .unwrap()
245 });
246 }
247 assert_eq!(resampled.len(), 48000);
248
249 converter.reset().unwrap();
251 converter.set_to_rate(44100);
252 converter.set_from_rate(48000);
253 let mut output = vec![0f32; 0];
254 let chunk_size = 4800; for i in 0..resampled.len() / chunk_size {
256 output.extend(if i < (resampled.len() / chunk_size - 1) {
257 converter
258 .process(&resampled[i * chunk_size..(i + 1) * chunk_size])
259 .unwrap()
260 } else {
261 converter
262 .process_last(&resampled[i * chunk_size..(i + 1) * chunk_size])
263 .unwrap()
264 });
265 }
266 assert_eq!(output.len(), 44100);
267
268 let error = input
271 .iter()
272 .zip(output)
273 .fold(0f32, |max, (input, output)| max.max((input - output).abs()));
274 assert!(error < 0.002);
275 }
276}