Upgrade rubato
This commit is contained in:
+37
-33
@@ -1,17 +1,17 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{Result, bail};
|
||||
use audioadapter_buffers::direct::InterleavedSlice;
|
||||
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||
use itertools::Itertools;
|
||||
use rubato::{FastFixedOut, Resampler};
|
||||
use rubato::Resampler;
|
||||
use tracing::error;
|
||||
|
||||
pub struct Audio {
|
||||
#[allow(unused)]
|
||||
stream: cpal::Stream,
|
||||
sampler: FastFixedOut<f32>,
|
||||
input_buffer: Vec<Vec<f32>>,
|
||||
output_buffer: Vec<Vec<f32>>,
|
||||
sampler: rubato::Async<f32>,
|
||||
input_buffer: Vec<f32>,
|
||||
output_buffer: Vec<f32>,
|
||||
sample_sink: rtrb::Producer<f32>,
|
||||
}
|
||||
|
||||
@@ -32,17 +32,18 @@ impl Audio {
|
||||
let mut config = config.with_max_sample_rate().config();
|
||||
let resample_ratio = config.sample_rate.0 as f64 / VB_FREQUENCY as f64;
|
||||
let chunk_size = (834.0 * resample_ratio) as usize;
|
||||
let sampler = FastFixedOut::new(
|
||||
let sampler = rubato::Async::new_poly(
|
||||
resample_ratio,
|
||||
64.0,
|
||||
rubato::PolynomialDegree::Cubic,
|
||||
chunk_size,
|
||||
2,
|
||||
rubato::FixedAsync::Output,
|
||||
)?;
|
||||
config.buffer_size = cpal::BufferSize::Fixed(sampler.output_frames_max() as u32);
|
||||
|
||||
let input_buffer = sampler.input_buffer_allocate(true);
|
||||
let output_buffer = sampler.output_buffer_allocate(true);
|
||||
let input_buffer = Vec::with_capacity(sampler.nbr_channels() * sampler.input_frames_max());
|
||||
let output_buffer = vec![0.0; sampler.nbr_channels() * sampler.output_frames_max()];
|
||||
let (sample_sink, mut sample_source) =
|
||||
rtrb::RingBuffer::new(sampler.output_frames_max() * 4);
|
||||
|
||||
@@ -78,34 +79,37 @@ impl Audio {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update(&mut self, samples: &[f32]) {
|
||||
for sample in samples.chunks_exact(2) {
|
||||
for (channel, value) in self.input_buffer.iter_mut().zip(sample) {
|
||||
channel.push(*value);
|
||||
}
|
||||
if self.input_buffer[0].len() >= self.sampler.input_frames_next() {
|
||||
let (_, output_samples) = self
|
||||
.sampler
|
||||
.process_into_buffer(&self.input_buffer, &mut self.output_buffer, None)
|
||||
pub fn update(&mut self, mut samples: &[f32]) {
|
||||
while self.input_buffer.len() + samples.len() >= self.sampler.input_frames_next() * 2 {
|
||||
let samples_needed = (self.sampler.input_frames_next() * 2) - self.input_buffer.len();
|
||||
let (current_samples, future_samples) = samples.split_at(samples_needed);
|
||||
self.input_buffer.extend_from_slice(current_samples);
|
||||
samples = future_samples;
|
||||
|
||||
let buffer_in =
|
||||
InterleavedSlice::new(&self.input_buffer, 2, self.sampler.input_frames_next())
|
||||
.unwrap();
|
||||
|
||||
let chunk = match self.sample_sink.write_chunk_uninit(output_samples * 2) {
|
||||
Ok(c) => c,
|
||||
Err(rtrb::chunks::ChunkError::TooFewSlots(n)) => {
|
||||
self.sample_sink.write_chunk_uninit(n).unwrap()
|
||||
}
|
||||
};
|
||||
let interleaved = self.output_buffer[0]
|
||||
.iter()
|
||||
.interleave(self.output_buffer[1].iter())
|
||||
.cloned();
|
||||
chunk.fill_from_iter(interleaved);
|
||||
|
||||
for channel in &mut self.input_buffer {
|
||||
channel.clear();
|
||||
let mut buffer_out = InterleavedSlice::new_mut(
|
||||
&mut self.output_buffer,
|
||||
2,
|
||||
self.sampler.output_frames_next(),
|
||||
)
|
||||
.unwrap();
|
||||
let (_, output_samples) = self
|
||||
.sampler
|
||||
.process_into_buffer(&buffer_in, &mut buffer_out, None)
|
||||
.unwrap();
|
||||
let chunk = match self.sample_sink.write_chunk_uninit(output_samples * 2) {
|
||||
Ok(c) => c,
|
||||
Err(rtrb::chunks::ChunkError::TooFewSlots(n)) => {
|
||||
self.sample_sink.write_chunk_uninit(n).unwrap()
|
||||
}
|
||||
}
|
||||
};
|
||||
chunk.fill_from_iter(self.output_buffer[..output_samples * 2].iter().copied());
|
||||
|
||||
self.input_buffer.clear();
|
||||
}
|
||||
self.input_buffer.extend_from_slice(samples);
|
||||
|
||||
while self.sample_sink.slots() < self.sampler.output_frames_max() * 2 {
|
||||
std::thread::sleep(Duration::from_micros(500));
|
||||
|
||||
Reference in New Issue
Block a user