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::*;