sea_codec/
resample.rs

1use alloc::vec::Vec;
2
3#[cfg(feature = "resample")]
4pub fn resample(input: &[i16], source_rate: u32, target_rate: u32, channels: u32) -> Vec<i16> {
5    if source_rate == target_rate {
6        return input.to_vec();
7    }
8
9    use audioadapter_buffers::direct::InterleavedSlice;
10    use rubato::{Fft, FixedSync, Resampler};
11
12    let mut resampler = Fft::<f64>::new(
13        source_rate as usize,
14        target_rate as usize,
15        1024,
16        1,
17        channels as usize,
18        FixedSync::Both,
19    )
20    .unwrap();
21
22    let nbr_input_frames = input.len() / channels as usize;
23    let input_f64: Vec<f64> = input.iter().map(|&s| s as f64 / 32768.0).collect();
24    let input_adapter =
25        InterleavedSlice::new(&input_f64, channels as usize, nbr_input_frames).unwrap();
26
27    let output_len = resampler.process_all_needed_output_len(nbr_input_frames);
28    let mut output_f64 = vec![0.0f64; output_len * channels as usize];
29    let mut output_adapter = audioadapter_buffers::direct::InterleavedSlice::new_mut(
30        &mut output_f64,
31        channels as usize,
32        output_len,
33    )
34    .unwrap();
35
36    let (_read, written) = resampler
37        .process_all_into_buffer(&input_adapter, &mut output_adapter, nbr_input_frames, None)
38        .unwrap();
39
40    let mut output = Vec::with_capacity(written * channels as usize);
41    for i in 0..written {
42        for ch in 0..channels as usize {
43            let sample =
44                (output_f64[i * channels as usize + ch] * 32768.0).clamp(-32768.0, 32767.0) as i16;
45            output.push(sample);
46        }
47    }
48
49    output
50}
51
52#[cfg(not(feature = "resample"))]
53pub fn resample(_input: &[i16], _source_rate: u32, _target_rate: u32, _channels: u32) -> Vec<i16> {
54    // If resample feature is not enabled, just return original but it's better to panic or warn if target differs
55    _input.to_vec()
56}