From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- .../src/backend/aggregate_device.rs | 45 ++++++++++++++++++---- 1 file changed, 38 insertions(+), 7 deletions(-) (limited to 'third_party/rust/cubeb-coreaudio/src/backend/aggregate_device.rs') diff --git a/third_party/rust/cubeb-coreaudio/src/backend/aggregate_device.rs b/third_party/rust/cubeb-coreaudio/src/backend/aggregate_device.rs index 2738631b87..782e76de2f 100644 --- a/third_party/rust/cubeb-coreaudio/src/backend/aggregate_device.rs +++ b/third_party/rust/cubeb-coreaudio/src/backend/aggregate_device.rs @@ -69,6 +69,7 @@ impl AggregateDevice { input_id: AudioObjectID, output_id: AudioObjectID, ) -> std::result::Result { + debug_assert_running_serially(); let plugin_id = Self::get_system_plugin_id()?; let device_id = Self::create_blank_device_sync(plugin_id)?; @@ -399,12 +400,12 @@ impl AggregateDevice { let sub_devices = CFArrayCreateMutable(ptr::null(), 0, &kCFTypeArrayCallBacks); // The order of the items in the array is significant and is used to determine the order of the streams // of the AudioAggregateDevice. - for device in output_sub_devices { + for device in input_sub_devices { let uid = get_device_global_uid(device)?; CFArrayAppendValue(sub_devices, uid.get_raw() as *const c_void); } - for device in input_sub_devices { + for device in output_sub_devices { let uid = get_device_global_uid(device)?; CFArrayAppendValue(sub_devices, uid.get_raw() as *const c_void); } @@ -466,6 +467,28 @@ impl AggregateDevice { } } + pub fn get_master_device_uid(device_id: AudioDeviceID) -> std::result::Result { + let address = AudioObjectPropertyAddress { + mSelector: kAudioAggregateDevicePropertyMainSubDevice, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster, + }; + + let mut master: CFStringRef = ptr::null_mut(); + let mut size = mem::size_of::(); + let status = audio_object_get_property_data(device_id, &address, &mut size, &mut master); + if status != NO_ERR { + return Err(Error::from(status)); + } + + if master.is_null() { + return Ok(String::default()); + } + + let master = StringRef::new(master as _); + Ok(master.into_string()) + } + pub fn set_master_device( device_id: AudioDeviceID, primary_id: AudioDeviceID, @@ -480,12 +503,12 @@ impl AggregateDevice { ); let address = AudioObjectPropertyAddress { - mSelector: kAudioAggregateDevicePropertyMasterSubDevice, + mSelector: kAudioAggregateDevicePropertyMainSubDevice, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMaster, }; - // Master become the 1st sub device of the primary device + // The master device will be the 1st sub device of the primary device. let output_sub_devices = Self::get_sub_devices(primary_id)?; assert!(!output_sub_devices.is_empty()); let master_sub_device_uid = get_device_global_uid(output_sub_devices[0]).unwrap(); @@ -548,16 +571,23 @@ impl AggregateDevice { return Err(Error::from(status)); } + let master_sub_device_uid = Self::get_master_device_uid(device_id)?; + let address = AudioObjectPropertyAddress { mSelector: kAudioSubDevicePropertyDriftCompensation, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMaster, }; - // Start from the second device since the first is the master clock - for device in &sub_devices[1..] { + for &device in &sub_devices { + let uid = get_device_global_uid(device) + .map(|sr| sr.into_string()) + .unwrap_or_default(); + if uid == master_sub_device_uid { + continue; + } let status = audio_object_set_property_data( - *device, + device, &address, mem::size_of::(), &DRIFT_COMPENSATION, @@ -671,6 +701,7 @@ impl Default for AggregateDevice { impl Drop for AggregateDevice { fn drop(&mut self) { + debug_assert_running_serially(); if self.plugin_id != kAudioObjectUnknown && self.device_id != kAudioObjectUnknown { if let Err(r) = Self::destroy_device(self.plugin_id, self.device_id) { cubeb_log!( -- cgit v1.2.3