diff --git a/src/host/asio/mod.rs b/src/host/asio/mod.rs index 917b958..a885db6 100644 --- a/src/host/asio/mod.rs +++ b/src/host/asio/mod.rs @@ -3,8 +3,8 @@ extern crate parking_lot; use crate::{ BuildStreamError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError, - PauseStreamError, PlayStreamError, StreamError, SupportedStreamConfig, - SupportedStreamConfigsError, + PauseStreamError, PlayStreamError, SampleFormat, StreamConfig, StreamError, + SupportedStreamConfig, SupportedStreamConfigsError, }; use traits::{DeviceTrait, HostTrait, StreamTrait}; @@ -84,7 +84,8 @@ impl DeviceTrait for Device { fn build_input_stream_raw( &self, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, data_callback: D, error_callback: E, ) -> Result @@ -92,12 +93,13 @@ impl DeviceTrait for Device { D: FnMut(&Data) + Send + 'static, E: FnMut(StreamError) + Send + 'static, { - Device::build_input_stream_raw(self, config, data_callback, error_callback) + Device::build_input_stream_raw(self, config, sample_format, data_callback, error_callback) } fn build_output_stream_raw( &self, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, data_callback: D, error_callback: E, ) -> Result @@ -105,7 +107,7 @@ impl DeviceTrait for Device { D: FnMut(&mut Data) + Send + 'static, E: FnMut(StreamError) + Send + 'static, { - Device::build_output_stream_raw(self, config, data_callback, error_callback) + Device::build_output_stream_raw(self, config, sample_format, data_callback, error_callback) } } diff --git a/src/host/asio/stream.rs b/src/host/asio/stream.rs index 42ff8ac..33f7974 100644 --- a/src/host/asio/stream.rs +++ b/src/host/asio/stream.rs @@ -14,6 +14,7 @@ use PauseStreamError; use PlayStreamError; use Sample; use SampleFormat; +use StreamConfig; use StreamError; use SupportedStreamConfig; @@ -59,7 +60,8 @@ impl Stream { impl Device { pub fn build_input_stream_raw( &self, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, mut data_callback: D, _error_callback: E, ) -> Result @@ -70,14 +72,14 @@ impl Device { let stream_type = self.driver.input_data_type().map_err(build_stream_err)?; // Ensure that the desired sample type is supported. - let sample_format = super::device::convert_data_type(&stream_type) + let expected_sample_format = super::device::convert_data_type(&stream_type) .ok_or(BuildStreamError::StreamConfigNotSupported)?; - if config.sample_format != sample_format { + if sample_format != expected_sample_format { return Err(BuildStreamError::StreamConfigNotSupported); } let num_channels = config.channels.clone(); - let buffer_size = self.get_or_create_input_stream(config)?; + let buffer_size = self.get_or_create_input_stream(config, sample_format)?; let cpal_num_samples = buffer_size * num_channels as usize; // Create the buffer depending on the size of the data type. @@ -225,7 +227,8 @@ impl Device { pub fn build_output_stream_raw( &self, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, mut data_callback: D, _error_callback: E, ) -> Result @@ -236,14 +239,14 @@ impl Device { let stream_type = self.driver.output_data_type().map_err(build_stream_err)?; // Ensure that the desired sample type is supported. - let sample_format = super::device::convert_data_type(&stream_type) + let expected_sample_format = super::device::convert_data_type(&stream_type) .ok_or(BuildStreamError::StreamConfigNotSupported)?; - if config.sample_format != sample_format { + if sample_format != expected_sample_format { return Err(BuildStreamError::StreamConfigNotSupported); } let num_channels = config.channels.clone(); - let buffer_size = self.get_or_create_output_stream(config)?; + let buffer_size = self.get_or_create_output_stream(config, sample_format)?; let cpal_num_samples = buffer_size * num_channels as usize; // Create buffers depending on data type. @@ -438,12 +441,13 @@ impl Device { /// On success, the buffer size of the stream is returned. fn get_or_create_input_stream( &self, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, ) -> Result { match self.default_input_config() { Ok(f) => { let num_asio_channels = f.channels; - check_config(&self.driver, config, num_asio_channels) + check_config(&self.driver, config, sample_format, num_asio_channels) } Err(_) => Err(BuildStreamError::StreamConfigNotSupported), }?; @@ -478,12 +482,13 @@ impl Device { /// If there is no existing ASIO Output Stream it will be created. fn get_or_create_output_stream( &self, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, ) -> Result { match self.default_output_config() { Ok(f) => { let num_asio_channels = f.channels; - check_config(&self.driver, config, num_asio_channels) + check_config(&self.driver, config, sample_format, num_asio_channels) } Err(_) => Err(BuildStreamError::StreamConfigNotSupported), }?; @@ -581,13 +586,13 @@ impl AsioSample for f64 { /// Checks sample rate, data type and then finally the number of channels. fn check_config( driver: &sys::Driver, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, num_asio_channels: u16, ) -> Result<(), BuildStreamError> { - let SupportedStreamConfig { + let StreamConfig { channels, sample_rate, - sample_format, } = config; // Try and set the sample rate to what the user selected. let sample_rate = sample_rate.0.into(); diff --git a/src/host/coreaudio/mod.rs b/src/host/coreaudio/mod.rs index 61800e4..e3a699f 100644 --- a/src/host/coreaudio/mod.rs +++ b/src/host/coreaudio/mod.rs @@ -22,7 +22,8 @@ use crate::traits::{DeviceTrait, HostTrait, StreamTrait}; use crate::{ BackendSpecificError, BuildStreamError, ChannelCount, Data, DefaultStreamConfigError, DeviceNameError, DevicesError, PauseStreamError, PlayStreamError, SampleFormat, SampleRate, - StreamError, SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError, + StreamConfig, StreamError, SupportedStreamConfig, SupportedStreamConfigRange, + SupportedStreamConfigsError, }; use std::cell::RefCell; use std::ffi::CStr; @@ -104,7 +105,8 @@ impl DeviceTrait for Device { fn build_input_stream_raw( &self, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, data_callback: D, error_callback: E, ) -> Result @@ -112,12 +114,13 @@ impl DeviceTrait for Device { D: FnMut(&Data) + Send + 'static, E: FnMut(StreamError) + Send + 'static, { - Device::build_input_stream_raw(self, config, data_callback, error_callback) + Device::build_input_stream_raw(self, config, sample_format, data_callback, error_callback) } fn build_output_stream_raw( &self, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, data_callback: D, error_callback: E, ) -> Result @@ -125,7 +128,7 @@ impl DeviceTrait for Device { D: FnMut(&mut Data) + Send + 'static, E: FnMut(StreamError) + Send + 'static, { - Device::build_output_stream_raw(self, config, data_callback, error_callback) + Device::build_output_stream_raw(self, config, sample_format, data_callback, error_callback) } } @@ -402,15 +405,17 @@ impl From for BuildStreamError { } // Create a coreaudio AudioStreamBasicDescription from a CPAL Format. -fn asbd_from_config(config: &SupportedStreamConfig) -> AudioStreamBasicDescription { +fn asbd_from_config( + config: &StreamConfig, + sample_format: SampleFormat, +) -> AudioStreamBasicDescription { let n_channels = config.channels as usize; let sample_rate = config.sample_rate.0; - let bytes_per_channel = config.sample_format.sample_size(); + let bytes_per_channel = sample_format.sample_size(); let bits_per_channel = bytes_per_channel * 8; let bytes_per_frame = n_channels * bytes_per_channel; let frames_per_packet = 1; let bytes_per_packet = frames_per_packet * bytes_per_frame; - let sample_format = config.sample_format; let format_flags = match sample_format { SampleFormat::F32 => (kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked) as u32, _ => kAudioFormatFlagIsPacked as u32, @@ -475,7 +480,8 @@ fn audio_unit_from_device(device: &Device, input: bool) -> Result( &self, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, mut data_callback: D, _error_callback: E, ) -> Result @@ -625,12 +631,11 @@ impl Device { let mut audio_unit = audio_unit_from_device(self, true)?; // Set the stream in interleaved mode. - let asbd = asbd_from_config(config); + let asbd = asbd_from_config(config, sample_format); audio_unit.set_property(kAudioUnitProperty_StreamFormat, scope, element, Some(&asbd))?; // Register the callback that is being called by coreaudio whenever it needs data to be // fed to the audio buffer. - let sample_format = config.sample_format; let bytes_per_channel = sample_format.sample_size(); type Args = render_callback::Args; audio_unit.set_input_callback(move |args: Args| unsafe { @@ -663,7 +668,8 @@ impl Device { fn build_output_stream_raw( &self, - config: &SupportedStreamConfig, + config: &StreamConfig, + sample_format: SampleFormat, mut data_callback: D, _error_callback: E, ) -> Result @@ -678,12 +684,11 @@ impl Device { let element = Element::Output; // Set the stream in interleaved mode. - let asbd = asbd_from_config(config); + let asbd = asbd_from_config(config, sample_format); audio_unit.set_property(kAudioUnitProperty_StreamFormat, scope, element, Some(&asbd))?; // Register the callback that is being called by coreaudio whenever it needs data to be // fed to the audio buffer. - let sample_format = config.sample_format; let bytes_per_channel = sample_format.sample_size(); type Args = render_callback::Args; audio_unit.set_render_callback(move |args: Args| unsafe {