speexdsp_resampler/
speex.rs

1#![allow(dead_code)]
2
3/// [speexdsp][1]-derived audio resampler
4///
5/// [1]: https://github.com/xiph/speexdsp
6use std::mem;
7
8use std::f64::consts::PI as PI_64;
9
10pub const RESAMPLER_ERR_SUCCESS: usize = 0;
11pub const RESAMPLER_ERR_ALLOC_FAILED: usize = 1;
12pub const RESAMPLER_ERR_INVALID_ARG: usize = 3;
13pub const RESAMPLER_ERR_OVERFLOW: usize = 5;
14
15#[derive(Clone)]
16pub struct SpeexResamplerState {
17    in_rate: u32,
18    out_rate: u32,
19    num_rate: u32,
20    den_rate: u32,
21    quality: u32,
22    nb_channels: u32,
23    filt_len: u32,
24    mem_alloc_size: u32,
25    buffer_size: u32,
26    int_advance: u32,
27    frac_advance: u32,
28    cutoff: f32,
29    oversample: u32,
30    initialised: u32,
31    started: u32,
32    last_sample: Vec<u32>,
33    samp_frac_num: Vec<u32>,
34    magic_samples: Vec<u32>,
35    mem: Vec<f32>,
36    sinc_table: Vec<f32>,
37    sinc_table_length: u32,
38    resampler_ptr: ResamplerBasicFunc,
39    in_stride: u32,
40    out_stride: u32,
41}
42
43#[derive(Copy, Clone)]
44pub struct FuncDef {
45    table: &'static [f64],
46    oversample: usize,
47}
48
49impl FuncDef {
50    pub const fn new(table: &'static [f64], oversample: usize) -> Self {
51        Self { table, oversample }
52    }
53}
54
55#[derive(Copy, Clone)]
56pub struct QualityMapping {
57    base_length: usize,
58    oversample: usize,
59    downsample_bandwidth: f32,
60    upsample_bandwidth: f32,
61    window_func: &'static FuncDef,
62}
63
64impl QualityMapping {
65    pub const fn new(
66        base_length: usize,
67        oversample: usize,
68        downsample_bandwidth: f32,
69        upsample_bandwidth: f32,
70        window_func: &'static FuncDef,
71    ) -> Self {
72        Self {
73            base_length,
74            oversample,
75            downsample_bandwidth,
76            upsample_bandwidth,
77            window_func,
78        }
79    }
80}
81
82pub type ResamplerBasicFunc = Option<
83    fn(
84        _: &mut SpeexResamplerState,
85        _: u32,
86        _: &[f32],
87        _: &mut u32,
88        _: &mut [f32],
89        _: &mut u32,
90    ) -> i32,
91>;
92
93macro_rules! chunk_assign {
94    ($ch_mut:ident, $lbound_mut:expr, $ubound_mut:expr, $val:expr) => {
95        $ch_mut[$lbound_mut as usize..$ubound_mut as usize]
96            .iter_mut()
97            .for_each(|x| *x = $val);
98    };
99}
100
101macro_rules! chunk_copy {
102    ($ch_mut:ident, $lbound_mut:expr, $ubound_mut:expr,
103     $ch:ident, $lbound:expr, $ubound:expr) => {
104        $ch_mut[$lbound_mut as usize..$ubound_mut as usize]
105            .iter_mut()
106            .zip($ch[$lbound as usize..$ubound as usize].iter())
107            .for_each(|(x, y)| *x = *y);
108    };
109}
110
111macro_rules! algo {
112    ($self:ident, $ch_mut:ident, $ch:ident,
113     $old_length:ident, $magic:expr) => {
114        let olen = $old_length + 2 * $magic;
115        let filt_len = $self.filt_len - 1;
116        if $self.filt_len > olen {
117            let new_filt_len = $self.filt_len - olen;
118            for new_last_sample in &mut $self.last_sample {
119                chunk_copy!($ch_mut, new_filt_len, filt_len, $ch, 0, olen - 1);
120                chunk_assign!($ch_mut, 0, new_filt_len, 0.0);
121                $magic = 0;
122                *new_last_sample += new_filt_len / 2;
123            }
124        } else {
125            $magic = (olen - $self.filt_len) / 2;
126            let ubound_mut = filt_len + $magic;
127            let ubound = ubound_mut + $magic;
128            chunk_copy!($ch_mut, 0, ubound_mut, $ch, $magic, ubound);
129        }
130    };
131}
132
133impl SpeexResamplerState {
134    /* * Create a new resampler with integer input and output rates.
135     * @param nb_channels number of channels to be processed
136     * @param in_rate Input sampling rate (integer number of Hz).
137     * @param out_rate Output sampling rate (integer number of Hz).
138     * @param quality Resampling quality between 0 and 10, where 0 has poor quality
139     * and 10 has very high quality.
140     * @return newly created resampler state
141     */
142    pub fn new(nb_channels: usize, in_rate: usize, out_rate: usize, quality: usize) -> Self {
143        Self::init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality)
144    }
145
146    /* * Create a new resampler with fractional input/output rates. The sampling
147     * rate ratio is an arbitrary rational number with both the numerator and
148     * denominator being 32-bit integers.
149     * @param nb_channels number of channels to be processed
150     * @param ratio_num numerator of the sampling rate ratio
151     * @param ratio_den Denominator of the sampling rate ratio
152     * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
153     * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
154     * @param quality Resampling quality between 0 and 10, where 0 has poor quality
155     * and 10 has very high quality.
156     * @return newly created resampler state
157     * @retval nULL Error: not enough memory
158     */
159    pub fn init_frac(
160        nb_channels: usize,
161        ratio_num: usize,
162        ratio_den: usize,
163        in_rate: usize,
164        out_rate: usize,
165        quality: usize,
166    ) -> Self {
167        if nb_channels == 0 || ratio_num == 0 || ratio_den == 0 || quality > 10 {
168            panic!("Set the correct parameters!");
169        }
170        let mut st = Self {
171            initialised: 0,
172            started: 0,
173            in_rate: 0,
174            out_rate: 0,
175            num_rate: 0,
176            den_rate: 0,
177            quality: 0,
178            sinc_table: Vec::new(),
179            sinc_table_length: 0,
180            mem: Vec::new(),
181            frac_advance: 0,
182            int_advance: 0,
183            mem_alloc_size: 0,
184            filt_len: 0,
185            resampler_ptr: None,
186            cutoff: 1.0,
187            nb_channels: nb_channels as u32,
188            in_stride: 1,
189            out_stride: 1,
190            buffer_size: 160,
191            oversample: 0,
192            last_sample: vec![0; nb_channels as usize],
193            magic_samples: vec![0; nb_channels as usize],
194            samp_frac_num: vec![0; nb_channels as usize],
195        };
196        st.set_quality(quality);
197        st.set_rate_frac(ratio_num, ratio_den, in_rate, out_rate);
198        let filter_err = st.update_filter();
199        if filter_err == RESAMPLER_ERR_SUCCESS {
200            st.initialised = 1;
201        } else {
202            panic!("Error");
203        }
204        st
205    }
206
207    /* * Resample a float array. The input and output buffers must *not* overlap.
208     * @param st Resampler state
209     * @param channel_index Index of the channel to process for the multi-channel
210     * base (0 otherwise)
211     * @param in Input buffer
212     * @param in_len number of input samples in the input buffer. Returns the
213     * number of samples processed
214     * @param out Output buffer
215     * @param out_len Size of the output buffer. Returns the number of samples written
216     */
217    pub fn process_float(
218        &mut self,
219        channel_index: u32,
220        mut in_0: &[f32],
221        in_len: &mut u32,
222        mut out: &mut [f32],
223        out_len: &mut u32,
224    ) -> usize {
225        if in_0.is_empty() {
226            panic!("Empty input slice is not allowed");
227        }
228        let mut ilen = *in_len;
229        let mut olen = *out_len;
230        let channel_idx = channel_index as usize;
231        let filt_offs = (self.filt_len - 1) as usize;
232        let mem_idx = filt_offs + channel_idx * self.mem_alloc_size as usize;
233        let xlen = self.mem_alloc_size - self.filt_len - 1;
234        let istride = self.in_stride as usize;
235        if self.magic_samples[channel_idx] != 0 {
236            olen -= speex_resampler_magic(self, channel_index, &mut out, olen);
237        }
238        if self.magic_samples[channel_idx] == 0 {
239            while 0 != ilen && 0 != olen {
240                let mut ichunk: u32 = if ilen > xlen { xlen } else { ilen };
241                let mut ochunk: u32 = olen;
242                let mem_slice = &mut self.mem[mem_idx..];
243                let mem_iter = mem_slice.iter_mut();
244                let in_iter = in_0.iter().step_by(istride);
245                mem_iter
246                    .zip(in_iter)
247                    .take(ichunk as usize)
248                    .for_each(|(x, &y)| {
249                        *x = y;
250                    });
251                speex_resampler_process_native(self, channel_index, &mut ichunk, out, &mut ochunk);
252                ilen -= ichunk;
253                olen -= ochunk;
254                out = &mut out[(ochunk * self.out_stride) as usize..][..];
255                in_0 = &in_0[(ichunk * self.in_stride) as usize..][..];
256            }
257        }
258        *in_len -= ilen;
259        *out_len -= olen;
260        let resampler = self.resampler_ptr.unwrap();
261        if resampler as usize == resampler_basic_zero as usize {
262            RESAMPLER_ERR_ALLOC_FAILED
263        } else {
264            RESAMPLER_ERR_SUCCESS
265        }
266    }
267
268    /* * Resample an int array. The input and output buffers muself *not* overlap.
269     * @param self Resampler selfate
270     * @param channel_index Index of the channel to process for the multi-channel
271     * base (0 otherwise)
272     * @param in Input buffer
273     * @param in_len number of input samples in the input buffer. Returns the number
274     * of samples processed
275     * @param out Output buffer
276     * @param out_len Size of the output buffer. Returns the number of samples written
277     */
278    pub fn process_int(
279        &mut self,
280        channel_index: u32,
281        mut in_0: &[i16],
282        in_len: &mut u32,
283        mut out: &mut [i16],
284        out_len: &mut u32,
285    ) -> usize {
286        if in_0.is_empty() {
287            panic!("Empty input slice is not allowed");
288        }
289        let mut j: u32;
290        let istride_save = self.in_stride;
291        let ostride_save = self.out_stride;
292        let mut ilen = *in_len;
293        let mut olen = *out_len;
294        let mem_idx = (channel_index * self.mem_alloc_size) as usize;
295        let xlen: u32 = self.mem_alloc_size - self.filt_len - 1;
296        let ylen: u32 = if olen < 8192 { olen } else { 8192 };
297        let mut yselfack: Vec<f32> = vec![0.; ylen as usize];
298        self.out_stride = 1;
299        while 0 != ilen && 0 != olen {
300            let mut ichunk: u32 = if ilen > xlen { xlen } else { ilen };
301            let mut ochunk: u32 = if olen > ylen { ylen } else { olen };
302            let mut omagic: u32 = 0;
303            if self.magic_samples[channel_index as usize] != 0 {
304                omagic = speex_resampler_magic(
305                    self,
306                    channel_index,
307                    &mut yselfack.as_mut_slice(),
308                    ochunk,
309                ) as u32;
310                ochunk -= omagic;
311                olen -= omagic
312            }
313            if 0 == self.magic_samples[channel_index as usize] {
314                j = 0u32;
315                while j < ichunk {
316                    self.mem[mem_idx + j as usize + (self.filt_len - 1) as usize] =
317                        in_0[(j * istride_save) as usize] as f32;
318                    j += 1
319                }
320                speex_resampler_process_native(
321                    self,
322                    channel_index,
323                    &mut ichunk,
324                    yselfack.as_mut_slice(),
325                    &mut ochunk,
326                );
327            } else {
328                ichunk = 0i32 as u32;
329                ochunk = 0i32 as u32
330            }
331            j = 0u32;
332            while j < ochunk + omagic {
333                out[(j * ostride_save) as usize] = (if yselfack[j as usize] < -32767.5 {
334                    -32768
335                } else if yselfack[j as usize] > 32766.5 {
336                    32767
337                } else {
338                    (0.5 + yselfack[j as usize]).floor() as i32
339                }) as i16;
340                j += 1
341            }
342            ilen -= ichunk;
343            olen -= ochunk;
344            out = &mut out[(ochunk + omagic * ostride_save as u32) as usize..];
345            in_0 = &in_0[(ichunk * istride_save as u32) as usize..];
346        }
347        self.out_stride = ostride_save;
348        *in_len -= ilen;
349        *out_len -= olen;
350        let resampler = self.resampler_ptr.unwrap();
351        if resampler as usize == resampler_basic_zero as usize {
352            RESAMPLER_ERR_ALLOC_FAILED
353        } else {
354            RESAMPLER_ERR_SUCCESS
355        }
356    }
357
358    /* * Resample an interleaved float array. The input and output buffers muself *not* overlap.
359     * @param self Resampler selfate
360     * @param in Input buffer
361     * @param in_len number of input samples in the input buffer. Returns the number
362     * of samples processed. This is all per-channel.
363     * @param out Output buffer
364     * @param out_len Size of the output buffer. Returns the number of samples written.
365     * This is all per-channel.
366     */
367    pub fn process_interleaved_float(
368        &mut self,
369        in_0: &[f32],
370        in_len: &mut u32,
371        out: &mut [f32],
372        out_len: &mut u32,
373    ) -> usize {
374        if in_0.is_empty() {
375            panic!("Empty input slice is not allowed");
376        }
377        let istride_save = self.in_stride;
378        let ostride_save = self.out_stride;
379        let bak_out_len = *out_len;
380        let bak_in_len = *in_len;
381
382        self.out_stride = self.nb_channels;
383        self.in_stride = self.out_stride;
384        for i in 0..self.nb_channels as usize {
385            *out_len = bak_out_len;
386            *in_len = bak_in_len;
387            self.process_float(i as u32, &in_0[i..], in_len, &mut out[i..], out_len);
388        }
389        self.in_stride = istride_save;
390        self.out_stride = ostride_save;
391        let resampler = self.resampler_ptr.unwrap();
392        if resampler as usize == resampler_basic_zero as usize {
393            RESAMPLER_ERR_ALLOC_FAILED
394        } else {
395            RESAMPLER_ERR_SUCCESS
396        }
397    }
398
399    /* * Resample an interleaved int array. The input and output buffers muself *not* overlap.
400     * @param self Resampler selfate
401     * @param in Input buffer
402     * @param in_len number of input samples in the input buffer. Returns the number
403     * of samples processed. This is all per-channel.
404     * @param out Output buffer
405     * @param out_len Size of the output buffer. Returns the number of samples written.
406     * This is all per-channel.
407     */
408    pub fn process_interleaved_int(
409        &mut self,
410        in_0: &[i16],
411        in_len: &mut u32,
412        out: &mut [i16],
413        out_len: &mut u32,
414    ) -> usize {
415        if in_0.is_empty() {
416            panic!("Empty input slice is not allowed");
417        }
418        let istride_save = self.in_stride;
419        let ostride_save = self.out_stride;
420        let bak_out_len = *out_len;
421        let bak_in_len = *in_len;
422
423        self.out_stride = self.nb_channels;
424        self.in_stride = self.out_stride;
425        for i in 0..self.nb_channels as usize {
426            *out_len = bak_out_len;
427            *in_len = bak_in_len;
428            self.process_int(i as u32, &in_0[i..], in_len, &mut out[i..], out_len);
429        }
430        self.in_stride = istride_save;
431        self.out_stride = ostride_save;
432        let resampler = self.resampler_ptr.unwrap();
433        if resampler as usize == resampler_basic_zero as usize {
434            RESAMPLER_ERR_ALLOC_FAILED
435        } else {
436            RESAMPLER_ERR_SUCCESS
437        }
438    }
439
440    /* * Set (change) the conversion quality.
441     * @param st Resampler state
442     * @param quality Resampling quality between 0 and 10, where 0 has poor
443     * quality and 10 has very high quality.
444     */
445    pub fn set_quality(&mut self, quality: usize) -> usize {
446        if quality > 10 {
447            RESAMPLER_ERR_INVALID_ARG
448        } else if self.quality as usize == quality {
449            RESAMPLER_ERR_SUCCESS
450        } else {
451            self.quality = quality as u32;
452            if self.initialised != 0 {
453                self.update_filter()
454            } else {
455                RESAMPLER_ERR_SUCCESS
456            }
457        }
458    }
459
460    /* * Set (change) the input/output sampling rates (integer value).
461     * @param st Resampler state
462     * @param in_rate Input sampling rate (integer number of Hz).
463     * @param out_rate Output sampling rate (integer number of Hz).
464     */
465    pub fn set_rate(&mut self, in_rate: usize, out_rate: usize) -> usize {
466        self.set_rate_frac(in_rate, out_rate, in_rate, out_rate)
467    }
468
469    /* * Set (change) the input/output sampling rates and resampling ratio
470     * (fractional values in Hz supported).
471     * @param st Resampler state
472     * @param ratio_num numerator of the sampling rate ratio
473     * @param ratio_den Denominator of the sampling rate ratio
474     * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
475     * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
476     */
477    pub fn set_rate_frac(
478        &mut self,
479        ratio_num: usize,
480        ratio_den: usize,
481        in_rate: usize,
482        out_rate: usize,
483    ) -> usize {
484        if ratio_num == 0 || ratio_den == 0 {
485            RESAMPLER_ERR_INVALID_ARG
486        } else if self.in_rate == in_rate as u32
487            && self.out_rate == out_rate as u32
488            && self.num_rate == ratio_num as u32
489            && self.den_rate == ratio_den as u32
490        {
491            RESAMPLER_ERR_SUCCESS
492        } else {
493            let old_den = self.den_rate;
494            self.in_rate = in_rate as u32;
495            self.out_rate = out_rate as u32;
496            self.num_rate = ratio_num as u32;
497            self.den_rate = ratio_den as u32;
498            let fact = _gcd(self.num_rate, self.den_rate);
499            self.num_rate = self.num_rate / fact;
500            self.den_rate = self.den_rate / fact;
501            if old_den > 0 {
502                for val in &mut self.samp_frac_num {
503                    let res = _muldiv(val, *val, self.den_rate, old_den);
504                    if res != RESAMPLER_ERR_SUCCESS {
505                        return RESAMPLER_ERR_OVERFLOW;
506                    } else {
507                        if *val >= self.den_rate {
508                            *val = self.den_rate - 1;
509                        }
510                    }
511                }
512            }
513            if self.initialised != 0 {
514                self.update_filter()
515            } else {
516                RESAMPLER_ERR_SUCCESS
517            }
518        }
519    }
520
521    /* * Get the current input/output sampling rates (integer value).
522     * @param st Resampler state
523     */
524    pub fn get_rate(&self) -> (usize, usize) {
525        (self.in_rate as usize, self.out_rate as usize)
526    }
527
528    /* * Get the current resampling ratio. This will be reduced to the least
529     * common denominator.
530     * @param st Resampler state
531     */
532    pub fn get_ratio(&self) -> (usize, usize) {
533        (self.num_rate as usize, self.den_rate as usize)
534    }
535
536    /* * Get the conversion quality.
537     * @param st Resampler state
538     * @return Resampling quality between 0 and 10, where 0 has poor
539     * quality and 10 has very high quality.
540     */
541    pub fn get_quality(&self) -> usize {
542        self.quality as usize
543    }
544
545    /* * Set (change) the input stride.
546     * @param st Resampler state
547     * @param stride Input stride
548     */
549    pub fn set_input_stride(&mut self, stride: usize) {
550        self.in_stride = stride as u32;
551    }
552
553    /* * Get the input stride.
554     * @param st Resampler state
555     * @return Input stride copied
556     */
557    pub fn get_input_stride(&mut self) -> usize {
558        self.in_stride as usize
559    }
560
561    /* * Set (change) the output stride.
562     * @param st Resampler state
563     * @param stride Output stride
564     */
565    pub fn set_output_stride(&mut self, stride: usize) {
566        self.out_stride = stride as u32;
567    }
568
569    /* * Get the output stride.
570     * @param st Resampler state copied
571     * @return Output stride
572     */
573    pub fn get_output_stride(&mut self) -> usize {
574        self.out_stride as usize
575    }
576
577    /* * Get the latency introduced by the resampler measured in input samples.
578     * @param st Resampler state
579     */
580    pub fn get_input_latency(&self) -> usize {
581        (self.filt_len / 2) as usize
582    }
583
584    /* * Get the latency introduced by the resampler measured in output samples.
585     * @param st Resampler state
586     */
587    pub fn get_output_latency(&self) -> usize {
588        (((self.filt_len / 2) * self.den_rate + (self.num_rate >> 1)) / self.num_rate) as usize
589    }
590
591    /* * Make sure that the first samples to go out of the resamplers don't have
592     * leading zeros. This is only useful before starting to use a newly created
593     * resampler. It is recommended to use that when resampling an audio file, as
594     * it will generate a file with the same length. For real-time processing,
595     * it is probably easier not to use this call (so that the output duration
596     * is the same for the first frame).
597     * @param st Resampler state
598     */
599    pub fn skip_zeros(&mut self) {
600        let filt_len = self.filt_len / 2;
601        self.last_sample.iter_mut().for_each(|v: &mut u32| {
602            *v = filt_len;
603        });
604    }
605
606    /* * Reset a resampler so a new (unrelated) stream can be processed.
607     * @param st Resampler state
608     */
609    pub fn reset_mem(&mut self) {
610        self.last_sample.iter_mut().for_each(|elem| *elem = 0);
611        self.magic_samples.iter_mut().for_each(|elem| *elem = 0);
612        self.samp_frac_num.iter_mut().for_each(|elem| *elem = 0);
613
614        self.mem.iter_mut().for_each(|elem| *elem = 0.);
615    }
616
617    #[inline]
618    fn num_den(&mut self) {
619        self.cutoff = QUALITY_MAP[self.quality as usize].downsample_bandwidth
620            * self.den_rate as f32
621            / self.num_rate as f32;
622        let pass = self.filt_len;
623        _muldiv(&mut self.filt_len, pass, self.num_rate, self.den_rate);
624        self.filt_len = ((self.filt_len - 1) & (!7)) + 8;
625        self.oversample = (1..5)
626            .filter(|x| 2u32.pow(*x) * self.den_rate < self.num_rate)
627            .fold(self.oversample, |acc, _| acc >> 1);
628
629        if self.oversample < 1 {
630            self.oversample = 1;
631        }
632    }
633
634    #[inline]
635    fn use_direct(&mut self) {
636        let iter_chunk = self.sinc_table.chunks_mut(self.filt_len as usize);
637        for (i, chunk) in iter_chunk.enumerate() {
638            for (j, elem) in chunk.iter_mut().enumerate() {
639                *elem = sinc(
640                    self.cutoff,
641                    (j as f32 - self.filt_len as f32 / 2.0 + 1.0)
642                        - (i as f32) / self.den_rate as f32,
643                    self.filt_len as i32,
644                    QUALITY_MAP[self.quality as usize].window_func,
645                );
646            }
647        }
648        if self.quality > 8 {
649            self.resampler_ptr = Some(resampler_basic_direct_double);
650        } else {
651            self.resampler_ptr = Some(resampler_basic_direct_single);
652        }
653    }
654
655    #[inline]
656    fn not_use_direct(&mut self) {
657        let quality = self.quality as usize;
658        let cutoff = self.cutoff;
659        let oversample = self.oversample;
660        let filt_len = self.filt_len;
661        self.sinc_table
662            .iter_mut()
663            .enumerate()
664            .take((oversample * filt_len + 8) as usize)
665            .for_each(|(i, x)| {
666                *x = sinc(
667                    cutoff,
668                    (i as i32 - 4) as f32 / oversample as f32 - filt_len as f32 / 2.0,
669                    filt_len as i32,
670                    QUALITY_MAP[quality].window_func,
671                )
672            });
673        if self.quality > 8 {
674            self.resampler_ptr = Some(resampler_basic_interpolate_double);
675        } else {
676            self.resampler_ptr = Some(resampler_basic_interpolate_single);
677        }
678    }
679
680    #[inline(always)]
681    fn chunks_iterator(&mut self, old_length: u32, alloc_size: usize, algo: usize) {
682        let mem_copy = self.mem.clone();
683
684        let mut_mem = self.mem.chunks_mut(self.mem_alloc_size as usize);
685        let mem = mem_copy.chunks(alloc_size);
686
687        for (ch_mut, ch) in mut_mem.zip(mem) {
688            for magic in &mut self.magic_samples {
689                if algo == 0 {
690                    let range = old_length - 1 + *magic;
691                    chunk_copy!(ch_mut, *magic, range, ch, 0, range);
692                    chunk_assign!(ch_mut, 0, *magic, 0.0);
693                } else if algo == 1 {
694                    algo!(self, ch_mut, ch, old_length, *magic);
695                } else {
696                    let skip = (old_length - self.filt_len) / 2;
697                    let ubound = self.filt_len - 1 + skip + *magic;
698                    chunk_copy!(ch_mut, 0, ubound, ch, skip, ubound + skip);
699                    *magic += skip;
700                }
701            }
702        }
703    }
704
705    fn update_filter(&mut self) -> usize {
706        let old_length = self.filt_len;
707        let quality = self.quality as usize;
708        let old_alloc_size = self.mem_alloc_size as usize;
709        self.int_advance = self.num_rate / self.den_rate;
710        self.frac_advance = self.num_rate % self.den_rate;
711        self.oversample = QUALITY_MAP[quality].oversample as u32;
712        self.filt_len = QUALITY_MAP[quality].base_length as u32;
713        if self.num_rate > self.den_rate {
714            self.num_den();
715        } else {
716            self.cutoff = QUALITY_MAP[quality].upsample_bandwidth;
717        }
718
719        let use_direct = self.filt_len * self.den_rate <= self.filt_len * self.oversample + 8
720            && 2147483647 as u64 / ::std::mem::size_of::<f32>() as u64 / self.den_rate as u64
721                >= self.filt_len as u64;
722
723        let mut min_sinc_table_length = self.filt_len * self.den_rate;
724        if !use_direct {
725            min_sinc_table_length = self.filt_len * self.oversample + 8;
726        }
727
728        if self.sinc_table_length < min_sinc_table_length {
729            self.sinc_table = vec![0.0; min_sinc_table_length as usize];
730            self.sinc_table_length = min_sinc_table_length;
731        }
732
733        if use_direct {
734            self.use_direct();
735        } else {
736            self.not_use_direct();
737        }
738
739        let min_alloc_size = self.filt_len - 1 + self.buffer_size;
740        if min_alloc_size > self.mem_alloc_size {
741            let mem = self.mem.clone();
742            self.mem = vec![0.0; (self.nb_channels * min_alloc_size) as usize];
743            self.mem[0..mem.len()].copy_from_slice(&mem);
744            self.mem_alloc_size = min_alloc_size;
745        }
746
747        if self.started == 0 {
748            let dim = (self.nb_channels * self.mem_alloc_size) as usize;
749            self.mem = vec![0.0; dim];
750        } else if self.filt_len > old_length {
751            self.chunks_iterator(old_length, old_alloc_size, 0);
752            self.chunks_iterator(old_length, self.mem_alloc_size as usize, 1);
753        } else if self.filt_len < old_length {
754            self.chunks_iterator(old_length, self.mem_alloc_size as usize, 2);
755        }
756        return RESAMPLER_ERR_SUCCESS;
757    }
758}
759
760fn resampler_basic_zero(
761    st: &mut SpeexResamplerState,
762    channel_index: u32,
763    _in_0: &[f32],
764    in_len: &mut u32,
765    out: &mut [f32],
766    out_len: &mut u32,
767) -> i32 {
768    let mut out_sample: u32 = 0;
769    let mut last_sample = st.last_sample[channel_index as usize];
770    let mut samp_frac_num = st.samp_frac_num[channel_index as usize];
771    let out_stride = st.out_stride;
772    let int_advance = st.int_advance;
773    let frac_advance = st.frac_advance;
774    let den_rate: u32 = st.den_rate;
775    while !(last_sample >= *in_len || out_sample >= *out_len) {
776        out[(out_stride * out_sample) as usize] = 0.0;
777        out_sample = out_sample + 1;
778        last_sample += int_advance;
779        samp_frac_num += frac_advance as u32;
780        if samp_frac_num >= den_rate {
781            samp_frac_num -= den_rate as u32;
782            last_sample += 1
783        }
784    }
785    st.last_sample[channel_index as usize] = last_sample;
786    st.samp_frac_num[channel_index as usize] = samp_frac_num;
787    out_sample as i32
788}
789
790fn resampler_basic_interpolate_single(
791    st: &mut SpeexResamplerState,
792    channel_index: u32,
793    in_0: &[f32],
794    in_len: &mut u32,
795    out: &mut [f32],
796    out_len: &mut u32,
797) -> i32 {
798    let n = st.filt_len as usize;
799    let channel_idx = channel_index as usize;
800    let mut last_sample = st.last_sample[channel_idx];
801    let mut samp_frac_num = st.samp_frac_num[channel_idx];
802    let out_stride = st.out_stride;
803    let int_advance = st.int_advance;
804    let frac_advance = st.frac_advance;
805    let den_rate = st.den_rate;
806    let oversample = st.oversample;
807    let sinc_table = &st.sinc_table;
808
809    let mut out_sample: u32 = 0;
810    while !(last_sample >= *in_len || out_sample >= *out_len) {
811        let iptr = &in_0[last_sample as usize..];
812        let offset = samp_frac_num * oversample / den_rate;
813        let frac = ((samp_frac_num * oversample) % den_rate) as f32 / den_rate as f32;
814        let mut accum: [f32; 4] = [0.; 4];
815        iptr.iter().zip(0..n).for_each(|(&curr_in, j)| {
816            let idx = (2 + (j + 1) * oversample as usize) - offset as usize;
817            accum
818                .iter_mut()
819                .zip(sinc_table.iter().skip(idx))
820                .for_each(|(v, &s)| {
821                    *v += curr_in * s;
822                });
823        });
824        let mut interp: [f32; 4] = [0.; 4];
825        cubic_coef(frac, &mut interp);
826        out[(out_stride * out_sample) as usize] = interp
827            .iter()
828            .zip(accum.iter())
829            .map(|(&x, &y)| x * y)
830            .fold(0., |acc, x| acc + x);
831        out_sample += 1;
832        last_sample += int_advance;
833        samp_frac_num += frac_advance as u32;
834        if samp_frac_num >= den_rate {
835            samp_frac_num -= den_rate;
836            last_sample += 1;
837        }
838    }
839    st.last_sample[channel_idx] = last_sample;
840    st.samp_frac_num[channel_idx] = samp_frac_num;
841    out_sample as i32
842}
843
844fn cubic_coef(frac: f32, interp: &mut [f32]) {
845    interp[0] = -0.16666999459266663 * frac + 0.16666999459266663 * frac * frac * frac;
846    interp[1] = frac + 0.5 * frac * frac - 0.5f32 * frac * frac * frac;
847    interp[3] =
848        -0.3333300054073334 * frac + 0.5 * frac * frac - 0.16666999459266663 * frac * frac * frac;
849    interp[2] = (1.0f64 - interp[0] as f64 - interp[1] as f64 - interp[3] as f64) as f32;
850}
851
852fn resampler_basic_interpolate_double(
853    st: &mut SpeexResamplerState,
854    channel_index: u32,
855    in_0: &[f32],
856    in_len: &mut u32,
857    out: &mut [f32],
858    out_len: &mut u32,
859) -> i32 {
860    let n = st.filt_len as usize;
861    let channel_idx = channel_index as usize;
862    let mut last_sample = st.last_sample[channel_idx];
863    let mut samp_frac_num = st.samp_frac_num[channel_idx];
864    let out_stride = st.out_stride;
865    let int_advance = st.int_advance;
866    let oversample = st.oversample;
867    let frac_advance = st.frac_advance;
868    let den_rate = st.den_rate;
869    let sinc_table = &st.sinc_table;
870
871    let mut out_sample: u32 = 0;
872
873    while !(last_sample >= *in_len || out_sample >= *out_len) {
874        let iptr: &[f32] = &in_0[last_sample as usize..];
875        let offset = samp_frac_num * st.oversample / st.den_rate;
876        let frac = (samp_frac_num * oversample % den_rate) as f32 / den_rate as f32;
877        let mut accum: [f64; 4] = [0.0; 4];
878        iptr.iter().zip(0..n).for_each(|(&curr_in, j)| {
879            let idx = (2 + (j + 1) * oversample as usize) - offset as usize;
880            accum
881                .iter_mut()
882                .zip(sinc_table.iter().skip(idx))
883                .for_each(|(v, &s)| {
884                    *v += (curr_in * s) as f64;
885                });
886        });
887        let mut interp: [f32; 4] = [0.; 4];
888        cubic_coef(frac, &mut interp);
889        out[(out_stride * out_sample) as usize] = interp
890            .iter()
891            .zip(accum.iter())
892            .map(|(&x, &y)| x * y as f32)
893            .fold(0., |acc, x| acc + x);
894        out_sample = out_sample + 1;
895        last_sample += int_advance;
896        samp_frac_num += frac_advance;
897        if samp_frac_num >= den_rate {
898            samp_frac_num -= den_rate;
899            last_sample += 1
900        }
901    }
902    st.last_sample[channel_index as usize] = last_sample;
903    st.samp_frac_num[channel_index as usize] = samp_frac_num;
904    out_sample as i32
905}
906
907static QUALITY_MAP: [QualityMapping; 11] = [
908    QualityMapping::new(8, 4, 0.8299999833106995, 0.8600000143051148, &_KAISER6),
909    QualityMapping::new(16, 4, 0.8500000238418579, 0.8799999952316284, &_KAISER6),
910    QualityMapping::new(32, 4, 0.8820000290870667, 0.9100000262260437, &_KAISER6),
911    QualityMapping::new(48, 8, 0.8949999809265137, 0.9169999957084656, &_KAISER8),
912    QualityMapping::new(64, 8, 0.9210000038146973, 0.9399999976158142, &_KAISER8),
913    QualityMapping::new(80, 16, 0.921999990940094, 0.9399999976158142, &_KAISER10),
914    QualityMapping::new(96, 16, 0.9399999976158142, 0.9449999928474426, &_KAISER10),
915    QualityMapping::new(128, 16, 0.949999988079071, 0.949999988079071, &_KAISER10),
916    QualityMapping::new(160, 16, 0.9599999785423279, 0.9599999785423279, &_KAISER10),
917    QualityMapping::new(192, 32, 0.9679999947547913, 0.9679999947547913, &_KAISER12),
918    QualityMapping::new(256, 32, 0.9750000238418579, 0.9750000238418579, &_KAISER12),
919];
920
921static _KAISER12: FuncDef = FuncDef::new(&KAISER12_TABLE, 64);
922
923static KAISER12_TABLE: [f64; 68] = {
924    [
925        0.99859849,
926        1.0,
927        0.99859849,
928        0.99440475,
929        0.98745105,
930        0.97779076,
931        0.9654977,
932        0.95066529,
933        0.93340547,
934        0.91384741,
935        0.89213598,
936        0.86843014,
937        0.84290116,
938        0.81573067,
939        0.78710866,
940        0.75723148,
941        0.7262997,
942        0.69451601,
943        0.66208321,
944        0.62920216,
945        0.59606986,
946        0.56287762,
947        0.52980938,
948        0.49704014,
949        0.46473455,
950        0.43304576,
951        0.40211431,
952        0.37206735,
953        0.343018,
954        0.3150649,
955        0.28829195,
956        0.26276832,
957        0.23854851,
958        0.21567274,
959        0.19416736,
960        0.17404546,
961        0.15530766,
962        0.13794293999999999,
963        0.12192957,
964        0.10723616,
965        0.09382272,
966        0.08164178,
967        0.0706395,
968        0.06075685,
969        0.05193064,
970        0.04409466,
971        0.03718069,
972        0.03111947,
973        0.02584161,
974        0.02127838,
975        0.0173625,
976        0.01402878,
977        0.01121463,
978        0.00886058,
979        0.00691064,
980        0.00531256,
981        0.00401805,
982        0.00298291,
983        0.00216702,
984        0.00153438,
985        0.00105297,
986        0.00069463,
987        0.00043489,
988        0.00025272,
989        0.00013031,
990        0.0000527734,
991        0.00001,
992        0.0,
993    ]
994};
995
996static _KAISER10: FuncDef = FuncDef::new(&KAISER10_TABLE, 32);
997
998static KAISER10_TABLE: [f64; 36] = {
999    [
1000        0.99537781, 1.0, 0.99537781, 0.98162644, 0.95908712, 0.92831446, 0.89005583, 0.84522401,
1001        0.79486424, 0.74011713, 0.68217934, 0.62226347, 0.56155915, 0.5011968, 0.44221549,
1002        0.38553619, 0.33194107, 0.28205962, 0.23636152, 0.19515633, 0.15859932, 0.1267028,
1003        0.09935205, 0.07632451, 0.05731132, 0.0419398, 0.02979584, 0.0204451, 0.01345224,
1004        0.00839739, 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.0, 0.0,
1005    ]
1006};
1007
1008static _KAISER8: FuncDef = FuncDef::new(&KAISER8_TABLE, 32);
1009
1010static KAISER8_TABLE: [f64; 36] = {
1011    [
1012        0.99635258, 1.0, 0.99635258, 0.98548012, 0.96759014, 0.943022, 0.91223751, 0.87580811,
1013        0.83439927, 0.78875245, 0.73966538, 0.68797126, 0.6345175, 0.58014482, 0.52566725,
1014        0.47185369, 0.4194115, 0.36897272, 0.32108304, 0.27619388, 0.23465776, 0.1967267,
1015        0.1625538, 0.13219758, 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321,
1016        0.0236949, 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.0005, 0.0,
1017    ]
1018};
1019
1020static _KAISER6: FuncDef = FuncDef::new(&KAISER6_TABLE, 32);
1021
1022static KAISER6_TABLE: [f64; 36] = {
1023    [
1024        0.99733006, 1.0, 0.99733006, 0.98935595, 0.97618418, 0.95799003, 0.93501423, 0.90755855,
1025        0.87598009, 0.84068475, 0.80211977, 0.76076565, 0.71712752, 0.67172623, 0.62508937,
1026        0.57774224, 0.53019925, 0.48295561, 0.43647969, 0.39120616, 0.34752997, 0.30580127,
1027        0.26632152, 0.22934058, 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.0869312,
1028        0.067226, 0.0503182, 0.03607231, 0.02432151, 0.01487334, 0.00752, 0.0,
1029    ]
1030};
1031
1032fn sinc(cutoff: f32, x: f32, n: i32, window_func: &FuncDef) -> f32 {
1033    let xx = f64::from(x * cutoff);
1034    let x_abs = f64::from(x).abs();
1035    let n_64 = f64::from(n);
1036    let cutoff_64 = f64::from(cutoff);
1037    if x_abs < 0.000001 {
1038        cutoff
1039    } else if x_abs > 0.5 * n_64 {
1040        0.0
1041    } else {
1042        let first_factor = cutoff_64 * (PI_64 * xx).sin() / (PI_64 * xx);
1043        let second_factor = compute_func((2.0 * f64::from(x) / n_64).abs() as f32, window_func);
1044        (first_factor * second_factor) as f32
1045    }
1046}
1047
1048fn compute_func(x: f32, func: &FuncDef) -> f64 {
1049    let mut interp: [f64; 4] = [0.0; 4];
1050    let y = x * func.oversample as f32;
1051    let ind = y.floor() as usize;
1052    let frac = f64::from(y - ind as f32);
1053    interp[3] = -0.1666666667 * frac + 0.1666666667 * frac.powi(3);
1054    interp[2] = frac + 0.5 * frac.powi(2) - 0.5 * frac.powi(3);
1055    interp[0] = -0.3333333333 * frac + 0.5 * frac.powi(2) - 0.1666666667 * frac.powi(3);
1056    interp[1] = 1.0 - interp[3] - interp[2] - interp[0];
1057
1058    interp
1059        .iter()
1060        .zip(func.table.iter().skip(ind))
1061        .map(|(&x, &y)| x * y)
1062        .sum()
1063}
1064
1065fn resampler_basic_direct_single(
1066    st: &mut SpeexResamplerState,
1067    channel_index: u32,
1068    in_0: &[f32],
1069    in_len: &mut u32,
1070    out: &mut [f32],
1071    out_len: &mut u32,
1072) -> i32 {
1073    let n: i32 = st.filt_len as i32;
1074    let mut out_sample: u32 = 0;
1075    let mut last_sample = st.last_sample[channel_index as usize];
1076    let mut samp_frac_num = st.samp_frac_num[channel_index as usize];
1077    let out_stride = st.out_stride;
1078    let int_advance = st.int_advance;
1079    let frac_advance = st.frac_advance;
1080    let den_rate: u32 = st.den_rate;
1081    while !(last_sample >= *in_len || out_sample >= *out_len) {
1082        let sinct: &[f32] = &st.sinc_table[(samp_frac_num * n as u32) as usize..];
1083        let iptr: &[f32] = &in_0[last_sample as usize..];
1084        let mut sum: f32 = 0.0;
1085        let mut j: i32 = 0;
1086        while j < n {
1087            sum += sinct[j as usize] * iptr[j as usize];
1088            j += 1
1089        }
1090        out[(out_stride * out_sample) as usize] = sum;
1091        out_sample += 1;
1092        last_sample += int_advance;
1093        samp_frac_num += frac_advance as u32;
1094        if samp_frac_num >= den_rate {
1095            samp_frac_num -= den_rate as u32;
1096            last_sample += 1
1097        }
1098    }
1099    st.last_sample[channel_index as usize] = last_sample;
1100    st.samp_frac_num[channel_index as usize] = samp_frac_num;
1101    out_sample as i32
1102}
1103
1104fn resampler_basic_direct_double(
1105    st: &mut SpeexResamplerState,
1106    channel_index: u32,
1107    in_0: &[f32],
1108    in_len: &mut u32,
1109    out: &mut [f32],
1110    out_len: &mut u32,
1111) -> i32 {
1112    let n: i32 = st.filt_len as i32;
1113    let mut out_sample: u32 = 0;
1114    let mut last_sample = st.last_sample[channel_index as usize];
1115    let mut samp_frac_num = st.samp_frac_num[channel_index as usize];
1116    let out_stride = st.out_stride;
1117    let int_advance = st.int_advance;
1118    let frac_advance = st.frac_advance;
1119    let den_rate: u32 = st.den_rate;
1120    while !(last_sample >= *in_len || out_sample >= *out_len) {
1121        let sinct: &[f32] = &st.sinc_table[(samp_frac_num * n as u32) as usize..];
1122        let iptr: &[f32] = &in_0[last_sample as usize..];
1123        let mut accum: [f64; 4] = [0.0; 4];
1124        let mut j: i32 = 0;
1125        while j < n {
1126            accum[0usize] += f64::from(sinct[j as usize] * iptr[j as usize]);
1127            accum[1usize] += f64::from(sinct[(j + 1) as usize] * iptr[(j + 1) as usize]);
1128            accum[2usize] += f64::from(sinct[(j + 2) as usize] * iptr[(j + 2) as usize]);
1129            accum[3usize] += f64::from(sinct[(j + 3) as usize] * iptr[(j + 3) as usize]);
1130            j += 4
1131        }
1132        let sum: f64 = accum[0usize] + accum[1usize] + accum[2usize] + accum[3usize];
1133        out[(out_stride * out_sample) as usize] = sum as f32;
1134        out_sample += 1;
1135        last_sample += int_advance;
1136        samp_frac_num += frac_advance as u32;
1137        if samp_frac_num >= den_rate {
1138            samp_frac_num -= den_rate as u32;
1139            last_sample += 1;
1140        }
1141    }
1142    st.last_sample[channel_index as usize] = last_sample as u32;
1143    st.samp_frac_num[channel_index as usize] = samp_frac_num;
1144    out_sample as i32
1145}
1146
1147fn _muldiv(result: &mut u32, value: u32, mul: u32, div: u32) -> usize {
1148    let major: u32 = value / div;
1149    let remainder: u32 = value % div;
1150    if remainder > 4294967295 / mul
1151        || major > 4294967295 / mul
1152        || major * mul > 4294967295 - remainder * mul / div
1153    {
1154        RESAMPLER_ERR_OVERFLOW
1155    } else {
1156        *result = remainder * mul / div + major * mul;
1157        RESAMPLER_ERR_SUCCESS
1158    }
1159}
1160
1161fn _gcd(mut a: u32, mut b: u32) -> u32 {
1162    while b != 0 {
1163        let temp = a;
1164        a = b;
1165        b = temp % b;
1166    }
1167    a
1168}
1169
1170fn speex_resampler_process_native(
1171    st: &mut SpeexResamplerState,
1172    channel_index: u32,
1173    in_len: &mut u32,
1174    out: &mut [f32],
1175    out_len: &mut u32,
1176) -> usize {
1177    let n: i32 = st.filt_len as i32;
1178    let mem_idx = (channel_index * st.mem_alloc_size) as usize;
1179    st.started = 1;
1180    let mem = &st.mem.clone();
1181    let out_sample: i32 = st.resampler_ptr.expect("non-null function pointer")(
1182        st,
1183        channel_index,
1184        mem,
1185        in_len,
1186        out,
1187        out_len,
1188    );
1189    if st.last_sample[channel_index as usize] < *in_len {
1190        *in_len = st.last_sample[channel_index as usize] as u32;
1191    }
1192    *out_len = out_sample as u32;
1193    st.last_sample[channel_index as usize] -= *in_len;
1194    let ilen: u32 = *in_len;
1195    let mut j: i32 = 0;
1196    while j < n - 1 {
1197        st.mem[mem_idx + j as usize] = st.mem[mem_idx + (j as u32 + ilen) as usize];
1198        j += 1
1199    }
1200    RESAMPLER_ERR_SUCCESS
1201}
1202
1203fn speex_resampler_magic<'a, 'b>(
1204    st: &mut SpeexResamplerState,
1205    channel_index: u32,
1206    out: &'a mut &'b mut [f32],
1207    mut out_len: u32,
1208) -> u32 {
1209    let channel_idx = channel_index as usize;
1210    let mut tmp_in_len = st.magic_samples[channel_idx];
1211    let mem_idx = (st.filt_len + channel_index * st.mem_alloc_size) as usize;
1212    speex_resampler_process_native(st, channel_index, &mut tmp_in_len, *out, &mut out_len);
1213    st.magic_samples[channel_idx] -= tmp_in_len;
1214    if st.magic_samples[channel_idx] != 0 {
1215        let mem = &st.mem[mem_idx - 1 + tmp_in_len as usize..].to_vec();
1216        st.mem
1217            .iter_mut()
1218            .skip(mem_idx - 1)
1219            .zip(mem.iter())
1220            .take(st.magic_samples[channel_idx] as usize)
1221            .for_each(|(x, &y)| *x = y);
1222    }
1223    let value: &'b mut [f32] = mem::replace(out, &mut []);
1224    *out = &mut value[(out_len * st.out_stride as u32) as usize..];
1225    out_len
1226}