Skip to main content

audio_toolbox/
audio_component.rs

1use std::ptr::{null_mut, NonNull};
2
3use core_foundation::base::OSStatus;
4use objc2_audio_toolbox as sys;
5pub use sys::{AudioComponentDescription, AudioComponentFlags, AudioComponentInstantiationOptions};
6
7use crate::base::status_to_result;
8
9#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub struct Component {
11    raw: NonNull<sys::OpaqueAudioComponent>,
12}
13
14impl Component {
15    #[inline]
16    pub unsafe fn from_raw(raw: sys::AudioComponent) -> Option<Self> {
17        NonNull::new(raw).map(|raw| Self {
18            raw,
19        })
20    }
21
22    #[inline]
23    pub fn as_raw(self) -> sys::AudioComponent {
24        self.raw.as_ptr()
25    }
26
27    #[inline]
28    pub fn find_next(previous: Option<Component>, description: &AudioComponentDescription) -> Option<Component> {
29        let raw = unsafe { sys::AudioComponentFindNext(previous.map_or(null_mut(), Component::as_raw), NonNull::from(description)) };
30        unsafe { Component::from_raw(raw) }
31    }
32
33    #[inline]
34    pub fn count(description: &AudioComponentDescription) -> u32 {
35        unsafe { sys::AudioComponentCount(NonNull::from(description)) }
36    }
37
38    pub fn description(self) -> Result<AudioComponentDescription, OSStatus> {
39        let mut description = AudioComponentDescription {
40            componentType: 0,
41            componentSubType: 0,
42            componentManufacturer: 0,
43            componentFlags: 0,
44            componentFlagsMask: 0,
45        };
46        let status = unsafe { sys::AudioComponentGetDescription(self.as_raw(), NonNull::from(&mut description)) };
47        status_to_result(status).map(|_| description)
48    }
49
50    pub fn version(self) -> Result<u32, OSStatus> {
51        let mut version = 0;
52        let status = unsafe { sys::AudioComponentGetVersion(self.as_raw(), NonNull::from(&mut version)) };
53        status_to_result(status).map(|_| version)
54    }
55
56    pub fn instantiate(self) -> Result<ComponentInstance, OSStatus> {
57        let mut instance = null_mut();
58        let status = unsafe { sys::AudioComponentInstanceNew(self.as_raw(), NonNull::from(&mut instance)) };
59        status_to_result(status)?;
60        unsafe { ComponentInstance::from_raw(instance).ok_or(sys::kAudioComponentErr_InstanceInvalidated) }
61    }
62}
63
64#[derive(Debug)]
65pub struct ComponentInstance {
66    raw: NonNull<sys::OpaqueAudioComponentInstance>,
67}
68
69impl ComponentInstance {
70    #[inline]
71    pub unsafe fn from_raw(raw: sys::AudioComponentInstance) -> Option<Self> {
72        NonNull::new(raw).map(|raw| Self {
73            raw,
74        })
75    }
76
77    #[inline]
78    pub fn as_raw(&self) -> sys::AudioComponentInstance {
79        self.raw.as_ptr()
80    }
81
82    #[inline]
83    pub fn into_raw(self) -> sys::AudioComponentInstance {
84        let raw = self.as_raw();
85        std::mem::forget(self);
86        raw
87    }
88
89    #[inline]
90    pub fn component(&self) -> Option<Component> {
91        let raw = unsafe { sys::AudioComponentInstanceGetComponent(self.as_raw()) };
92        unsafe { Component::from_raw(raw) }
93    }
94
95    #[inline]
96    pub fn can_do(&self, selector_id: i16) -> bool {
97        unsafe { sys::AudioComponentInstanceCanDo(self.as_raw(), selector_id) }
98    }
99}
100
101impl Drop for ComponentInstance {
102    fn drop(&mut self) {
103        unsafe {
104            sys::AudioComponentInstanceDispose(self.as_raw());
105        }
106    }
107}