feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")
# Driver source files
env.add_source_files(env.drivers_sources, "*.cpp")
env.add_source_files(env.drivers_sources, "*.mm")

View file

@ -38,6 +38,8 @@
#import <AudioUnit/AudioUnit.h>
#ifdef MACOS_ENABLED
#import <CoreAudio/AudioHardware.h>
#else
#import <AVFoundation/AVFoundation.h>
#endif
class AudioDriverCoreAudio : public AudioDriver {
@ -51,9 +53,11 @@ class AudioDriverCoreAudio : public AudioDriver {
String input_device_name = "Default";
int mix_rate = 0;
int capture_mix_rate = 0;
unsigned int channels = 2;
unsigned int capture_channels = 2;
unsigned int buffer_frames = 0;
unsigned int capture_buffer_frames = 0;
Vector<int32_t> samples_in;
Vector<int16_t> input_buf;
@ -89,11 +93,12 @@ class AudioDriverCoreAudio : public AudioDriver {
public:
virtual const char *get_name() const override {
return "CoreAudio";
};
}
virtual Error init() override;
virtual void start() override;
virtual int get_mix_rate() const override;
virtual int get_input_mix_rate() const override;
virtual SpeakerMode get_speaker_mode() const override;
virtual void lock() override;

View file

@ -1,5 +1,5 @@
/**************************************************************************/
/* audio_driver_coreaudio.cpp */
/* audio_driver_coreaudio.mm */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@ -66,6 +66,11 @@ OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID
return noErr;
}
// Switch to kAudioObjectPropertyElementMain everywhere to remove deprecated warnings.
#if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MAX_ALLOWED < 120000) || (TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED < 150000)
#define kAudioObjectPropertyElementMain kAudioObjectPropertyElementMaster
#endif
#endif
Error AudioDriverCoreAudio::init() {
@ -89,7 +94,7 @@ Error AudioDriverCoreAudio::init() {
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
prop.mElement = kAudioObjectPropertyElementMaster;
prop.mElement = kAudioObjectPropertyElementMain;
result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this);
ERR_FAIL_COND_V(result != noErr, FAILED);
@ -116,7 +121,24 @@ Error AudioDriverCoreAudio::init() {
break;
}
mix_rate = _get_configured_mix_rate();
#ifdef MACOS_ENABLED
AudioDeviceID device_id;
UInt32 dev_id_size = sizeof(AudioDeviceID);
AudioObjectPropertyAddress property_dev_id = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property_dev_id, 0, nullptr, &dev_id_size, &device_id);
ERR_FAIL_COND_V(result != noErr, FAILED);
double hw_mix_rate;
UInt32 hw_mix_rate_size = sizeof(hw_mix_rate);
AudioObjectPropertyAddress property_sr = { kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain };
result = AudioObjectGetPropertyData(device_id, &property_sr, 0, nullptr, &hw_mix_rate_size, &hw_mix_rate);
ERR_FAIL_COND_V(result != noErr, FAILED);
#else
double hw_mix_rate = [AVAudioSession sharedInstance].sampleRate;
#endif
mix_rate = hw_mix_rate;
memset(&strdesc, 0, sizeof(strdesc));
strdesc.mFormatID = kAudioFormatLinearPCM;
@ -142,10 +164,10 @@ Error AudioDriverCoreAudio::init() {
unsigned int buffer_size = buffer_frames * channels;
samples_in.resize(buffer_size);
input_buf.resize(buffer_size);
print_verbose("CoreAudio: detected " + itos(channels) + " channels");
print_verbose("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
print_verbose("CoreAudio: output sampling rate: " + itos(mix_rate) + " Hz");
print_verbose("CoreAudio: output audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
AURenderCallbackStruct callback;
memset(&callback, 0, sizeof(AURenderCallbackStruct));
@ -245,7 +267,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
}
void AudioDriverCoreAudio::start() {
if (!active) {
if (!active && audio_unit != nullptr) {
OSStatus result = AudioOutputUnitStart(audio_unit);
if (result != noErr) {
ERR_PRINT("AudioOutputUnitStart failed, code: " + itos(result));
@ -270,6 +292,10 @@ int AudioDriverCoreAudio::get_mix_rate() const {
return mix_rate;
}
int AudioDriverCoreAudio::get_input_mix_rate() const {
return capture_mix_rate;
}
AudioDriver::SpeakerMode AudioDriverCoreAudio::get_speaker_mode() const {
return get_speaker_mode_by_total_channels(channels);
}
@ -319,7 +345,7 @@ void AudioDriverCoreAudio::finish() {
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
prop.mElement = kAudioObjectPropertyElementMaster;
prop.mElement = kAudioObjectPropertyElementMain;
result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this);
if (result != noErr) {
@ -358,7 +384,7 @@ Error AudioDriverCoreAudio::init_input_device() {
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultInputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
prop.mElement = kAudioObjectPropertyElementMaster;
prop.mElement = kAudioObjectPropertyElementMain;
result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &input_device_address_cb, this);
ERR_FAIL_COND_V(result != noErr, FAILED);
@ -373,14 +399,14 @@ Error AudioDriverCoreAudio::init_input_device() {
UInt32 size;
#ifdef MACOS_ENABLED
AudioDeviceID deviceId;
AudioDeviceID device_id;
size = sizeof(AudioDeviceID);
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain };
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, nullptr, &size, &deviceId);
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, nullptr, &size, &device_id);
ERR_FAIL_COND_V(result != noErr, FAILED);
result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID));
result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &device_id, sizeof(AudioDeviceID));
ERR_FAIL_COND_V(result != noErr, FAILED);
#endif
@ -405,13 +431,23 @@ Error AudioDriverCoreAudio::init_input_device() {
break;
}
mix_rate = _get_configured_mix_rate();
#ifdef MACOS_ENABLED
double hw_mix_rate;
UInt32 hw_mix_rate_size = sizeof(hw_mix_rate);
AudioObjectPropertyAddress property_sr = { kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain };
result = AudioObjectGetPropertyData(device_id, &property_sr, 0, nullptr, &hw_mix_rate_size, &hw_mix_rate);
ERR_FAIL_COND_V(result != noErr, FAILED);
#else
double hw_mix_rate = [AVAudioSession sharedInstance].sampleRate;
#endif
capture_mix_rate = hw_mix_rate;
memset(&strdesc, 0, sizeof(strdesc));
strdesc.mFormatID = kAudioFormatLinearPCM;
strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
strdesc.mChannelsPerFrame = capture_channels;
strdesc.mSampleRate = mix_rate;
strdesc.mSampleRate = capture_mix_rate;
strdesc.mFramesPerPacket = 1;
strdesc.mBitsPerChannel = 16;
strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
@ -420,6 +456,13 @@ Error AudioDriverCoreAudio::init_input_device() {
result = AudioUnitSetProperty(input_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &strdesc, sizeof(strdesc));
ERR_FAIL_COND_V(result != noErr, FAILED);
int latency = Engine::get_singleton()->get_audio_output_latency();
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
capture_buffer_frames = closest_power_of_2(latency * capture_mix_rate / 1000);
unsigned int buffer_size = capture_buffer_frames * capture_channels;
input_buf.resize(buffer_size);
AURenderCallbackStruct callback;
memset(&callback, 0, sizeof(AURenderCallbackStruct));
callback.inputProc = &AudioDriverCoreAudio::input_callback;
@ -430,6 +473,9 @@ Error AudioDriverCoreAudio::init_input_device() {
result = AudioUnitInitialize(input_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
print_verbose("CoreAudio: input sampling rate: " + itos(capture_mix_rate) + " Hz");
print_verbose("CoreAudio: input audio buffer frames: " + itos(capture_buffer_frames) + " calculated latency: " + itos(capture_buffer_frames * 1000 / capture_mix_rate) + "ms");
return OK;
}
@ -453,7 +499,7 @@ void AudioDriverCoreAudio::finish_input_device() {
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultInputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
prop.mElement = kAudioObjectPropertyElementMaster;
prop.mElement = kAudioObjectPropertyElementMain;
result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop, &input_device_address_cb, this);
if (result != noErr) {
@ -472,7 +518,7 @@ void AudioDriverCoreAudio::finish_input_device() {
}
Error AudioDriverCoreAudio::input_start() {
input_buffer_init(buffer_frames);
input_buffer_init(capture_buffer_frames);
OSStatus result = AudioOutputUnitStart(input_unit);
if (result != noErr) {
@ -504,7 +550,7 @@ PackedStringArray AudioDriverCoreAudio::_get_device_list(bool input) {
prop.mSelector = kAudioHardwarePropertyDevices;
prop.mScope = kAudioObjectPropertyScopeGlobal;
prop.mElement = kAudioObjectPropertyElementMaster;
prop.mElement = kAudioObjectPropertyElementMain;
UInt32 size = 0;
AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &prop, 0, nullptr, &size);
@ -556,14 +602,14 @@ PackedStringArray AudioDriverCoreAudio::_get_device_list(bool input) {
}
void AudioDriverCoreAudio::_set_device(const String &output_device, bool input) {
AudioDeviceID deviceId;
AudioDeviceID device_id;
bool found = false;
if (output_device != "Default") {
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDevices;
prop.mScope = kAudioObjectPropertyScopeGlobal;
prop.mElement = kAudioObjectPropertyElementMaster;
prop.mElement = kAudioObjectPropertyElementMain;
UInt32 size = 0;
AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &prop, 0, nullptr, &size);
@ -603,7 +649,7 @@ void AudioDriverCoreAudio::_set_device(const String &output_device, bool input)
if (CFStringGetCString(cfname, buffer, maxSize, kCFStringEncodingUTF8)) {
String name = String::utf8(buffer) + " (" + itos(audioDevices[i]) + ")";
if (name == output_device) {
deviceId = audioDevices[i];
device_id = audioDevices[i];
found = true;
}
}
@ -619,16 +665,16 @@ void AudioDriverCoreAudio::_set_device(const String &output_device, bool input)
// If we haven't found the desired device get the system default one
UInt32 size = sizeof(AudioDeviceID);
UInt32 elem = input ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice;
AudioObjectPropertyAddress property = { elem, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
AudioObjectPropertyAddress property = { elem, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain };
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, nullptr, &size, &deviceId);
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, nullptr, &size, &device_id);
ERR_FAIL_COND(result != noErr);
found = true;
}
if (found) {
OSStatus result = AudioUnitSetProperty(input ? input_unit : audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID));
OSStatus result = AudioUnitSetProperty(input ? input_unit : audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &device_id, sizeof(AudioDeviceID));
ERR_FAIL_COND(result != noErr);
if (input) {