Commit 3efb8896 authored by David Reid's avatar David Reid

Core Audio: Use a callback for the onStop event.

parent 19be46de
...@@ -13782,6 +13782,28 @@ OSStatus mal_on_input__coreaudio(void* pUserData, AudioUnitRenderActionFlags* pA ...@@ -13782,6 +13782,28 @@ OSStatus mal_on_input__coreaudio(void* pUserData, AudioUnitRenderActionFlags* pA
return noErr; return noErr;
} }
void on_start_stop__coreaudio(void* pUserData, AudioUnit audioUnit, AudioUnitPropertyID propertyID, AudioUnitScope scope, AudioUnitElement element)
{
(void)propertyID;
mal_device* pDevice = (mal_device*)pUserData;
mal_assert(pDevice != NULL);
UInt32 isRunning;
UInt32 isRunningSize = sizeof(isRunning);
OSStatus status = AudioUnitGetProperty(audioUnit, kAudioOutputUnitProperty_IsRunning, scope, element, &isRunning, &isRunningSize);
if (status != noErr) {
return; // Don't really know what to do in this case... just ignore it, I suppose...
}
if (!isRunning) {
mal_stop_proc onStop = pDevice->onStop;
if (onStop) {
onStop(pDevice);
}
}
}
mal_result mal_device_init__coreaudio(mal_context* pContext, mal_device_type deviceType, const mal_device_id* pDeviceID, const mal_device_config* pConfig, mal_device* pDevice) mal_result mal_device_init__coreaudio(mal_context* pContext, mal_device_type deviceType, const mal_device_id* pDeviceID, const mal_device_config* pConfig, mal_device* pDevice)
{ {
...@@ -13947,6 +13969,33 @@ mal_result mal_device_init__coreaudio(mal_context* pContext, mal_device_type dev ...@@ -13947,6 +13969,33 @@ mal_result mal_device_init__coreaudio(mal_context* pContext, mal_device_type dev
pDevice->bufferSizeInFrames = actualBufferSizeInFrames * pDevice->periods; pDevice->bufferSizeInFrames = actualBufferSizeInFrames * pDevice->periods;
// Callbacks.
AURenderCallbackStruct callbackInfo;
callbackInfo.inputProcRefCon = pDevice;
if (deviceType == mal_device_type_playback) {
callbackInfo.inputProc = mal_on_output__coreaudio;
status = AudioUnitSetProperty((AudioUnit)pDevice->coreaudio.audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, MAL_COREAUDIO_OUTPUT_BUS, &callbackInfo, sizeof(callbackInfo));
if (status != noErr) {
AudioComponentInstanceDispose((AudioUnit)pDevice->coreaudio.audioUnit);
return mal_result_from_OSStatus(status);
}
} else {
callbackInfo.inputProc = mal_on_input__coreaudio;
status = AudioUnitSetProperty((AudioUnit)pDevice->coreaudio.audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, MAL_COREAUDIO_INPUT_BUS, &callbackInfo, sizeof(callbackInfo));
if (status != noErr) {
AudioComponentInstanceDispose((AudioUnit)pDevice->coreaudio.audioUnit);
return mal_result_from_OSStatus(status);
}
}
// We need to listen for stop events.
status = AudioUnitAddPropertyListener((AudioUnit)pDevice->coreaudio.audioUnit, kAudioOutputUnitProperty_IsRunning, on_start_stop__coreaudio, pDevice);
if (status != noErr) {
AudioComponentInstanceDispose((AudioUnit)pDevice->coreaudio.audioUnit);
return mal_result_from_OSStatus(status);
}
// We need a buffer list if this is an input device. We render into this in the input callback. // We need a buffer list if this is an input device. We render into this in the input callback.
if (deviceType == mal_device_type_capture) { if (deviceType == mal_device_type_capture) {
...@@ -13987,29 +14036,10 @@ mal_result mal_device_init__coreaudio(mal_context* pContext, mal_device_type dev ...@@ -13987,29 +14036,10 @@ mal_result mal_device_init__coreaudio(mal_context* pContext, mal_device_type dev
} }
// Callbacks.
AURenderCallbackStruct callbackInfo;
callbackInfo.inputProcRefCon = pDevice;
if (deviceType == mal_device_type_playback) {
callbackInfo.inputProc = mal_on_output__coreaudio;
status = AudioUnitSetProperty((AudioUnit)pDevice->coreaudio.audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, MAL_COREAUDIO_OUTPUT_BUS, &callbackInfo, sizeof(callbackInfo));
if (status != noErr) {
AudioComponentInstanceDispose((AudioUnit)pDevice->coreaudio.audioUnit);
return mal_result_from_OSStatus(status);
}
} else {
callbackInfo.inputProc = mal_on_input__coreaudio;
status = AudioUnitSetProperty((AudioUnit)pDevice->coreaudio.audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, MAL_COREAUDIO_INPUT_BUS, &callbackInfo, sizeof(callbackInfo));
if (status != noErr) {
AudioComponentInstanceDispose((AudioUnit)pDevice->coreaudio.audioUnit);
return mal_result_from_OSStatus(status);
}
}
// Initialize the audio unit. // Initialize the audio unit.
status = AudioUnitInitialize((AudioUnit)pDevice->coreaudio.audioUnit); status = AudioUnitInitialize((AudioUnit)pDevice->coreaudio.audioUnit);
if (status != noErr) { if (status != noErr) {
mal_free(pDevice->coreaudio.pAudioBufferList);
AudioComponentInstanceDispose((AudioUnit)pDevice->coreaudio.audioUnit); AudioComponentInstanceDispose((AudioUnit)pDevice->coreaudio.audioUnit);
return mal_result_from_OSStatus(status); return mal_result_from_OSStatus(status);
} }
...@@ -14039,11 +14069,6 @@ mal_result mal_device__stop_backend__coreaudio(mal_device* pDevice) ...@@ -14039,11 +14069,6 @@ mal_result mal_device__stop_backend__coreaudio(mal_device* pDevice)
return mal_result_from_OSStatus(status); return mal_result_from_OSStatus(status);
} }
mal_stop_proc onStop = pDevice->onStop;
if (onStop) {
onStop(pDevice);
}
return MAL_SUCCESS; return MAL_SUCCESS;
} }
#endif // Core Audio #endif // Core Audio
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment