diff --git a/client/src/audio_streams.rs b/client/src/audio_streams.rs index 96248ce..267cbce 100644 --- a/client/src/audio_streams.rs +++ b/client/src/audio_streams.rs @@ -1,5 +1,5 @@ use cpal::{ - Device, FromSample, SampleFormat, SizedSample, StreamConfig, SupportedStreamConfig, + Device, FromSample, Sample, SampleFormat, SizedSample, StreamConfig, SupportedStreamConfig, traits::{DeviceTrait, StreamTrait}, }; use ringbuf::{ @@ -21,16 +21,16 @@ use crate::models::{ InputAudioStreamsInfo, InputAudioStreamsProducers, }; -pub async fn audio_stream_receiver( - output_device: Device, - output_device_config: SupportedStreamConfig, - active_input_audio_streams_producers: InputAudioStreamsProducers, +fn cpal_build_output_stream( + output_device: &Device, + output_device_config: StreamConfig, active_input_audio_streams_consumers: InputAudioStreamsConsumers, - active_input_audio_streams_encoders: InputAudioStreamsEncoders, - active_input_audio_streams_info: InputAudioStreamsInfo, - udp_socket: Arc, -) { - let output_data_fn = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| { +) -> cpal::Stream +where + T: SizedSample, + T: FromSample, +{ + let output_data_fn = move |data: &mut [T], _: &cpal::OutputCallbackInfo| { let mut streams = active_input_audio_streams_consumers.lock().unwrap(); for sample in data { let mut mixed_value: f32 = 0.0; @@ -42,14 +42,51 @@ pub async fn audio_stream_receiver( } } - *sample = mixed_value; + *sample = mixed_value.to_sample::(); } }; - let err_fn = |err| eprintln!("stream error: {}", err); - let output_stream = output_device - .build_output_stream(output_device_config.into(), output_data_fn, err_fn, None) + + return output_device + .build_output_stream(output_device_config, output_data_fn, err_fn, None) .expect("building output stream failed"); +} + +pub async fn audio_stream_receiver( + output_device: Device, + output_device_config: SupportedStreamConfig, + active_input_audio_streams_producers: InputAudioStreamsProducers, + active_input_audio_streams_consumers: InputAudioStreamsConsumers, + active_input_audio_streams_encoders: InputAudioStreamsEncoders, + active_input_audio_streams_info: InputAudioStreamsInfo, + udp_socket: Arc, +) { + let output_stream = match output_device_config.sample_format() { + SampleFormat::F32 => cpal_build_output_stream::( + &output_device, + output_device_config.into(), + active_input_audio_streams_consumers, + ), + SampleFormat::I32 => cpal_build_output_stream::( + &output_device, + output_device_config.into(), + active_input_audio_streams_consumers, + ), + SampleFormat::I16 => cpal_build_output_stream::( + &output_device, + output_device_config.into(), + active_input_audio_streams_consumers, + ), + SampleFormat::U16 => cpal_build_output_stream::( + &output_device, + output_device_config.into(), + active_input_audio_streams_consumers, + ), + _ => { + eprintln!("unsupported output stream format :("); + return; + } + }; output_stream.play().expect("failed to play output stream"); @@ -226,7 +263,7 @@ pub async fn audio_stream_spawner( cpal_build_input_stream::(&input_device, input_device_config.into(), producer) } _ => { - eprintln!("unsupported stream format :("); + eprintln!("unsupported input stream format :("); return; } }; diff --git a/client/src/tui.rs b/client/src/tui.rs index f1ff322..5d9d678 100644 --- a/client/src/tui.rs +++ b/client/src/tui.rs @@ -172,7 +172,6 @@ impl DeviceSelectScreen { if let Some(default_output_device) = host.default_output_device() { if let Ok(default_config) = default_output_device.default_output_config() { if default_config.sample_rate() == SAMPLE_RATE_48K - && default_config.sample_format() == SampleFormat::F32 && (default_config.channels() == 1 || default_config.channels() == 2) { output_devices.push((default_output_device.clone(), default_config.into())); @@ -182,9 +181,7 @@ impl DeviceSelectScreen { if let Some(output_config) = supported_config.try_with_sample_rate(SAMPLE_RATE_48K) { - if output_config.sample_format() == SampleFormat::F32 - && (output_config.channels() == 1 || output_config.channels() == 2) - { + if output_config.channels() == 1 || output_config.channels() == 2 { output_devices.push((default_output_device, output_config.into())); break; } @@ -197,7 +194,6 @@ impl DeviceSelectScreen { for possible_output_device in possible_output_devices { if let Ok(default_config) = possible_output_device.default_output_config() { if default_config.sample_rate() == SAMPLE_RATE_48K - && default_config.sample_format() == SampleFormat::F32 && (default_config.channels() == 1 || default_config.channels() == 2) { output_devices @@ -210,9 +206,7 @@ impl DeviceSelectScreen { if let Some(output_config) = supported_config.try_with_sample_rate(SAMPLE_RATE_48K) { - if output_config.sample_format() == SampleFormat::F32 - && (output_config.channels() == 1 || output_config.channels() == 2) - { + if output_config.channels() == 1 || output_config.channels() == 2 { output_devices.push((possible_output_device, output_config.into())); break; }