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 ratio: f64,
65 interleaved: bool,
66}
67
68impl<T: Sample, const MAX_CHANNELS: usize> FixedResampler<T, MAX_CHANNELS> {
69 pub fn new(
86 num_channels: NonZeroUsize,
87 in_sample_rate: u32,
88 out_sample_rate: u32,
89 quality: ResampleQuality,
90 interleaved: bool,
91 ) -> Self {
92 Self::from_custom(
93 ResamplerType::from_quality(
94 in_sample_rate,
95 out_sample_rate,
96 num_channels,
97 quality.into(),
98 ),
99 in_sample_rate,
100 out_sample_rate,
101 interleaved,
102 )
103 }
104
105 pub fn arbitrary_ratio_sinc(
132 in_sample_rate: u32,
133 ratio: f64,
134 num_channels: NonZeroUsize,
135 interleaved: bool,
136 ) -> Self {
137 Self::from_custom_inner(
138 ResamplerType::arbitrary_ratio_sinc(ratio, num_channels),
139 in_sample_rate,
140 (in_sample_rate as f64 * ratio).ceil() as u32,
141 interleaved,
142 ratio,
143 )
144 }
145
146 pub fn from_custom(
162 resampler: impl Into<ResamplerType<T>>,
163 in_sample_rate: u32,
164 out_sample_rate: u32,
165 interleaved: bool,
166 ) -> Self {
167 Self::from_custom_inner(
168 resampler,
169 in_sample_rate,
170 out_sample_rate,
171 interleaved,
172 out_sample_rate as f64 / in_sample_rate as f64,
173 )
174 }
175
176 fn from_custom_inner(
177 resampler: impl Into<ResamplerType<T>>,
178 in_sample_rate: u32,
179 out_sample_rate: u32,
180 interleaved: bool,
181 ratio: f64,
182 ) -> Self {
183 assert_ne!(in_sample_rate, 0);
184 assert_ne!(out_sample_rate, 0);
185
186 let mut resampler: ResamplerType<T> = resampler.into();
187
188 let num_channels = NonZeroUsize::new(resampler.num_channels()).unwrap();
189
190 assert!(num_channels.get() <= MAX_CHANNELS);
191
192 let input_block_frames = resampler.input_frames_max();
193 let max_output_block_frames = resampler.output_frames_max();
194 let output_delay = resampler.output_delay();
195
196 let tmp_in_buf_len = input_block_frames * num_channels.get();
197 let tmp_out_buf_len = max_output_block_frames * num_channels.get();
198
199 let mut tmp_deintlv_in_buf = Vec::new();
200 tmp_deintlv_in_buf.reserve_exact(tmp_in_buf_len);
201 tmp_deintlv_in_buf.resize(tmp_in_buf_len, T::zero());
202
203 let mut tmp_deintlv_out_buf = Vec::new();
204 tmp_deintlv_out_buf.reserve_exact(tmp_out_buf_len);
205 tmp_deintlv_out_buf.resize(tmp_out_buf_len, T::zero());
206
207 let tmp_intlv_buf = if interleaved && num_channels.get() > 1 {
208 let intlv_buf_len =
209 input_block_frames.max(max_output_block_frames) * num_channels.get();
210 let mut v = Vec::new();
211 v.reserve_exact(intlv_buf_len);
212 v.resize(intlv_buf_len, T::zero());
213 v
214 } else {
215 Vec::new()
216 };
217
218 Self {
219 resampler,
220 tmp_deintlv_in_buf,
221 tmp_deintlv_out_buf,
222 tmp_intlv_buf,
223 tmp_deintlv_in_buf_len: 0,
224 num_channels,
225 input_block_frames,
226 max_output_block_frames,
227 output_delay,
228 delay_frames_left: output_delay,
229 in_sample_rate,
230 out_sample_rate,
231 ratio,
232 interleaved,
233 }
234 }
235
236 pub fn num_channels(&self) -> NonZeroUsize {
238 self.num_channels
239 }
240
241 pub fn in_sample_rate(&self) -> u32 {
243 self.in_sample_rate
244 }
245
246 pub fn out_sample_rate(&self) -> u32 {
248 self.out_sample_rate
249 }
250
251 pub fn ratio(&self) -> f64 {
253 self.ratio
254 }
255
256 pub fn input_block_frames(&self) -> usize {
259 self.input_block_frames
260 }
261
262 pub fn max_output_block_frames(&self) -> usize {
266 self.max_output_block_frames
267 }
268
269 pub fn output_delay(&self) -> usize {
272 self.output_delay
273 }
274
275 pub fn is_interleaved(&self) -> bool {
277 self.interleaved
278 }
279
280 pub fn out_alloc_frames(&self, input_frames: u64) -> u64 {
283 ((input_frames * self.out_sample_rate as u64) / self.in_sample_rate as u64) + 1
284 }
285
286 #[allow(unused)]
287 pub(crate) fn tmp_input_frames(&self) -> usize {
288 self.tmp_deintlv_in_buf_len
289 }
290
291 pub fn process<Vin: AsRef<[T]>>(
312 &mut self,
313 input: &[Vin],
314 input_range: Range<usize>,
315 mut on_output_packet: impl FnMut(ArrayVec<&[T], MAX_CHANNELS>),
316 last_packet: Option<LastPacketInfo>,
317 trim_delay: bool,
318 ) {
319 assert!(input.len() >= self.num_channels.get());
320
321 {
322 let mut on_output_packet_inner =
323 move |output_packet: ArrayVec<&[T], MAX_CHANNELS>, _tmp_intlv_buf: &mut Vec<T>| {
324 (on_output_packet)(output_packet);
325 };
326
327 let total_input_frames = input_range.end - input_range.start;
328
329 let mut tmp_deintlv_in_buf_slices: ArrayVec<&mut [T], MAX_CHANNELS> = self
330 .tmp_deintlv_in_buf
331 .chunks_exact_mut(self.input_block_frames)
332 .collect();
333 let mut tmp_deintlv_out_buf_slices: ArrayVec<&mut [T], MAX_CHANNELS> = self
334 .tmp_deintlv_out_buf
335 .chunks_exact_mut(self.max_output_block_frames)
336 .collect();
337
338 let mut input_frames_processed = 0;
339 let mut output_frames_processed = 0;
340
341 let desired_output_frames = last_packet.and_then(|info| info.desired_output_frames);
342
343 while input_frames_processed < total_input_frames {
344 if self.tmp_deintlv_in_buf_len == 0
345 && (total_input_frames - input_frames_processed) >= self.input_block_frames
346 {
347 let input_slices: ArrayVec<&[T], MAX_CHANNELS> = input
350 [..self.num_channels.get()]
351 .iter()
352 .map(|s| {
353 &s.as_ref()[input_range.start + input_frames_processed
354 ..input_range.start
355 + input_frames_processed
356 + self.input_block_frames]
357 })
358 .collect();
359
360 resample_inner(
361 &mut self.resampler,
362 &input_slices,
363 &mut tmp_deintlv_out_buf_slices,
364 &mut on_output_packet_inner,
365 &mut output_frames_processed,
366 desired_output_frames,
367 &mut self.delay_frames_left,
368 trim_delay,
369 &mut self.tmp_intlv_buf,
370 );
371
372 input_frames_processed += self.input_block_frames;
373 } else {
374 let copy_frames = (self.input_block_frames - self.tmp_deintlv_in_buf_len)
375 .min(total_input_frames - input_frames_processed);
376
377 for (in_slice_ch, input_ch) in
378 tmp_deintlv_in_buf_slices.iter_mut().zip(input.iter())
379 {
380 in_slice_ch[self.tmp_deintlv_in_buf_len
381 ..self.tmp_deintlv_in_buf_len + copy_frames]
382 .copy_from_slice(
383 &input_ch.as_ref()[input_range.start + input_frames_processed
384 ..input_range.start + input_frames_processed + copy_frames],
385 );
386 }
387
388 self.tmp_deintlv_in_buf_len += copy_frames;
389 input_frames_processed += copy_frames;
390
391 if self.tmp_deintlv_in_buf_len < self.input_block_frames {
392 break;
394 }
395
396 resample_inner(
397 &mut self.resampler,
398 &tmp_deintlv_in_buf_slices,
399 &mut tmp_deintlv_out_buf_slices,
400 &mut on_output_packet_inner,
401 &mut output_frames_processed,
402 desired_output_frames,
403 &mut self.delay_frames_left,
404 trim_delay,
405 &mut self.tmp_intlv_buf,
406 );
407
408 self.tmp_deintlv_in_buf_len = 0;
409 }
410 }
411
412 if last_packet.is_some() {
413 process_last_packet(
414 &mut tmp_deintlv_in_buf_slices,
415 &mut tmp_deintlv_out_buf_slices,
416 &mut self.resampler,
417 &mut on_output_packet_inner,
418 &mut output_frames_processed,
419 desired_output_frames,
420 &mut self.delay_frames_left,
421 trim_delay,
422 &mut self.tmp_intlv_buf,
423 self.tmp_deintlv_in_buf_len,
424 );
425 }
426 }
427
428 if last_packet.is_some() {
429 self.reset();
430 }
431 }
432
433 pub fn process_interleaved(
451 &mut self,
452 input: &[T],
453 mut on_output_packet: impl FnMut(&[T]),
454 last_packet: Option<LastPacketInfo>,
455 trim_delay: bool,
456 ) {
457 assert!(self.interleaved, "The constructor argument \"interleaved\" must be set to \"true\" in order to call FixedResampler::process_interleaved");
458
459 {
460 let num_channels = self.num_channels;
461
462 let mut on_output_packet_inner =
463 move |output_packet: ArrayVec<&[T], MAX_CHANNELS>, tmp_intlv_buf: &mut Vec<T>| {
464 let frames = output_packet[0].len();
465
466 if num_channels.get() == 1 {
467 (on_output_packet)(&output_packet[0]);
468 } else {
469 fast_interleave::interleave_variable(
470 &output_packet,
471 0..frames,
472 tmp_intlv_buf.as_mut_slice(),
473 num_channels,
474 );
475
476 (on_output_packet)(&tmp_intlv_buf[..frames * num_channels.get()]);
477 }
478 };
479
480 let total_input_frames = input.len() / self.num_channels;
481
482 let mut tmp_deintlv_in_buf_slices: ArrayVec<&mut [T], MAX_CHANNELS> = self
483 .tmp_deintlv_in_buf
484 .chunks_exact_mut(self.input_block_frames)
485 .collect();
486 let mut tmp_deintlv_out_buf_slices: ArrayVec<&mut [T], MAX_CHANNELS> = self
487 .tmp_deintlv_out_buf
488 .chunks_exact_mut(self.max_output_block_frames)
489 .collect();
490
491 let mut input_frames_processed = 0;
492 let mut output_frames_processed = 0;
493
494 let desired_output_frames = last_packet.and_then(|info| info.desired_output_frames);
495
496 while input_frames_processed < total_input_frames {
497 let copy_frames = (self.input_block_frames - self.tmp_deintlv_in_buf_len)
498 .min(total_input_frames - input_frames_processed);
499
500 fast_interleave::deinterleave_variable(
501 &input[input_frames_processed * self.num_channels.get()
502 ..(input_frames_processed + copy_frames) * self.num_channels.get()],
503 self.num_channels,
504 &mut tmp_deintlv_in_buf_slices,
505 self.tmp_deintlv_in_buf_len..self.tmp_deintlv_in_buf_len + copy_frames,
506 );
507
508 self.tmp_deintlv_in_buf_len += copy_frames;
509 input_frames_processed += copy_frames;
510
511 if self.tmp_deintlv_in_buf_len < self.input_block_frames {
512 break;
514 }
515
516 resample_inner(
517 &mut self.resampler,
518 &tmp_deintlv_in_buf_slices,
519 &mut tmp_deintlv_out_buf_slices,
520 &mut on_output_packet_inner,
521 &mut output_frames_processed,
522 desired_output_frames,
523 &mut self.delay_frames_left,
524 trim_delay,
525 &mut self.tmp_intlv_buf,
526 );
527
528 self.tmp_deintlv_in_buf_len = 0;
529 }
530
531 if last_packet.is_some() {
532 process_last_packet(
533 &mut tmp_deintlv_in_buf_slices,
534 &mut tmp_deintlv_out_buf_slices,
535 &mut self.resampler,
536 &mut on_output_packet_inner,
537 &mut output_frames_processed,
538 desired_output_frames,
539 &mut self.delay_frames_left,
540 trim_delay,
541 &mut self.tmp_intlv_buf,
542 self.tmp_deintlv_in_buf_len,
543 );
544 }
545 }
546
547 if last_packet.is_some() {
548 self.reset();
549 }
550 }
551
552 pub fn reset(&mut self) {
556 self.resampler.reset();
557 self.tmp_deintlv_in_buf_len = 0;
558 self.delay_frames_left = self.output_delay;
559 }
560}
561
562impl<T: Sample, const MAX_CHANNELS: usize> Into<ResamplerType<T>>
563 for FixedResampler<T, MAX_CHANNELS>
564{
565 fn into(self) -> ResamplerType<T> {
566 self.resampler
567 }
568}
569
570fn process_last_packet<T: Sample, const MAX_CHANNELS: usize>(
571 tmp_deintlv_in_buf_slices: &mut ArrayVec<&mut [T], MAX_CHANNELS>,
572 tmp_deintlv_out_buf_slices: &mut ArrayVec<&mut [T], MAX_CHANNELS>,
573 resampler: &mut ResamplerType<T>,
574 on_output_packet: &mut impl FnMut(ArrayVec<&[T], MAX_CHANNELS>, &mut Vec<T>),
575 output_frames_processed: &mut u64,
576 desired_output_frames: Option<u64>,
577 delay_frames_left: &mut usize,
578 trim_delay: bool,
579 tmp_intlv_buf: &mut Vec<T>,
580 tmp_deintlv_in_buf_len: usize,
581) {
582 if tmp_deintlv_in_buf_len > 0 {
583 for ch in tmp_deintlv_in_buf_slices.iter_mut() {
584 ch[tmp_deintlv_in_buf_len..].fill(T::zero());
585 }
586
587 resample_inner(
588 resampler,
589 &tmp_deintlv_in_buf_slices,
590 tmp_deintlv_out_buf_slices,
591 on_output_packet,
592 output_frames_processed,
593 desired_output_frames,
594 delay_frames_left,
595 trim_delay,
596 tmp_intlv_buf,
597 );
598 }
599
600 for ch in tmp_deintlv_in_buf_slices.iter_mut() {
601 ch.fill(T::zero());
602 }
603
604 if let Some(desired_output_frames) = desired_output_frames {
605 if *output_frames_processed >= desired_output_frames {
606 return;
607 }
608
609 while *output_frames_processed < desired_output_frames {
610 resample_inner(
611 resampler,
612 &tmp_deintlv_in_buf_slices,
613 tmp_deintlv_out_buf_slices,
614 on_output_packet,
615 output_frames_processed,
616 Some(desired_output_frames),
617 delay_frames_left,
618 trim_delay,
619 tmp_intlv_buf,
620 );
621 }
622 } else {
623 resample_inner(
624 resampler,
625 &tmp_deintlv_in_buf_slices,
626 tmp_deintlv_out_buf_slices,
627 on_output_packet,
628 output_frames_processed,
629 desired_output_frames,
630 delay_frames_left,
631 trim_delay,
632 tmp_intlv_buf,
633 );
634 }
635}
636
637fn resample_inner<T: Sample, Vin: AsRef<[T]>, const MAX_CHANNELS: usize>(
638 resampler: &mut ResamplerType<T>,
639 input: &[Vin],
640 tmp_deintlv_out_buf_slices: &mut ArrayVec<&mut [T], MAX_CHANNELS>,
641 on_output_packet: &mut impl FnMut(ArrayVec<&[T], MAX_CHANNELS>, &mut Vec<T>),
642 output_frames_processed: &mut u64,
643 desired_output_frames: Option<u64>,
644 delay_frames_left: &mut usize,
645 trim_delay: bool,
646 tmp_intlv_buf: &mut Vec<T>,
647) {
648 let (_, output_frames) = resampler
649 .process_into_buffer(input, tmp_deintlv_out_buf_slices, None)
650 .unwrap();
651
652 let (output_packet_start, mut packet_output_frames) = if trim_delay && *delay_frames_left > 0 {
653 let delay_frames = output_frames.min(*delay_frames_left);
654 *delay_frames_left -= delay_frames;
655 (delay_frames, output_frames - delay_frames)
656 } else {
657 (0, output_frames)
658 };
659
660 if let Some(desired_output_frames) = desired_output_frames {
661 if desired_output_frames <= *output_frames_processed {
662 packet_output_frames = 0;
663 } else if (desired_output_frames - *output_frames_processed) < packet_output_frames as u64 {
664 packet_output_frames = (desired_output_frames - *output_frames_processed) as usize
665 }
666 }
667
668 if packet_output_frames > 0 {
669 let out_packet_slices: ArrayVec<&[T], MAX_CHANNELS> = tmp_deintlv_out_buf_slices
670 .iter()
671 .map(|s| &s[output_packet_start..output_packet_start + packet_output_frames])
672 .collect();
673
674 (on_output_packet)(out_packet_slices, tmp_intlv_buf);
675 }
676
677 *output_frames_processed += packet_output_frames as u64;
678}