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.get();
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 == 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,
410 frames,
411 );
412
413 (on_output_packet)(&tmp_intlv_buf[..frames * num_channels]);
414 }
415 };
416
417 let total_input_frames = input.len() / self.num_channels;
418
419 let mut tmp_deintlv_in_buf_slices: ArrayVec<&mut [T], MAX_CHANNELS> = self
420 .tmp_deintlv_in_buf
421 .chunks_exact_mut(self.input_block_frames)
422 .collect();
423 let mut tmp_deintlv_out_buf_slices: ArrayVec<&mut [T], MAX_CHANNELS> = self
424 .tmp_deintlv_out_buf
425 .chunks_exact_mut(self.max_output_block_frames)
426 .collect();
427
428 let mut input_frames_processed = 0;
429 let mut output_frames_processed = 0;
430
431 let desired_output_frames = last_packet.and_then(|info| info.desired_output_frames);
432
433 while input_frames_processed < total_input_frames {
434 let copy_frames = (self.input_block_frames - self.tmp_deintlv_in_buf_len)
435 .min(total_input_frames - input_frames_processed);
436
437 crate::interleave::deinterleave(
438 &input[input_frames_processed * self.num_channels.get()
439 ..(input_frames_processed + copy_frames) * self.num_channels.get()],
440 &mut tmp_deintlv_in_buf_slices,
441 self.num_channels.get(),
442 self.tmp_deintlv_in_buf_len,
443 copy_frames,
444 );
445
446 self.tmp_deintlv_in_buf_len += copy_frames;
447 input_frames_processed += copy_frames;
448
449 if self.tmp_deintlv_in_buf_len < self.input_block_frames {
450 break;
452 }
453
454 resample_inner(
455 &mut self.resampler,
456 &tmp_deintlv_in_buf_slices,
457 &mut tmp_deintlv_out_buf_slices,
458 &mut on_output_packet_inner,
459 &mut output_frames_processed,
460 desired_output_frames,
461 &mut self.delay_frames_left,
462 trim_delay,
463 &mut self.tmp_intlv_buf,
464 );
465
466 self.tmp_deintlv_in_buf_len = 0;
467 }
468
469 if last_packet.is_some() {
470 process_last_packet(
471 &mut tmp_deintlv_in_buf_slices,
472 &mut tmp_deintlv_out_buf_slices,
473 &mut self.resampler,
474 &mut on_output_packet_inner,
475 &mut output_frames_processed,
476 desired_output_frames,
477 &mut self.delay_frames_left,
478 trim_delay,
479 &mut self.tmp_intlv_buf,
480 self.tmp_deintlv_in_buf_len,
481 );
482 }
483 }
484
485 if last_packet.is_some() {
486 self.reset();
487 }
488 }
489
490 pub fn reset(&mut self) {
494 self.resampler.reset();
495 self.tmp_deintlv_in_buf_len = 0;
496 self.delay_frames_left = self.output_delay;
497 }
498}
499
500impl<T: Sample, const MAX_CHANNELS: usize> Into<ResamplerType<T>>
501 for FixedResampler<T, MAX_CHANNELS>
502{
503 fn into(self) -> ResamplerType<T> {
504 self.resampler
505 }
506}
507
508fn process_last_packet<T: Sample, const MAX_CHANNELS: usize>(
509 tmp_deintlv_in_buf_slices: &mut ArrayVec<&mut [T], MAX_CHANNELS>,
510 tmp_deintlv_out_buf_slices: &mut ArrayVec<&mut [T], MAX_CHANNELS>,
511 resampler: &mut ResamplerType<T>,
512 on_output_packet: &mut impl FnMut(ArrayVec<&[T], MAX_CHANNELS>, &mut Vec<T>),
513 output_frames_processed: &mut u64,
514 desired_output_frames: Option<u64>,
515 delay_frames_left: &mut usize,
516 trim_delay: bool,
517 tmp_intlv_buf: &mut Vec<T>,
518 tmp_deintlv_in_buf_len: usize,
519) {
520 if tmp_deintlv_in_buf_len > 0 {
521 for ch in tmp_deintlv_in_buf_slices.iter_mut() {
522 ch[tmp_deintlv_in_buf_len..].fill(T::zero());
523 }
524
525 resample_inner(
526 resampler,
527 &tmp_deintlv_in_buf_slices,
528 tmp_deintlv_out_buf_slices,
529 on_output_packet,
530 output_frames_processed,
531 desired_output_frames,
532 delay_frames_left,
533 trim_delay,
534 tmp_intlv_buf,
535 );
536 }
537
538 for ch in tmp_deintlv_in_buf_slices.iter_mut() {
539 ch.fill(T::zero());
540 }
541
542 if let Some(desired_output_frames) = desired_output_frames {
543 if *output_frames_processed >= desired_output_frames {
544 return;
545 }
546
547 while *output_frames_processed < desired_output_frames {
548 resample_inner(
549 resampler,
550 &tmp_deintlv_in_buf_slices,
551 tmp_deintlv_out_buf_slices,
552 on_output_packet,
553 output_frames_processed,
554 Some(desired_output_frames),
555 delay_frames_left,
556 trim_delay,
557 tmp_intlv_buf,
558 );
559 }
560 } else {
561 resample_inner(
562 resampler,
563 &tmp_deintlv_in_buf_slices,
564 tmp_deintlv_out_buf_slices,
565 on_output_packet,
566 output_frames_processed,
567 desired_output_frames,
568 delay_frames_left,
569 trim_delay,
570 tmp_intlv_buf,
571 );
572 }
573}
574
575fn resample_inner<T: Sample, Vin: AsRef<[T]>, const MAX_CHANNELS: usize>(
576 resampler: &mut ResamplerType<T>,
577 input: &[Vin],
578 tmp_deintlv_out_buf_slices: &mut ArrayVec<&mut [T], MAX_CHANNELS>,
579 on_output_packet: &mut impl FnMut(ArrayVec<&[T], MAX_CHANNELS>, &mut Vec<T>),
580 output_frames_processed: &mut u64,
581 desired_output_frames: Option<u64>,
582 delay_frames_left: &mut usize,
583 trim_delay: bool,
584 tmp_intlv_buf: &mut Vec<T>,
585) {
586 let (_, output_frames) = resampler
587 .process_into_buffer(input, tmp_deintlv_out_buf_slices, None)
588 .unwrap();
589
590 let (output_packet_start, mut packet_output_frames) = if trim_delay && *delay_frames_left > 0 {
591 let delay_frames = output_frames.min(*delay_frames_left);
592 *delay_frames_left -= delay_frames;
593 (delay_frames, output_frames - delay_frames)
594 } else {
595 (0, output_frames)
596 };
597
598 if let Some(desired_output_frames) = desired_output_frames {
599 if desired_output_frames <= *output_frames_processed {
600 packet_output_frames = 0;
601 } else if (desired_output_frames - *output_frames_processed) < packet_output_frames as u64 {
602 packet_output_frames = (desired_output_frames - *output_frames_processed) as usize
603 }
604 }
605
606 if packet_output_frames > 0 {
607 let out_packet_slices: ArrayVec<&[T], MAX_CHANNELS> = tmp_deintlv_out_buf_slices
608 .iter()
609 .map(|s| &s[output_packet_start..output_packet_start + packet_output_frames])
610 .collect();
611
612 (on_output_packet)(out_packet_slices, tmp_intlv_buf);
613 }
614
615 *output_frames_processed += packet_output_frames as u64;
616}