use audioadapter::AdapterMut;
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use fixed_resample::{audioadapter_buffers::direct::InterleavedSlice, PushStatus, ReadStatus};
fn main() {
let host = cpal::default_host();
let input_device = host.default_input_device().unwrap();
let output_device = host.default_output_device().unwrap();
let output_config: cpal::StreamConfig = output_device.default_output_config().unwrap().into();
let mut input_config = None;
for config in input_device.supported_input_configs().unwrap() {
if let Some(config) = config.try_with_sample_rate(output_config.sample_rate) {
input_config = Some(config);
break;
}
}
let input_config: cpal::StreamConfig = input_config
.unwrap_or_else(|| input_device.default_input_config().unwrap())
.into();
let output_channels = output_config.channels as usize;
let input_channels = (input_config.channels as usize).min(output_channels);
dbg!(&input_config);
dbg!(&output_config);
let (mut prod, mut cons) = fixed_resample::resampling_channel::<f32>(
input_channels, input_config.sample_rate,
output_config.sample_rate,
true, Default::default(), );
let input_data_fn = move |data: &[f32], _: &cpal::InputCallbackInfo| {
let status = prod.push_interleaved(data);
match status {
PushStatus::Ok => {}
PushStatus::OutputNotReady => {}
PushStatus::OverflowOccurred {
num_frames_pushed: _,
} => {
eprintln!("output stream fell behind: try increasing channel capacity");
}
PushStatus::UnderflowCorrected {
num_zero_frames_pushed: _,
} => {
eprintln!("input stream fell behind: try increasing channel latency");
}
}
};
let mut in_buffer = vec![0.0; 2048 * input_channels];
let output_data_fn = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
let frames = data.len() / output_channels;
let in_samples = frames * input_channels;
if in_buffer.len() < in_samples {
in_buffer.resize(in_samples, 0.0);
}
let mut input_adapter =
InterleavedSlice::new_mut(&mut in_buffer, input_channels, frames).unwrap();
let mut output_adapter = InterleavedSlice::new_mut(data, output_channels, frames).unwrap();
let status = cons.read(
&mut input_adapter,
None, None, false, );
match status {
ReadStatus::Ok => {}
ReadStatus::InputNotReady => {}
ReadStatus::UnderflowOccurred { num_frames_read: _ } => {
eprintln!("input stream fell behind: try increasing channel latency");
}
ReadStatus::OverflowCorrected {
num_frames_discarded: _,
} => {
eprintln!("output stream fell behind: try increasing channel capacity");
}
}
if input_channels == 1 {
for ch_i in 0..output_channels {
output_adapter.copy_from_other_to_channel(&input_adapter, 0, ch_i, 0, 0, frames);
}
} else {
output_adapter.copy_from_other(&input_adapter, 0, 0, frames);
}
};
let input_stream = input_device
.build_input_stream(input_config, input_data_fn, err_fn, None)
.unwrap();
let output_stream = output_device
.build_output_stream(output_config, output_data_fn, err_fn, None)
.unwrap();
input_stream.play().unwrap();
output_stream.play().unwrap();
std::thread::sleep(std::time::Duration::from_secs(10));
}
fn err_fn(err: cpal::Error) {
eprintln!("an error occurred on stream: {}", err);
}