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,
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,

View File

@ -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,

View File

@ -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<SupportedBufferSizeRange, coreaudio::Error> {
) -> Result<SupportedBufferSize, coreaudio::Error> {
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,

View File

@ -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();

View File

@ -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
}