From b85f96b0bb1d1c1e2a6058ad31f79617b0805eea Mon Sep 17 00:00:00 2001 From: Dennis Ranke Date: Sun, 16 Jun 2024 13:21:23 +0200 Subject: [PATCH] add support to output sound on devices that only offer surround configs --- src/run_native.rs | 52 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/run_native.rs b/src/run_native.rs index b6457cc..7d8b3c7 100644 --- a/src/run_native.rs +++ b/src/run_native.rs @@ -328,9 +328,8 @@ fn init_sound( let mut configs: Vec<_> = device .supported_output_configs()? .filter(|config| { - config.channels() <= 2 - && (config.sample_format() == cpal::SampleFormat::F32 - || config.sample_format() == cpal::SampleFormat::I16) + config.sample_format() == cpal::SampleFormat::F32 + || config.sample_format() == cpal::SampleFormat::I16 }) .collect(); @@ -532,6 +531,25 @@ fn init_sound( } } + fn stereo_to_surround(mut buffer: &mut [f32], num_channels: usize, callback: &mut F) + where + F: FnMut(&mut [f32]), + { + let mut in_buffer = [0f32; 256]; + buffer.fill(0.); + + while !buffer.is_empty() { + let step_size = (buffer.len() / num_channels).min(in_buffer.len() / 2); + let step_buffer = &mut in_buffer[..step_size * 2]; + callback(step_buffer); + for index in 0..step_size { + buffer[index * num_channels + 0] = step_buffer[index * 2 + 0]; + buffer[index * num_channels + 1] = step_buffer[index * 2 + 1]; + } + buffer = &mut buffer[step_size * num_channels..]; + } + } + let stream = if sample_format == cpal::SampleFormat::F32 { if num_channels == 2 { device.build_output_stream( @@ -542,7 +560,7 @@ fn init_sound( }, None, )? - } else { + } else if num_channels == 1 { device.build_output_stream( &config, move |buffer: &mut [f32], _| stereo_to_mono(buffer, &mut callback), @@ -551,6 +569,17 @@ fn init_sound( }, None, )? + } else { + device.build_output_stream( + &config, + move |buffer: &mut [f32], _| { + stereo_to_surround(buffer, num_channels as usize, &mut callback) + }, + move |err| { + dbg!(err); + }, + None, + )? } } else { if num_channels == 2 { @@ -562,7 +591,7 @@ fn init_sound( }, None, )? - } else { + } else if num_channels == 1 { device.build_output_stream( &config, move |buffer: &mut [i16], _| { @@ -573,6 +602,19 @@ fn init_sound( }, None, )? + } else { + device.build_output_stream( + &config, + move |buffer: &mut [i16], _| { + f32_to_i16(buffer, &mut |b| { + stereo_to_surround(b, num_channels as usize, &mut callback) + }) + }, + move |err| { + dbg!(err); + }, + None, + )? } };