diff --git a/Cargo.toml b/Cargo.toml index 93f3e6b49..9dafdc83b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,9 +18,14 @@ name = "coreaudio" [features] default = ["audio_toolbox", "core_audio"] -audio_toolbox = ["dep:objc2-audio-toolbox", "dep:objc2-core-foundation"] +audio_toolbox = [ + "dep:objc2-audio-toolbox", + "dep:objc2-core-foundation", + "dep:objc2-core-audio", + "dep:objc2-core-audio-types", +] core_audio = ["dep:objc2-core-audio", "dep:objc2-core-audio-types"] -core_midi = ["dep:objc2-core-midi"] +core_midi = [] # Deprecated audio_unit = ["audio_toolbox"] @@ -33,7 +38,6 @@ bitflags = "1.0" libc = "0.2" objc2-core-foundation = { version = "0.3", optional = true, default-features = false, features = [ "std", - "CFBase", "CFString", ] } objc2-audio-toolbox = { version = "0.3", optional = true, default-features = false, features = [ @@ -41,72 +45,25 @@ objc2-audio-toolbox = { version = "0.3", optional = true, default-features = fal "bitflags", "libc", "objc2-core-foundation", - "AUAudioUnit", - "AUAudioUnitImplementation", - "AUCocoaUIView", + "objc2-core-audio", + "objc2-core-audio-types", "AUComponent", - "AUGraph", - "AUParameters", - "AudioCodec", "AudioComponent", - "AudioConverter", - "AudioFile", - "AudioFileStream", - "AudioFormat", "AudioOutputUnit", - "AudioQueue", - "AudioServices", - "AudioSession", - "AudioUnit", - "AudioUnitCarbonView", - "AudioUnitParameters", "AudioUnitProperties", - "AudioUnitUtilities", - "AudioWorkInterval", - "CAFFile", - "CAShow", - "DefaultAudioOutput", - "ExtendedAudioFile", - "MusicDevice", - "MusicPlayer", - "objc2-core-audio", - "objc2-core-audio-types", + "AudioSession", ] } objc2-core-audio = { version = "0.3", optional = true, default-features = false, features = [ "std", "objc2-core-audio-types", "AudioHardware", "AudioHardwareDeprecated", - "AudioServerPlugIn", - "HostTime", ] } objc2-core-audio-types = { version = "0.3", optional = true, default-features = false, features = [ "std", "bitflags", - "AudioSessionTypes", "CoreAudioBaseTypes", ] } -objc2-core-midi = { version = "0.3", optional = true, default-features = false, features = [ - "std", - "objc2-core-foundation", - "MIDIBluetoothConnection", - "MIDICIDevice", - "MIDICIDeviceManager", - "MIDICapabilityInquiry", - "MIDIDriver", - "MIDIMessages", - "MIDINetworkSession", - "MIDIServices", - "MIDISetup", - "MIDIThruConnection", - "MIDIUMPCI", - "MIDIUMPCIProfile", - "MIDIUMPEndpoint", - "MIDIUMPEndpointManager", - "MIDIUMPFunctionBlock", - "MIDIUMPMutableEndpoint", - "MIDIUMPMutableFunctionBlock", -] } [package.metadata.docs.rs] all-features = true diff --git a/examples/feedback.rs b/examples/feedback.rs index f40b80944..4fd5adb0c 100644 --- a/examples/feedback.rs +++ b/examples/feedback.rs @@ -9,7 +9,7 @@ use coreaudio::audio_unit::audio_format::LinearPcmFlags; use coreaudio::audio_unit::macos_helpers::{audio_unit_from_device_id, get_default_device_id}; use coreaudio::audio_unit::render_callback::{self, data}; use coreaudio::audio_unit::{Element, SampleFormat, Scope, StreamFormat}; -use coreaudio::sys::*; +use objc2_audio_toolbox::kAudioUnitProperty_StreamFormat; const SAMPLE_RATE: f64 = 44100.0; diff --git a/examples/feedback_interleaved.rs b/examples/feedback_interleaved.rs index 3a2b05c71..ecc01be38 100644 --- a/examples/feedback_interleaved.rs +++ b/examples/feedback_interleaved.rs @@ -11,7 +11,7 @@ use coreaudio::audio_unit::macos_helpers::{ }; use coreaudio::audio_unit::render_callback::{self, data}; use coreaudio::audio_unit::{Element, SampleFormat, Scope, StreamFormat}; -use coreaudio::sys::*; +use objc2_audio_toolbox::kAudioUnitProperty_StreamFormat; const SAMPLE_RATE: f64 = 44100.0; diff --git a/examples/ios/Cargo.toml b/examples/ios/Cargo.toml index c04bf362d..bcb4c86b5 100644 --- a/examples/ios/Cargo.toml +++ b/examples/ios/Cargo.toml @@ -12,4 +12,11 @@ crate-type = ["staticlib"] [dependencies] coreaudio-rs = { path = "../.." } - +objc2-audio-toolbox = { version = "0.3", default-features = false, features = [ + "std", + "AudioUnitProperties", +] } +objc2-core-audio-types = { version = "0.3", default-features = false, features = [ + "std", + "CoreAudioBaseTypes", +] } diff --git a/examples/ios/src/feedback.rs b/examples/ios/src/feedback.rs index 659860ab2..f29f3be39 100644 --- a/examples/ios/src/feedback.rs +++ b/examples/ios/src/feedback.rs @@ -8,7 +8,8 @@ use std::sync::{Arc, Mutex}; use coreaudio::audio_unit::audio_format::LinearPcmFlags; use coreaudio::audio_unit::render_callback::{self, data}; use coreaudio::audio_unit::{AudioUnit, Element, SampleFormat, Scope, StreamFormat}; -use coreaudio::sys::*; +use objc2_audio_toolbox::{kAudioOutputUnitProperty_EnableIO, kAudioUnitProperty_StreamFormat}; +use objc2_core_audio_types::AudioStreamBasicDescription; type S = f32; const SAMPLE_FORMAT: SampleFormat = SampleFormat::F32; @@ -36,8 +37,10 @@ pub fn run_example() -> Result<(), coreaudio::Error> { SampleFormat::F32 => LinearPcmFlags::IS_FLOAT, SampleFormat::I32 | SampleFormat::I16 | SampleFormat::I8 => { LinearPcmFlags::IS_SIGNED_INTEGER - }, - SampleFormat::I24 => { unimplemented!("Not implemented for I24")}, + } + SampleFormat::I24 => { + unimplemented!("Not implemented for I24") + } }; // Using IS_NON_INTERLEAVED everywhere because data::Interleaved is commented out / not implemented diff --git a/examples/sine_advanced.rs b/examples/sine_advanced.rs index 8e2685538..b2c6a2c29 100644 --- a/examples/sine_advanced.rs +++ b/examples/sine_advanced.rs @@ -11,7 +11,7 @@ use coreaudio::audio_unit::macos_helpers::{ }; use coreaudio::audio_unit::render_callback::{self, data}; use coreaudio::audio_unit::{Element, SampleFormat, Scope, StreamFormat}; -use coreaudio::sys::kAudioUnitProperty_StreamFormat; +use objc2_audio_toolbox::kAudioUnitProperty_StreamFormat; use std::f64::consts::PI; use std::process; diff --git a/src/audio_unit/macos_helpers.rs b/src/audio_unit/macos_helpers.rs index 8a08fbd52..948c43fd4 100644 --- a/src/audio_unit/macos_helpers.rs +++ b/src/audio_unit/macos_helpers.rs @@ -10,7 +10,11 @@ use std::sync::Mutex; use std::time::Duration; use std::{mem, thread}; -use crate::sys::{ +use libc::pid_t; +use objc2_audio_toolbox::{ + kAudioOutputUnitProperty_CurrentDevice, kAudioOutputUnitProperty_EnableIO, +}; +use objc2_core_audio::{ kAudioDevicePropertyAvailableNominalSampleRates, kAudioDevicePropertyDeviceIsAlive, kAudioDevicePropertyDeviceNameCFString, kAudioDevicePropertyHogMode, kAudioDevicePropertyNominalSampleRate, kAudioDevicePropertyScopeOutput, @@ -19,22 +23,20 @@ use crate::sys::{ kAudioHardwarePropertyDevices, kAudioObjectPropertyElementMaster, kAudioObjectPropertyElementWildcard, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyScopeInput, kAudioObjectPropertyScopeOutput, kAudioObjectSystemObject, - kAudioOutputUnitProperty_CurrentDevice, kAudioOutputUnitProperty_EnableIO, kAudioStreamPropertyAvailablePhysicalFormats, kAudioStreamPropertyPhysicalFormat, AudioDeviceID, AudioObjectAddPropertyListener, AudioObjectGetPropertyData, AudioObjectGetPropertyDataSize, AudioObjectID, AudioObjectPropertyAddress, - AudioObjectPropertyScope, AudioObjectRemovePropertyListener, AudioObjectSetPropertyData, - AudioStreamBasicDescription, AudioStreamRangedDescription, AudioValueRange, OSStatus, + AudioObjectPropertyListenerProc, AudioObjectPropertyScope, AudioObjectRemovePropertyListener, + AudioObjectSetPropertyData, AudioStreamRangedDescription, }; -use libc::pid_t; -use objc2_core_audio::AudioObjectPropertyListenerProc; +use objc2_core_audio_types::{AudioBufferList, AudioStreamBasicDescription, AudioValueRange}; use objc2_core_foundation::CFString; use crate::audio_unit::audio_format::{AudioFormat, LinearPcmFlags}; use crate::audio_unit::sample_format::SampleFormat; use crate::audio_unit::stream_format::StreamFormat; use crate::audio_unit::{AudioUnit, Element, IOType, Scope}; -use crate::sys; +use crate::OSStatus; /// Helper function to get the device id of the default input or output device. pub fn get_default_device_id(input: bool) -> Option { @@ -236,7 +238,7 @@ pub fn get_audio_device_supports_scope(devid: AudioDeviceID, scope: Scope) -> Re try_status_or_return!(status); let mut bfrs: Vec = Vec::with_capacity(data_size as usize); - let buffers = bfrs.as_mut_ptr() as *mut sys::AudioBufferList; + let buffers = bfrs.as_mut_ptr() as *mut AudioBufferList; unsafe { let status = AudioObjectGetPropertyData( devid, diff --git a/src/audio_unit/mod.rs b/src/audio_unit/mod.rs index 48f698114..b667a80fa 100644 --- a/src/audio_unit/mod.rs +++ b/src/audio_unit/mod.rs @@ -18,8 +18,16 @@ //! If you can find documentation on these, please feel free to submit an issue or PR with the //! fixes! +use objc2_audio_toolbox::{ + kAudioUnitManufacturer_Apple, kAudioUnitProperty_SampleRate, kAudioUnitProperty_StreamFormat, + AudioComponentDescription, AudioComponentFindNext, AudioComponentInstanceDispose, + AudioComponentInstanceNew, AudioOutputUnitStart, AudioOutputUnitStop, + AudioUnit as InnerAudioUnit, AudioUnitGetProperty, AudioUnitInitialize, AudioUnitSetProperty, + AudioUnitUninitialize, +}; +use objc2_core_audio_types::AudioBufferList; + use crate::error::Error; -use crate::sys; use std::mem; use std::os::raw::{c_uint, c_void}; use std::ptr::{self, NonNull}; @@ -65,18 +73,19 @@ pub enum Element { Input = 1, } -/// A rust representation of the sys::AudioUnit, including a pointer to the current rendering callback. +/// A rust representation of the [`objc2_audio_toolbox::AudioUnit`], including +/// a pointer to the current rendering callback. /// /// Find the original Audio Unit Programming Guide [here](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/TheAudioUnit/TheAudioUnit.html). pub struct AudioUnit { - instance: sys::AudioUnit, + instance: InnerAudioUnit, maybe_render_callback: Option<*mut render_callback::InputProcFnWrapper>, maybe_input_callback: Option, } struct InputCallback { // The audio buffer list to which input data is rendered. - buffer_list: *mut sys::AudioBufferList, + buffer_list: *mut AudioBufferList, callback: *mut render_callback::InputProcFnWrapper, } @@ -119,7 +128,7 @@ impl AudioUnit { where T: Into, { - const MANUFACTURER_IDENTIFIER: u32 = sys::kAudioUnitManufacturer_Apple; + const MANUFACTURER_IDENTIFIER: u32 = kAudioUnitManufacturer_Apple; let au_type: Type = ty.into(); let sub_type_u32 = match au_type.as_subtype_u32() { Some(u) => u, @@ -127,7 +136,7 @@ impl AudioUnit { }; // A description of the audio unit we desire. - let desc = sys::AudioComponentDescription { + let desc = AudioComponentDescription { componentType: au_type.as_u32() as c_uint, componentSubType: sub_type_u32 as c_uint, componentManufacturer: MANUFACTURER_IDENTIFIER, @@ -144,21 +153,21 @@ impl AudioUnit { // find the first system audio unit matching the description, using a system-defined // ordering. If you instead pass a previously found audio unit reference in this // parameter, the function locates the next audio unit matching the description. - let component = sys::AudioComponentFindNext(ptr::null_mut(), NonNull::from(&desc)); + let component = AudioComponentFindNext(ptr::null_mut(), NonNull::from(&desc)); if component.is_null() { return Err(Error::NoMatchingDefaultAudioUnitFound); } // Create an instance of the default audio unit using the component. - let mut instance_uninit = mem::MaybeUninit::::uninit(); - try_os_status!(sys::AudioComponentInstanceNew( + let mut instance_uninit = mem::MaybeUninit::::uninit(); + try_os_status!(AudioComponentInstanceNew( component, NonNull::from(&mut instance_uninit).cast() )); - let instance: sys::AudioUnit = instance_uninit.assume_init(); + let instance: InnerAudioUnit = instance_uninit.assume_init(); // Initialise the audio unit! - try_os_status!(sys::AudioUnitInitialize(instance)); + try_os_status!(AudioUnitInitialize(instance)); Ok(AudioUnit { instance, maybe_render_callback: None, @@ -176,7 +185,7 @@ impl AudioUnit { /// cannot be changed while an audio unit is initialized. pub fn initialize(&mut self) -> Result<(), Error> { unsafe { - try_os_status!(sys::AudioUnitInitialize(self.instance)); + try_os_status!(AudioUnitInitialize(self.instance)); } Ok(()) } @@ -189,7 +198,7 @@ impl AudioUnit { /// AudioUnitInitialize to reinitialize it. pub fn uninitialize(&mut self) -> Result<(), Error> { unsafe { - try_os_status!(sys::AudioUnitUninitialize(self.instance)); + try_os_status!(AudioUnitUninitialize(self.instance)); } Ok(()) } @@ -241,7 +250,7 @@ impl AudioUnit { /// **Available** in OS X v10.0 and later. pub fn start(&mut self) -> Result<(), Error> { unsafe { - try_os_status!(sys::AudioOutputUnitStart(self.instance)); + try_os_status!(AudioOutputUnitStart(self.instance)); } Ok(()) } @@ -252,7 +261,7 @@ impl AudioUnit { /// **Available** in OS X v10.0 and later. pub fn stop(&mut self) -> Result<(), Error> { unsafe { - try_os_status!(sys::AudioOutputUnitStop(self.instance)); + try_os_status!(AudioOutputUnitStop(self.instance)); } Ok(()) } @@ -261,13 +270,13 @@ impl AudioUnit { /// /// **Available** in iOS 2.0 and later. pub fn set_sample_rate(&mut self, sample_rate: f64) -> Result<(), Error> { - let id = sys::kAudioUnitProperty_SampleRate; + let id = kAudioUnitProperty_SampleRate; self.set_property(id, Scope::Input, Element::Output, Some(&sample_rate)) } /// Get the **AudioUnit**'s sample rate. pub fn sample_rate(&self) -> Result { - let id = sys::kAudioUnitProperty_SampleRate; + let id = kAudioUnitProperty_SampleRate; self.get_property(id, Scope::Input, Element::Output) } @@ -291,14 +300,14 @@ impl AudioUnit { scope: Scope, element: Element, ) -> Result<(), Error> { - let id = sys::kAudioUnitProperty_StreamFormat; + let id = kAudioUnitProperty_StreamFormat; let asbd = stream_format.to_asbd(); self.set_property(id, scope, element, Some(&asbd)) } /// Return the current Stream Format for the AudioUnit. pub fn stream_format(&self, scope: Scope, element: Element) -> Result { - let id = sys::kAudioUnitProperty_StreamFormat; + let id = kAudioUnitProperty_StreamFormat; let asbd = self.get_property(id, scope, element)?; StreamFormat::from_asbd(asbd) } @@ -314,14 +323,14 @@ impl AudioUnit { } } -impl AsRef for AudioUnit { - fn as_ref(&self) -> &sys::AudioUnit { +impl AsRef for AudioUnit { + fn as_ref(&self) -> &InnerAudioUnit { &self.instance } } -impl AsMut for AudioUnit { - fn as_mut(&mut self) -> &mut sys::AudioUnit { +impl AsMut for AudioUnit { + fn as_mut(&mut self) -> &mut InnerAudioUnit { &mut self.instance } } @@ -338,12 +347,12 @@ impl Drop for AudioUnit { // A user should explicitly terminate the `AudioUnit` if they want to handle errors (we // still need to provide a way to actually do that). self.stop().ok(); - error::Error::from_os_status(sys::AudioUnitUninitialize(self.instance)).ok(); + error::Error::from_os_status(AudioUnitUninitialize(self.instance)).ok(); self.free_render_callback(); self.free_input_callback(); - error::Error::from_os_status(sys::AudioComponentInstanceDispose(self.instance)).ok(); + error::Error::from_os_status(AudioComponentInstanceDispose(self.instance)).ok(); } } } @@ -367,7 +376,7 @@ impl Drop for AudioUnit { /// - **elem**: The audio unit element for the property. /// - **maybe_data**: The value that you want to apply to the property. pub fn set_property( - au: sys::AudioUnit, + au: InnerAudioUnit, id: u32, scope: Scope, elem: Element, @@ -382,11 +391,7 @@ pub fn set_property( .unwrap_or_else(|| (::std::ptr::null(), 0)); let scope = scope as c_uint; let elem = elem as c_uint; - unsafe { - try_os_status!(sys::AudioUnitSetProperty( - au, id, scope, elem, data_ptr, size - )) - } + unsafe { try_os_status!(AudioUnitSetProperty(au, id, scope, elem, data_ptr, size)) } Ok(()) } @@ -402,7 +407,7 @@ pub fn set_property( /// - **scope**: The audio unit scope for the property. /// - **elem**: The audio unit element for the property. pub fn get_property( - au: sys::AudioUnit, + au: InnerAudioUnit, id: u32, scope: Scope, elem: Element, @@ -414,7 +419,7 @@ pub fn get_property( let mut data_uninit = ::std::mem::MaybeUninit::::uninit(); let data_ptr = NonNull::from(&mut data_uninit).cast::(); let size_ptr = NonNull::from(&mut size); - try_os_status!(sys::AudioUnitGetProperty( + try_os_status!(AudioUnitGetProperty( au, id, scope, elem, data_ptr, size_ptr )); let data: T = data_uninit.assume_init(); @@ -438,7 +443,9 @@ pub fn audio_session_get_property(id: u32) -> Result { let mut data_uninit = ::std::mem::MaybeUninit::::uninit(); let data_ptr = data_uninit.as_mut_ptr() as *mut _ as *mut c_void; let size_ptr = &mut size as *mut _; - try_os_status!(sys::AudioSessionGetProperty(id, size_ptr, data_ptr)); + try_os_status!(objc2_audio_toolbox::AudioSessionGetProperty( + id, size_ptr, data_ptr + )); let data: T = data_uninit.assume_init(); Ok(data) } diff --git a/src/audio_unit/render_callback.rs b/src/audio_unit/render_callback.rs index 7c21d1492..0f625bedf 100644 --- a/src/audio_unit/render_callback.rs +++ b/src/audio_unit/render_callback.rs @@ -1,7 +1,14 @@ +use objc2_audio_toolbox::{ + kAudioOutputUnitProperty_SetInputCallback, kAudioUnitProperty_SetRenderCallback, + kAudioUnitProperty_StreamFormat, AURenderCallbackStruct, AudioUnitRender, + AudioUnitRenderActionFlags, +}; +use objc2_core_audio_types::{AudioBuffer, AudioBufferList, AudioTimeStamp}; + use super::audio_format::LinearPcmFlags; use super::{AudioUnit, Element, Scope}; use crate::error::{self, Error}; -use crate::sys; +use crate::OSStatus; use std::mem; use std::os::raw::c_void; use std::ptr::NonNull; @@ -16,12 +23,12 @@ pub use self::data::Data; /// This allows the user to provide a custom, more rust-esque callback function type that takes /// greater advantage of rust's type safety. pub type InputProcFn = dyn FnMut( - NonNull, - NonNull, + NonNull, + NonNull, u32, u32, - *mut sys::AudioBufferList, -) -> sys::OSStatus; + *mut AudioBufferList, +) -> OSStatus; /// This type allows us to safely wrap a boxed `RenderCallback` to use within the input proc. pub struct InputProcFnWrapper { @@ -34,7 +41,7 @@ pub struct Args { /// A type wrapping the the buffer that matches the expected audio format. pub data: D, /// Timing information for the callback. - pub time_stamp: sys::AudioTimeStamp, + pub time_stamp: AudioTimeStamp, /// TODO pub bus_number: u32, /// The number of frames in the buffer as `usize` for easier indexing. @@ -50,10 +57,12 @@ pub struct Args { /// Format specific render callback data. pub mod data { + use objc2_core_audio_types::AudioBuffer; + use objc2_core_audio_types::AudioBufferList; + use super::super::Sample; use super::super::StreamFormat; use crate::audio_unit::audio_format::LinearPcmFlags; - use crate::sys; use std::marker::PhantomData; use std::slice; @@ -64,24 +73,20 @@ pub mod data { /// We must be able to construct Self from arguments given to the `input_proc`. /// # Safety /// TODO document how to use this function safely. - unsafe fn from_input_proc_args(num_frames: u32, io_data: *mut sys::AudioBufferList) - -> Self; + unsafe fn from_input_proc_args(num_frames: u32, io_data: *mut AudioBufferList) -> Self; } /// A raw pointer to the audio data so that the user may handle it themselves. #[derive(Debug)] pub struct Raw { - pub data: *mut sys::AudioBufferList, + pub data: *mut AudioBufferList, } impl Data for Raw { fn does_stream_format_match(_: &StreamFormat) -> bool { true } - unsafe fn from_input_proc_args( - _num_frames: u32, - io_data: *mut sys::AudioBufferList, - ) -> Self { + unsafe fn from_input_proc_args(_num_frames: u32, io_data: *mut AudioBufferList) -> Self { Raw { data: io_data } } } @@ -105,7 +110,7 @@ pub mod data { /// A wrapper around the pointer to the `mBuffers` array. pub struct NonInterleaved { /// The list of audio buffers. - buffers: &'static mut [sys::AudioBuffer], + buffers: &'static mut [AudioBuffer], /// The number of frames in each channel. frames: usize, sample_format: PhantomData, @@ -113,14 +118,14 @@ pub mod data { /// An iterator produced by a `NonInterleaved`, yielding a reference to each channel. pub struct Channels<'a, S: 'a> { - buffers: slice::Iter<'a, sys::AudioBuffer>, + buffers: slice::Iter<'a, AudioBuffer>, frames: usize, sample_format: PhantomData, } /// An iterator produced by a `NonInterleaved`, yielding a mutable reference to each channel. pub struct ChannelsMut<'a, S: 'a> { - buffers: slice::IterMut<'a, sys::AudioBuffer>, + buffers: slice::IterMut<'a, AudioBuffer>, frames: usize, sample_format: PhantomData, } @@ -132,7 +137,7 @@ pub mod data { #[allow(non_snake_case)] fn next(&mut self) -> Option { self.buffers.next().map( - |&sys::AudioBuffer { + |&AudioBuffer { mNumberChannels, mData, .. @@ -150,7 +155,7 @@ pub mod data { #[allow(non_snake_case)] fn next(&mut self) -> Option { self.buffers.next().map( - |&mut sys::AudioBuffer { + |&mut AudioBuffer { mNumberChannels, mData, .. @@ -196,8 +201,8 @@ pub mod data { } #[allow(non_snake_case)] - unsafe fn from_input_proc_args(frames: u32, io_data: *mut sys::AudioBufferList) -> Self { - let ptr = (*io_data).mBuffers.as_ptr() as *mut sys::AudioBuffer; + unsafe fn from_input_proc_args(frames: u32, io_data: *mut AudioBufferList) -> Self { + let ptr = (*io_data).mBuffers.as_ptr() as *mut AudioBuffer; let len = (*io_data).mNumberBuffers as usize; let buffers = slice::from_raw_parts_mut(ptr, len); NonInterleaved { @@ -221,9 +226,9 @@ pub mod data { } #[allow(non_snake_case)] - unsafe fn from_input_proc_args(frames: u32, io_data: *mut sys::AudioBufferList) -> Self { + unsafe fn from_input_proc_args(frames: u32, io_data: *mut AudioBufferList) -> Self { // // We're expecting a single interleaved buffer which will be the first in the array. - let sys::AudioBuffer { + let AudioBuffer { mNumberChannels, mDataByteSize, mData, @@ -262,9 +267,9 @@ pub mod data { } #[allow(non_snake_case)] - unsafe fn from_input_proc_args(frames: u32, io_data: *mut sys::AudioBufferList) -> Self { + unsafe fn from_input_proc_args(frames: u32, io_data: *mut AudioBufferList) -> Self { // // We're expecting a single interleaved buffer which will be the first in the array. - let sys::AudioBuffer { + let AudioBuffer { mNumberChannels, mDataByteSize, mData, @@ -292,7 +297,8 @@ pub mod data { } pub mod action_flags { - use crate::sys; + use objc2_audio_toolbox::AudioUnitRenderActionFlags; + use std::fmt; bitflags! { @@ -302,20 +308,20 @@ pub mod action_flags { /// before the render operation is performed. /// /// **Available** in OS X v10.0 and later. - const PRE_RENDER = sys::AudioUnitRenderActionFlags::UnitRenderAction_PreRender.0; + const PRE_RENDER = AudioUnitRenderActionFlags::UnitRenderAction_PreRender.0; /// Called on a render notification Proc, which is called either before or after the /// render operation of the audio unit. If this flag is set, the proc is being called /// after the render operation is completed. /// /// **Available** in OS X v10.0 and later. - const POST_RENDER = sys::AudioUnitRenderActionFlags::UnitRenderAction_PostRender.0; + const POST_RENDER = AudioUnitRenderActionFlags::UnitRenderAction_PostRender.0; /// This flag can be set in a render input callback (or in the audio unit's render /// operation itself) and is used to indicate that the render buffer contains only /// silence. It can then be used by the caller as a hint to whether the buffer needs to /// be processed or not. /// /// **Available** in OS X v10.2 and later. - const OUTPUT_IS_SILENCE = sys::AudioUnitRenderActionFlags::UnitRenderAction_OutputIsSilence.0; + const OUTPUT_IS_SILENCE = AudioUnitRenderActionFlags::UnitRenderAction_OutputIsSilence.0; /// This is used with offline audio units (of type 'auol'). It is used when an offline /// unit is being preflighted, which is performed prior to when the actual offline /// rendering actions are performed. It is used for those cases where the offline @@ -324,32 +330,32 @@ pub mod action_flags { /// normalization). /// /// **Available** in OS X v10.3 and later. - const OFFLINE_PREFLIGHT = sys::AudioUnitRenderActionFlags::OfflineUnitRenderAction_Preflight.0; + const OFFLINE_PREFLIGHT = AudioUnitRenderActionFlags::OfflineUnitRenderAction_Preflight.0; /// Once an offline unit has been successfully preflighted, it is then put into its /// render mode. This flag is set to indicate to the audio unit that it is now in that /// state and that it should perform processing on the input data. /// /// **Available** in OS X v10.3 and later. - const OFFLINE_RENDER = sys::AudioUnitRenderActionFlags::OfflineUnitRenderAction_Render.0; + const OFFLINE_RENDER = AudioUnitRenderActionFlags::OfflineUnitRenderAction_Render.0; /// This flag is set when an offline unit has completed either its preflight or /// performed render operation. /// /// **Available** in OS X v10.3 and later. - const OFFLINE_COMPLETE = sys::AudioUnitRenderActionFlags::OfflineUnitRenderAction_Complete.0; + const OFFLINE_COMPLETE = AudioUnitRenderActionFlags::OfflineUnitRenderAction_Complete.0; /// If this flag is set on the post-render call an error was returned by the audio /// unit's render operation. In this case, the error can be retrieved through the /// `lastRenderError` property and the audio data in `ioData` handed to the post-render /// notification will be invalid. /// /// **Available** in OS X v10.5 and later. - const POST_RENDER_ERROR = sys::AudioUnitRenderActionFlags::UnitRenderAction_PostRenderError.0; + const POST_RENDER_ERROR = AudioUnitRenderActionFlags::UnitRenderAction_PostRenderError.0; /// If this flag is set, then checks that are done on the arguments provided to render /// are not performed. This can be useful to use to save computation time in situations /// where you are sure you are providing the correct arguments and structures to the /// various render calls. /// /// **Available** in OS X v10.7 and later. - const DO_NOT_CHECK_RENDER_ARGS = sys::AudioUnitRenderActionFlags::UnitRenderAction_DoNotCheckRenderArgs.0; + const DO_NOT_CHECK_RENDER_ARGS = AudioUnitRenderActionFlags::UnitRenderAction_DoNotCheckRenderArgs.0; } } @@ -361,7 +367,7 @@ pub mod action_flags { /// For example: if there is no audio to process, we can insert the `OUTPUT_IS_SILENCE` flag to /// indicate to the audio unit that the buffer does not need to be processed. pub struct Handle { - ptr: *mut sys::AudioUnitRenderActionFlags, + ptr: *mut AudioUnitRenderActionFlags, } impl fmt::Debug for Handle { @@ -431,7 +437,7 @@ pub mod action_flags { } /// Wrap the given pointer with a `Handle`. - pub fn from_ptr(ptr: *mut sys::AudioUnitRenderActionFlags) -> Self { + pub fn from_ptr(ptr: *mut AudioUnitRenderActionFlags) -> Self { Handle { ptr } } } @@ -443,20 +449,19 @@ pub mod action_flags { write!( f, "{:?}", - match sys::AudioUnitRenderActionFlags(self.bits()) { - sys::AudioUnitRenderActionFlags::UnitRenderAction_PreRender => "PRE_RENDER", - sys::AudioUnitRenderActionFlags::UnitRenderAction_PostRender => "POST_RENDER", - sys::AudioUnitRenderActionFlags::UnitRenderAction_OutputIsSilence => + match AudioUnitRenderActionFlags(self.bits()) { + AudioUnitRenderActionFlags::UnitRenderAction_PreRender => "PRE_RENDER", + AudioUnitRenderActionFlags::UnitRenderAction_PostRender => "POST_RENDER", + AudioUnitRenderActionFlags::UnitRenderAction_OutputIsSilence => "OUTPUT_IS_SILENCE", - sys::AudioUnitRenderActionFlags::OfflineUnitRenderAction_Preflight => + AudioUnitRenderActionFlags::OfflineUnitRenderAction_Preflight => "OFFLINE_PREFLIGHT", - sys::AudioUnitRenderActionFlags::OfflineUnitRenderAction_Render => - "OFFLINE_RENDER", - sys::AudioUnitRenderActionFlags::OfflineUnitRenderAction_Complete => + AudioUnitRenderActionFlags::OfflineUnitRenderAction_Render => "OFFLINE_RENDER", + AudioUnitRenderActionFlags::OfflineUnitRenderAction_Complete => "OFFLINE_COMPLETE", - sys::AudioUnitRenderActionFlags::UnitRenderAction_PostRenderError => + AudioUnitRenderActionFlags::UnitRenderAction_PostRenderError => "POST_RENDER_ERROR", - sys::AudioUnitRenderActionFlags::UnitRenderAction_DoNotCheckRenderArgs => + AudioUnitRenderActionFlags::UnitRenderAction_DoNotCheckRenderArgs => "DO_NOT_CHECK_RENDER_ARGS", _ => "", } @@ -486,12 +491,12 @@ impl AudioUnit { // // This allows us to take advantage of rust's type system and provide format-specific // `Args` types which can be checked at compile time. - let input_proc_fn = move |io_action_flags: NonNull, - in_time_stamp: NonNull, + let input_proc_fn = move |io_action_flags: NonNull, + in_time_stamp: NonNull, in_bus_number: u32, in_number_frames: u32, - io_data: *mut sys::AudioBufferList| - -> sys::OSStatus { + io_data: *mut AudioBufferList| + -> OSStatus { let args = unsafe { let data = D::from_input_proc_args(in_number_frames, io_data); let flags = action_flags::Handle::from_ptr(io_action_flags.as_ptr()); @@ -520,13 +525,13 @@ impl AudioUnit { // within our AudioUnit's Drop implementation (otherwise it would leak). let input_proc_fn_wrapper_ptr = Box::into_raw(input_proc_fn_wrapper) as *mut c_void; - let render_callback = sys::AURenderCallbackStruct { + let render_callback = AURenderCallbackStruct { inputProc: Some(input_proc), inputProcRefCon: input_proc_fn_wrapper_ptr, }; self.set_property( - sys::kAudioUnitProperty_SetRenderCallback, + kAudioUnitProperty_SetRenderCallback, Scope::Input, Element::Output, Some(&render_callback), @@ -562,15 +567,15 @@ impl AudioUnit { // First, get the current buffer size for pre-allocating the `AudioBuffer`s. #[cfg(target_os = "macos")] let mut buffer_frame_size: u32 = { - let id = sys::kAudioDevicePropertyBufferFrameSize; + let id = objc2_core_audio::kAudioDevicePropertyBufferFrameSize; let buffer_frame_size: u32 = self.get_property(id, Scope::Global, Element::Output)?; buffer_frame_size }; #[cfg(target_os = "ios")] let mut buffer_frame_size: u32 = { - let id = sys::kAudioSessionProperty_CurrentHardwareIOBufferDuration; + let id = objc2_audio_toolbox::kAudioSessionProperty_CurrentHardwareIOBufferDuration; let seconds: f32 = super::audio_session_get_property(id)?; - let id = sys::kAudioSessionProperty_CurrentHardwareSampleRate; + let id = objc2_audio_toolbox::kAudioSessionProperty_CurrentHardwareSampleRate; let sample_rate: f64 = super::audio_session_get_property(id)?; (sample_rate * seconds as f64).round() as u32 }; @@ -583,7 +588,7 @@ impl AudioUnit { let data_byte_size = buffer_frame_size * sample_bytes as u32 * n_channels; let mut data = vec![0u8; data_byte_size as usize]; let mut buffer_capacity = data_byte_size as usize; - let audio_buffer = sys::AudioBuffer { + let audio_buffer = AudioBuffer { mDataByteSize: data_byte_size, mNumberChannels: n_channels, mData: data.as_mut_ptr() as *mut _, @@ -592,7 +597,7 @@ impl AudioUnit { // TODO: This leaks the len & capacity fields, since only the buffer pointer is released mem::forget(data); - let audio_buffer_list = Box::new(sys::AudioBufferList { + let audio_buffer_list = Box::new(AudioBufferList { mNumberBuffers: 1, mBuffers: [audio_buffer], }); @@ -607,17 +612,17 @@ impl AudioUnit { // This allows us to take advantage of rust's type system and provide format-specific // `Args` types which can be checked at compile time. let audio_unit = self.instance; - let input_proc_fn = move |io_action_flags: NonNull, - in_time_stamp: NonNull, + let input_proc_fn = move |io_action_flags: NonNull, + in_time_stamp: NonNull, in_bus_number: u32, in_number_frames: u32, - _io_data: *mut sys::AudioBufferList| - -> sys::OSStatus { + _io_data: *mut AudioBufferList| + -> OSStatus { // If the buffer size has changed, ensure the AudioBuffer is the correct size. if buffer_frame_size != in_number_frames { unsafe { // Retrieve the up-to-date stream format. - let id = sys::kAudioUnitProperty_StreamFormat; + let id = kAudioUnitProperty_StreamFormat; let asbd = match super::get_property(audio_unit, id, Scope::Output, Element::Input) { Err(err) => return err.as_os_status(), @@ -631,10 +636,10 @@ impl AudioUnit { let n_channels = stream_format.channels; let data_byte_size = in_number_frames as usize * sample_bytes * n_channels as usize; - let ptr = (*audio_buffer_list_ptr).mBuffers.as_ptr() as *mut sys::AudioBuffer; + let ptr = (*audio_buffer_list_ptr).mBuffers.as_ptr() as *mut AudioBuffer; let len = (*audio_buffer_list_ptr).mNumberBuffers as usize; - let buffers: &mut [sys::AudioBuffer] = slice::from_raw_parts_mut(ptr, len); + let buffers: &mut [AudioBuffer] = slice::from_raw_parts_mut(ptr, len); let old_capacity = buffer_capacity; for buffer in buffers { let current_len = buffer.mDataByteSize as usize; @@ -653,7 +658,7 @@ impl AudioUnit { } unsafe { - let status = sys::AudioUnitRender( + let status = AudioUnitRender( audio_unit, io_action_flags.as_ptr(), in_time_stamp, @@ -694,13 +699,13 @@ impl AudioUnit { // within our AudioUnit's Drop implementation (otherwise it would leak). let input_proc_fn_wrapper_ptr = Box::into_raw(input_proc_fn_wrapper) as *mut c_void; - let render_callback = sys::AURenderCallbackStruct { + let render_callback = AURenderCallbackStruct { inputProc: Some(input_proc), inputProcRefCon: input_proc_fn_wrapper_ptr, }; self.set_property( - sys::kAudioOutputUnitProperty_SetInputCallback, + kAudioOutputUnitProperty_SetInputCallback, Scope::Global, Element::Output, Some(&render_callback), @@ -737,11 +742,11 @@ impl AudioUnit { } = input_callback; unsafe { // Take ownership over the AudioBufferList in order to safely free it. - let buffer_list: Box = Box::from_raw(buffer_list); + let buffer_list: Box = Box::from_raw(buffer_list); // Free the allocated data from the individual audio buffers. - let ptr = buffer_list.mBuffers.as_ptr() as *const sys::AudioBuffer; + let ptr = buffer_list.mBuffers.as_ptr() as *const AudioBuffer; let len = buffer_list.mNumberBuffers as usize; - let buffers: &[sys::AudioBuffer] = slice::from_raw_parts(ptr, len); + let buffers: &[AudioBuffer] = slice::from_raw_parts(ptr, len); for &buffer in buffers { let ptr = buffer.mData as *mut u8; let len = buffer.mDataByteSize as usize; @@ -760,12 +765,12 @@ impl AudioUnit { /// Callback procedure that will be called each time our audio_unit requests audio. extern "C-unwind" fn input_proc( in_ref_con: NonNull, - io_action_flags: NonNull, - in_time_stamp: NonNull, + io_action_flags: NonNull, + in_time_stamp: NonNull, in_bus_number: u32, in_number_frames: u32, - io_data: *mut sys::AudioBufferList, -) -> sys::OSStatus { + io_data: *mut AudioBufferList, +) -> OSStatus { let wrapper = unsafe { in_ref_con.cast::().as_mut() }; (wrapper.callback)( io_action_flags, diff --git a/src/audio_unit/stream_format.rs b/src/audio_unit/stream_format.rs index 3b78008ce..974fb8e05 100644 --- a/src/audio_unit/stream_format.rs +++ b/src/audio_unit/stream_format.rs @@ -2,11 +2,12 @@ //! //! Find the original `AudioStreamBasicDescription` reference [here](https://developer.apple.com/library/mac/documentation/MusicAudio/Reference/CoreAudioDataTypesRef/#//apple_ref/c/tdef/AudioStreamBasicDescription). +use objc2_core_audio_types::AudioStreamBasicDescription; + use super::audio_format::AudioFormat; use super::audio_format::LinearPcmFlags; use super::SampleFormat; use crate::error::{self, Error}; -use crate::sys; /// A representation of the AudioStreamBasicDescription specifically for use with the AudioUnit API. /// @@ -68,10 +69,10 @@ impl StreamFormat { /// /// Returns an `Error` if the sample format of the asbd cannot be matched to a format supported by SampleFormat. #[allow(non_snake_case)] - pub fn from_asbd(asbd: sys::AudioStreamBasicDescription) -> Result { + pub fn from_asbd(asbd: AudioStreamBasicDescription) -> Result { const NOT_SUPPORTED: Error = Error::AudioUnit(error::audio_unit::Error::FormatNotSupported); - let sys::AudioStreamBasicDescription { + let AudioStreamBasicDescription { mSampleRate, mFormatID, mFormatFlags, @@ -106,7 +107,7 @@ impl StreamFormat { /// Note that this function assumes that only packed formats are used. /// This only affects I24, since all other formats supported by `StreamFormat` /// are always packed. - pub fn to_asbd(self) -> sys::AudioStreamBasicDescription { + pub fn to_asbd(self) -> AudioStreamBasicDescription { let StreamFormat { sample_rate, flags, @@ -129,7 +130,7 @@ impl StreamFormat { let bytes_per_packet = bytes_per_frame * FRAMES_PER_PACKET; let bits_per_channel = sample_format.size_in_bits(); - sys::AudioStreamBasicDescription { + AudioStreamBasicDescription { mSampleRate: sample_rate, mFormatID: format, mFormatFlags: flag, diff --git a/src/error.rs b/src/error.rs index ff32cbc64..c62738c13 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,10 +4,10 @@ pub use self::audio::Error as AudioError; pub use self::audio_codec::Error as AudioCodecError; pub use self::audio_format::Error as AudioFormatError; pub use self::audio_unit::Error as AudioUnitError; -use crate::sys::OSStatus; +use crate::OSStatus; pub mod audio { - use crate::sys::OSStatus; + use crate::OSStatus; #[derive(Copy, Clone, Debug)] pub enum Error { @@ -61,7 +61,7 @@ pub mod audio { } pub mod audio_codec { - use crate::sys::OSStatus; + use crate::OSStatus; #[derive(Copy, Clone, Debug)] pub enum Error { @@ -115,7 +115,7 @@ pub mod audio_codec { } pub mod audio_format { - use crate::sys::OSStatus; + use crate::OSStatus; // TODO: Finish implementing these values. #[derive(Copy, Clone, Debug)] @@ -162,7 +162,7 @@ pub mod audio_format { } pub mod audio_unit { - use crate::sys::OSStatus; + use crate::OSStatus; #[derive(Copy, Clone, Debug)] pub enum Error { diff --git a/src/lib.rs b/src/lib.rs index f02d0c25f..83a6e9e08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,16 +17,5 @@ pub use error::Error; pub mod audio_unit; pub mod error; -pub mod sys { - #[cfg(feature = "audio_toolbox")] - pub use objc2_audio_toolbox::*; - #[cfg(feature = "core_audio")] - pub use objc2_core_audio::*; - #[cfg(feature = "core_audio")] - pub use objc2_core_audio_types::*; - #[cfg(feature = "core_midi")] - pub use objc2_core_midi::*; - - // MacTypes.h - pub type OSStatus = i32; -} +// MacTypes.h +pub type OSStatus = i32;