diff --git a/mini_al.h b/mini_al.h index 05b03774..5a6102a4 100644 --- a/mini_al.h +++ b/mini_al.h @@ -1698,6 +1698,7 @@ struct mal_context mal_proc AudioOutputUnitStart; mal_proc AudioOutputUnitStop; mal_proc AudioUnitAddPropertyListener; + mal_proc AudioUnitGetPropertyInfo; mal_proc AudioUnitGetProperty; mal_proc AudioUnitSetProperty; mal_proc AudioUnitInitialize; @@ -13685,6 +13686,7 @@ typedef OSStatus (* mal_AudioComponentInstanceNew_proc)(AudioComponent inCompone typedef OSStatus (* mal_AudioOutputUnitStart_proc)(AudioUnit inUnit); typedef OSStatus (* mal_AudioOutputUnitStop_proc)(AudioUnit inUnit); typedef OSStatus (* mal_AudioUnitAddPropertyListener_proc)(AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitPropertyListenerProc inProc, void* inProcUserData); +typedef OSStatus (* mal_AudioUnitGetPropertyInfo_proc)(AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, UInt32* outDataSize, Boolean* outWriteable); typedef OSStatus (* mal_AudioUnitGetProperty_proc)(AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void* outData, UInt32* ioDataSize); typedef OSStatus (* mal_AudioUnitSetProperty_proc)(AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, const void* inData, UInt32 inDataSize); typedef OSStatus (* mal_AudioUnitInitialize_proc)(AudioUnit inUnit); @@ -14118,7 +14120,6 @@ mal_result mal_get_AudioObject_stream_descriptions(mal_context* pContext, AudioO } - mal_result mal_get_AudioObject_channel_layout(mal_context* pContext, AudioObjectID deviceObjectID, mal_device_type deviceType, AudioChannelLayout** ppChannelLayout) // NOTE: Free the returned pointer with mal_free(). { mal_assert(pContext != NULL); @@ -14262,12 +14263,45 @@ mal_result mal_get_AudioObject_channel_map(mal_context* pContext, AudioObjectID result = mal_get_channel_map_from_AudioChannelLayout(pChannelLayout, channelMap); if (result != MAL_SUCCESS) { + mal_free(pChannelLayout); return result; } + mal_free(pChannelLayout); return result; } +mal_result mal_get_AudioUnit_channel_map(mal_context* pContext, AudioUnit audioUnit, mal_device_type deviceType, mal_channel channelMap[MAL_MAX_CHANNELS]) +{ + mal_assert(pContext != NULL); + + UInt32 channelLayoutSize; + OSStatus status = ((mal_AudioUnitGetPropertyInfo_proc)pContext->coreaudio.AudioUnitGetPropertyInfo)(audioUnit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Output, MAL_COREAUDIO_OUTPUT_BUS, &channelLayoutSize, NULL); + if (status != noErr) { + return mal_result_from_OSStatus(status); + } + + AudioChannelLayout* pChannelLayout = (AudioChannelLayout*)mal_malloc(channelLayoutSize); + if (pChannelLayout == NULL) { + return MAL_OUT_OF_MEMORY; + } + + status = ((mal_AudioUnitGetProperty_proc)pContext->coreaudio.AudioUnitGetProperty)(audioUnit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Output, MAL_COREAUDIO_OUTPUT_BUS, pChannelLayout, &channelLayoutSize); + if (status != noErr) { + mal_free(pChannelLayout); + return mal_result_from_OSStatus(status); + } + + mal_result result = mal_get_channel_map_from_AudioChannelLayout(pChannelLayout, channelMap); + if (result != MAL_SUCCESS) { + mal_free(pChannelLayout); + return result; + } + + mal_free(pChannelLayout); + return MAL_SUCCESS; +} + mal_result mal_get_AudioObject_sample_rates(mal_context* pContext, AudioObjectID deviceObjectID, mal_device_type deviceType, UInt32* pSampleRateRangesCount, AudioValueRange** ppSampleRateRanges) // NOTE: Free the returned pointer with mal_free(). { mal_assert(pContext != NULL); @@ -15393,7 +15427,7 @@ mal_result mal_device_init_internal__coreaudio(mal_context* pContext, mal_device // Internal channel map. #if defined(MAL_APPLE_DESKTOP) - result = mal_get_AudioObject_channel_map(pContext, deviceObjectID, deviceType, pData->channelMapOut); + result = mal_get_AudioUnit_channel_map(pContext, pData->audioUnit, deviceType, pData->channelMapOut); if (result != MAL_SUCCESS) { return result; } @@ -15759,6 +15793,7 @@ mal_result mal_context_init__coreaudio(mal_context* pContext) pContext->coreaudio.AudioOutputUnitStart = mal_dlsym(pContext->coreaudio.hAudioUnit, "AudioOutputUnitStart"); pContext->coreaudio.AudioOutputUnitStop = mal_dlsym(pContext->coreaudio.hAudioUnit, "AudioOutputUnitStop"); pContext->coreaudio.AudioUnitAddPropertyListener = mal_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitAddPropertyListener"); + pContext->coreaudio.AudioUnitGetPropertyInfo = mal_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitGetPropertyInfo"); pContext->coreaudio.AudioUnitGetProperty = mal_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitGetProperty"); pContext->coreaudio.AudioUnitSetProperty = mal_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitSetProperty"); pContext->coreaudio.AudioUnitInitialize = mal_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitInitialize"); @@ -15779,6 +15814,7 @@ mal_result mal_context_init__coreaudio(mal_context* pContext) pContext->coreaudio.AudioOutputUnitStart = (mal_proc)AudioOutputUnitStart; pContext->coreaudio.AudioOutputUnitStop = (mal_proc)AudioOutputUnitStop; pContext->coreaudio.AudioUnitAddPropertyListener = (mal_proc)AudioUnitAddPropertyListener; + pContext->coreaudio.AudioUnitGetPropertyInfo = (mal_proc)AudioUnitGetPropertyInfo; pContext->coreaudio.AudioUnitGetProperty = (mal_proc)AudioUnitGetProperty; pContext->coreaudio.AudioUnitSetProperty = (mal_proc)AudioUnitSetProperty; pContext->coreaudio.AudioUnitInitialize = (mal_proc)AudioUnitInitialize;