From 179bd4b31da3fe7966514b2d0b939ddaaac0e60b Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 26 Jan 2025 22:00:50 +0100 Subject: [PATCH] Update coreaudio-rs --- Cargo.toml | 8 +- src/host/coreaudio/ios/mod.rs | 1 - src/host/coreaudio/macos/enumerate.rs | 43 +++--- src/host/coreaudio/macos/mod.rs | 131 ++++++------------ src/host/coreaudio/macos/property_listener.rs | 10 +- src/host/coreaudio/mod.rs | 2 +- 6 files changed, 76 insertions(+), 119 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ecf4cf002..6f57a5503 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,14 +48,13 @@ libc = "0.2" jack = { version = "0.13.0", optional = true } [target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies] -core-foundation-sys = "0.8.2" # For linking to CoreFoundation.framework and handling device name `CFString`s. mach2 = "0.4" # For access to mach_timebase type. [target.'cfg(target_os = "macos")'.dependencies] -coreaudio-rs = { version = "0.11", default-features = false, features = ["audio_unit", "core_audio"] } +coreaudio-rs = { version = "0.12", default-features = false, features = ["core_audio", "audio_toolbox"] } [target.'cfg(target_os = "ios")'.dependencies] -coreaudio-rs = { version = "0.11", default-features = false, features = ["audio_unit", "core_audio", "audio_toolbox"] } +coreaudio-rs = { version = "0.12", default-features = false, features = ["core_audio", "audio_toolbox"] } [target.'cfg(target_os = "emscripten")'.dependencies] wasm-bindgen = { version = "0.2.89" } @@ -93,3 +92,6 @@ name = "record_wav" [[example]] name = "synth_tones" + +[patch.crates-io] +coreaudio-rs = { path = "../coreaudio" } diff --git a/src/host/coreaudio/ios/mod.rs b/src/host/coreaudio/ios/mod.rs index 8d7176c61..20a9bef9d 100644 --- a/src/host/coreaudio/ios/mod.rs +++ b/src/host/coreaudio/ios/mod.rs @@ -7,7 +7,6 @@ //! buffer size. //! -extern crate core_foundation_sys; extern crate coreaudio; use std::cell::RefCell; diff --git a/src/host/coreaudio/macos/enumerate.rs b/src/host/coreaudio/macos/enumerate.rs index 8d15f18e1..e616df7e8 100644 --- a/src/host/coreaudio/macos/enumerate.rs +++ b/src/host/coreaudio/macos/enumerate.rs @@ -1,16 +1,17 @@ +#![allow(deprecated)] extern crate coreaudio; use self::coreaudio::sys::{ kAudioHardwareNoError, kAudioHardwarePropertyDefaultInputDevice, kAudioHardwarePropertyDefaultOutputDevice, kAudioHardwarePropertyDevices, kAudioObjectPropertyElementMaster, kAudioObjectPropertyScopeGlobal, kAudioObjectSystemObject, - AudioDeviceID, AudioObjectGetPropertyData, AudioObjectGetPropertyDataSize, + AudioDeviceID, AudioObjectGetPropertyData, AudioObjectGetPropertyDataSize, AudioObjectID, AudioObjectPropertyAddress, OSStatus, }; use super::Device; use crate::{BackendSpecificError, DevicesError, SupportedStreamConfigRange}; use std::mem; -use std::ptr::null; +use std::ptr::{null, NonNull}; use std::vec::IntoIter as VecIntoIter; unsafe fn audio_devices() -> Result, OSStatus> { @@ -30,11 +31,11 @@ unsafe fn audio_devices() -> Result, OSStatus> { let data_size = 0u32; let status = AudioObjectGetPropertyDataSize( - kAudioObjectSystemObject, - &property_address as *const _, + kAudioObjectSystemObject as AudioObjectID, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, + NonNull::from(&data_size), ); try_status_or_return!(status); @@ -43,12 +44,12 @@ unsafe fn audio_devices() -> Result, OSStatus> { audio_devices.reserve_exact(device_count as usize); let status = AudioObjectGetPropertyData( - kAudioObjectSystemObject, - &property_address as *const _, + kAudioObjectSystemObject as AudioObjectID, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, - audio_devices.as_mut_ptr() as *mut _, + NonNull::from(&data_size), + NonNull::new(audio_devices.as_mut_ptr()).unwrap().cast(), ); try_status_or_return!(status); @@ -95,16 +96,16 @@ pub fn default_input_device() -> Option { mElement: kAudioObjectPropertyElementMaster, }; - let audio_device_id: AudioDeviceID = 0; - let data_size = mem::size_of::(); + let mut audio_device_id: AudioDeviceID = 0; + let data_size = mem::size_of::() as u32; let status = unsafe { AudioObjectGetPropertyData( - kAudioObjectSystemObject, - &property_address as *const _, + kAudioObjectSystemObject as AudioObjectID, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, - &audio_device_id as *const _ as *mut _, + NonNull::from(&data_size), + NonNull::from(&mut audio_device_id).cast(), ) }; if status != kAudioHardwareNoError as i32 { @@ -125,16 +126,16 @@ pub fn default_output_device() -> Option { mElement: kAudioObjectPropertyElementMaster, }; - let audio_device_id: AudioDeviceID = 0; - let data_size = mem::size_of::(); + let mut audio_device_id: AudioDeviceID = 0; + let data_size = mem::size_of::() as u32; let status = unsafe { AudioObjectGetPropertyData( - kAudioObjectSystemObject, - &property_address as *const _, + kAudioObjectSystemObject as AudioObjectID, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, - &audio_device_id as *const _ as *mut _, + NonNull::from(&data_size), + NonNull::from(&mut audio_device_id).cast(), ) }; if status != kAudioHardwareNoError as i32 { diff --git a/src/host/coreaudio/macos/mod.rs b/src/host/coreaudio/macos/mod.rs index e066b1376..8bb3dacd5 100644 --- a/src/host/coreaudio/macos/mod.rs +++ b/src/host/coreaudio/macos/mod.rs @@ -1,24 +1,21 @@ -extern crate core_foundation_sys; +#![allow(deprecated)] extern crate coreaudio; use super::{asbd_from_config, check_os_status, frames_to_duration, host_time_to_stream_instant}; -use self::core_foundation_sys::string::{CFStringGetCString, CFStringGetCStringPtr, CFStringRef}; use self::coreaudio::audio_unit::render_callback::{self, data}; use self::coreaudio::audio_unit::{AudioUnit, Element, Scope}; use self::coreaudio::sys::{ kAudioDevicePropertyAvailableNominalSampleRates, kAudioDevicePropertyBufferFrameSize, kAudioDevicePropertyBufferFrameSizeRange, kAudioDevicePropertyDeviceIsAlive, - kAudioDevicePropertyDeviceNameCFString, kAudioDevicePropertyNominalSampleRate, - kAudioDevicePropertyScopeOutput, kAudioDevicePropertyStreamConfiguration, + kAudioDevicePropertyNominalSampleRate, kAudioDevicePropertyStreamConfiguration, kAudioDevicePropertyStreamFormat, kAudioObjectPropertyElementMaster, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyScopeInput, kAudioObjectPropertyScopeOutput, kAudioOutputUnitProperty_CurrentDevice, - kAudioOutputUnitProperty_EnableIO, kAudioUnitProperty_StreamFormat, kCFStringEncodingUTF8, - AudioBuffer, AudioBufferList, AudioDeviceID, AudioObjectGetPropertyData, - AudioObjectGetPropertyDataSize, AudioObjectID, AudioObjectPropertyAddress, - AudioObjectPropertyScope, AudioObjectSetPropertyData, AudioStreamBasicDescription, - AudioValueRange, OSStatus, + kAudioOutputUnitProperty_EnableIO, kAudioUnitProperty_StreamFormat, AudioBuffer, + AudioBufferList, AudioDeviceID, AudioObjectGetPropertyData, AudioObjectGetPropertyDataSize, + AudioObjectID, AudioObjectPropertyAddress, AudioObjectPropertyScope, + AudioObjectSetPropertyData, AudioStreamBasicDescription, AudioValueRange, OSStatus, }; use crate::traits::{DeviceTrait, HostTrait, StreamTrait}; use crate::{ @@ -28,11 +25,9 @@ use crate::{ SupportedBufferSize, SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError, }; -use std::ffi::CStr; use std::fmt; use std::mem; -use std::os::raw::c_char; -use std::ptr::null; +use std::ptr::{null, NonNull}; use std::slice; use std::sync::mpsc::{channel, RecvTimeoutError}; use std::sync::{Arc, Mutex}; @@ -43,6 +38,7 @@ pub use self::enumerate::{ SupportedOutputConfigs, }; +use coreaudio::audio_unit::macos_helpers::get_device_name; use property_listener::AudioObjectPropertyListener; pub mod enumerate; @@ -162,54 +158,11 @@ pub struct Device { impl Device { fn name(&self) -> Result { - let property_address = AudioObjectPropertyAddress { - mSelector: kAudioDevicePropertyDeviceNameCFString, - mScope: kAudioDevicePropertyScopeOutput, - mElement: kAudioObjectPropertyElementMaster, - }; - let device_name: CFStringRef = null(); - let data_size = mem::size_of::(); - let c_str = unsafe { - let status = AudioObjectGetPropertyData( - self.audio_device_id, - &property_address as *const _, - 0, - null(), - &data_size as *const _ as *mut _, - &device_name as *const _ as *mut _, - ); - check_os_status(status)?; - - let c_string: *const c_char = CFStringGetCStringPtr(device_name, kCFStringEncodingUTF8); - if c_string.is_null() { - let status = AudioObjectGetPropertyData( - self.audio_device_id, - &property_address as *const _, - 0, - null(), - &data_size as *const _ as *mut _, - &device_name as *const _ as *mut _, - ); - check_os_status(status)?; - let mut buf: [i8; 255] = [0; 255]; - let result = CFStringGetCString( - device_name, - buf.as_mut_ptr(), - buf.len() as _, - kCFStringEncodingUTF8, - ); - if result == 0 { - let description = - "core foundation failed to return device name string".to_string(); - let err = BackendSpecificError { description }; - return Err(err.into()); - } - let name: &CStr = CStr::from_ptr(buf.as_ptr()); - return Ok(name.to_str().unwrap().to_owned()); - } - CStr::from_ptr(c_string as *mut _) - }; - Ok(c_str.to_string_lossy().into_owned()) + get_device_name(self.audio_device_id).map_err(|err| DeviceNameError::BackendSpecific { + err: BackendSpecificError { + description: err.to_string(), + }, + }) } // Logic re-used between `supported_input_configs` and `supported_output_configs`. @@ -229,10 +182,10 @@ impl Device { let data_size = 0u32; let status = AudioObjectGetPropertyDataSize( self.audio_device_id, - &property_address as *const _, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, + NonNull::from(&data_size), ); check_os_status(status)?; @@ -240,11 +193,11 @@ impl Device { audio_buffer_list.reserve_exact(data_size as usize); let status = AudioObjectGetPropertyData( self.audio_device_id, - &property_address as *const _, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, - audio_buffer_list.as_mut_ptr() as *mut _, + NonNull::from(&data_size), + NonNull::new(audio_buffer_list.as_mut_ptr()).unwrap().cast(), ); check_os_status(status)?; @@ -273,10 +226,10 @@ impl Device { let data_size = 0u32; let status = AudioObjectGetPropertyDataSize( self.audio_device_id, - &property_address as *const _, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, + NonNull::from(&data_size), ); check_os_status(status)?; @@ -285,11 +238,11 @@ impl Device { ranges.reserve_exact(data_size as usize); let status = AudioObjectGetPropertyData( self.audio_device_id, - &property_address as *const _, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, - ranges.as_mut_ptr() as *mut _, + NonNull::from(&data_size), + NonNull::new(ranges.as_mut_ptr()).unwrap().cast(), ); check_os_status(status)?; @@ -365,15 +318,15 @@ impl Device { }; unsafe { - let asbd: AudioStreamBasicDescription = mem::zeroed(); + let mut asbd: AudioStreamBasicDescription = mem::zeroed(); let data_size = mem::size_of::() as u32; let status = AudioObjectGetPropertyData( self.audio_device_id, - &property_address as *const _, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, - &asbd as *const _ as *mut _, + NonNull::from(&data_size), + NonNull::from(&mut asbd).cast(), ); default_config_error_from_os_status(status)?; @@ -768,16 +721,16 @@ fn set_sample_rate( mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMaster, }; - let sample_rate: f64 = 0.0; + let mut sample_rate: f64 = 0.0; let data_size = mem::size_of::() as u32; let status = unsafe { AudioObjectGetPropertyData( audio_device_id, - &property_address as *const _, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, - &sample_rate as *const _ as *mut _, + NonNull::from(&data_size), + NonNull::from(&mut sample_rate).cast(), ) }; coreaudio::Error::from_os_status(status)?; @@ -790,10 +743,10 @@ fn set_sample_rate( let status = unsafe { AudioObjectGetPropertyDataSize( audio_device_id, - &property_address as *const _, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, + NonNull::from(&data_size), ) }; coreaudio::Error::from_os_status(status)?; @@ -803,11 +756,11 @@ fn set_sample_rate( let status = unsafe { AudioObjectGetPropertyData( audio_device_id, - &property_address as *const _, + NonNull::from(&property_address), 0, null(), - &data_size as *const _ as *mut _, - ranges.as_mut_ptr() as *mut _, + NonNull::from(&data_size), + NonNull::new(ranges.as_mut_ptr()).unwrap().cast(), ) }; coreaudio::Error::from_os_status(status)?; @@ -833,16 +786,16 @@ fn set_sample_rate( // Send sample rate updates back on a channel. let sample_rate_handler = move || { let mut rate: f64 = 0.0; - let data_size = mem::size_of::(); + let data_size = mem::size_of::() as u32; let result = unsafe { AudioObjectGetPropertyData( audio_device_id, - &sample_rate_address as *const _, + NonNull::from(&sample_rate_address), 0, null(), - &data_size as *const _ as *mut _, - &mut rate as *const _ as *mut _, + NonNull::from(&data_size), + NonNull::from(&mut rate).cast(), ) }; send.send(coreaudio::Error::from_os_status(result).map(|_| rate)) @@ -860,11 +813,11 @@ fn set_sample_rate( let status = unsafe { AudioObjectSetPropertyData( audio_device_id, - &property_address as *const _, + NonNull::from(&property_address), 0, null(), data_size, - &ranges[range_index] as *const _ as *const _, + NonNull::from(&ranges[range_index]).cast(), ) }; coreaudio::Error::from_os_status(status)?; diff --git a/src/host/coreaudio/macos/property_listener.rs b/src/host/coreaudio/macos/property_listener.rs index cbe8ec2c2..944b328a8 100644 --- a/src/host/coreaudio/macos/property_listener.rs +++ b/src/host/coreaudio/macos/property_listener.rs @@ -1,4 +1,6 @@ //! Helper code for registering audio object property listeners. +use std::ptr::NonNull; + use super::coreaudio::sys::{ AudioObjectAddPropertyListener, AudioObjectID, AudioObjectPropertyAddress, AudioObjectRemovePropertyListener, OSStatus, @@ -30,7 +32,7 @@ impl AudioObjectPropertyListener { unsafe { coreaudio::Error::from_os_status(AudioObjectAddPropertyListener( audio_object_id, - &property_address as *const _, + NonNull::from(&property_address), Some(property_listener_handler_shim), &*callback as *const _ as *mut _, ))?; @@ -54,7 +56,7 @@ impl AudioObjectPropertyListener { unsafe { coreaudio::Error::from_os_status(AudioObjectRemovePropertyListener( self.audio_object_id, - &self.property_address as *const _, + NonNull::from(&self.property_address), Some(property_listener_handler_shim), &*self.callback as *const _ as *mut _, ))?; @@ -73,10 +75,10 @@ impl Drop for AudioObjectPropertyListener { } /// Callback used to call user-provided closure as a property listener. -unsafe extern "C" fn property_listener_handler_shim( +unsafe extern "C-unwind" fn property_listener_handler_shim( _: AudioObjectID, _: u32, - _: *const AudioObjectPropertyAddress, + _: NonNull, callback: *mut ::std::os::raw::c_void, ) -> OSStatus { let wrapper = callback as *mut PropertyListenerCallbackWrapper; diff --git a/src/host/coreaudio/mod.rs b/src/host/coreaudio/mod.rs index f82f5da5c..388d15068 100644 --- a/src/host/coreaudio/mod.rs +++ b/src/host/coreaudio/mod.rs @@ -64,7 +64,7 @@ fn asbd_from_config( mFormatFlags: format_flags, mFormatID: kAudioFormatLinearPCM, mSampleRate: sample_rate as _, - ..Default::default() + mReserved: 0, } }