From 32d28747a8444ef97707d1154a67eecfe1ccd8c2 Mon Sep 17 00:00:00 2001 From: Giovanni Petrantoni <7008900+sinkingsugar@users.noreply.github.com> Date: Sun, 18 Apr 2021 08:56:54 +0900 Subject: [PATCH] Attempt to fix ubsan issue under macOS #295 --- miniaudio.h | 74 ++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/miniaudio.h b/miniaudio.h index 053dfff3..9683056e 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -1901,7 +1901,7 @@ typedef enum ma_standard_sample_rate_32000 = 32000, /* Lows */ ma_standard_sample_rate_24000 = 24000, ma_standard_sample_rate_22050 = 22050, - + ma_standard_sample_rate_88200 = 88200, /* Highs */ ma_standard_sample_rate_96000 = 96000, ma_standard_sample_rate_176400 = 176400, @@ -6860,7 +6860,7 @@ static MA_INLINE void ma_yield() #else #if defined(__DMC__) /* Digital Mars does not recognize the PAUSE opcode. Fall back to NOP. */ - __asm nop; + __asm nop; #else __asm pause; #endif @@ -13611,7 +13611,7 @@ static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceStateChanged(m ma_bool32 isThisDevice = MA_FALSE; ma_bool32 isCapture = MA_FALSE; ma_bool32 isPlayback = MA_FALSE; - + #ifdef MA_DEBUG_OUTPUT printf("IMMNotificationClient_OnDeviceStateChanged(pDeviceID=%S, dwNewState=%u)\n", (pDeviceID != NULL) ? pDeviceID : L"(NULL)", (unsigned int)dwNewState); @@ -13783,7 +13783,7 @@ static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDefaultDeviceChanged if (pThis->pDevice->wasapi.isDetachedPlayback) { pThis->pDevice->wasapi.isDetachedPlayback = MA_FALSE; - + if (pThis->pDevice->type == ma_device_type_duplex && pThis->pDevice->wasapi.isDetachedCapture) { restartDevice = MA_FALSE; /* It's a duplex device and the capture side is detached. We cannot be restarting the device just yet. */ } else { @@ -13795,7 +13795,7 @@ static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDefaultDeviceChanged if (pThis->pDevice->wasapi.isDetachedCapture) { pThis->pDevice->wasapi.isDetachedCapture = MA_FALSE; - + if (pThis->pDevice->type == ma_device_type_duplex && pThis->pDevice->wasapi.isDetachedPlayback) { restartDevice = MA_FALSE; /* It's a duplex device and the playback side is detached. We cannot be restarting the device just yet. */ } else { @@ -13851,7 +13851,7 @@ typedef ma_IUnknown ma_WASAPIDeviceInterface; static ma_context_command__wasapi ma_context_init_command__wasapi(int code) { ma_context_command__wasapi cmd; - + MA_ZERO_OBJECT(&cmd); cmd.code = code; @@ -13896,7 +13896,7 @@ static ma_result ma_context_post_command__wasapi(ma_context* pContext, const ma_ /* Now that the command has been added, release the semaphore so ma_context_next_command__wasapi() can return. */ ma_semaphore_release(&pContext->wasapi.commandSem); } - ma_mutex_unlock(&pContext->wasapi.commandLock); + ma_mutex_unlock(&pContext->wasapi.commandLock); if (isUsingLocalEvent) { ma_event_wait(&localEvent); @@ -13922,7 +13922,7 @@ static ma_result ma_context_next_command__wasapi(ma_context* pContext, ma_contex pContext->wasapi.commandCount -= 1; } ma_mutex_unlock(&pContext->wasapi.commandLock); - } + } return result; } @@ -13958,7 +13958,7 @@ static ma_thread_result MA_THREADCALL ma_context_command_thread__wasapi(void* pU case MA_CONTEXT_COMMAND_RELEASE_IAUDIOCLIENT__WASAPI: { - if (cmd.data.releaseAudioClient.deviceType == ma_device_type_playback) { + if (cmd.data.releaseAudioClient.deviceType == ma_device_type_playback) { if (cmd.data.releaseAudioClient.pDevice->wasapi.pAudioClientPlayback != NULL) { ma_IAudioClient_Release((ma_IAudioClient*)cmd.data.releaseAudioClient.pDevice->wasapi.pAudioClientPlayback); cmd.data.releaseAudioClient.pDevice->wasapi.pAudioClientPlayback = NULL; @@ -14000,7 +14000,7 @@ static ma_result ma_device_create_IAudioClient_service__wasapi(ma_context* pCont cmd.data.createAudioClient.pAudioClient = (void*)pAudioClient; cmd.data.createAudioClient.ppAudioClientService = ppAudioClientService; cmd.data.createAudioClient.result = MA_SUCCESS; - + result = ma_context_post_command__wasapi(pContext, &cmd); /* This will not return until the command has actually been run. */ if (result != MA_SUCCESS) { return result; @@ -15047,7 +15047,7 @@ static ma_result ma_device_init_internal__wasapi(ma_context* pContext, ma_device pData->usingAudioClient3 = wasInitializedUsingIAudioClient3; - + if (deviceType == ma_device_type_playback) { result = ma_device_create_IAudioClient_service__wasapi(pContext, deviceType, (ma_IAudioClient*)pData->pAudioClient, (void**)&pData->pRenderClient); } else { @@ -16191,7 +16191,7 @@ static ma_result ma_context_uninit__wasapi(ma_context* pContext) { MA_ASSERT(pContext != NULL); MA_ASSERT(pContext->backend == ma_backend_wasapi); - + if (pContext->wasapi.commandThread != NULL) { ma_context_command__wasapi cmd = ma_context_init_command__wasapi(MA_CONTEXT_COMMAND_QUIT__WASAPI); ma_context_post_command__wasapi(pContext, &cmd); @@ -20073,7 +20073,7 @@ static ma_result ma_context_get_device_info__alsa(ma_context* pContext, ma_devic We want to ensure the the first data formats are the best. We have a list of favored sample formats and sample rates, so these will be the basis of our iteration. */ - + /* Formats. We just iterate over our standard formats and test them, making sure we reset the configuration space each iteration. */ for (iFormat = 0; iFormat < ma_countof(g_maFormatPriorities); iFormat += 1) { ma_format format = g_maFormatPriorities[iFormat]; @@ -22552,7 +22552,7 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi if (pDescriptorCapture->pDeviceID != NULL) { devCapture = pDescriptorCapture->pDeviceID->pulse; } - + format = pDescriptorCapture->format; channels = pDescriptorCapture->channels; sampleRate = pDescriptorCapture->sampleRate; @@ -25137,7 +25137,7 @@ static ma_result ma_context_get_device_info__coreaudio(ma_context* pContext, ma_ if (deviceObjectID == defaultDeviceObjectID) { pDeviceInfo->isDefault = MA_TRUE; } - + /* There could be a large number of permutations here. Fortunately there is only a single channel count being reported which reduces this quite a bit. For sample rates we're only reporting those that are @@ -25147,19 +25147,20 @@ static ma_result ma_context_get_device_info__coreaudio(ma_context* pContext, ma_ sample rate. */ pDeviceInfo->nativeDataFormatCount = 0; - + /* Formats. */ { ma_format uniqueFormats[ma_format_count]; + memset(uniqueFormats, 0xFF, sizeof(ma_format) * ma_format_count); ma_uint32 uniqueFormatCount = 0; ma_uint32 channels; - + /* Channels. */ result = ma_get_AudioObject_channel_count(pContext, deviceObjectID, deviceType, &channels); if (result != MA_SUCCESS) { return result; } - + /* Formats. */ result = ma_get_AudioObject_stream_descriptions(pContext, deviceObjectID, deviceType, &streamDescriptionCount, &pStreamDescriptions); if (result != MA_SUCCESS) { @@ -25186,21 +25187,20 @@ static ma_result ma_context_get_device_info__coreaudio(ma_context* pContext, ma_ break; } } - + /* If we've already handled this format just skip it. */ if (hasFormatBeenHandled) { continue; } - - uniqueFormatCount += 1; - + + uniqueFormats[uniqueFormatCount++] = format; /* Sample Rates */ result = ma_get_AudioObject_sample_rates(pContext, deviceObjectID, deviceType, &sampleRateRangeCount, &pSampleRateRanges); if (result != MA_SUCCESS) { return result; } - + /* Annoyingly Core Audio reports a sample rate range. We just get all the standard rates that are between this range. @@ -25216,14 +25216,14 @@ static ma_result ma_context_get_device_info__coreaudio(ma_context* pContext, ma_ pDeviceInfo->nativeDataFormats[pDeviceInfo->nativeDataFormatCount].sampleRate = standardSampleRate; pDeviceInfo->nativeDataFormats[pDeviceInfo->nativeDataFormatCount].flags = 0; pDeviceInfo->nativeDataFormatCount += 1; - + if (pDeviceInfo->nativeDataFormatCount >= ma_countof(pDeviceInfo->nativeDataFormats)) { break; /* No more room for any more formats. */ } } } } - + if (pDeviceInfo->nativeDataFormatCount >= ma_countof(pDeviceInfo->nativeDataFormats)) { break; /* No more room for any more formats. */ } @@ -25315,12 +25315,12 @@ static ma_result ma_context_get_device_info__coreaudio(ma_context* pContext, ma_ /* Only a single format is being reported for iOS. */ pDeviceInfo->nativeDataFormatCount = 1; - + result = ma_format_from_AudioStreamBasicDescription(&bestFormat, &pDeviceInfo->nativeDataFormats[0].format); if (result != MA_SUCCESS) { return result; } - + pDeviceInfo->nativeDataFormats[0].channels = bestFormat.mChannelsPerFrame; /* @@ -25478,7 +25478,7 @@ static OSStatus ma_on_output__coreaudio(void* pUserData, AudioUnitRenderActionFl if (framesToRead > framesRemaining) { framesToRead = framesRemaining; } - + ma_device_handle_backend_data_callback(pDevice, tempBuffer, NULL, framesToRead); for (iChannel = 0; iChannel < pDevice->playback.internalChannels; ++iChannel) { @@ -25583,7 +25583,7 @@ static OSStatus ma_on_input__coreaudio(void* pUserData, AudioUnitRenderActionFla if (framesToSend > framesRemaining) { framesToSend = framesRemaining; } - + ma_device_handle_backend_data_callback(pDevice, NULL, silentBuffer, framesToSend); framesRemaining -= framesToSend; @@ -26706,7 +26706,7 @@ static ma_result ma_device_init__coreaudio(ma_device* pDevice, const ma_device_c #endif } - + /* When stopping the device, a callback is called on another thread. We need to wait for this callback @@ -26993,7 +26993,7 @@ static ma_result ma_context_init__coreaudio(ma_context* pContext, const ma_conte #endif pContext->coreaudio.noAudioSessionDeactivate = pConfig->coreaudio.noAudioSessionDeactivate; - + pCallbacks->onContextInit = ma_context_init__coreaudio; pCallbacks->onContextUninit = ma_context_uninit__coreaudio; pCallbacks->onContextEnumerateDevices = ma_context_enumerate_devices__coreaudio; @@ -27630,7 +27630,7 @@ static ma_result ma_device_init_handle__sndio(ma_device* pDevice, const ma_devic par.sig = 1; } break; } - + if (deviceType == ma_device_type_capture) { par.rchan = channels; } else { @@ -29037,7 +29037,7 @@ static ma_result ma_device_init_fd__oss(ma_device* pDevice, const ma_device_conf MA_ASSERT(pDevice != NULL); MA_ASSERT(pConfig != NULL); MA_ASSERT(deviceType != ma_device_type_duplex); - + pDeviceID = pDescriptor->pDeviceID; shareMode = pDescriptor->shareMode; ossFormat = ma_format_to_oss((pDescriptor->format != ma_format_unknown) ? pDescriptor->format : ma_format_s16); /* Use s16 by default because OSS doesn't like floating point. */ @@ -29625,7 +29625,7 @@ static ma_result ma_create_and_configure_AAudioStreamBuilder__aaudio(ma_context* /* Not sure how this affects things, but since there's a mapping between miniaudio's performance profiles and AAudio's performance modes, let go ahead and set it. */ ((MA_PFN_AAudioStreamBuilder_setPerformanceMode)pContext->aaudio.AAudioStreamBuilder_setPerformanceMode)(pBuilder, (pConfig->performanceProfile == ma_performance_profile_low_latency) ? MA_AAUDIO_PERFORMANCE_MODE_LOW_LATENCY : MA_AAUDIO_PERFORMANCE_MODE_NONE); - + /* We need to set an error callback to detect device changes. */ if (pDevice != NULL) { /* <-- pDevice should never be null if pDescriptor is not null, which is always the case if we hit this branch. Check anyway for safety. */ ((MA_PFN_AAudioStreamBuilder_setErrorCallback)pContext->aaudio.AAudioStreamBuilder_setErrorCallback)(pBuilder, ma_stream_error_callback__aaudio, (void*)pDevice); @@ -32930,13 +32930,13 @@ MA_API ma_result ma_device_init(ma_context* pContext, const ma_device_config* pC pDevice->capture.channels = pConfig->capture.channels; ma_channel_map_copy(pDevice->capture.channelMap, pConfig->capture.channelMap, pConfig->capture.channels); pDevice->capture.channelMixMode = pConfig->capture.channelMixMode; - + pDevice->playback.shareMode = pConfig->playback.shareMode; pDevice->playback.format = pConfig->playback.format; pDevice->playback.channels = pConfig->playback.channels; ma_channel_map_copy(pDevice->playback.channelMap, pConfig->playback.channelMap, pConfig->playback.channels); pDevice->playback.channelMixMode = pConfig->playback.channelMixMode; - + result = ma_mutex_init(&pDevice->startStopLock); if (result != MA_SUCCESS) { @@ -43290,7 +43290,7 @@ static ma_result ma_audio_buffer_init_ex(const ma_audio_buffer_config* pConfig, if (result != MA_SUCCESS) { return result; } - + ma_allocation_callbacks_init_copy(&pAudioBuffer->allocationCallbacks, &pConfig->allocationCallbacks); if (doCopy) {