diff --git a/src/audio/resampling.rs b/src/audio/resampling.rs index 6a6024b..be51989 100644 --- a/src/audio/resampling.rs +++ b/src/audio/resampling.rs @@ -1,28 +1,18 @@ -use rubato::{ - Resampler, SincFixedIn, SincInterpolationParameters, SincInterpolationType, WindowFunction, -}; +use rubato::{FastFixedIn, PolynomialDegree, Resampler}; +#[inline] pub fn resampling( current_sample_rate: u32, target_sample_rate: u32, data: Vec>, ) -> Vec> { - let params = SincInterpolationParameters { - sinc_len: 8, - f_cutoff: 0.95, - interpolation: SincInterpolationType::Linear, - oversampling_factor: 64, - window: WindowFunction::Hann2, - }; - - let mut resampler = SincFixedIn::::new( + let mut resampler = FastFixedIn::::new( current_sample_rate as f64 / target_sample_rate as f64, 2.0, - params, + PolynomialDegree::Cubic, data[0].len(), data.len(), ) .unwrap(); - resampler.process(&data, None).unwrap() } diff --git a/src/commands/run.rs b/src/commands/run.rs index 71519d8..6cdaba4 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -239,6 +239,8 @@ pub fn run(run: Run) { } } + std::thread::sleep(std::time::Duration::from_millis(500)); + for output_route in &config.routes.output { match &output_route.device { crate::config::Device::Local { local } => { @@ -259,7 +261,7 @@ pub fn run(run: Run) { .cloned() .collect::>()[0] .clone(); - let index = virtual_device.lock().unwrap().add_output(); + let index = virtual_device.lock().unwrap().add_output(sample_rate); let stream = match config.sample_format() { cpal::SampleFormat::I8 => device.build_output_stream( @@ -357,11 +359,6 @@ fn input_callback( { let data: Vec = data.iter().map(|d| d.to_f32().unwrap()).collect(); let audio_data = reshape_audio_data(&data, channels); - let audio_data = crate::audio::resampling::resampling( - sample_rate, - virtual_device.lock().unwrap().sample_rate, - audio_data, - ); virtual_device .lock() .unwrap() @@ -379,16 +376,17 @@ fn output_callback( { let mut virtual_device = virtual_device.lock().unwrap(); let vd_channels = virtual_device.channels; - let mut audio_data = virtual_device - .take_output( - index, - min(channels as u8, vd_channels), - data.len() / channels, - ) - .unwrap_or(vec![vec![0.; data.len() / channels]; channels]); - let audio_data = - crate::audio::resampling::resampling(virtual_device.sample_rate, sample_rate, audio_data); - let mut audio_data = to_flat_audio_data(&audio_data); + let audio_data = virtual_device.take_output( + index, + min(channels as u8, vd_channels), + sample_rate, + data.len() / channels, + ); + if audio_data.is_none() { + println!("audio_data is none"); + return; + } + let mut audio_data = to_flat_audio_data(&audio_data.unwrap()); let data_len = data.len(); let audio_data_len = audio_data.len(); diff --git a/src/device/virtual_device.rs b/src/device/virtual_device.rs index a337eef..2d76634 100644 --- a/src/device/virtual_device.rs +++ b/src/device/virtual_device.rs @@ -1,9 +1,14 @@ +use std::collections::HashMap; + +use crate::audio::resampling::resampling; + pub struct VirtualDevice { pub name: String, pub channels: u8, pub sample_rate: u32, - output_index: Vec, - output_buffer: Vec>, + + output_index: HashMap>, + output_buffer: HashMap>>, } impl VirtualDevice { @@ -12,68 +17,77 @@ impl VirtualDevice { name, channels, sample_rate, - output_index: Vec::new(), - output_buffer: vec![vec![]; channels as usize], + output_index: HashMap::new(), + output_buffer: HashMap::new(), } } #[inline] - fn get_min_index(&self) -> usize { - *self.output_index.iter().min().unwrap_or(&0) + fn get_min_index(&self, sample_rate: u32) -> usize { + *self.output_index[&sample_rate].iter().min().unwrap_or(&0) } - pub fn add_output(&mut self) -> usize { - self.output_index.push(self.get_min_index()); - self.output_index.len() - 1 + pub fn add_output(&mut self, sample_rate: u32) -> usize { + if let std::collections::hash_map::Entry::Vacant(e) = self.output_index.entry(sample_rate) { + e.insert(Vec::new()); + self.output_buffer + .insert(sample_rate, vec![vec![]; self.channels as usize]); + } + let min_index = self.get_min_index(sample_rate); + self.output_index + .get_mut(&sample_rate) + .unwrap() + .push(min_index); + self.output_index[&sample_rate].len() - 1 } pub fn take_output( &mut self, index: usize, channels: u8, + sample_rate: u32, take_size: usize, ) -> Option>> { let mut buffer = vec![Vec::with_capacity(take_size); channels as usize]; - let start = self.output_index[index]; + let start = self.output_index[&sample_rate][index]; let end = start + take_size; for channel in 0..channels { - if end > self.output_buffer[channel as usize].len() { + if end > self.output_buffer[&sample_rate][channel as usize].len() { return None; } - if start >= self.output_buffer[channel as usize].len() { + if start >= self.output_buffer[&sample_rate][channel as usize].len() { return None; } } for i in start..end { for channel in 0..channels { - buffer[channel as usize].push(self.output_buffer[channel as usize][i]); + buffer[channel as usize] + .push(self.output_buffer[&sample_rate][channel as usize][i]); } } - self.output_index[index] = end; + self.output_index.get_mut(&sample_rate).unwrap()[index] = end; - let min = self.get_min_index(); + let min = self.get_min_index(sample_rate); if min != 0 { for i in 0..self.channels as usize { - let len = self.output_buffer[i].len(); - self.output_buffer[i].drain(0..(if len < min { len } else { min })); + let len = self.output_buffer[&sample_rate][i].len(); + self.output_buffer.get_mut(&sample_rate).unwrap()[i] + .drain(0..(if len < min { len } else { min })); } for i in 0..self.output_index.len() { - self.output_index[i] -= min; + self.output_index.get_mut(&sample_rate).unwrap()[i] -= min; } } Some(buffer) } - pub fn write_input_multiple_channels(&mut self, buffer: &[Vec]) { - (0..self.channels as usize).for_each(|i| { - self.output_buffer[i].extend(buffer[i].iter()); - }); - } - - pub fn write_input(&mut self, channel: u8, buffer: Vec) { - self.output_buffer[channel as usize].extend(buffer); + pub fn write_input_multiple_channels(&mut self, input_buffer: &[Vec]) { + for (sample_rate, buffer) in self.output_buffer.iter_mut() { + let buffer_resample = resampling(self.sample_rate, *sample_rate, input_buffer.to_vec()); + (0..self.channels as usize).for_each(|i| buffer[i].extend(buffer_resample[i].iter())); + } } }