Properly cleanup up CoreAudio unit using AudioComponentInstanceDispose

This commit is contained in:
Marcelo Fernandez 2018-07-11 08:38:32 -03:00
parent a184126e8b
commit de9a77ebde
2 changed files with 40 additions and 45 deletions

View file

@ -52,7 +52,9 @@ OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID
} }
#endif #endif
Error AudioDriverCoreAudio::init_device() { Error AudioDriverCoreAudio::init() {
mutex = Mutex::create();
AudioComponentDescription desc; AudioComponentDescription desc;
zeromem(&desc, sizeof(desc)); zeromem(&desc, sizeof(desc));
desc.componentType = kAudioUnitType_Output; desc.componentType = kAudioUnitType_Output;
@ -69,6 +71,16 @@ Error AudioDriverCoreAudio::init_device() {
OSStatus result = AudioComponentInstanceNew(comp, &audio_unit); OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED); ERR_FAIL_COND_V(result != noErr, FAILED);
#ifdef OSX_ENABLED
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
prop.mElement = kAudioObjectPropertyElementMaster;
result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this);
ERR_FAIL_COND_V(result != noErr, FAILED);
#endif
AudioStreamBasicDescription strdesc; AudioStreamBasicDescription strdesc;
zeromem(&strdesc, sizeof(strdesc)); zeromem(&strdesc, sizeof(strdesc));
@ -135,42 +147,6 @@ Error AudioDriverCoreAudio::init_device() {
return OK; return OK;
} }
Error AudioDriverCoreAudio::finish_device() {
OSStatus result;
if (active) {
result = AudioOutputUnitStop(audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
active = false;
}
result = AudioUnitUninitialize(audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
return OK;
}
Error AudioDriverCoreAudio::init() {
OSStatus result;
mutex = Mutex::create();
active = false;
channels = 2;
#ifdef OSX_ENABLED
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
prop.mElement = kAudioObjectPropertyElementMaster;
result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this);
ERR_FAIL_COND_V(result != noErr, FAILED);
#endif
return init_device();
};
OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon, OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, const AudioTimeStamp *inTimeStamp,
@ -370,6 +346,7 @@ void AudioDriverCoreAudio::set_device(String device) {
} }
if (!found) { if (!found) {
// If we haven't found the desired device get the system default one
UInt32 size = sizeof(AudioDeviceID); UInt32 size = sizeof(AudioDeviceID);
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
@ -406,7 +383,28 @@ bool AudioDriverCoreAudio::try_lock() {
void AudioDriverCoreAudio::finish() { void AudioDriverCoreAudio::finish() {
OSStatus result; OSStatus result;
finish_device(); lock();
AURenderCallbackStruct callback;
zeromem(&callback, sizeof(AURenderCallbackStruct));
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
if (result != noErr) {
ERR_PRINT("AudioUnitSetProperty failed");
}
if (active) {
result = AudioOutputUnitStop(audio_unit);
if (result != noErr) {
ERR_PRINT("AudioOutputUnitStop failed");
}
active = false;
}
result = AudioUnitUninitialize(audio_unit);
if (result != noErr) {
ERR_PRINT("AudioUnitUninitialize failed");
}
#ifdef OSX_ENABLED #ifdef OSX_ENABLED
AudioObjectPropertyAddress prop; AudioObjectPropertyAddress prop;
@ -420,13 +418,13 @@ void AudioDriverCoreAudio::finish() {
} }
#endif #endif
AURenderCallbackStruct callback; result = AudioComponentInstanceDispose(audio_unit);
zeromem(&callback, sizeof(AURenderCallbackStruct));
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
if (result != noErr) { if (result != noErr) {
ERR_PRINT("AudioUnitSetProperty failed"); ERR_PRINT("AudioComponentInstanceDispose failed");
} }
unlock();
if (mutex) { if (mutex) {
memdelete(mutex); memdelete(mutex);
mutex = NULL; mutex = NULL;

View file

@ -68,9 +68,6 @@ class AudioDriverCoreAudio : public AudioDriver {
UInt32 inBusNumber, UInt32 inNumberFrames, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData); AudioBufferList *ioData);
Error init_device();
Error finish_device();
public: public:
const char *get_name() const { const char *get_name() const {
return "CoreAudio"; return "CoreAudio";