summaryrefslogtreecommitdiffstats
path: root/third_party/rust/coreaudio-sys-utils/src/audio_unit.rs
blob: 30e5a3cf4b24447c536f00e25274e30321615a6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
use crate::dispatch::debug_assert_running_serially;
use coreaudio_sys::*;
use std::convert::TryFrom;
use std::os::raw::c_void;
use std::ptr;

pub fn audio_unit_get_property_info(
    unit: AudioUnit,
    property: AudioUnitPropertyID,
    scope: AudioUnitScope,
    element: AudioUnitElement,
    size: &mut usize,
    writable: Option<&mut bool>, // Use `Option` since `writable` is nullable.
) -> OSStatus {
    assert!(!unit.is_null());
    assert!(UInt32::try_from(*size).is_ok()); // Check if `size` can be converted to a UInt32.
    debug_assert_running_serially();
    unsafe {
        AudioUnitGetPropertyInfo(
            unit,
            property,
            scope,
            element,
            size as *mut usize as *mut UInt32,
            writable.map_or(ptr::null_mut(), |v| v as *mut bool as *mut Boolean),
        )
    }
}

pub fn audio_unit_get_property<T>(
    unit: AudioUnit,
    property: AudioUnitPropertyID,
    scope: AudioUnitScope,
    element: AudioUnitElement,
    data: &mut T,
    size: &mut usize,
) -> OSStatus {
    assert!(!unit.is_null());
    assert!(UInt32::try_from(*size).is_ok()); // Check if `size` can be converted to a UInt32.
    debug_assert_running_serially();
    unsafe {
        AudioUnitGetProperty(
            unit,
            property,
            scope,
            element,
            data as *mut T as *mut c_void,
            size as *mut usize as *mut UInt32,
        )
    }
}

pub fn audio_unit_set_property<T>(
    unit: AudioUnit,
    property: AudioUnitPropertyID,
    scope: AudioUnitScope,
    element: AudioUnitElement,
    data: &T,
    size: usize,
) -> OSStatus {
    assert!(!unit.is_null());
    debug_assert_running_serially();
    unsafe {
        AudioUnitSetProperty(
            unit,
            property,
            scope,
            element,
            data as *const T as *const c_void,
            size as UInt32,
        )
    }
}

pub fn audio_unit_get_parameter(
    unit: AudioUnit,
    id: AudioUnitParameterID,
    scope: AudioUnitScope,
    element: AudioUnitElement,
    value: &mut AudioUnitParameterValue,
) -> OSStatus {
    assert!(!unit.is_null());
    debug_assert_running_serially();
    unsafe {
        AudioUnitGetParameter(
            unit,
            id,
            scope,
            element,
            value as *mut AudioUnitParameterValue,
        )
    }
}

pub fn audio_unit_set_parameter(
    unit: AudioUnit,
    id: AudioUnitParameterID,
    scope: AudioUnitScope,
    element: AudioUnitElement,
    value: AudioUnitParameterValue,
    buffer_offset_in_frames: UInt32,
) -> OSStatus {
    assert!(!unit.is_null());
    debug_assert_running_serially();
    unsafe { AudioUnitSetParameter(unit, id, scope, element, value, buffer_offset_in_frames) }
}

pub fn audio_unit_initialize(unit: AudioUnit) -> OSStatus {
    assert!(!unit.is_null());
    debug_assert_running_serially();
    unsafe { AudioUnitInitialize(unit) }
}

pub fn audio_unit_uninitialize(unit: AudioUnit) -> OSStatus {
    assert!(!unit.is_null());
    debug_assert_running_serially();
    unsafe { AudioUnitUninitialize(unit) }
}

pub fn dispose_audio_unit(unit: AudioUnit) -> OSStatus {
    debug_assert_running_serially();
    unsafe { AudioComponentInstanceDispose(unit) }
}

pub fn audio_output_unit_start(unit: AudioUnit) -> OSStatus {
    assert!(!unit.is_null());
    debug_assert_running_serially();
    unsafe { AudioOutputUnitStart(unit) }
}

pub fn audio_output_unit_stop(unit: AudioUnit) -> OSStatus {
    assert!(!unit.is_null());
    debug_assert_running_serially();
    unsafe { AudioOutputUnitStop(unit) }
}

pub fn audio_unit_render(
    in_unit: AudioUnit,
    io_action_flags: &mut AudioUnitRenderActionFlags,
    in_time_stamp: &AudioTimeStamp,
    in_output_bus_number: u32,
    in_number_frames: u32,
    io_data: &mut AudioBufferList,
) -> OSStatus {
    assert!(!in_unit.is_null());
    unsafe {
        AudioUnitRender(
            in_unit,
            io_action_flags,
            in_time_stamp,
            in_output_bus_number,
            in_number_frames,
            io_data,
        )
    }
}

#[allow(non_camel_case_types)]
pub type audio_unit_property_listener_proc =
    extern "C" fn(*mut c_void, AudioUnit, AudioUnitPropertyID, AudioUnitScope, AudioUnitElement);

pub fn audio_unit_add_property_listener<T>(
    unit: AudioUnit,
    id: AudioUnitPropertyID,
    listener: audio_unit_property_listener_proc,
    data: *mut T,
) -> OSStatus {
    assert!(!unit.is_null());
    debug_assert_running_serially();
    unsafe { AudioUnitAddPropertyListener(unit, id, Some(listener), data as *mut c_void) }
}

pub fn audio_unit_remove_property_listener_with_user_data<T>(
    unit: AudioUnit,
    id: AudioUnitPropertyID,
    listener: audio_unit_property_listener_proc,
    data: *mut T,
) -> OSStatus {
    assert!(!unit.is_null());
    debug_assert_running_serially();
    unsafe {
        AudioUnitRemovePropertyListenerWithUserData(unit, id, Some(listener), data as *mut c_void)
    }
}