coreaudio buffersize wip

This commit is contained in:
JoshuaBatty 2020-05-21 11:21:02 +02:00
parent d72b546dca
commit 6edee6c6c2
1 changed files with 51 additions and 11 deletions

View File

@ -6,8 +6,8 @@ use self::coreaudio::audio_unit::render_callback::{self, data};
use self::coreaudio::audio_unit::{AudioUnit, Element, Scope}; use self::coreaudio::audio_unit::{AudioUnit, Element, Scope};
use self::coreaudio::sys::{ use self::coreaudio::sys::{
kAudioDevicePropertyAvailableNominalSampleRates, kAudioDevicePropertyDeviceNameCFString, kAudioDevicePropertyAvailableNominalSampleRates, kAudioDevicePropertyDeviceNameCFString,
kAudioDevicePropertyBufferFrameSizeRange,kAudioDevicePropertyNominalSampleRate, kAudioDevicePropertyScopeOutput, kAudioDevicePropertyBufferFrameSize, kAudioDevicePropertyBufferFrameSizeRange,kAudioDevicePropertyNominalSampleRate,
kAudioDevicePropertyStreamConfiguration, kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeOutput, kAudioDevicePropertyStreamConfiguration, kAudioDevicePropertyStreamFormat,
kAudioFormatFlagIsFloat, kAudioFormatFlagIsPacked, kAudioFormatLinearPCM, kAudioFormatFlagIsFloat, kAudioFormatFlagIsPacked, kAudioFormatLinearPCM,
kAudioObjectPropertyElementMaster, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster, kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyScopeInput, kAudioObjectPropertyScopeOutput, kAudioObjectPropertyScopeInput, kAudioObjectPropertyScopeOutput,
@ -277,15 +277,9 @@ impl Device {
let ranges: &'static [AudioValueRange] = slice::from_raw_parts(ranges, n_ranges); let ranges: &'static [AudioValueRange] = slice::from_raw_parts(ranges, n_ranges);
let mut audio_unit = audio_unit_from_device(self, true)?; let mut audio_unit = audio_unit_from_device(self, true)?;
let buffer_size_range = audio_unit.get_property( let buffer_size = match get_io_buffer_frame_size_range(&audio_unit) {
kAudioDevicePropertyBufferFrameSizeRange, Ok(v) => v.unwrap(),
Scope::Global, Err(_) => return SupportedStreamConfigsError::DeviceNotAvailable,
Element::Output)?;
let buffer_size = SupportedBufferSizeRange {
min: buffer_size_range.mMinimum;
max: buffer_size_range.mMaximum;
requires_power_of_two: false,
}; };
// Collect the supported formats for the device. // Collect the supported formats for the device.
@ -387,9 +381,13 @@ impl Device {
} }
}; };
let mut audio_unit = audio_unit_from_device(self, true)?;
let buffer_size = get_io_buffer_frame_size_range(&audio_unit)?;
let config = SupportedStreamConfig { let config = SupportedStreamConfig {
sample_rate: SampleRate(asbd.mSampleRate as _), sample_rate: SampleRate(asbd.mSampleRate as _),
channels: asbd.mChannelsPerFrame as _, channels: asbd.mChannelsPerFrame as _,
buffer_size: buffer_size,
sample_format: sample_format, sample_format: sample_format,
}; };
Ok(config) Ok(config)
@ -669,6 +667,19 @@ impl Device {
let asbd = asbd_from_config(config, sample_format); let asbd = asbd_from_config(config, sample_format);
audio_unit.set_property(kAudioUnitProperty_StreamFormat, scope, element, Some(&asbd))?; audio_unit.set_property(kAudioUnitProperty_StreamFormat, scope, element, Some(&asbd))?;
// Set the buffersize
match config.buffer_size {
BufferSize::Fixed(v) => {
audio_unit.set_property(
kAudioDevicePropertyBufferFrameSize,
scope,
element,
Some(&v),
)?
},
BufferSize::Default => (),
}
// Register the callback that is being called by coreaudio whenever it needs data to be // Register the callback that is being called by coreaudio whenever it needs data to be
// fed to the audio buffer. // fed to the audio buffer.
let bytes_per_channel = sample_format.sample_size(); let bytes_per_channel = sample_format.sample_size();
@ -740,6 +751,19 @@ impl Device {
let asbd = asbd_from_config(config, sample_format); let asbd = asbd_from_config(config, sample_format);
audio_unit.set_property(kAudioUnitProperty_StreamFormat, scope, element, Some(&asbd))?; audio_unit.set_property(kAudioUnitProperty_StreamFormat, scope, element, Some(&asbd))?;
// Set the buffersize
match config.buffer_size {
BufferSize::Fixed(v) => {
audio_unit.set_property(
kAudioDevicePropertyBufferFrameSize,
scope,
element,
Some(&v),
)?
},
BufferSize::Default => (),
}
// Register the callback that is being called by coreaudio whenever it needs data to be // Register the callback that is being called by coreaudio whenever it needs data to be
// fed to the audio buffer. // fed to the audio buffer.
let bytes_per_channel = sample_format.sample_size(); let bytes_per_channel = sample_format.sample_size();
@ -861,3 +885,19 @@ fn check_os_status(os_status: OSStatus) -> Result<(), BackendSpecificError> {
} }
} }
} }
fn get_io_buffer_frame_size_range(
audio_unit: &AudioUnit,
) -> Result<SupportedBufferSizeRange, coreaudio::Error> {
let buffer_size_range: AudioValueRange = audio_unit.get_property(
kAudioDevicePropertyBufferFrameSizeRange,
Scope::Global,
Element::Output,
)?;
Ok(SupportedBufferSizeRange {
min: buffer_size_range.mMinimum as u32,
max: buffer_size_range.mMaximum as u32,
requires_power_of_two: false,
})
}