1
1
/* *************************************************************************/
2
- /* audio_driver_coreaudio.cpp */
2
+ /* audio_driver_coreaudio.mm */
3
3
/* *************************************************************************/
4
4
/* This file is part of: */
5
5
/* GODOT ENGINE */
@@ -116,7 +116,24 @@ Error AudioDriverCoreAudio::init() {
116
116
break ;
117
117
}
118
118
119
- mix_rate = _get_configured_mix_rate ();
119
+ #if MACOS_ENABLED
120
+ AudioDeviceID deviceId;
121
+ UInt32 devIDsize = sizeof (AudioDeviceID);
122
+
123
+ AudioObjectPropertyAddress property_dev_id = { kAudioHardwarePropertyDefaultOutputDevice , kAudioObjectPropertyScopeGlobal , kAudioObjectPropertyElementMaster };
124
+ result = AudioObjectGetPropertyData (kAudioObjectSystemObject , &property_dev_id, 0 , nullptr , &devIDsize, &deviceId);
125
+ ERR_FAIL_COND_V (result != noErr , FAILED);
126
+
127
+ double hw_mix_rate;
128
+ UInt32 hw_mix_rate_size = sizeof (hw_mix_rate);
129
+
130
+ AudioObjectPropertyAddress property_sr = { kAudioDevicePropertyNominalSampleRate , kAudioObjectPropertyScopeGlobal , kAudioObjectPropertyElementMain };
131
+ result = AudioObjectGetPropertyData (deviceId, &property_sr, 0 , nullptr , &hw_mix_rate_size, &hw_mix_rate);
132
+ ERR_FAIL_COND_V (result != noErr , FAILED);
133
+ #else
134
+ double hw_mix_rate = [AVAudioSession sharedInstance ].sampleRate ;
135
+ #endif
136
+ mix_rate = hw_mix_rate;
120
137
121
138
memset (&strdesc, 0 , sizeof (strdesc));
122
139
strdesc.mFormatID = kAudioFormatLinearPCM ;
@@ -142,10 +159,10 @@ Error AudioDriverCoreAudio::init() {
142
159
143
160
unsigned int buffer_size = buffer_frames * channels;
144
161
samples_in.resize (buffer_size);
145
- input_buf.resize (buffer_size);
146
162
147
163
print_verbose (" CoreAudio: detected " + itos (channels) + " channels" );
148
- print_verbose (" CoreAudio: audio buffer frames: " + itos (buffer_frames) + " calculated latency: " + itos (buffer_frames * 1000 / mix_rate) + " ms" );
164
+ print_verbose (" CoreAudio: output sampling rate: " + itos (mix_rate) + " Hz" );
165
+ print_verbose (" CoreAudio: output audio buffer frames: " + itos (buffer_frames) + " calculated latency: " + itos (buffer_frames * 1000 / mix_rate) + " ms" );
149
166
150
167
AURenderCallbackStruct callback;
151
168
memset (&callback, 0 , sizeof (AURenderCallbackStruct));
@@ -270,6 +287,10 @@ int AudioDriverCoreAudio::get_mix_rate() const {
270
287
return mix_rate;
271
288
}
272
289
290
+ int AudioDriverCoreAudio::get_capture_mix_rate () const {
291
+ return capture_mix_rate;
292
+ }
293
+
273
294
AudioDriver::SpeakerMode AudioDriverCoreAudio::get_speaker_mode () const {
274
295
return get_speaker_mode_by_total_channels (channels);
275
296
}
@@ -405,13 +426,23 @@ Error AudioDriverCoreAudio::init_input_device() {
405
426
break ;
406
427
}
407
428
408
- mix_rate = _get_configured_mix_rate ();
429
+ #if MACOS_ENABLED
430
+ double hw_mix_rate;
431
+ UInt32 hw_mix_rate_size = sizeof (hw_mix_rate);
432
+
433
+ AudioObjectPropertyAddress property_sr = { kAudioDevicePropertyNominalSampleRate , kAudioObjectPropertyScopeGlobal , kAudioObjectPropertyElementMain };
434
+ result = AudioObjectGetPropertyData (deviceId, &property_sr, 0 , nullptr , &hw_mix_rate_size, &hw_mix_rate);
435
+ ERR_FAIL_COND_V (result != noErr , FAILED);
436
+ #else
437
+ double hw_mix_rate = [AVAudioSession sharedInstance ].sampleRate ;
438
+ #endif
439
+ capture_mix_rate = hw_mix_rate;
409
440
410
441
memset (&strdesc, 0 , sizeof (strdesc));
411
442
strdesc.mFormatID = kAudioFormatLinearPCM ;
412
443
strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked ;
413
444
strdesc.mChannelsPerFrame = capture_channels;
414
- strdesc.mSampleRate = mix_rate ;
445
+ strdesc.mSampleRate = capture_mix_rate ;
415
446
strdesc.mFramesPerPacket = 1 ;
416
447
strdesc.mBitsPerChannel = 16 ;
417
448
strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8 ;
@@ -420,6 +451,13 @@ Error AudioDriverCoreAudio::init_input_device() {
420
451
result = AudioUnitSetProperty (input_unit, kAudioUnitProperty_StreamFormat , kAudioUnitScope_Output , kInputBus , &strdesc, sizeof (strdesc));
421
452
ERR_FAIL_COND_V (result != noErr , FAILED);
422
453
454
+ int latency = Engine::get_singleton ()->get_audio_output_latency ();
455
+ // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
456
+ capture_buffer_frames = closest_power_of_2 (latency * capture_mix_rate / 1000 );
457
+
458
+ unsigned int buffer_size = capture_buffer_frames * capture_channels;
459
+ input_buf.resize (buffer_size);
460
+
423
461
AURenderCallbackStruct callback;
424
462
memset (&callback, 0 , sizeof (AURenderCallbackStruct));
425
463
callback.inputProc = &AudioDriverCoreAudio::input_callback;
@@ -430,6 +468,9 @@ Error AudioDriverCoreAudio::init_input_device() {
430
468
result = AudioUnitInitialize (input_unit);
431
469
ERR_FAIL_COND_V (result != noErr , FAILED);
432
470
471
+ print_verbose (" CoreAudio: input sampling rate: " + itos (capture_mix_rate) + " Hz" );
472
+ print_verbose (" CoreAudio: input audio buffer frames: " + itos (capture_buffer_frames) + " calculated latency: " + itos (capture_buffer_frames * 1000 / capture_mix_rate) + " ms" );
473
+
433
474
return OK;
434
475
}
435
476
@@ -472,7 +513,7 @@ void AudioDriverCoreAudio::finish_input_device() {
472
513
}
473
514
474
515
Error AudioDriverCoreAudio::input_start () {
475
- input_buffer_init (buffer_frames );
516
+ input_buffer_init (capture_buffer_frames );
476
517
477
518
OSStatus result = AudioOutputUnitStart (input_unit);
478
519
if (result != noErr ) {
0 commit comments