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 */
@@ -121,7 +121,24 @@ Error AudioDriverCoreAudio::init() {
121
121
break ;
122
122
}
123
123
124
- mix_rate = _get_configured_mix_rate ();
124
+ #ifdef MACOS_ENABLED
125
+ AudioDeviceID device_id;
126
+ UInt32 dev_id_size = sizeof (AudioDeviceID);
127
+
128
+ AudioObjectPropertyAddress property_dev_id = { kAudioHardwarePropertyDefaultOutputDevice , kAudioObjectPropertyScopeGlobal , kAudioObjectPropertyElementMaster };
129
+ result = AudioObjectGetPropertyData (kAudioObjectSystemObject , &property_dev_id, 0 , nullptr , &dev_id_size, &device_id);
130
+ ERR_FAIL_COND_V (result != noErr , FAILED);
131
+
132
+ double hw_mix_rate;
133
+ UInt32 hw_mix_rate_size = sizeof (hw_mix_rate);
134
+
135
+ AudioObjectPropertyAddress property_sr = { kAudioDevicePropertyNominalSampleRate , kAudioObjectPropertyScopeGlobal , kAudioObjectPropertyElementMain };
136
+ result = AudioObjectGetPropertyData (device_id, &property_sr, 0 , nullptr , &hw_mix_rate_size, &hw_mix_rate);
137
+ ERR_FAIL_COND_V (result != noErr , FAILED);
138
+ #else
139
+ double hw_mix_rate = [AVAudioSession sharedInstance ].sampleRate ;
140
+ #endif
141
+ mix_rate = hw_mix_rate;
125
142
126
143
memset (&strdesc, 0 , sizeof (strdesc));
127
144
strdesc.mFormatID = kAudioFormatLinearPCM ;
@@ -147,10 +164,10 @@ Error AudioDriverCoreAudio::init() {
147
164
148
165
unsigned int buffer_size = buffer_frames * channels;
149
166
samples_in.resize (buffer_size);
150
- input_buf.resize (buffer_size);
151
167
152
168
print_verbose (" CoreAudio: detected " + itos (channels) + " channels" );
153
- print_verbose (" CoreAudio: audio buffer frames: " + itos (buffer_frames) + " calculated latency: " + itos (buffer_frames * 1000 / mix_rate) + " ms" );
169
+ print_verbose (" CoreAudio: output sampling rate: " + itos (mix_rate) + " Hz" );
170
+ print_verbose (" CoreAudio: output audio buffer frames: " + itos (buffer_frames) + " calculated latency: " + itos (buffer_frames * 1000 / mix_rate) + " ms" );
154
171
155
172
AURenderCallbackStruct callback;
156
173
memset (&callback, 0 , sizeof (AURenderCallbackStruct));
@@ -275,6 +292,10 @@ int AudioDriverCoreAudio::get_mix_rate() const {
275
292
return mix_rate;
276
293
}
277
294
295
+ int AudioDriverCoreAudio::get_input_mix_rate () const {
296
+ return capture_mix_rate;
297
+ }
298
+
278
299
AudioDriver::SpeakerMode AudioDriverCoreAudio::get_speaker_mode () const {
279
300
return get_speaker_mode_by_total_channels (channels);
280
301
}
@@ -378,14 +399,14 @@ Error AudioDriverCoreAudio::init_input_device() {
378
399
379
400
UInt32 size;
380
401
#ifdef MACOS_ENABLED
381
- AudioDeviceID deviceId ;
402
+ AudioDeviceID device_id ;
382
403
size = sizeof (AudioDeviceID);
383
404
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice , kAudioObjectPropertyScopeGlobal , kAudioObjectPropertyElementMain };
384
405
385
- result = AudioObjectGetPropertyData (kAudioObjectSystemObject , &property, 0 , nullptr , &size, &deviceId );
406
+ result = AudioObjectGetPropertyData (kAudioObjectSystemObject , &property, 0 , nullptr , &size, &device_id );
386
407
ERR_FAIL_COND_V (result != noErr , FAILED);
387
408
388
- result = AudioUnitSetProperty (input_unit, kAudioOutputUnitProperty_CurrentDevice , kAudioUnitScope_Global , 0 , &deviceId , sizeof (AudioDeviceID));
409
+ result = AudioUnitSetProperty (input_unit, kAudioOutputUnitProperty_CurrentDevice , kAudioUnitScope_Global , 0 , &device_id , sizeof (AudioDeviceID));
389
410
ERR_FAIL_COND_V (result != noErr , FAILED);
390
411
#endif
391
412
@@ -410,13 +431,23 @@ Error AudioDriverCoreAudio::init_input_device() {
410
431
break ;
411
432
}
412
433
413
- mix_rate = _get_configured_mix_rate ();
434
+ #ifdef MACOS_ENABLED
435
+ double hw_mix_rate;
436
+ UInt32 hw_mix_rate_size = sizeof (hw_mix_rate);
437
+
438
+ AudioObjectPropertyAddress property_sr = { kAudioDevicePropertyNominalSampleRate , kAudioObjectPropertyScopeGlobal , kAudioObjectPropertyElementMain };
439
+ result = AudioObjectGetPropertyData (device_id, &property_sr, 0 , nullptr , &hw_mix_rate_size, &hw_mix_rate);
440
+ ERR_FAIL_COND_V (result != noErr , FAILED);
441
+ #else
442
+ double hw_mix_rate = [AVAudioSession sharedInstance ].sampleRate ;
443
+ #endif
444
+ capture_mix_rate = hw_mix_rate;
414
445
415
446
memset (&strdesc, 0 , sizeof (strdesc));
416
447
strdesc.mFormatID = kAudioFormatLinearPCM ;
417
448
strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked ;
418
449
strdesc.mChannelsPerFrame = capture_channels;
419
- strdesc.mSampleRate = mix_rate ;
450
+ strdesc.mSampleRate = capture_mix_rate ;
420
451
strdesc.mFramesPerPacket = 1 ;
421
452
strdesc.mBitsPerChannel = 16 ;
422
453
strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8 ;
@@ -425,6 +456,13 @@ Error AudioDriverCoreAudio::init_input_device() {
425
456
result = AudioUnitSetProperty (input_unit, kAudioUnitProperty_StreamFormat , kAudioUnitScope_Output , kInputBus , &strdesc, sizeof (strdesc));
426
457
ERR_FAIL_COND_V (result != noErr , FAILED);
427
458
459
+ int latency = Engine::get_singleton ()->get_audio_output_latency ();
460
+ // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
461
+ capture_buffer_frames = closest_power_of_2 (latency * capture_mix_rate / 1000 );
462
+
463
+ unsigned int buffer_size = capture_buffer_frames * capture_channels;
464
+ input_buf.resize (buffer_size);
465
+
428
466
AURenderCallbackStruct callback;
429
467
memset (&callback, 0 , sizeof (AURenderCallbackStruct));
430
468
callback.inputProc = &AudioDriverCoreAudio::input_callback;
@@ -435,6 +473,9 @@ Error AudioDriverCoreAudio::init_input_device() {
435
473
result = AudioUnitInitialize (input_unit);
436
474
ERR_FAIL_COND_V (result != noErr , FAILED);
437
475
476
+ print_verbose (" CoreAudio: input sampling rate: " + itos (capture_mix_rate) + " Hz" );
477
+ print_verbose (" CoreAudio: input audio buffer frames: " + itos (capture_buffer_frames) + " calculated latency: " + itos (capture_buffer_frames * 1000 / capture_mix_rate) + " ms" );
478
+
438
479
return OK;
439
480
}
440
481
@@ -477,7 +518,7 @@ void AudioDriverCoreAudio::finish_input_device() {
477
518
}
478
519
479
520
Error AudioDriverCoreAudio::input_start () {
480
- input_buffer_init (buffer_frames );
521
+ input_buffer_init (capture_buffer_frames );
481
522
482
523
OSStatus result = AudioOutputUnitStart (input_unit);
483
524
if (result != noErr ) {
@@ -561,7 +602,7 @@ PackedStringArray AudioDriverCoreAudio::_get_device_list(bool input) {
561
602
}
562
603
563
604
void AudioDriverCoreAudio::_set_device (const String &output_device, bool input) {
564
- AudioDeviceID deviceId ;
605
+ AudioDeviceID device_id ;
565
606
bool found = false ;
566
607
if (output_device != " Default" ) {
567
608
AudioObjectPropertyAddress prop;
@@ -608,7 +649,7 @@ void AudioDriverCoreAudio::_set_device(const String &output_device, bool input)
608
649
if (CFStringGetCString (cfname, buffer, maxSize, kCFStringEncodingUTF8 )) {
609
650
String name = String::utf8 (buffer) + " (" + itos (audioDevices[i]) + " )" ;
610
651
if (name == output_device) {
611
- deviceId = audioDevices[i];
652
+ device_id = audioDevices[i];
612
653
found = true ;
613
654
}
614
655
}
@@ -626,14 +667,14 @@ void AudioDriverCoreAudio::_set_device(const String &output_device, bool input)
626
667
UInt32 elem = input ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice ;
627
668
AudioObjectPropertyAddress property = { elem, kAudioObjectPropertyScopeGlobal , kAudioObjectPropertyElementMain };
628
669
629
- OSStatus result = AudioObjectGetPropertyData (kAudioObjectSystemObject , &property, 0 , nullptr , &size, &deviceId );
670
+ OSStatus result = AudioObjectGetPropertyData (kAudioObjectSystemObject , &property, 0 , nullptr , &size, &device_id );
630
671
ERR_FAIL_COND (result != noErr );
631
672
632
673
found = true ;
633
674
}
634
675
635
676
if (found) {
636
- OSStatus result = AudioUnitSetProperty (input ? input_unit : audio_unit, kAudioOutputUnitProperty_CurrentDevice , kAudioUnitScope_Global , 0 , &deviceId , sizeof (AudioDeviceID));
677
+ OSStatus result = AudioUnitSetProperty (input ? input_unit : audio_unit, kAudioOutputUnitProperty_CurrentDevice , kAudioUnitScope_Global , 0 , &device_id , sizeof (AudioDeviceID));
637
678
ERR_FAIL_COND (result != noErr );
638
679
639
680
if (input) {
0 commit comments