1use crate::base::{Error, Format};
2use crate::frames::{Frames, FramesMut};
3use miniaudio_sys as sys;
4
5#[repr(C)]
6#[derive(Clone, Copy, PartialEq, Eq)]
7pub enum ResampleAlgorithmType {
8 Linear = sys::ma_resample_algorithm_linear as _,
9 Speex = sys::ma_resample_algorithm_speex as _,
10}
11impl_from_c!(ResampleAlgorithmType, sys::ma_resample_algorithm);
12
13#[derive(Clone, Copy, PartialEq)]
19pub enum ResampleAlgorithm {
20 Linear {
21 lpf_order: u32,
22 lpf_nyquist_factor: f64,
23 },
24
25 Speex {
26 quality: u32,
27 },
28}
29
30impl ResampleAlgorithm {
31 pub fn algorithm_type(&self) -> ResampleAlgorithmType {
32 match *self {
33 ResampleAlgorithm::Linear { .. } => ResampleAlgorithmType::Linear,
34 ResampleAlgorithm::Speex { .. } => ResampleAlgorithmType::Speex,
35 }
36 }
37}
38
39#[repr(transparent)]
40#[derive(Clone)]
41pub struct LinearResamplerConfig(sys::ma_linear_resampler_config);
42
43impl LinearResamplerConfig {
44 #[inline]
45 pub fn new(
46 format: Format,
47 channels: u32,
48 sample_rate_in: u32,
49 sample_rate_out: u32,
50 ) -> LinearResamplerConfig {
51 LinearResamplerConfig(unsafe {
52 sys::ma_linear_resampler_config_init(
53 format as _,
54 channels,
55 sample_rate_in,
56 sample_rate_out,
57 )
58 })
59 }
60
61 #[inline]
62 pub fn format(&self) -> Format {
63 Format::from_c(self.0.format)
64 }
65
66 pub fn channels(&self) -> u32 {
67 self.0.channels
68 }
69
70 #[inline]
71 pub fn sample_rate_in(&self) -> u32 {
72 self.0.sampleRateIn
73 }
74
75 #[inline]
76 pub fn set_sample_rate_in(&mut self, sample_rate: u32) {
77 self.0.sampleRateIn = sample_rate;
78 }
79
80 #[inline]
81 pub fn sample_rate_out(&self) -> u32 {
82 self.0.sampleRateOut
83 }
84
85 #[inline]
86 pub fn set_sample_rate_out(&mut self, sample_rate: u32) {
87 self.0.sampleRateOut = sample_rate;
88 }
89
90 #[inline]
91 pub fn lpf_nyquist_factor(&self) -> f64 {
92 self.0.lpfNyquistFactor
93 }
94
95 #[inline]
96 pub fn set_lpf_nyquist_factor(&mut self, factor: f64) {
97 self.0.lpfNyquistFactor = factor;
98 }
99
100 #[inline]
101 pub fn lpf_order(&self) -> u32 {
102 self.0.lpfOrder
103 }
104
105 #[inline]
106 pub fn set_lpf_order(&mut self, order: u32) {
107 self.0.lpfOrder = order;
108 }
109}
110
111#[repr(transparent)]
112pub struct LinearResampler(sys::ma_linear_resampler);
113
114impl LinearResampler {
115 #[inline]
116 pub fn new(config: &LinearResamplerConfig) -> Result<LinearResampler, Error> {
117 let mut lr = std::mem::MaybeUninit::<LinearResampler>::uninit();
118 unsafe {
119 Error::from_c_result(sys::ma_linear_resampler_init(
120 config as *const LinearResamplerConfig as *const _,
121 lr.as_mut_ptr() as *mut _,
122 ))?;
123 Ok(lr.assume_init())
124 }
125 }
126
127 #[inline]
128 pub fn config(&self) -> &LinearResamplerConfig {
129 unsafe {
130 &*(&self.0.config as *const sys::ma_linear_resampler_config
131 as *const LinearResamplerConfig)
132 }
133 }
134
135 #[inline]
148 pub fn process_pcm_frames(
149 &mut self,
150 output: &mut FramesMut,
151 input: &Frames,
152 ) -> Result<(u64, u64), Error> {
153 let mut output_frames = output.frame_count() as u64;
154 let mut input_frames = input.frame_count() as u64;
155
156 Error::from_c_result(unsafe {
157 sys::ma_linear_resampler_process_pcm_frames(
158 &mut self.0,
159 input.as_ptr() as *const _,
160 &mut input_frames,
161 output.as_mut_ptr() as *mut _,
162 &mut output_frames,
163 )
164 })?;
165
166 Ok((output_frames, input_frames))
167 }
168
169 #[inline]
171 pub fn set_rate(&mut self, sample_rate_in: u32, sample_rate_out: u32) -> Result<(), Error> {
172 Error::from_c_result(unsafe {
173 sys::ma_linear_resampler_set_rate(&mut self.0, sample_rate_in, sample_rate_out)
174 })
175 }
176
177 #[inline]
181 pub fn set_rate_ratio(&mut self, ratio_in_out: f32) -> Result<(), Error> {
182 Error::from_c_result(unsafe {
183 sys::ma_linear_resampler_set_rate_ratio(&mut self.0, ratio_in_out)
184 })
185 }
186
187 #[inline]
194 pub fn required_input_frame_count(&self, output_frame_count: u64) -> u64 {
195 unsafe {
196 sys::ma_linear_resampler_get_required_input_frame_count(
197 &self.0 as *const _ as *mut _,
198 output_frame_count,
199 )
200 }
201 }
202
203 #[inline]
206 pub fn expected_output_frame_count(&self, input_frame_count: u64) -> u64 {
207 unsafe {
208 sys::ma_linear_resampler_get_expected_output_frame_count(
209 &self.0 as *const _ as *mut _,
210 input_frame_count,
211 )
212 }
213 }
214 #[inline]
215
216 pub fn input_latency(&mut self) -> u64 {
218 unsafe { sys::ma_linear_resampler_get_input_latency(&self.0 as *const _ as *mut _) }
219 }
220
221 #[inline]
223 pub fn output_latency(&mut self) -> u64 {
224 unsafe { sys::ma_linear_resampler_get_output_latency(&self.0 as *const _ as *mut _) }
225 }
226
227 #[inline]
228 pub fn in_advance_int(&self) -> u32 {
229 self.0.inAdvanceInt
230 }
231
232 #[inline]
233 pub fn in_advance_frac(&self) -> u32 {
234 self.0.inAdvanceFrac
235 }
236
237 #[inline]
238 pub fn in_time_int(&self) -> u32 {
239 self.0.inTimeInt
240 }
241
242 #[inline]
243 pub fn in_time_frac(&self) -> u32 {
244 self.0.inTimeFrac
245 }
246}
247
248impl Drop for LinearResampler {
249 fn drop(&mut self) {
250 unsafe { sys::ma_linear_resampler_uninit(self as *mut LinearResampler as *mut _) };
251 }
252}
253
254impl Clone for LinearResampler {
255 fn clone(&self) -> Self {
256 Self::new(self.config()).expect("failed to clone linear resampler")
258 }
259}
260
261#[repr(transparent)]
262#[derive(Clone)]
263pub struct ResamplerConfig(sys::ma_resampler_config);
264
265impl ResamplerConfig {
266 pub fn new(
267 format: Format,
268 channels: u32,
269 sample_rate_in: u32,
270 sample_rate_out: u32,
271 algorithm: ResampleAlgorithmType,
272 ) -> ResamplerConfig {
273 ResamplerConfig(unsafe {
274 sys::ma_resampler_config_init(
275 format as _,
276 channels,
277 sample_rate_in,
278 sample_rate_out,
279 algorithm as _,
280 )
281 })
282 }
283
284 #[inline]
285 pub fn format(&self) -> Format {
286 Format::from_c(self.0.format)
287 }
288
289 #[inline]
290 pub fn channels(&self) -> u32 {
291 self.0.channels
292 }
293
294 #[inline]
295 pub fn sample_rate_in(&self) -> u32 {
296 self.0.sampleRateIn
297 }
298
299 #[inline]
300 pub fn set_sample_rate_in(&mut self, sample_rate: u32) {
301 self.0.sampleRateIn = sample_rate;
302 }
303
304 #[inline]
305 pub fn sample_rate_out(&self) -> u32 {
306 self.0.sampleRateOut
307 }
308
309 #[inline]
310 pub fn set_sample_rate_out(&mut self, sample_rate: u32) {
311 self.0.sampleRateOut = sample_rate;
312 }
313
314 pub fn set_algorithm(&mut self, algo: ResampleAlgorithm) {
315 match algo {
316 ResampleAlgorithm::Linear {
317 lpf_order,
318 lpf_nyquist_factor,
319 } => {
320 self.0.algorithm = sys::ma_resample_algorithm_linear;
321 self.0.linear.lpfOrder = lpf_order;
322 self.0.linear.lpfNyquistFactor = lpf_nyquist_factor;
323 }
324
325 ResampleAlgorithm::Speex { quality } => {
326 self.0.algorithm = sys::ma_resample_algorithm_speex;
327 self.0.speex.quality = quality as _;
328 }
329 }
330 }
331
332 pub fn algorithm(&self) -> ResampleAlgorithm {
333 match self.0.algorithm {
334 sys::ma_resample_algorithm_linear => ResampleAlgorithm::Linear {
335 lpf_order: self.0.linear.lpfOrder,
336 lpf_nyquist_factor: self.0.linear.lpfNyquistFactor,
337 },
338
339 sys::ma_resample_algorithm_speex => ResampleAlgorithm::Speex {
340 quality: self.0.speex.quality as _,
341 },
342
343 _ => unreachable!(),
344 }
345 }
346}
347
348#[repr(transparent)]
349pub struct Resampler(sys::ma_resampler);
350
351impl Resampler {
352 pub fn new(config: &ResamplerConfig) -> Result<Resampler, Error> {
353 let mut resampler = std::mem::MaybeUninit::<Resampler>::uninit();
354 unsafe {
355 sys::ma_resampler_init(&config.0, resampler.as_mut_ptr() as *mut _);
356 Ok(resampler.assume_init())
357 }
358 }
359
360 #[inline]
361 pub fn config(&self) -> &ResamplerConfig {
362 unsafe { &*(&self.0.config as *const sys::ma_resampler_config as *const ResamplerConfig) }
363 }
364
365 #[inline]
378 pub fn process_pcm_frames(
379 &mut self,
380 output: &mut FramesMut,
381 input: &Frames,
382 ) -> Result<(u64, u64), Error> {
383 if output.format() != input.format() {
384 ma_debug_panic!(
385 "output and input format did not match (output: {:?}, input: {:?}",
386 output.format(),
387 input.format()
388 );
389 return Err(Error::InvalidArgs);
390 }
391
392 let mut output_frames = output.frame_count() as u64;
393 let mut input_frames = input.frame_count() as u64;
394
395 Error::from_c_result(unsafe {
396 sys::ma_resampler_process_pcm_frames(
397 &mut self.0,
398 input.as_ptr() as *const _,
399 &mut input_frames,
400 output.as_mut_ptr() as *mut _,
401 &mut output_frames,
402 )
403 })?;
404
405 Ok((input_frames, output_frames))
406 }
407
408 #[inline]
410 pub fn set_rate(&mut self, sample_rate_in: u32, sample_rate_out: u32) -> Result<(), Error> {
411 Error::from_c_result(unsafe {
412 sys::ma_resampler_set_rate(&mut self.0, sample_rate_in, sample_rate_out)
413 })
414 }
415
416 #[inline]
420 pub fn set_rate_ratio(&mut self, ratio_in_out: f32) -> Result<(), Error> {
421 Error::from_c_result(unsafe { sys::ma_resampler_set_rate_ratio(&mut self.0, ratio_in_out) })
422 }
423
424 #[inline]
431 pub fn required_input_frame_count(&self, output_frame_count: u64) -> u64 {
432 unsafe {
433 sys::ma_resampler_get_required_input_frame_count(
434 &self.0 as *const _ as *mut _,
435 output_frame_count,
436 )
437 }
438 }
439
440 #[inline]
443 pub fn expected_output_frame_count(&self, input_frame_count: u64) -> u64 {
444 unsafe {
445 sys::ma_linear_resampler_get_expected_output_frame_count(
446 &self.0 as *const _ as *mut _,
447 input_frame_count,
448 )
449 }
450 }
451 #[inline]
452
453 pub fn input_latency(&mut self) -> u64 {
455 unsafe { sys::ma_linear_resampler_get_input_latency(&self.0 as *const _ as *mut _) }
456 }
457
458 #[inline]
460 pub fn output_latency(&mut self) -> u64 {
461 unsafe { sys::ma_linear_resampler_get_output_latency(&self.0 as *const _ as *mut _) }
462 }
463}
464
465impl Clone for Resampler {
466 fn clone(&self) -> Self {
467 Self::new(self.config()).expect("failed to clone resampler")
469 }
470}
471
472impl Drop for Resampler {
473 fn drop(&mut self) {
474 unsafe { sys::ma_resampler_uninit(&mut self.0) };
475 }
476}