fixed_resample/
realtime.rs

1use std::{num::NonZeroUsize, ops::Range};
2
3use rubato::Sample;
4
5use crate::{ResampleQuality, ResamplerType};
6
7/// An easy to use resampler that can be used in realtime applications.
8pub struct RtResampler<T: Sample> {
9    resampler: ResamplerType<T>,
10    in_buf: Vec<Vec<T>>,
11    resampled_buf: Vec<Vec<T>>,
12    intlv_buf: Vec<T>,
13    resampled_buf_len: usize,
14    remaining_frames_in_resampled_buf: usize,
15    num_channels: NonZeroUsize,
16    input_frames_max: usize,
17    output_delay: usize,
18}
19
20impl<T: Sample> RtResampler<T> {
21    /// Create a new realtime resampler.
22    ///
23    /// * `in_sample_rate` - The sample rate of the input stream.
24    /// * `out_sample_rate` - The sample rate of the output stream.
25    /// * `num_channels` - The number of channels.
26    /// * `interleaved` - If you are planning to use [`RtResampler::process_interleaved`],
27    /// set this to `true`. Otherwise you can set this to `false` to save a bit of
28    /// memory.
29    /// * `quality` - The quality of the resampling algorithm.
30    ///
31    /// # Panics
32    ///
33    /// Panics if:
34    /// * `in_sample_rate == 0`
35    /// * `out_sample_rate == 0`
36    /// * `num_channels == 0`,
37    pub fn new(
38        in_sample_rate: u32,
39        out_sample_rate: u32,
40        num_channels: usize,
41        interleaved: bool,
42        quality: ResampleQuality,
43    ) -> Self {
44        let resampler =
45            ResamplerType::from_quality(in_sample_rate, out_sample_rate, num_channels, quality);
46        Self::from_custom(resampler, interleaved)
47    }
48
49    /// Create a new realtime resampler using the given rubato resampler.
50    ///
51    /// * `resampler` - The rubato resampler.
52    /// * `interleaved` - If you are planning to use [`RtResampler::process_interleaved`],
53    /// set this to `true`. Otherwise you can set this to `false` to save a bit of
54    /// memory.
55    pub fn from_custom(resampler: impl Into<ResamplerType<T>>, interleaved: bool) -> Self {
56        let mut resampler: ResamplerType<T> = resampler.into();
57
58        let num_channels = resampler.num_channels();
59        assert_ne!(num_channels, 0);
60
61        let input_frames_max = resampler.input_frames_max();
62        let output_frames_max = resampler.output_frames_max();
63        let output_delay = resampler.output_delay();
64
65        let intlv_buf = if num_channels == 1 || !interleaved {
66            Vec::new()
67        } else {
68            let mut v = Vec::new();
69            v.reserve_exact(input_frames_max * num_channels);
70            v.resize(input_frames_max * num_channels, T::zero());
71            v
72        };
73
74        Self {
75            resampler,
76            in_buf: (0..num_channels)
77                .map(|_| {
78                    let mut v = Vec::new();
79                    v.reserve_exact(input_frames_max);
80                    v.resize(input_frames_max, T::zero());
81                    v
82                })
83                .collect(),
84            resampled_buf: (0..num_channels)
85                .map(|_| {
86                    let mut v = Vec::new();
87                    v.reserve_exact(output_frames_max);
88                    v.resize(output_frames_max, T::zero());
89                    v
90                })
91                .collect(),
92            num_channels: NonZeroUsize::new(num_channels).unwrap(),
93            intlv_buf,
94            input_frames_max,
95            output_delay,
96            resampled_buf_len: 0,
97            remaining_frames_in_resampled_buf: 0,
98        }
99    }
100
101    /// Get the number of channels this resampler is configured for.
102    pub fn num_channels(&self) -> NonZeroUsize {
103        self.num_channels
104    }
105
106    /// Reset the resampler state and clear all internal buffers.
107    pub fn reset(&mut self) {
108        self.resampler.reset();
109        self.resampled_buf_len = 0;
110        self.remaining_frames_in_resampled_buf = 0;
111    }
112
113    /// The number of frames in each call to `on_frames_requested` in [`RtResampler::process`].
114    pub fn request_frames(&self) -> usize {
115        self.input_frames_max
116    }
117
118    /// Get the delay of the internal resampler, reported as a number of output frames.
119    pub fn output_delay(&self) -> usize {
120        self.output_delay
121    }
122
123    /// The number of frames that are currently stored in the temporary buffer.
124    pub fn temp_frames(&self) -> usize {
125        self.remaining_frames_in_resampled_buf
126    }
127
128    /// Resample the input stream and process into a block of data for the output stream.
129    ///
130    /// This method is realtime-safe.
131    ///
132    /// * `on_frames_requested` - This gets called whenever the resampler needs more
133    /// data from the input stream. The given buffer must be fully filled with new samples.
134    /// If there is not enough data to fill the buffer (i.e. an underflow occured), then fill
135    /// the rest of the frames with zeros. Do *NOT* resize the `Vec`s.
136    /// * `output` - The channels of audio data to write data to.
137    /// * `range` - The range in each slice in `output` to write data to. Data
138    /// inside this range will be fully filled, and any data outside this range
139    /// will be untouched.
140    pub fn process<Vout: AsMut<[T]>>(
141        &mut self,
142        mut on_frames_requested: impl FnMut(&mut [Vec<T>]),
143        output: &mut [Vout],
144        range: Range<usize>,
145    ) {
146        let num_channels = output.len().min(self.resampled_buf.len());
147        let out_frames = range.end - range.start;
148
149        if output.len() > num_channels {
150            for ch in output.iter_mut().skip(num_channels) {
151                ch.as_mut()[range.clone()].fill(T::zero());
152            }
153        }
154
155        let mut frames_filled = if self.remaining_frames_in_resampled_buf > 0 {
156            let start_frame = self.resampled_buf_len - self.remaining_frames_in_resampled_buf;
157            let copy_frames = self.remaining_frames_in_resampled_buf.min(out_frames);
158
159            for (out_ch, in_ch) in output.iter_mut().zip(self.resampled_buf.iter()) {
160                let out_ch = out_ch.as_mut();
161                out_ch[range.start..range.start + copy_frames]
162                    .copy_from_slice(&in_ch[start_frame..start_frame + copy_frames]);
163            }
164
165            self.remaining_frames_in_resampled_buf -= copy_frames;
166
167            copy_frames
168        } else {
169            0
170        };
171
172        while frames_filled < out_frames {
173            (on_frames_requested)(&mut self.in_buf);
174
175            debug_assert!(self.in_buf[0].len() == self.input_frames_max);
176
177            let (_, out_frames_processed) = self
178                .resampler
179                .process_into_buffer(
180                    &self.in_buf[..num_channels],
181                    &mut self.resampled_buf[..num_channels],
182                    None,
183                )
184                .unwrap();
185
186            self.resampled_buf_len = out_frames_processed;
187            let copy_frames = out_frames_processed.min(out_frames - frames_filled);
188
189            for (out_ch, in_ch) in output.iter_mut().zip(self.resampled_buf.iter()) {
190                let out_ch = out_ch.as_mut();
191                out_ch[range.start + frames_filled..range.start + frames_filled + copy_frames]
192                    .copy_from_slice(&in_ch[..copy_frames]);
193            }
194
195            self.remaining_frames_in_resampled_buf = self.resampled_buf_len - copy_frames;
196
197            frames_filled += copy_frames;
198        }
199    }
200
201    /// Resample the input stream and process into an interleaved block of data for the
202    /// output stream.
203    ///
204    /// * `on_frames_requested` - This gets called whenever the resampler needs more
205    /// data from the input stream. The given buffer is in interleaved format, and it
206    /// must be completely filled with new data. If there is not enough data to fill
207    /// the buffer (i.e. an underflow occured), then fill the rest of the frames with
208    /// zeros.
209    /// * `output` - The interleaved output buffer to write the resampled data to.
210    ///
211    /// # Panics
212    ///
213    /// * Panics if the number of output channels does not equal the number of channels
214    /// in this resampler.
215    /// * Also panics if the `interleaved` argument was `false` when this struct was
216    /// created and `self.num_channels() > 1`.
217    pub fn process_interleaved(
218        &mut self,
219        mut on_frames_requested: impl FnMut(&mut [T]),
220        output: &mut [T],
221    ) {
222        let num_channels = self.num_channels.get();
223
224        let out_frames = output.len() / num_channels;
225
226        if num_channels > 1 {
227            assert!(!self.intlv_buf.is_empty());
228        }
229
230        let mut frames_filled = if self.remaining_frames_in_resampled_buf > 0 {
231            let start_frame = self.resampled_buf_len - self.remaining_frames_in_resampled_buf;
232            let copy_frames = self.remaining_frames_in_resampled_buf.min(out_frames);
233
234            crate::interleave::interleave(
235                &self.resampled_buf,
236                output,
237                self.num_channels,
238                start_frame..start_frame + copy_frames,
239            );
240
241            self.remaining_frames_in_resampled_buf -= copy_frames;
242
243            copy_frames
244        } else {
245            0
246        };
247
248        while frames_filled < out_frames {
249            if num_channels == 1 {
250                // Mono, no need for the temporary interleaved buffer.
251                (on_frames_requested)(&mut self.in_buf[0]);
252            } else {
253                (on_frames_requested)(&mut self.intlv_buf);
254
255                crate::interleave::deinterleave(
256                    &self.intlv_buf,
257                    &mut self.in_buf,
258                    self.num_channels,
259                    0..self.input_frames_max,
260                );
261            }
262
263            let (_, out_frames_processed) = self
264                .resampler
265                .process_into_buffer(&self.in_buf, &mut self.resampled_buf, None)
266                .unwrap();
267
268            self.resampled_buf_len = out_frames_processed;
269            let copy_frames = out_frames_processed.min(out_frames - frames_filled);
270
271            crate::interleave::interleave(
272                &self.resampled_buf,
273                &mut output
274                    [frames_filled * num_channels..(frames_filled + copy_frames) * num_channels],
275                self.num_channels,
276                0..copy_frames,
277            );
278
279            self.remaining_frames_in_resampled_buf = self.resampled_buf_len - copy_frames;
280
281            frames_filled += copy_frames;
282        }
283    }
284
285    pub fn resampler_type(&self) -> &ResamplerType<T> {
286        &self.resampler
287    }
288
289    pub fn resampler_type_mut(&mut self) -> &mut ResamplerType<T> {
290        &mut self.resampler
291    }
292}
293
294impl<T: Sample> Into<ResamplerType<T>> for RtResampler<T> {
295    fn into(self) -> ResamplerType<T> {
296        self.resampler
297    }
298}