diff --git a/src/host/alsa/mod.rs b/src/host/alsa/mod.rs index 3155bc6..90cc34a 100644 --- a/src/host/alsa/mod.rs +++ b/src/host/alsa/mod.rs @@ -6,7 +6,7 @@ use crate::{ BackendSpecificError, BufferSize, BuildStreamError, ChannelCount, Data, DefaultStreamConfigError, DeviceNameError, DevicesError, InputCallbackInfo, OutputCallbackInfo, PauseStreamError, PlayStreamError, SampleFormat, SampleRate, StreamConfig, StreamError, - SupportedBufferSizeRange, SupportedStreamConfig, SupportedStreamConfigRange, + SupportedBufferSize, SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError, }; use std::convert::TryInto; @@ -343,7 +343,7 @@ impl Device { let min_buffer_size = hw_params.get_buffer_size_min()?; let max_buffer_size = hw_params.get_buffer_size_max()?; - let buffer_size_range = SupportedBufferSizeRange { + let buffer_size_range = SupportedBufferSize::Range { min: min_buffer_size as u32, max: max_buffer_size as u32, requires_power_of_two: false, diff --git a/src/host/asio/device.rs b/src/host/asio/device.rs index 0d5b9ce..05aa723 100644 --- a/src/host/asio/device.rs +++ b/src/host/asio/device.rs @@ -12,7 +12,7 @@ use DeviceNameError; use DevicesError; use SampleFormat; use SampleRate; -use SupportedBufferSizeRange; +use SupportedBufferSize; use SupportedStreamConfig; use SupportedStreamConfigRange; use SupportedStreamConfigsError; @@ -132,7 +132,7 @@ impl Device { let channels = self.driver.channels().map_err(default_config_err)?.ins as u16; let sample_rate = SampleRate(self.driver.sample_rate().map_err(default_config_err)? as _); let (min, max) = self.driver.buffersize_range().map_err(default_config_err)?; - let buffer_size = SupportedBufferSizeRange { + let buffer_size = SupportedBufferSize::Range { min: min as u32, max: max as u32, requires_power_of_two: false, @@ -154,7 +154,7 @@ impl Device { let channels = self.driver.channels().map_err(default_config_err)?.outs as u16; let sample_rate = SampleRate(self.driver.sample_rate().map_err(default_config_err)? as _); let (min, max) = self.driver.buffersize_range().map_err(default_config_err)?; - let buffer_size = SupportedBufferSizeRange { + let buffer_size = SupportedBufferSize::Range { min: min as u32, max: max as u32, requires_power_of_two: false, diff --git a/src/host/coreaudio/mod.rs b/src/host/coreaudio/mod.rs index bb1f8ed..640370b 100644 --- a/src/host/coreaudio/mod.rs +++ b/src/host/coreaudio/mod.rs @@ -24,7 +24,7 @@ use crate::{ BackendSpecificError, BufferSize, BuildStreamError, ChannelCount, Data, DefaultStreamConfigError, DeviceNameError, DevicesError, InputCallbackInfo, OutputCallbackInfo, PauseStreamError, PlayStreamError, SampleFormat, SampleRate, StreamConfig, StreamError, - SupportedBufferSizeRange, SupportedStreamConfig, SupportedStreamConfigRange, + SupportedBufferSize, SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError, }; use std::cell::RefCell; @@ -915,14 +915,14 @@ fn check_os_status(os_status: OSStatus) -> Result<(), BackendSpecificError> { fn get_io_buffer_frame_size_range( audio_unit: &AudioUnit, -) -> Result { +) -> Result { let buffer_size_range: AudioValueRange = audio_unit.get_property( kAudioDevicePropertyBufferFrameSizeRange, Scope::Global, Element::Output, )?; - Ok(SupportedBufferSizeRange { + Ok(SupportedBufferSize::Range { min: buffer_size_range.mMinimum as u32, max: buffer_size_range.mMaximum as u32, requires_power_of_two: false, diff --git a/src/host/wasapi/device.rs b/src/host/wasapi/device.rs index 430aa02..8a176b8 100644 --- a/src/host/wasapi/device.rs +++ b/src/host/wasapi/device.rs @@ -1,8 +1,8 @@ use crate::{ - BackendSpecificError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError, - InputCallbackInfo, OutputCallbackInfo, SampleFormat, SampleRate, StreamConfig, - SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError, - COMMON_SAMPLE_RATES, + BackendSpecificError, BufferSize, Data, DefaultStreamConfigError, DeviceNameError, + DevicesError, InputCallbackInfo, OutputCallbackInfo, SampleFormat, SampleRate, + StreamConfig, SupportedBufferSize, SupportedStreamConfig, SupportedStreamConfigRange, + SupportedStreamConfigsError, COMMON_SAMPLE_RATES, }; use std; use std::ffi::OsString; @@ -27,6 +27,7 @@ use super::winapi::shared::mmreg; use super::winapi::shared::winerror; use super::winapi::shared::wtypes; use super::winapi::Interface; + // https://msdn.microsoft.com/en-us/library/cc230355.aspx use super::winapi::um::audioclient::{ self, IAudioClient, IID_IAudioClient, AUDCLNT_E_DEVICE_INVALIDATED, @@ -318,10 +319,11 @@ unsafe fn format_from_waveformatex_ptr( // Unknown data format returned by GetMixFormat. _ => return None, }; + let format = SupportedStreamConfig { - buffer_size: unimplemented!(), channels: (*waveformatex_ptr).nChannels as _, sample_rate: SampleRate((*waveformatex_ptr).nSamplesPerSec), + buffer_size: SupportedBufferSize::Unknown, sample_format, }; Some(format) @@ -514,7 +516,7 @@ impl Device { // TODO: Test the different sample formats? // Create the supported formats. - let mut format = match format_from_waveformatex_ptr(default_waveformatex_ptr.0) { + let format = match format_from_waveformatex_ptr(default_waveformatex_ptr.0) { Some(fmt) => fmt, None => { let description = @@ -526,9 +528,13 @@ impl Device { }; let mut supported_formats = Vec::with_capacity(supported_sample_rates.len()); for rate in supported_sample_rates { - format.sample_rate = SampleRate(rate as _); - unimplemented!(); - //supported_formats.push(SupportedStreamConfigRange::from(format.clone())); + supported_formats.push(SupportedStreamConfigRange { + channels: format.channels.clone(), + min_sample_rate: SampleRate(rate as _), + max_sample_rate: SampleRate(rate as _), + buffer_size: format.buffer_size.clone(), + sample_format: format.sample_format.clone(), + }) } Ok(supported_formats.into_iter()) } @@ -641,6 +647,16 @@ impl Device { } }; + match config.buffer_size { + BufferSize::Fixed(_) => { + // TO DO: We need IAudioClient3 to get buffersize ranges first + // Otherwise the supported ranges are unknown. In the mean time + // the smallest buffersize is selected and used. + return Err(BuildStreamError::StreamConfigNotSupported) + }, + BufferSize::Default => (), + }; + // Computing the format and initializing the device. let waveformatex = { let format_attempt = config_to_waveformatextensible(config, sample_format) @@ -793,6 +809,16 @@ impl Device { } }; + match config.buffer_size { + BufferSize::Fixed(_) => { + // TO DO: We need IAudioClient3 to get buffersize ranges first + // Otherwise the supported ranges are unknown. In the mean time + // the smallest buffersize is selected and used. + return Err(BuildStreamError::StreamConfigNotSupported) + }, + BufferSize::Default => (), + }; + // Computing the format and initializing the device. let waveformatex = { let format_attempt = config_to_waveformatextensible(config, sample_format) @@ -815,6 +841,7 @@ impl Device { &format_attempt.Format, ptr::null(), ); + match check_result(hresult) { Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => { (*audio_client).Release(); diff --git a/src/lib.rs b/src/lib.rs index ee12f21..a5c3a76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -202,10 +202,15 @@ pub struct StreamConfig { /// Describes the minimum and maximum supported buffer size for the device /// and if requested buffersize must be a power of 2 value. #[derive(Clone, Debug, Eq, PartialEq)] -pub struct SupportedBufferSizeRange { - pub min: FrameCount, - pub max: FrameCount, - pub requires_power_of_two: bool, +pub enum SupportedBufferSize { + Range { + min: FrameCount, + max: FrameCount, + requires_power_of_two: bool, + }, + /// In the case that the platform provides no way of getting the default + /// buffersize before starting a stream. + Unknown, } /// Describes a range of supported stream configurations, retrieved via the @@ -218,7 +223,7 @@ pub struct SupportedStreamConfigRange { /// Maximum value for the samples rate of the supported formats. pub(crate) max_sample_rate: SampleRate, /// Buffersize ranges supported by the device - pub(crate) buffer_size: SupportedBufferSizeRange, + pub(crate) buffer_size: SupportedBufferSize, /// Type of data expected by the device. pub(crate) sample_format: SampleFormat, } @@ -229,7 +234,7 @@ pub struct SupportedStreamConfigRange { pub struct SupportedStreamConfig { channels: ChannelCount, sample_rate: SampleRate, - buffer_size: SupportedBufferSizeRange, + buffer_size: SupportedBufferSize, sample_format: SampleFormat, } @@ -311,7 +316,7 @@ impl SupportedStreamConfig { self.sample_rate } - pub fn buffer_size(&self) -> &SupportedBufferSizeRange { + pub fn buffer_size(&self) -> &SupportedBufferSize { &self.buffer_size } @@ -519,7 +524,7 @@ impl SupportedStreamConfigRange { self.max_sample_rate } - pub fn buffer_size(&self) -> &SupportedBufferSizeRange { + pub fn buffer_size(&self) -> &SupportedBufferSize { &self.buffer_size }