1use std::{num::NonZeroUsize, ops::Range};
2
3use arrayvec::ArrayVec;
4use rubato::Sample;
5
6use crate::resampler_type::ResamplerType;
7
8#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
10pub enum ResampleQuality {
11 Low,
19 #[default]
20 High,
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub struct LastPacketInfo {
40 pub desired_output_frames: Option<u64>,
46}
47
48pub struct FixedResampler<T: Sample, const MAX_CHANNELS: usize> {
52 resampler: ResamplerType<T>,
53 tmp_deintlv_in_buf: Vec<T>,
54 tmp_deintlv_out_buf: Vec<T>,
55 tmp_intlv_buf: Vec<T>,
56 tmp_deintlv_in_buf_len: usize,
57 num_channels: NonZeroUsize,
58 input_block_frames: usize,
59 max_output_block_frames: usize,
60 output_delay: usize,
61 delay_frames_left: usize,
62 in_sample_rate: u32,
63 out_sample_rate: u32,
64 interleaved: bool,
65}
66
67impl<T: Sample, const MAX_CHANNELS: usize> FixedResampler<T, MAX_CHANNELS> {
68 pub fn new(
85 num_channels: NonZeroUsize,
86 in_sample_rate: u32,
87 out_sample_rate: u32,
88 quality: ResampleQuality,
89 interleaved: bool,
90 ) -> Self {
91 Self::from_custom(
92 ResamplerType::from_quality(
93 in_sample_rate,
94 out_sample_rate,
95 num_channels,
96 quality.into(),
97 ),
98 in_sample_rate,
99 out_sample_rate,
100 interleaved,
101 )
102 }
103
104 pub fn from_custom(
120 resampler: impl Into<ResamplerType<T>>,
121 in_sample_rate: u32,
122 out_sample_rate: u32,
123 interleaved: bool,
124 ) -> Self {
125 assert_ne!(in_sample_rate, 0);
126 assert_ne!(out_sample_rate, 0);
127
128 let mut resampler: ResamplerType<T> = resampler.into();
129
130 let num_channels = NonZeroUsize::new(resampler.num_channels()).unwrap();
131
132 assert!(num_channels.get() <= MAX_CHANNELS);
133
134 let input_block_frames = resampler.input_frames_max();
135 let max_output_block_frames = resampler.output_frames_max();
136 let output_delay = resampler.output_delay();
137
138 let tmp_in_buf_len = input_block_frames * num_channels.get();
139 let tmp_out_buf_len = max_output_block_frames * num_channels.get();
140
141 let mut tmp_deintlv_in_buf = Vec::new();
142 tmp_deintlv_in_buf.reserve_exact(tmp_in_buf_len);
143 tmp_deintlv_in_buf.resize(tmp_in_buf_len, T::zero());
144
145 let mut tmp_deintlv_out_buf = Vec::new();
146 tmp_deintlv_out_buf.reserve_exact(tmp_out_buf_len);
147 tmp_deintlv_out_buf.resize(tmp_out_buf_len, T::zero());
148
149 let tmp_intlv_buf = if interleaved && num_channels.get() > 1 {
150 let intlv_buf_len =
151 input_block_frames.max(max_output_block_frames) * num_channels.get();
152 let mut v = Vec::new();
153 v.reserve_exact(intlv_buf_len);
154 v.resize(intlv_buf_len, T::zero());
155 v
156 } else {
157 Vec::new()
158 };
159
160 Self {
161 resampler,
162 tmp_deintlv_in_buf,
163 tmp_deintlv_out_buf,
164 tmp_intlv_buf,
165 tmp_deintlv_in_buf_len: 0,
166 num_channels,
167 input_block_frames,
168 max_output_block_frames,
169 output_delay,
170 delay_frames_left: output_delay,
171 in_sample_rate,
172 out_sample_rate,
173 interleaved,
174 }
175 }
176
177 pub fn num_channels(&self) -> NonZeroUsize {
179 self.num_channels
180 }
181
182 pub fn in_sample_rate(&self) -> u32 {
184 self.in_sample_rate
185 }
186
187 pub fn out_sample_rate(&self) -> u32 {
189 self.out_sample_rate
190 }
191
192 pub fn input_block_frames(&self) -> usize {
195 self.input_block_frames
196 }
197
198 pub fn max_output_block_frames(&self) -> usize {
202 self.max_output_block_frames
203 }
204
205 pub fn output_delay(&self) -> usize {
208 self.output_delay
209 }
210
211 pub fn is_interleaved(&self) -> bool {
213 self.interleaved
214 }
215
216 pub fn out_alloc_frames(&self, input_frames: u64) -> u64 {
219 ((input_frames * self.out_sample_rate as u64) / self.in_sample_rate as u64) + 1
220 }
221
222 #[allow(unused)]
223 pub(crate) fn tmp_input_frames(&self) -> usize {
224 self.tmp_deintlv_in_buf_len
225 }
226
227 pub fn process<Vin: AsRef<[T]>>(
248 &mut self,
249 input: &[Vin],
250 input_range: Range<usize>,
251 mut on_output_packet: impl FnMut(ArrayVec<&[T], MAX_CHANNELS>),
252 last_packet: Option<LastPacketInfo>,
253 trim_delay: bool,
254 ) {
255 assert!(input.len() >= self.num_channels.get());
256
257 {
258 let mut on_output_packet_inner =
259 move |output_packet: ArrayVec<&[T], MAX_CHANNELS>, _tmp_intlv_buf: &mut Vec<T>| {
260 (on_output_packet)(output_packet);
261 };
262
263 let total_input_frames = input_range.end - input_range.start;
264
265 let mut tmp_deintlv_in_buf_slices: ArrayVec<&mut [T], MAX_CHANNELS> = self
266 .tmp_deintlv_in_buf
267 .chunks_exact_mut(self.input_block_frames)
268 .collect();
269 let mut tmp_deintlv_out_buf_slices: ArrayVec<&mut [T], MAX_CHANNELS> = self
270 .tmp_deintlv_out_buf
271 .chunks_exact_mut(self.max_output_block_frames)
272 .collect();
273
274 let mut input_frames_processed = 0;
275 let mut output_frames_processed = 0;
276
277 let desired_output_frames = last_packet.and_then(|info| info.desired_output_frames);
278
279 while input_frames_processed < total_input_frames {
280 if self.tmp_deintlv_in_buf_len == 0
281 && (total_input_frames - input_frames_processed) >= self.input_block_frames
282 {
283 let input_slices: ArrayVec<&[T], MAX_CHANNELS> = input
286 [..self.num_channels.get()]
287 .iter()
288 .map(|s| {
289 &s.as_ref()[input_range.start + input_frames_processed
290 ..input_range.start
291 + input_frames_processed
292 + self.input_block_frames]
293 })
294 .collect();
295
296 resample_inner(
297 &mut self.resampler,
298 &input_slices,
299 &mut tmp_deintlv_out_buf_slices,
300 &mut on_output_packet_inner,
301 &mut output_frames_processed,
302 desired_output_frames,
303 &mut self.delay_frames_left,
304 trim_delay,
305 &mut self.tmp_intlv_buf,
306 );
307
308 input_frames_processed += self.input_block_frames;
309 } else {
310 let copy_frames = (self.input_block_frames - self.tmp_deintlv_in_buf_len)
311 .min(total_input_frames - input_frames_processed);
312
313 for (in_slice_ch, input_ch) in
314 tmp_deintlv_in_buf_slices.iter_mut().zip(input.iter())
315 {
316 in_slice_ch[self.tmp_deintlv_in_buf_len
317 ..self.tmp_deintlv_in_buf_len + copy_frames]
318 .copy_from_slice(
319 &input_ch.as_ref()[input_range.start + input_frames_processed
320 ..input_range.start + input_frames_processed + copy_frames],
321 );
322 }
323
324 self.tmp_deintlv_in_buf_len += copy_frames;
325 input_frames_processed += copy_frames;
326
327 if self.tmp_deintlv_in_buf_len < self.input_block_frames {
328 break;
330 }
331
332 resample_inner(
333 &mut self.resampler,
334 &tmp_deintlv_in_buf_slices,
335 &mut tmp_deintlv_out_buf_slices,
336 &mut on_output_packet_inner,
337 &mut output_frames_processed,
338 desired_output_frames,
339 &mut self.delay_frames_left,
340 trim_delay,
341 &mut self.tmp_intlv_buf,
342 );
343
344 self.tmp_deintlv_in_buf_len = 0;
345 }
346 }
347
348 if last_packet.is_some() {
349 process_last_packet(
350 &mut tmp_deintlv_in_buf_slices,
351 &mut tmp_deintlv_out_buf_slices,
352 &mut self.resampler,
353 &mut on_output_packet_inner,
354 &mut output_frames_processed,
355 desired_output_frames,
356 &mut self.delay_frames_left,
357 trim_delay,
358 &mut self.tmp_intlv_buf,
359 self.tmp_deintlv_in_buf_len,
360 );
361 }
362 }
363
364 if last_packet.is_some() {
365 self.reset();
366 }
367 }
368
369 pub fn process_interleaved(
387 &mut self,
388 input: &[T],
389 mut on_output_packet: impl FnMut(&[T]),
390 last_packet: Option<LastPacketInfo>,
391 trim_delay: bool,
392 ) {
393 assert!(self.interleaved, "The constructor argument \"interleaved\" must be set to \"true\" in order to call FixedResampler::process_interleaved");
394
395 {
396 let num_channels = self.num_channels;
397
398 let mut on_output_packet_inner =
399 move |output_packet: ArrayVec<&[T], MAX_CHANNELS>, tmp_intlv_buf: &mut Vec<T>| {
400 let frames = output_packet[0].len();
401
402 if num_channels.get() == 1 {
403 (on_output_packet)(&output_packet[0]);
404 } else {
405 crate::interleave::interleave(
406 &output_packet,
407 tmp_intlv_buf.as_mut_slice(),
408 num_channels,
409 0..frames,
410 );
411
412 (on_output_packet)(&tmp_intlv_buf[..frames * num_channels.get()]);
413 }
414 };
415
416 let total_input_frames = input.len() / self.num_channels;
417
418 let mut tmp_deintlv_in_buf_slices: ArrayVec<&mut [T], MAX_CHANNELS> = self
419 .tmp_deintlv_in_buf
420 .chunks_exact_mut(self.input_block_frames)
421 .collect();
422 let mut tmp_deintlv_out_buf_slices: ArrayVec<&mut [T], MAX_CHANNELS> = self
423 .tmp_deintlv_out_buf
424 .chunks_exact_mut(self.max_output_block_frames)
425 .collect();
426
427 let mut input_frames_processed = 0;
428 let mut output_frames_processed = 0;
429
430 let desired_output_frames = last_packet.and_then(|info| info.desired_output_frames);
431
432 while input_frames_processed < total_input_frames {
433 let copy_frames = (self.input_block_frames - self.tmp_deintlv_in_buf_len)
434 .min(total_input_frames - input_frames_processed);
435
436 crate::interleave::deinterleave(
437 &input[input_frames_processed * self.num_channels.get()
438 ..(input_frames_processed + copy_frames) * self.num_channels.get()],
439 &mut tmp_deintlv_in_buf_slices,
440 self.num_channels,
441 self.tmp_deintlv_in_buf_len..self.tmp_deintlv_in_buf_len + copy_frames,
442 );
443
444 self.tmp_deintlv_in_buf_len += copy_frames;
445 input_frames_processed += copy_frames;
446
447 if self.tmp_deintlv_in_buf_len < self.input_block_frames {
448 break;
450 }
451
452 resample_inner(
453 &mut self.resampler,
454 &tmp_deintlv_in_buf_slices,
455 &mut tmp_deintlv_out_buf_slices,
456 &mut on_output_packet_inner,
457 &mut output_frames_processed,
458 desired_output_frames,
459 &mut self.delay_frames_left,
460 trim_delay,
461 &mut self.tmp_intlv_buf,
462 );
463
464 self.tmp_deintlv_in_buf_len = 0;
465 }
466
467 if last_packet.is_some() {
468 process_last_packet(
469 &mut tmp_deintlv_in_buf_slices,
470 &mut tmp_deintlv_out_buf_slices,
471 &mut self.resampler,
472 &mut on_output_packet_inner,
473 &mut output_frames_processed,
474 desired_output_frames,
475 &mut self.delay_frames_left,
476 trim_delay,
477 &mut self.tmp_intlv_buf,
478 self.tmp_deintlv_in_buf_len,
479 );
480 }
481 }
482
483 if last_packet.is_some() {
484 self.reset();
485 }
486 }
487
488 pub fn reset(&mut self) {
492 self.resampler.reset();
493 self.tmp_deintlv_in_buf_len = 0;
494 self.delay_frames_left = self.output_delay;
495 }
496}
497
498impl<T: Sample, const MAX_CHANNELS: usize> Into<ResamplerType<T>>
499 for FixedResampler<T, MAX_CHANNELS>
500{
501 fn into(self) -> ResamplerType<T> {
502 self.resampler
503 }
504}
505
506fn process_last_packet<T: Sample, const MAX_CHANNELS: usize>(
507 tmp_deintlv_in_buf_slices: &mut ArrayVec<&mut [T], MAX_CHANNELS>,
508 tmp_deintlv_out_buf_slices: &mut ArrayVec<&mut [T], MAX_CHANNELS>,
509 resampler: &mut ResamplerType<T>,
510 on_output_packet: &mut impl FnMut(ArrayVec<&[T], MAX_CHANNELS>, &mut Vec<T>),
511 output_frames_processed: &mut u64,
512 desired_output_frames: Option<u64>,
513 delay_frames_left: &mut usize,
514 trim_delay: bool,
515 tmp_intlv_buf: &mut Vec<T>,
516 tmp_deintlv_in_buf_len: usize,
517) {
518 if tmp_deintlv_in_buf_len > 0 {
519 for ch in tmp_deintlv_in_buf_slices.iter_mut() {
520 ch[tmp_deintlv_in_buf_len..].fill(T::zero());
521 }
522
523 resample_inner(
524 resampler,
525 &tmp_deintlv_in_buf_slices,
526 tmp_deintlv_out_buf_slices,
527 on_output_packet,
528 output_frames_processed,
529 desired_output_frames,
530 delay_frames_left,
531 trim_delay,
532 tmp_intlv_buf,
533 );
534 }
535
536 for ch in tmp_deintlv_in_buf_slices.iter_mut() {
537 ch.fill(T::zero());
538 }
539
540 if let Some(desired_output_frames) = desired_output_frames {
541 if *output_frames_processed >= desired_output_frames {
542 return;
543 }
544
545 while *output_frames_processed < desired_output_frames {
546 resample_inner(
547 resampler,
548 &tmp_deintlv_in_buf_slices,
549 tmp_deintlv_out_buf_slices,
550 on_output_packet,
551 output_frames_processed,
552 Some(desired_output_frames),
553 delay_frames_left,
554 trim_delay,
555 tmp_intlv_buf,
556 );
557 }
558 } else {
559 resample_inner(
560 resampler,
561 &tmp_deintlv_in_buf_slices,
562 tmp_deintlv_out_buf_slices,
563 on_output_packet,
564 output_frames_processed,
565 desired_output_frames,
566 delay_frames_left,
567 trim_delay,
568 tmp_intlv_buf,
569 );
570 }
571}
572
573fn resample_inner<T: Sample, Vin: AsRef<[T]>, const MAX_CHANNELS: usize>(
574 resampler: &mut ResamplerType<T>,
575 input: &[Vin],
576 tmp_deintlv_out_buf_slices: &mut ArrayVec<&mut [T], MAX_CHANNELS>,
577 on_output_packet: &mut impl FnMut(ArrayVec<&[T], MAX_CHANNELS>, &mut Vec<T>),
578 output_frames_processed: &mut u64,
579 desired_output_frames: Option<u64>,
580 delay_frames_left: &mut usize,
581 trim_delay: bool,
582 tmp_intlv_buf: &mut Vec<T>,
583) {
584 let (_, output_frames) = resampler
585 .process_into_buffer(input, tmp_deintlv_out_buf_slices, None)
586 .unwrap();
587
588 let (output_packet_start, mut packet_output_frames) = if trim_delay && *delay_frames_left > 0 {
589 let delay_frames = output_frames.min(*delay_frames_left);
590 *delay_frames_left -= delay_frames;
591 (delay_frames, output_frames - delay_frames)
592 } else {
593 (0, output_frames)
594 };
595
596 if let Some(desired_output_frames) = desired_output_frames {
597 if desired_output_frames <= *output_frames_processed {
598 packet_output_frames = 0;
599 } else if (desired_output_frames - *output_frames_processed) < packet_output_frames as u64 {
600 packet_output_frames = (desired_output_frames - *output_frames_processed) as usize
601 }
602 }
603
604 if packet_output_frames > 0 {
605 let out_packet_slices: ArrayVec<&[T], MAX_CHANNELS> = tmp_deintlv_out_buf_slices
606 .iter()
607 .map(|s| &s[output_packet_start..output_packet_start + packet_output_frames])
608 .collect();
609
610 (on_output_packet)(out_packet_slices, tmp_intlv_buf);
611 }
612
613 *output_frames_processed += packet_output_frames as u64;
614}