buffersizes api for wasapi
This commit is contained in:
parent
4cd9d0bcec
commit
935fa280d3
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
21
src/lib.rs
21
src/lib.rs
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue