Properly cleanup up CoreAudio unit using AudioComponentInstanceDispose
This commit is contained in:
parent
a184126e8b
commit
de9a77ebde
2 changed files with 40 additions and 45 deletions
|
@ -52,7 +52,9 @@ OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID
|
|||
}
|
||||
#endif
|
||||
|
||||
Error AudioDriverCoreAudio::init_device() {
|
||||
Error AudioDriverCoreAudio::init() {
|
||||
mutex = Mutex::create();
|
||||
|
||||
AudioComponentDescription desc;
|
||||
zeromem(&desc, sizeof(desc));
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
|
@ -69,6 +71,16 @@ Error AudioDriverCoreAudio::init_device() {
|
|||
OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
|
||||
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;
|
||||
|
||||
zeromem(&strdesc, sizeof(strdesc));
|
||||
|
@ -135,42 +147,6 @@ Error AudioDriverCoreAudio::init_device() {
|
|||
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,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp *inTimeStamp,
|
||||
|
@ -370,6 +346,7 @@ void AudioDriverCoreAudio::set_device(String device) {
|
|||
}
|
||||
|
||||
if (!found) {
|
||||
// If we haven't found the desired device get the system default one
|
||||
UInt32 size = sizeof(AudioDeviceID);
|
||||
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
|
||||
|
||||
|
@ -406,7 +383,28 @@ bool AudioDriverCoreAudio::try_lock() {
|
|||
void AudioDriverCoreAudio::finish() {
|
||||
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
|
||||
AudioObjectPropertyAddress prop;
|
||||
|
@ -420,13 +418,13 @@ void AudioDriverCoreAudio::finish() {
|
|||
}
|
||||
#endif
|
||||
|
||||
AURenderCallbackStruct callback;
|
||||
zeromem(&callback, sizeof(AURenderCallbackStruct));
|
||||
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
|
||||
result = AudioComponentInstanceDispose(audio_unit);
|
||||
if (result != noErr) {
|
||||
ERR_PRINT("AudioUnitSetProperty failed");
|
||||
ERR_PRINT("AudioComponentInstanceDispose failed");
|
||||
}
|
||||
|
||||
unlock();
|
||||
|
||||
if (mutex) {
|
||||
memdelete(mutex);
|
||||
mutex = NULL;
|
||||
|
|
|
@ -68,9 +68,6 @@ class AudioDriverCoreAudio : public AudioDriver {
|
|||
UInt32 inBusNumber, UInt32 inNumberFrames,
|
||||
AudioBufferList *ioData);
|
||||
|
||||
Error init_device();
|
||||
Error finish_device();
|
||||
|
||||
public:
|
||||
const char *get_name() const {
|
||||
return "CoreAudio";
|
||||
|
|
Loading…
Reference in a new issue