3
3
extern crate coreaudio;
4
4
5
5
use std:: collections:: VecDeque ;
6
- use std:: mem;
7
- use std:: ptr:: null;
8
6
use std:: sync:: { Arc , Mutex } ;
9
7
10
8
use coreaudio:: audio_unit:: audio_format:: LinearPcmFlags ;
11
9
use coreaudio:: audio_unit:: render_callback:: { self , data} ;
12
- use coreaudio:: audio_unit:: { AudioUnit , Element , SampleFormat , Scope , StreamFormat } ;
10
+ use coreaudio:: audio_unit:: { Element , SampleFormat , Scope , StreamFormat } ;
11
+ use coreaudio:: audio_unit:: macos_helpers:: { audio_unit_from_device_id, get_default_device_id} ;
13
12
use coreaudio:: sys:: * ;
14
13
15
14
const SAMPLE_RATE : f64 = 44100.0 ;
16
15
17
- type S = f32 ; const SAMPLE_FORMAT : SampleFormat = SampleFormat :: F32 ;
16
+ type S = f32 ;
17
+ const SAMPLE_FORMAT : SampleFormat = SampleFormat :: F32 ;
18
18
// type S = i32; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I32;
19
19
// type S = i16; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I16;
20
20
// type S = i8; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I8;
21
21
22
22
fn main ( ) -> Result < ( ) , coreaudio:: Error > {
23
- let mut input_audio_unit = audio_unit_from_device ( default_input_device ( ) . unwrap ( ) , true ) ?;
24
- let mut output_audio_unit = audio_unit_from_device ( default_output_device ( ) . unwrap ( ) , false ) ?;
23
+ let mut input_audio_unit = audio_unit_from_device_id ( get_default_device_id ( true ) . unwrap ( ) , true ) ?;
24
+ let mut output_audio_unit = audio_unit_from_device_id ( get_default_device_id ( false ) . unwrap ( ) , false ) ?;
25
25
26
26
let format_flag = match SAMPLE_FORMAT {
27
27
SampleFormat :: F32 => LinearPcmFlags :: IS_FLOAT ,
28
- SampleFormat :: I32 | SampleFormat :: I16 | SampleFormat :: I8 => LinearPcmFlags :: IS_SIGNED_INTEGER ,
28
+ SampleFormat :: I32 | SampleFormat :: I16 | SampleFormat :: I8 => {
29
+ LinearPcmFlags :: IS_SIGNED_INTEGER
30
+ }
31
+ _ => {
32
+ unimplemented ! ( "Other formats are not implemented for this example." ) ;
33
+ }
29
34
} ;
30
35
31
36
// Using IS_NON_INTERLEAVED everywhere because data::Interleaved is commented out / not implemented
@@ -35,15 +40,15 @@ fn main() -> Result<(), coreaudio::Error> {
35
40
flags : format_flag | LinearPcmFlags :: IS_PACKED | LinearPcmFlags :: IS_NON_INTERLEAVED ,
36
41
// audio_unit.set_input_callback is hardcoded to 1 buffer, and when using non_interleaved
37
42
// we are forced to 1 channel
38
- channels_per_frame : 1 ,
43
+ channels : 1 ,
39
44
} ;
40
45
41
46
let out_stream_format = StreamFormat {
42
47
sample_rate : SAMPLE_RATE ,
43
48
sample_format : SAMPLE_FORMAT ,
44
49
flags : format_flag | LinearPcmFlags :: IS_PACKED | LinearPcmFlags :: IS_NON_INTERLEAVED ,
45
50
// you can change this to 1
46
- channels_per_frame : 2 ,
51
+ channels : 2 ,
47
52
} ;
48
53
49
54
println ! ( "input={:#?}" , & in_stream_format) ;
@@ -81,6 +86,11 @@ fn main() -> Result<(), coreaudio::Error> {
81
86
mut data,
82
87
..
83
88
} = args;
89
+ // Print the number of frames the callback provides.
90
+ // Included to aid understanding, don't use println and other things
91
+ // that may block for an unknown amount of time inside the callback
92
+ // of a real application.
93
+ println ! ( "input cb {} frames" , num_frames) ;
84
94
let buffer_left = producer_left. lock ( ) . unwrap ( ) ;
85
95
let buffer_right = producer_right. lock ( ) . unwrap ( ) ;
86
96
let mut buffers = vec ! [ buffer_left, buffer_right] ;
@@ -100,7 +110,11 @@ fn main() -> Result<(), coreaudio::Error> {
100
110
mut data,
101
111
..
102
112
} = args;
103
-
113
+ // Print the number of frames the callback requests.
114
+ // Included to aid understanding, don't use println and other things
115
+ // that may block for an unknown amount of time inside the callback
116
+ // of a real application.
117
+ println ! ( "output cb {} frames" , num_frames) ;
104
118
let buffer_left = consumer_left. lock ( ) . unwrap ( ) ;
105
119
let buffer_right = consumer_right. lock ( ) . unwrap ( ) ;
106
120
let mut buffers = vec ! [ buffer_left, buffer_right] ;
@@ -121,94 +135,3 @@ fn main() -> Result<(), coreaudio::Error> {
121
135
122
136
Ok ( ( ) )
123
137
}
124
-
125
- /// Copied from cpal
126
- pub fn default_input_device ( ) -> Option < AudioDeviceID > {
127
- let property_address = AudioObjectPropertyAddress {
128
- mSelector : kAudioHardwarePropertyDefaultInputDevice,
129
- mScope : kAudioObjectPropertyScopeGlobal,
130
- mElement : kAudioObjectPropertyElementMaster,
131
- } ;
132
-
133
- let audio_device_id: AudioDeviceID = 0 ;
134
- let data_size = mem:: size_of :: < AudioDeviceID > ( ) ;
135
- let status = unsafe {
136
- AudioObjectGetPropertyData (
137
- kAudioObjectSystemObject,
138
- & property_address as * const _ ,
139
- 0 ,
140
- null ( ) ,
141
- & data_size as * const _ as * mut _ ,
142
- & audio_device_id as * const _ as * mut _ ,
143
- )
144
- } ;
145
- if status != kAudioHardwareNoError as i32 {
146
- return None ;
147
- }
148
-
149
- Some ( audio_device_id)
150
- }
151
-
152
- /// Copied from cpal
153
- pub fn default_output_device ( ) -> Option < AudioDeviceID > {
154
- let property_address = AudioObjectPropertyAddress {
155
- mSelector : kAudioHardwarePropertyDefaultOutputDevice,
156
- mScope : kAudioObjectPropertyScopeGlobal,
157
- mElement : kAudioObjectPropertyElementMaster,
158
- } ;
159
-
160
- let audio_device_id: AudioDeviceID = 0 ;
161
- let data_size = mem:: size_of :: < AudioDeviceID > ( ) ;
162
- let status = unsafe {
163
- AudioObjectGetPropertyData (
164
- kAudioObjectSystemObject,
165
- & property_address as * const _ ,
166
- 0 ,
167
- null ( ) ,
168
- & data_size as * const _ as * mut _ ,
169
- & audio_device_id as * const _ as * mut _ ,
170
- )
171
- } ;
172
- if status != kAudioHardwareNoError as i32 {
173
- return None ;
174
- }
175
-
176
- Some ( audio_device_id)
177
- }
178
-
179
- /// Copied from cpal
180
- fn audio_unit_from_device (
181
- device_id : AudioDeviceID ,
182
- input : bool ,
183
- ) -> Result < AudioUnit , coreaudio:: Error > {
184
- let mut audio_unit = AudioUnit :: new ( coreaudio:: audio_unit:: IOType :: HalOutput ) ?;
185
-
186
- if input {
187
- // Enable input processing.
188
- let enable_input = 1u32 ;
189
- audio_unit. set_property (
190
- kAudioOutputUnitProperty_EnableIO,
191
- Scope :: Input ,
192
- Element :: Input ,
193
- Some ( & enable_input) ,
194
- ) ?;
195
-
196
- // Disable output processing.
197
- let disable_output = 0u32 ;
198
- audio_unit. set_property (
199
- kAudioOutputUnitProperty_EnableIO,
200
- Scope :: Output ,
201
- Element :: Output ,
202
- Some ( & disable_output) ,
203
- ) ?;
204
- }
205
-
206
- audio_unit. set_property (
207
- kAudioOutputUnitProperty_CurrentDevice,
208
- Scope :: Global ,
209
- Element :: Output ,
210
- Some ( & device_id) ,
211
- ) ?;
212
-
213
- Ok ( audio_unit)
214
- }
0 commit comments