speexdsp/
resampler.rs

1#![allow(non_camel_case_types)]
2#![allow(unreachable_patterns)]
3
4#[derive(Clone, Copy, Debug)]
5pub enum Error {
6    AllocFailed = 1,
7    BadState = 2,
8    InvalidArg = 3,
9    PtrOverlap = 4,
10}
11
12use std::fmt;
13
14impl fmt::Display for Error {
15    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
16        let v = match self {
17            Error::AllocFailed => "Memory allocation failed.",
18            Error::BadState => "Bad resampler state.",
19            Error::InvalidArg => "Invalid argument.",
20            Error::PtrOverlap => "Input and output buffers overlap.",
21        };
22
23        write!(f, "{}", v)
24    }
25}
26
27pub trait Resampler: Sized {
28    fn new(
29        channels: usize,
30        in_rate: usize,
31        out_rate: usize,
32        quality: usize,
33    ) -> Result<Self, Error>;
34    fn set_rate(
35        &mut self,
36        in_rate: usize,
37        out_rate: usize,
38    ) -> Result<(), Error>;
39    fn get_rate(&self) -> (usize, usize);
40    fn get_ratio(&self) -> (usize, usize);
41    fn process_float(
42        &mut self,
43        index: usize,
44        input: &[f32],
45        output: &mut [f32],
46    ) -> Result<(usize, usize), Error>;
47    fn skip_zeros(&mut self);
48    fn reset(&mut self);
49    fn get_input_latency(&self) -> usize;
50    fn get_output_latency(&self) -> usize;
51    fn set_quality(&mut self, quality: usize) -> Result<(), Error>;
52    fn get_quality(&self) -> usize;
53}
54
55#[cfg(feature = "sys")]
56mod sys {
57    use super::{Error, Resampler};
58    use speexdsp_sys::resampler::*;
59
60    impl From<i32> for Error {
61        fn from(v: i32) -> Error {
62            match v as u32 {
63                RESAMPLER_ERR_ALLOC_FAILED => Error::AllocFailed,
64                RESAMPLER_ERR_BAD_STATE => Error::BadState,
65                RESAMPLER_ERR_INVALID_ARG => Error::InvalidArg,
66                RESAMPLER_ERR_PTR_OVERLAP => Error::PtrOverlap,
67                _ => unreachable!(),
68            }
69        }
70    }
71
72    pub struct State {
73        st: *mut SpeexResamplerState,
74    }
75
76    impl Resampler for State {
77        fn new(
78            channels: usize,
79            in_rate: usize,
80            out_rate: usize,
81            quality: usize,
82        ) -> Result<Self, Error> {
83            let mut err = 0;
84            let st = unsafe {
85                speex_resampler_init(
86                    channels as u32,
87                    in_rate as u32,
88                    out_rate as u32,
89                    quality as i32,
90                    &mut err,
91                )
92            };
93
94            if st.is_null() {
95                Err(err.into())
96            } else {
97                Ok(State { st })
98            }
99        }
100
101        fn set_rate(
102            &mut self,
103            in_rate: usize,
104            out_rate: usize,
105        ) -> Result<(), Error> {
106            let ret = unsafe {
107                speex_resampler_set_rate(
108                    self.st,
109                    in_rate as u32,
110                    out_rate as u32,
111                )
112            };
113            if ret != 0 {
114                Err(ret.into())
115            } else {
116                Ok(())
117            }
118        }
119
120        fn get_rate(&self) -> (usize, usize) {
121            let mut in_rate = 0;
122            let mut out_rate = 0;
123
124            unsafe {
125                speex_resampler_get_rate(self.st, &mut in_rate, &mut out_rate)
126            };
127
128            (in_rate as usize, out_rate as usize)
129        }
130
131        fn get_ratio(&self) -> (usize, usize) {
132            let mut num = 0;
133            let mut den = 0;
134
135            unsafe { speex_resampler_get_ratio(self.st, &mut num, &mut den) };
136
137            (num as usize, den as usize)
138        }
139
140        fn process_float(
141            &mut self,
142            index: usize,
143            input: &[f32],
144            output: &mut [f32],
145        ) -> Result<(usize, usize), Error> {
146            let mut in_len = input.len() as u32;
147            let mut out_len = output.len() as u32;
148            let ret = unsafe {
149                speex_resampler_process_float(
150                    self.st,
151                    index as u32,
152                    input.as_ptr(),
153                    &mut in_len,
154                    output.as_mut_ptr(),
155                    &mut out_len,
156                )
157            };
158
159            if ret != 0 {
160                Err(ret.into())
161            } else {
162                Ok((in_len as usize, out_len as usize))
163            }
164        }
165
166        fn skip_zeros(&mut self) {
167            unsafe { speex_resampler_skip_zeros(self.st) };
168        }
169
170        fn reset(&mut self) {
171            unsafe { speex_resampler_reset_mem(self.st) };
172        }
173
174        fn get_input_latency(&self) -> usize {
175            unsafe { speex_resampler_get_input_latency(self.st) as usize }
176        }
177
178        fn get_output_latency(&self) -> usize {
179            unsafe { speex_resampler_get_output_latency(self.st) as usize }
180        }
181
182        fn set_quality(&mut self, quality: usize) -> Result<(), Error> {
183            let ret = unsafe {
184                speex_resampler_set_quality(self.st, quality as i32)
185            };
186            if ret != 0 {
187                Err(ret.into())
188            } else {
189                Ok(())
190            }
191        }
192
193        fn get_quality(&self) -> usize {
194            let mut c_get = 0;
195            unsafe { speex_resampler_get_quality(self.st, &mut c_get) };
196            c_get as usize
197        }
198    }
199
200    impl Drop for State {
201        fn drop(&mut self) {
202            unsafe { speex_resampler_destroy(self.st) };
203        }
204    }
205}
206
207pub mod native {
208    use super::{Error, Resampler};
209    pub use speexdsp_resampler::State;
210
211    impl From<speexdsp_resampler::Error> for Error {
212        fn from(v: speexdsp_resampler::Error) -> Error {
213            match v {
214                speexdsp_resampler::Error::AllocFailed => Error::AllocFailed,
215                speexdsp_resampler::Error::InvalidArg => Error::InvalidArg,
216            }
217        }
218    }
219
220    impl Resampler for State {
221        fn new(
222            channels: usize,
223            in_rate: usize,
224            out_rate: usize,
225            quality: usize,
226        ) -> Result<Self, Error> {
227            State::new(channels, in_rate, out_rate, quality)
228                .map_err(|e| e.into())
229        }
230        fn set_rate(
231            &mut self,
232            in_rate: usize,
233            out_rate: usize,
234        ) -> Result<(), Error> {
235            State::set_rate(self, in_rate, out_rate).map_err(|e| e.into())
236        }
237        fn get_rate(&self) -> (usize, usize) {
238            State::get_rate(self)
239        }
240        fn get_ratio(&self) -> (usize, usize) {
241            State::get_ratio(self)
242        }
243        fn process_float(
244            &mut self,
245            index: usize,
246            input: &[f32],
247            output: &mut [f32],
248        ) -> Result<(usize, usize), Error> {
249            State::process(self, index, input, output).map_err(|e| e.into())
250        }
251        fn skip_zeros(&mut self) {
252            State::skip_zeros(self);
253        }
254        fn reset(&mut self) {
255            State::reset(self);
256        }
257        fn get_input_latency(&self) -> usize {
258            State::get_input_latency(self)
259        }
260        fn get_output_latency(&self) -> usize {
261            State::get_output_latency(self)
262        }
263        fn set_quality(&mut self, quality: usize) -> Result<(), Error> {
264            State::set_quality(self, quality).map_err(|e| e.into())
265        }
266        fn get_quality(&self) -> usize {
267            State::get_quality(self)
268        }
269    }
270}
271
272#[cfg(feature = "sys")]
273pub use self::sys::*;
274
275#[cfg(not(feature = "sys"))]
276pub use self::native::*;