buffersizes api for wasapi

This commit is contained in:
JoshuaBatty 2020-05-26 14:47:57 +02:00
parent 4cd9d0bcec
commit 935fa280d3
5 changed files with 57 additions and 25 deletions

View File

@ -6,7 +6,7 @@ use crate::{
BackendSpecificError, BufferSize, BuildStreamError, ChannelCount, Data, BackendSpecificError, BufferSize, BuildStreamError, ChannelCount, Data,
DefaultStreamConfigError, DeviceNameError, DevicesError, InputCallbackInfo, OutputCallbackInfo, DefaultStreamConfigError, DeviceNameError, DevicesError, InputCallbackInfo, OutputCallbackInfo,
PauseStreamError, PlayStreamError, SampleFormat, SampleRate, StreamConfig, StreamError, PauseStreamError, PlayStreamError, SampleFormat, SampleRate, StreamConfig, StreamError,
SupportedBufferSizeRange, SupportedStreamConfig, SupportedStreamConfigRange, SupportedBufferSize, SupportedStreamConfig, SupportedStreamConfigRange,
SupportedStreamConfigsError, SupportedStreamConfigsError,
}; };
use std::convert::TryInto; use std::convert::TryInto;
@ -343,7 +343,7 @@ impl Device {
let min_buffer_size = hw_params.get_buffer_size_min()?; let min_buffer_size = hw_params.get_buffer_size_min()?;
let max_buffer_size = hw_params.get_buffer_size_max()?; 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, min: min_buffer_size as u32,
max: max_buffer_size as u32, max: max_buffer_size as u32,
requires_power_of_two: false, requires_power_of_two: false,

View File

@ -12,7 +12,7 @@ use DeviceNameError;
use DevicesError; use DevicesError;
use SampleFormat; use SampleFormat;
use SampleRate; use SampleRate;
use SupportedBufferSizeRange; use SupportedBufferSize;
use SupportedStreamConfig; use SupportedStreamConfig;
use SupportedStreamConfigRange; use SupportedStreamConfigRange;
use SupportedStreamConfigsError; use SupportedStreamConfigsError;
@ -132,7 +132,7 @@ impl Device {
let channels = self.driver.channels().map_err(default_config_err)?.ins as u16; 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 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 (min, max) = self.driver.buffersize_range().map_err(default_config_err)?;
let buffer_size = SupportedBufferSizeRange { let buffer_size = SupportedBufferSize::Range {
min: min as u32, min: min as u32,
max: max as u32, max: max as u32,
requires_power_of_two: false, 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 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 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 (min, max) = self.driver.buffersize_range().map_err(default_config_err)?;
let buffer_size = SupportedBufferSizeRange { let buffer_size = SupportedBufferSize::Range {
min: min as u32, min: min as u32,
max: max as u32, max: max as u32,
requires_power_of_two: false, requires_power_of_two: false,

View File

@ -24,7 +24,7 @@ use crate::{
BackendSpecificError, BufferSize, BuildStreamError, ChannelCount, Data, BackendSpecificError, BufferSize, BuildStreamError, ChannelCount, Data,
DefaultStreamConfigError, DeviceNameError, DevicesError, InputCallbackInfo, OutputCallbackInfo, DefaultStreamConfigError, DeviceNameError, DevicesError, InputCallbackInfo, OutputCallbackInfo,
PauseStreamError, PlayStreamError, SampleFormat, SampleRate, StreamConfig, StreamError, PauseStreamError, PlayStreamError, SampleFormat, SampleRate, StreamConfig, StreamError,
SupportedBufferSizeRange, SupportedStreamConfig, SupportedStreamConfigRange, SupportedBufferSize, SupportedStreamConfig, SupportedStreamConfigRange,
SupportedStreamConfigsError, SupportedStreamConfigsError,
}; };
use std::cell::RefCell; use std::cell::RefCell;
@ -915,14 +915,14 @@ fn check_os_status(os_status: OSStatus) -> Result<(), BackendSpecificError> {
fn get_io_buffer_frame_size_range( fn get_io_buffer_frame_size_range(
audio_unit: &AudioUnit, audio_unit: &AudioUnit,
) -> Result<SupportedBufferSizeRange, coreaudio::Error> { ) -> Result<SupportedBufferSize, coreaudio::Error> {
let buffer_size_range: AudioValueRange = audio_unit.get_property( let buffer_size_range: AudioValueRange = audio_unit.get_property(
kAudioDevicePropertyBufferFrameSizeRange, kAudioDevicePropertyBufferFrameSizeRange,
Scope::Global, Scope::Global,
Element::Output, Element::Output,
)?; )?;
Ok(SupportedBufferSizeRange { Ok(SupportedBufferSize::Range {
min: buffer_size_range.mMinimum as u32, min: buffer_size_range.mMinimum as u32,
max: buffer_size_range.mMaximum as u32, max: buffer_size_range.mMaximum as u32,
requires_power_of_two: false, requires_power_of_two: false,

View File

@ -1,8 +1,8 @@
use crate::{ use crate::{
BackendSpecificError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError, BackendSpecificError, BufferSize, Data, DefaultStreamConfigError, DeviceNameError,
InputCallbackInfo, OutputCallbackInfo, SampleFormat, SampleRate, StreamConfig, DevicesError, InputCallbackInfo, OutputCallbackInfo, SampleFormat, SampleRate,
SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError, StreamConfig, SupportedBufferSize, SupportedStreamConfig, SupportedStreamConfigRange,
COMMON_SAMPLE_RATES, SupportedStreamConfigsError, COMMON_SAMPLE_RATES,
}; };
use std; use std;
use std::ffi::OsString; use std::ffi::OsString;
@ -27,6 +27,7 @@ use super::winapi::shared::mmreg;
use super::winapi::shared::winerror; use super::winapi::shared::winerror;
use super::winapi::shared::wtypes; use super::winapi::shared::wtypes;
use super::winapi::Interface; use super::winapi::Interface;
// https://msdn.microsoft.com/en-us/library/cc230355.aspx // https://msdn.microsoft.com/en-us/library/cc230355.aspx
use super::winapi::um::audioclient::{ use super::winapi::um::audioclient::{
self, IAudioClient, IID_IAudioClient, AUDCLNT_E_DEVICE_INVALIDATED, self, IAudioClient, IID_IAudioClient, AUDCLNT_E_DEVICE_INVALIDATED,
@ -318,10 +319,11 @@ unsafe fn format_from_waveformatex_ptr(
// Unknown data format returned by GetMixFormat. // Unknown data format returned by GetMixFormat.
_ => return None, _ => return None,
}; };
let format = SupportedStreamConfig { let format = SupportedStreamConfig {
buffer_size: unimplemented!(),
channels: (*waveformatex_ptr).nChannels as _, channels: (*waveformatex_ptr).nChannels as _,
sample_rate: SampleRate((*waveformatex_ptr).nSamplesPerSec), sample_rate: SampleRate((*waveformatex_ptr).nSamplesPerSec),
buffer_size: SupportedBufferSize::Unknown,
sample_format, sample_format,
}; };
Some(format) Some(format)
@ -514,7 +516,7 @@ impl Device {
// TODO: Test the different sample formats? // TODO: Test the different sample formats?
// Create the supported 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, Some(fmt) => fmt,
None => { None => {
let description = let description =
@ -526,9 +528,13 @@ impl Device {
}; };
let mut supported_formats = Vec::with_capacity(supported_sample_rates.len()); let mut supported_formats = Vec::with_capacity(supported_sample_rates.len());
for rate in supported_sample_rates { for rate in supported_sample_rates {
format.sample_rate = SampleRate(rate as _); supported_formats.push(SupportedStreamConfigRange {
unimplemented!(); channels: format.channels.clone(),
//supported_formats.push(SupportedStreamConfigRange::from(format.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()) 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. // Computing the format and initializing the device.
let waveformatex = { let waveformatex = {
let format_attempt = config_to_waveformatextensible(config, sample_format) 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. // Computing the format and initializing the device.
let waveformatex = { let waveformatex = {
let format_attempt = config_to_waveformatextensible(config, sample_format) let format_attempt = config_to_waveformatextensible(config, sample_format)
@ -815,6 +841,7 @@ impl Device {
&format_attempt.Format, &format_attempt.Format,
ptr::null(), ptr::null(),
); );
match check_result(hresult) { match check_result(hresult) {
Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => { Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
(*audio_client).Release(); (*audio_client).Release();

View File

@ -202,10 +202,15 @@ pub struct StreamConfig {
/// Describes the minimum and maximum supported buffer size for the device /// Describes the minimum and maximum supported buffer size for the device
/// and if requested buffersize must be a power of 2 value. /// and if requested buffersize must be a power of 2 value.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub struct SupportedBufferSizeRange { pub enum SupportedBufferSize {
pub min: FrameCount, Range {
pub max: FrameCount, min: FrameCount,
pub requires_power_of_two: bool, 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 /// 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. /// Maximum value for the samples rate of the supported formats.
pub(crate) max_sample_rate: SampleRate, pub(crate) max_sample_rate: SampleRate,
/// Buffersize ranges supported by the device /// Buffersize ranges supported by the device
pub(crate) buffer_size: SupportedBufferSizeRange, pub(crate) buffer_size: SupportedBufferSize,
/// Type of data expected by the device. /// Type of data expected by the device.
pub(crate) sample_format: SampleFormat, pub(crate) sample_format: SampleFormat,
} }
@ -229,7 +234,7 @@ pub struct SupportedStreamConfigRange {
pub struct SupportedStreamConfig { pub struct SupportedStreamConfig {
channels: ChannelCount, channels: ChannelCount,
sample_rate: SampleRate, sample_rate: SampleRate,
buffer_size: SupportedBufferSizeRange, buffer_size: SupportedBufferSize,
sample_format: SampleFormat, sample_format: SampleFormat,
} }
@ -311,7 +316,7 @@ impl SupportedStreamConfig {
self.sample_rate self.sample_rate
} }
pub fn buffer_size(&self) -> &SupportedBufferSizeRange { pub fn buffer_size(&self) -> &SupportedBufferSize {
&self.buffer_size &self.buffer_size
} }
@ -519,7 +524,7 @@ impl SupportedStreamConfigRange {
self.max_sample_rate self.max_sample_rate
} }
pub fn buffer_size(&self) -> &SupportedBufferSizeRange { pub fn buffer_size(&self) -> &SupportedBufferSize {
&self.buffer_size &self.buffer_size
} }