31 #ifndef miniaudio_engine_h
32 #define miniaudio_engine_h
45 #define MA_ALLOCATION_TYPE_GENERAL 0x00000001
46 #define MA_ALLOCATION_TYPE_CONTEXT 0x00000002
47 #define MA_ALLOCATION_TYPE_DEVICE 0x00000003
48 #define MA_ALLOCATION_TYPE_DECODER 0x00000004
49 #define MA_ALLOCATION_TYPE_AUDIO_BUFFER 0x00000005
50 #define MA_ALLOCATION_TYPE_ENCODED_BUFFER 0x00000006
51 #define MA_ALLOCATION_TYPE_DECODED_BUFFER 0x00000007
52 #define MA_ALLOCATION_TYPE_RESOURCE_MANAGER_DATA_BUFFER_NODE 0x00000010
53 #define MA_ALLOCATION_TYPE_RESOURCE_MANAGER_DATA_BUFFER 0x00000011
54 #define MA_ALLOCATION_TYPE_RESOURCE_MANAGER_DATA_STREAM 0x00000012
55 #define MA_ALLOCATION_TYPE_RESOURCE_MANAGER_DATA_SOURCE 0x00000013
861 #ifndef MA_MAX_NODE_BUS_COUNT
862 #define MA_MAX_NODE_BUS_COUNT 254
866 #ifndef MA_MAX_NODE_LOCAL_BUS_COUNT
867 #define MA_MAX_NODE_LOCAL_BUS_COUNT 2
871 #define MA_NODE_BUS_COUNT_UNKNOWN 255
878 #define MA_NODE_FLAG_PASSTHROUGH 0x00000001
879 #define MA_NODE_FLAG_CONTINUOUS_PROCESSING 0x00000002
880 #define MA_NODE_FLAG_ALLOW_NULL_INPUT 0x00000004
881 #define MA_NODE_FLAG_DIFFERENT_PROCESSING_RATES 0x00000008
905 void (* onProcess)(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut);
952 #define MA_NODE_OUTPUT_BUS_FLAG_HAS_READ 0x01
1121 #define MA_DATA_SOURCE_FLAG_STREAM 0x00000001
1122 #define MA_DATA_SOURCE_FLAG_DECODE 0x00000002
1123 #define MA_DATA_SOURCE_FLAG_ASYNC 0x00000004
1124 #define MA_DATA_SOURCE_FLAG_WAIT_INIT 0x00000008
1135 #ifndef MA_RESOURCE_MANAGER_JOB_QUEUE_CAPACITY
1136 #define MA_RESOURCE_MANAGER_JOB_QUEUE_CAPACITY 1024
1139 #define MA_JOB_QUIT 0x00000000
1140 #define MA_JOB_LOAD_DATA_BUFFER_NODE 0x00000001
1141 #define MA_JOB_FREE_DATA_BUFFER_NODE 0x00000002
1142 #define MA_JOB_PAGE_DATA_BUFFER_NODE 0x00000003
1143 #define MA_JOB_LOAD_DATA_BUFFER 0x00000004
1144 #define MA_JOB_FREE_DATA_BUFFER 0x00000005
1145 #define MA_JOB_LOAD_DATA_STREAM 0x00000006
1146 #define MA_JOB_FREE_DATA_STREAM 0x00000007
1147 #define MA_JOB_PAGE_DATA_STREAM 0x00000008
1148 #define MA_JOB_SEEK_DATA_STREAM 0x00000009
1149 #define MA_JOB_CUSTOM 0x00000100
1290 wchar_t* pFilePathW;
1296 } loadDataBufferNode;
1302 } freeDataBufferNode;
1309 } pageDataBufferNode;
1330 wchar_t* pFilePathW;
1369 #define MA_JOB_QUEUE_FLAG_NON_BLOCKING 0x00000001
1388 #ifndef MA_RESOURCE_MANAGER_MAX_JOB_THREAD_COUNT
1389 #define MA_RESOURCE_MANAGER_MAX_JOB_THREAD_COUNT 64
1393 #define MA_RESOURCE_MANAGER_FLAG_NON_BLOCKING 0x00000001
1396 #define MA_RESOURCE_MANAGER_FLAG_NO_THREADING 0x00000002
1523 void* pCustomDecodingBackendUserData;
1720 float coneInnerAngleInRadians;
1721 float coneOuterAngleInRadians;
1722 float coneOuterGain;
1774 float coneInnerAngleInRadians;
1775 float coneOuterAngleInRadians;
1776 float coneOuterGain;
1777 float dopplerFactor;
1792 float* pNewChannelGainsOut;
1834 #define MA_SOUND_FLAG_STREAM MA_DATA_SOURCE_FLAG_STREAM
1835 #define MA_SOUND_FLAG_DECODE MA_DATA_SOURCE_FLAG_DECODE
1836 #define MA_SOUND_FLAG_ASYNC MA_DATA_SOURCE_FLAG_ASYNC
1837 #define MA_SOUND_FLAG_WAIT_INIT MA_DATA_SOURCE_FLAG_WAIT_INIT
1838 #define MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT 0x00000010
1839 #define MA_SOUND_FLAG_NO_PITCH 0x00000020
1840 #define MA_SOUND_FLAG_NO_SPATIALIZATION 0x00000040
1842 #ifndef MA_ENGINE_MAX_LISTENERS
1843 #define MA_ENGINE_MAX_LISTENERS 4
1846 #define MA_LISTENER_INDEX_CLOSEST ((ma_uint8)-1)
1881 float oldDopplerPitch;
1899 const char* pFilePath;
1900 const wchar_t* pFilePathW;
1903 ma_uint32 initialAttachmentInputBusIndex;
1925 #ifndef MA_NO_RESOURCE_MANAGER
1962 ma_vfs* pResourceManagerVFS;
2017 #ifndef MA_NO_RESOURCE_MANAGER
2381 #if defined(MA_IMPLEMENTATION) || defined(MINIAUDIO_IMPLEMENTATION)
2385 if (pData ==
NULL) {
2402 if (pData ==
NULL) {
2408 while (pPage !=
NULL) {
2411 ma_free(pPage, pAllocationCallbacks);
2418 if (pData ==
NULL) {
2422 return &pData->
head;
2427 if (pData ==
NULL) {
2431 return pData->
pTail;
2438 if (pLength ==
NULL) {
2444 if (pData ==
NULL) {
2461 if (ppPage ==
NULL) {
2467 if (pData ==
NULL) {
2477 if (pPage ==
NULL) {
2484 if (pInitialData !=
NULL) {
2495 if (pData ==
NULL || pPage ==
NULL) {
2500 ma_free(pPage, pAllocationCallbacks);
2507 if (pData ==
NULL || pPage ==
NULL) {
2586 ma_paged_audio_buffer__data_source_on_read,
2587 ma_paged_audio_buffer__data_source_on_seek,
2590 ma_paged_audio_buffer__data_source_on_get_data_format,
2591 ma_paged_audio_buffer__data_source_on_get_cursor,
2592 ma_paged_audio_buffer__data_source_on_get_length
2600 if (pPagedAudioBuffer ==
NULL) {
2607 if (pConfig ==
NULL) {
2616 dataSourceConfig.
vtable = &g_ma_paged_audio_buffer_data_source_vtable;
2633 if (pPagedAudioBuffer ==
NULL) {
2647 if (pPagedAudioBuffer ==
NULL) {
2654 while (totalFramesRead < frameCount) {
2657 ma_uint64 framesRemainingToRead = frameCount - totalFramesRead;
2664 framesToReadThisIteration =
ma_min(framesRemainingInCurrentPage, framesRemainingToRead);
2665 ma_copy_pcm_frames(
ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, format, channels),
ma_offset_pcm_frames_ptr(pPagedAudioBuffer->
pCurrent->
pAudioData, pPagedAudioBuffer->
relativeCursor, format, channels), framesToReadThisIteration, format, channels);
2666 totalFramesRead += framesToReadThisIteration;
2677 if (pNext ==
NULL) {
2681 pPagedAudioBuffer->
pCurrent = pNext;
2687 if (pFramesRead !=
NULL) {
2688 *pFramesRead = totalFramesRead;
2696 if (pPagedAudioBuffer ==
NULL) {
2704 if (frameIndex < pPagedAudioBuffer->absoluteCursor) {
2722 if (frameIndex >= pageRangeBeg) {
2725 pPagedAudioBuffer->
pCurrent = pPage;
2732 runningCursor = pageRangeEnd;
2744 if (pCursor ==
NULL) {
2750 if (pPagedAudioBuffer ==
NULL) {
2777 return bytesPerSample[format];
2792 config.channels = channels;
2793 config.smoothTimeInFrames = smoothTimeInFrames;
2802 size_t oldGainsOffset;
2803 size_t newGainsOffset;
2804 } ma_gainer_heap_layout;
2812 if (pConfig ==
NULL) {
2820 pHeapLayout->sizeInBytes = 0;
2823 pHeapLayout->oldGainsOffset = pHeapLayout->sizeInBytes;
2824 pHeapLayout->sizeInBytes +=
sizeof(float) * pConfig->
channels;
2827 pHeapLayout->newGainsOffset = pHeapLayout->sizeInBytes;
2828 pHeapLayout->sizeInBytes +=
sizeof(
float) * pConfig->
channels;
2831 pHeapLayout->sizeInBytes =
ma_align_64(pHeapLayout->sizeInBytes);
2840 ma_gainer_heap_layout heapLayout;
2842 if (pHeapSizeInBytes ==
NULL) {
2846 *pHeapSizeInBytes = 0;
2848 result = ma_gainer_get_heap_layout(pConfig, &heapLayout);
2853 *pHeapSizeInBytes = heapLayout.sizeInBytes;
2862 ma_gainer_heap_layout heapLayout;
2865 if (pGainer ==
NULL) {
2871 if (pConfig ==
NULL || pHeap ==
NULL) {
2875 result = ma_gainer_get_heap_layout(pConfig, &heapLayout);
2884 pGainer->
config = *pConfig;
2887 for (iChannel = 0; iChannel < pConfig->
channels; iChannel += 1) {
2898 size_t heapSizeInBytes;
2906 if (heapSizeInBytes > 0) {
2907 pHeap =
ma_malloc(heapSizeInBytes, pAllocationCallbacks);
2908 if (pHeap ==
NULL) {
2926 if (pGainer ==
NULL) {
2935 static float ma_gainer_calculate_current_gain(
const ma_gainer* pGainer,
ma_uint32 channel)
2945 float* pFramesOutF32 = (
float*)pFramesOut;
2946 const float* pFramesInF32 = (
const float*)pFramesIn;
2948 if (pGainer ==
NULL) {
2964 if (pFramesOut !=
NULL && pFramesIn !=
NULL) {
2969 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
2970 for (iChannel = 0; iChannel < channelCount; iChannel += 1) {
2974 pFramesOutF32 += channelCount;
2975 pFramesInF32 += channelCount;
2987 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
2989 if (pFramesOut !=
NULL && pFramesIn !=
NULL) {
2990 for (iChannel = 0; iChannel < pGainer->
config.
channels; iChannel += 1) {
2991 pFramesOutF32[iFrame*pGainer->
config.
channels + iChannel] = pFramesInF32[iFrame*pGainer->
config.
channels + iChannel] * ma_gainer_calculate_current_gain(pGainer, iChannel);
3004 static void ma_gainer_set_gain_by_index(
ma_gainer* pGainer,
float newGain,
ma_uint32 iChannel)
3006 pGainer->
pOldGains[iChannel] = ma_gainer_calculate_current_gain(pGainer, iChannel);
3010 static void ma_gainer_reset_smoothing_time(
ma_gainer* pGainer)
3023 if (pGainer ==
NULL) {
3027 for (iChannel = 0; iChannel < pGainer->
config.
channels; iChannel += 1) {
3028 ma_gainer_set_gain_by_index(pGainer, newGain, iChannel);
3032 ma_gainer_reset_smoothing_time(pGainer);
3041 if (pGainer ==
NULL || pNewGains ==
NULL) {
3045 for (iChannel = 0; iChannel < pGainer->
config.
channels; iChannel += 1) {
3046 ma_gainer_set_gain_by_index(pGainer, pNewGains[iChannel], iChannel);
3050 ma_gainer_reset_smoothing_time(pGainer);
3059 #ifndef MA_DEFAULT_NODE_CACHE_CAP_IN_FRAMES_PER_BUS
3060 #define MA_DEFAULT_NODE_CACHE_CAP_IN_FRAMES_PER_BUS 480
3069 #ifndef MA_NO_GENERATION
3085 #if defined(MA_DEBUG_OUTPUT)
3087 #warning ma_debug_fill_pcm_frames_with_sine_wave() will do nothing because MA_NO_GENERATION is enabled.
3109 return (
ma_int32)((x * volume) >> 8);
3114 return (
ma_int64)((x * volume) >> 8);
3119 return (
ma_int64)((x * volume) >> 8);
3122 static MA_INLINE float ma_apply_volume_unclipped_f32(
float x,
float volume)
3143 for (iChannelOut = 0; iChannelOut < channelCountOut; iChannelOut += 1) {
3150 for (iChannelIn = 0; iChannelIn < channelCountIn; iChannelIn += 1) {
3154 if (channelOut == channelIn) {
3155 pShuffleTable[iChannelOut] = (
ma_uint8)iChannelIn;
3173 switch (channelIn) {
3177 pShuffleTable[iChannelOut] = (
ma_uint8)iChannelIn;
3186 switch (channelIn) {
3190 pShuffleTable[iChannelOut] = (
ma_uint8)iChannelIn;
3212 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
3213 for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
3214 ma_uint8 iChannelIn = pShuffleTable[iChannelOut];
3215 if (iChannelIn < channelsIn) {
3216 pFramesOut[iChannelOut] = pFramesIn[iChannelIn];
3218 pFramesOut[iChannelOut] = 0;
3222 pFramesOut += channelsOut;
3223 pFramesIn += channelsIn;
3235 if (pFramesOut ==
NULL || pFramesIn ==
NULL || channelsIn == 0) {
3242 accumulationCount = 0;
3243 for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
3245 accumulationCount += 1;
3249 if (accumulationCount > 0) {
3250 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
3251 float accumulation = 0;
3253 for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
3256 accumulation += pFramesIn[iChannelIn];
3260 pFramesOut[0] = accumulation / accumulationCount;
3262 pFramesIn += channelsIn;
3276 if (pFramesOut ==
NULL || channelsOut == 0 || pFramesIn ==
NULL) {
3281 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
3282 for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
3285 pFramesOut[iChannelOut] = pFramesIn[0];
3289 pFramesOut += channelsOut;
3300 if (channelsOut == channelsIn) {
3301 if (pChannelMapOut == pChannelMapIn) {
3317 if (channelsOut == 1 && (pChannelMapOut ==
NULL || pChannelMapOut[0] ==
MA_CHANNEL_MONO)) {
3318 ma_channel_map_apply_mono_out_f32(pFramesOut, pFramesIn, pChannelMapIn, channelsIn, frameCount);
3324 ma_channel_map_apply_mono_in_f32(pFramesOut, pChannelMapOut, channelsOut, pFramesIn, frameCount);
3335 result = ma_channel_map_build_shuffle_table(pChannelMapIn, channelsIn, pChannelMapOut, channelsOut, shuffleTable);
3340 result = ma_channel_map_apply_shuffle_table_f32(pFramesOut, channelsOut, pFramesIn, channelsIn, frameCount, shuffleTable);
3348 float weights[32][32];
3356 for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
3358 for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
3364 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
3365 for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
3366 float accumulation = 0;
3368 for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
3369 accumulation += pFramesIn[iChannelIn] * weights[iChannelOut][iChannelIn];
3372 pFramesOut[iChannelOut] = accumulation;
3375 pFramesOut += channelsOut;
3376 pFramesIn += channelsIn;
3380 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
3381 for (iChannelOut = 0; iChannelOut < channelsOut; iChannelOut += 1) {
3382 float accumulation = 0;
3385 for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
3390 pFramesOut[iChannelOut] = accumulation;
3393 pFramesOut += channelsOut;
3394 pFramesIn += channelsIn;
3410 if (channels == 2) {
3414 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
3416 for (iChannel = 0; iChannel < channels; iChannel += 1) {
3417 pFramesOut[iFrame * channels + iChannel] = pFramesIn[iFrame * channels + iChannel] * pChannelGains[iChannel];
3435 if (pDst ==
NULL || pSrc ==
NULL || channels == 0) {
3443 sampleCount = frameCount * channels;
3446 for (iSample = 0; iSample < sampleCount; iSample += 1) {
3450 ma_int16 volumeFixed = ma_float_to_fixed_16(volume);
3451 for (iSample = 0; iSample < sampleCount; iSample += 1) {
3464 if (pDst ==
NULL || pSrc ==
NULL || channels == 0) {
3472 sampleCount = frameCount * channels;
3475 for (iSample = 0; iSample < sampleCount; iSample += 1) {
3476 pDst[iSample] += pSrc[iSample];
3479 ma_int16 volumeFixed = ma_float_to_fixed_16(volume);
3480 for (iSample = 0; iSample < sampleCount; iSample += 1) {
3481 pDst[iSample] += ma_apply_volume_unclipped_s16(pSrc[iSample], volumeFixed);
3493 if (pDst ==
NULL || pSrc ==
NULL || channels == 0) {
3501 sampleCount = frameCount * channels;
3504 for (iSample = 0; iSample < sampleCount; iSample += 1) {
3508 ma_int16 volumeFixed = ma_float_to_fixed_16(volume);
3509 for (iSample = 0; iSample < sampleCount; iSample += 1) {
3522 if (pDst ==
NULL || pSrc ==
NULL || channels == 0) {
3531 sampleCount = frameCount * channels;
3534 for (iSample = 0; iSample < sampleCount; iSample += 1) {
3535 pDst[iSample] += pSrc[iSample];
3538 ma_int16 volumeFixed = ma_float_to_fixed_16(volume);
3539 for (iSample = 0; iSample < sampleCount; iSample += 1) {
3540 pDst[iSample] += ma_apply_volume_unclipped_s32(pSrc[iSample], volumeFixed);
3553 if (pDst ==
NULL || pSrc ==
NULL || channels == 0) {
3561 sampleCount = frameCount * channels;
3564 for (iSample = 0; iSample < sampleCount; iSample += 1) {
3565 pDst[iSample] += pSrc[iSample];
3568 for (iSample = 0; iSample < sampleCount; iSample += 1) {
3569 pDst[iSample] += ma_apply_volume_unclipped_f32(pSrc[iSample], volume);
3587 case ma_format_f32: result = ma_mix_pcm_frames_f32((
float*)pDst, (
const float*)pSrc, frameCount, channels, volume);
break;
3602 config.channels = channels;
3623 static void ma_node_graph_endpoint_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
3635 (void)pFrameCountIn;
3637 (void)pFrameCountOut;
3641 if (ppFramesIn !=
NULL) {
3649 ma_node_graph_endpoint_process_pcm_frames,
3661 if (pNodeGraph ==
NULL) {
3668 endpointConfig.
vtable = &g_node_graph_endpoint_vtable;
3672 result =
ma_node_init(pNodeGraph, &endpointConfig, pAllocationCallbacks, &pNodeGraph->
endpoint);
3682 if (pNodeGraph ==
NULL) {
3691 if (pNodeGraph ==
NULL) {
3704 if (pFramesRead !=
NULL) {
3708 if (pNodeGraph ==
NULL) {
3716 totalFramesRead = 0;
3717 while (totalFramesRead < frameCount) {
3719 ma_uint32 framesToRead = frameCount - totalFramesRead;
3721 ma_node_graph_set_is_reading(pNodeGraph,
MA_TRUE);
3725 ma_node_graph_set_is_reading(pNodeGraph,
MA_FALSE);
3727 totalFramesRead += framesJustRead;
3734 if (framesJustRead == 0) {
3740 if (totalFramesRead < frameCount) {
3744 if (pFramesRead !=
NULL) {
3745 *pFramesRead = totalFramesRead;
3753 if (pNodeGraph ==
NULL) {
3762 if (pNodeGraph ==
NULL) {
3771 if (pNodeGraph ==
NULL) {
3789 if (channels == 0) {
3793 pOutputBus->
pNode = pNode;
3849 if (volume < 0.0f) {
3871 if (channels == 0) {
3922 ma_node_output_bus_set_is_attached(pOutputBus,
MA_FALSE);
3936 ma_node_input_bus_lock(pInputBus);
3941 if (pOldPrev !=
NULL) {
3944 if (pOldNext !=
NULL) {
3948 ma_node_input_bus_unlock(pInputBus);
3971 while (ma_node_input_bus_get_next_counter(pInputBus) > 0) {
3992 ma_node_output_bus_lock(pOutputBus);
3994 ma_node_input_bus_detach__no_output_bus_lock(pInputBus, pOutputBus);
3996 ma_node_output_bus_unlock(pOutputBus);
4005 ma_node_output_bus_lock(pOutputBus);
4010 if (pOldInputNode !=
NULL) {
4011 ma_node_input_bus_detach__no_output_bus_lock(pInputBus, pOutputBus);
4034 ma_node_input_bus_lock(pInputBus);
4047 if (pNewNext !=
NULL) {
4051 ma_node_input_bus_unlock(pInputBus);
4057 ma_node_output_bus_set_is_attached(pOutputBus,
MA_TRUE);
4059 ma_node_output_bus_unlock(pOutputBus);
4068 if (pOutputBus ==
NULL) {
4072 ma_node_input_bus_next_begin(pInputBus);
4077 if (pNext ==
NULL) {
4081 if (ma_node_output_bus_is_attached(pNext) ==
MA_FALSE) {
4090 if (pNext !=
NULL) {
4097 ma_node_input_bus_next_end(pInputBus);
4104 return ma_node_input_bus_next(pInputBus, &pInputBus->
head);
4138 inputChannels = ma_node_input_bus_get_channels(pInputBus);
4148 pFirst = ma_node_input_bus_first(pInputBus);
4149 if (pFirst ==
NULL) {
4153 for (pOutputBus = pFirst; pOutputBus !=
NULL; pOutputBus = ma_node_input_bus_next(pInputBus, pOutputBus)) {
4158 if (pFramesOut !=
NULL) {
4162 float volume = ma_node_output_bus_get_volume(pOutputBus);
4164 while (framesProcessed < frameCount) {
4165 float* pRunningFramesOut;
4169 framesToRead = frameCount - framesProcessed;
4170 if (framesToRead > tempCapInFrames) {
4171 framesToRead = tempCapInFrames;
4176 if (pOutputBus == pFirst) {
4178 result = ma_node_read_pcm_frames(pOutputBus->
pNode, pOutputBus->
outputBusIndex, pRunningFramesOut, framesToRead, &framesJustRead, globalTime + framesProcessed);
4187 result = ma_node_read_pcm_frames(pOutputBus->
pNode, pOutputBus->
outputBusIndex, temp, framesToRead, &framesJustRead, globalTime + framesProcessed);
4194 ma_mix_pcm_frames_f32(pRunningFramesOut, temp, framesJustRead, inputChannels, 1);
4198 framesProcessed += framesJustRead;
4206 if (framesJustRead == 0) {
4212 if (pOutputBus == pFirst && framesProcessed < frameCount) {
4217 ma_node_read_pcm_frames(pOutputBus->
pNode, pOutputBus->
outputBusIndex,
NULL, frameCount, &framesProcessed, globalTime);
4222 *pFramesRead = frameCount;
4244 static float* ma_node_get_cached_input_ptr(
ma_node* pNode,
ma_uint32 inputBusIndex)
4254 for (iInputBus = 0; iInputBus < inputBusIndex; iInputBus += 1) {
4261 static float* ma_node_get_cached_output_ptr(
ma_node* pNode,
ma_uint32 outputBusIndex)
4276 for (iOutputBus = 0; iOutputBus < outputBusIndex; iOutputBus += 1) {
4287 size_t inputBusOffset;
4288 size_t outputBusOffset;
4289 size_t cachedDataOffset;
4292 } ma_node_heap_layout;
4348 *pInputBusCount = inputBusCount;
4349 *pOutputBusCount = outputBusCount;
4368 result = ma_node_translate_bus_counts(pConfig, &inputBusCount, &outputBusCount);
4373 pHeapLayout->sizeInBytes = 0;
4377 pHeapLayout->inputBusOffset = pHeapLayout->sizeInBytes;
4385 pHeapLayout->outputBusOffset = pHeapLayout->sizeInBytes;
4407 if (inputBusCount == 0 && outputBusCount == 1) {
4412 size_t cachedDataSizeInBytes = 0;
4415 MA_ASSERT(MA_DEFAULT_NODE_CACHE_CAP_IN_FRAMES_PER_BUS <= 0xFFFF);
4417 for (iBus = 0; iBus < inputBusCount; iBus += 1) {
4421 for (iBus = 0; iBus < outputBusCount; iBus += 1) {
4425 pHeapLayout->cachedDataOffset = pHeapLayout->sizeInBytes;
4426 pHeapLayout->sizeInBytes +=
ma_align_64(cachedDataSizeInBytes);
4434 pHeapLayout->inputBusCount = inputBusCount;
4435 pHeapLayout->outputBusCount = outputBusCount;
4443 ma_node_heap_layout heapLayout;
4445 if (pHeapSizeInBytes ==
NULL) {
4449 *pHeapSizeInBytes = 0;
4451 result = ma_node_get_heap_layout(pConfig, &heapLayout);
4456 *pHeapSizeInBytes = heapLayout.sizeInBytes;
4465 ma_node_heap_layout heapLayout;
4469 if (pNodeBase ==
NULL) {
4475 result = ma_node_get_heap_layout(pConfig, &heapLayout);
4480 pNodeBase->
_pHeap = pHeap;
4519 result = ma_node_output_bus_init(pNodeBase, iOutputBus, pConfig->
pOutputChannels[iOutputBus], &pNodeBase->
pOutputBuses[iOutputBus]);
4555 size_t heapSizeInBytes;
4563 if (heapSizeInBytes > 0) {
4564 pHeap =
ma_malloc(heapSizeInBytes, pAllocationCallbacks);
4565 if (pHeap ==
NULL) {
4574 ma_free(pHeap, pAllocationCallbacks);
4586 if (pNodeBase ==
NULL) {
4596 ma_node_detach_full(pNode);
4610 if (pNode ==
NULL) {
4619 if (pNode ==
NULL) {
4628 if (pNode ==
NULL) {
4640 if (pNode ==
NULL) {
4648 return ma_node_input_bus_get_channels(&pNodeBase->
pInputBuses[inputBusIndex]);
4655 if (pNode ==
NULL) {
4663 return ma_node_output_bus_get_channels(&pNodeBase->
pOutputBuses[outputBusIndex]);
4672 if (pNodeBase ==
NULL) {
4713 if (pNode ==
NULL) {
4722 ma_node_output_bus_lock(&pNodeBase->
pOutputBuses[outputBusIndex]);
4725 if (pInputNodeBase !=
NULL) {
4729 ma_node_output_bus_unlock(&pNodeBase->
pOutputBuses[outputBusIndex]);
4738 if (pNode ==
NULL) {
4754 if (pNodeBase ==
NULL || pOtherNodeBase ==
NULL) {
4758 if (pNodeBase == pOtherNodeBase) {
4772 ma_node_input_bus_attach(&pOtherNodeBase->
pInputBuses[otherNodeInputBusIndex], &pNodeBase->
pOutputBuses[outputBusIndex], pOtherNode, otherNodeInputBusIndex);
4781 if (pNodeBase ==
NULL) {
4789 return ma_node_output_bus_set_volume(&pNodeBase->
pOutputBuses[outputBusIndex], volume);
4796 if (pNodeBase ==
NULL) {
4804 return ma_node_output_bus_get_volume(&pNodeBase->
pOutputBuses[outputBusIndex]);
4811 if (pNodeBase ==
NULL) {
4824 if (pNodeBase ==
NULL) {
4833 if (pNode ==
NULL) {
4849 if (pNode ==
NULL) {
4863 if (pNode ==
NULL) {
4874 if (pNode ==
NULL) {
4904 if (pNode ==
NULL) {
4913 if (pNode ==
NULL) {
4924 static void ma_node_process_pcm_frames_internal(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
4931 pNodeBase->
vtable->
onProcess(pNode, ppFramesIn, pFrameCountIn, ppFramesOut, pFrameCountOut);
4961 if (pFramesRead ==
NULL) {
4967 if (pNodeBase ==
NULL) {
4981 globalTimeBeg = globalTime;
4982 globalTimeEnd = globalTime + frameCount;
4995 timeOffsetBeg = (globalTimeBeg < startTime) ? (
ma_uint32)(globalTimeEnd - startTime) : 0;
4996 timeOffsetEnd = (globalTimeEnd > stopTime) ? (
ma_uint32)(globalTimeEnd - stopTime) : 0;
4999 if (timeOffsetBeg > 0) {
5002 frameCount -= timeOffsetBeg;
5006 if (timeOffsetEnd > 0) {
5007 frameCount -= timeOffsetEnd;
5020 if (inputBusCount == 0 && outputBusCount == 1) {
5023 frameCountOut = frameCount;
5026 ppFramesOut[0] = pFramesOut;
5027 ma_node_process_pcm_frames_internal(pNode,
NULL, &frameCountIn, ppFramesOut, &frameCountOut);
5028 totalFramesRead = frameCountOut;
5037 MA_ASSERT(outputBusCount == inputBusCount);
5042 ppFramesOut[0] = pFramesOut;
5043 ppFramesIn[0] = ppFramesOut[0];
5045 result = ma_node_input_bus_read_pcm_frames(pNodeBase, &pNodeBase->
pInputBuses[0], ppFramesIn[0], frameCount, &totalFramesRead, globalTime);
5048 frameCountIn = totalFramesRead;
5049 frameCountOut = totalFramesRead;
5051 if (totalFramesRead > 0) {
5052 ma_node_process_pcm_frames_internal(pNode, (
const float**)ppFramesIn, &frameCountIn, ppFramesOut, &frameCountOut);
5059 MA_ASSERT(frameCountIn == totalFramesRead);
5060 MA_ASSERT(frameCountOut == totalFramesRead);
5087 framesToProcessOut = frameCount;
5092 framesToProcessIn = frameCount;
5102 MA_ASSERT(framesToProcessOut <= 0xFFFF);
5104 if (ma_node_output_bus_has_read(&pNodeBase->
pOutputBuses[outputBusIndex])) {
5113 for (iOutputBus = 0; iOutputBus < outputBusCount; iOutputBus += 1) {
5115 ppFramesOut[iOutputBus] = ma_node_get_cached_output_ptr(pNode, iOutputBus);
5123 for (iInputBus = 0; iInputBus < inputBusCount; iInputBus += 1) {
5127 ppFramesIn[iInputBus] = ma_node_get_cached_input_ptr(pNode, iInputBus);
5130 result = ma_node_input_bus_read_pcm_frames(pNodeBase, &pNodeBase->
pInputBuses[iInputBus], ppFramesIn[iInputBus], framesToProcessIn, &framesRead, globalTime);
5138 if (framesRead < framesToProcessIn) {
5142 maxFramesReadIn =
ma_max(maxFramesReadIn, framesRead);
5159 for (iInputBus = 0; iInputBus < inputBusCount; iInputBus += 1) {
5169 if (pFramesOut !=
NULL) {
5170 ppFramesOut[outputBusIndex] = pFramesOut;
5175 frameCountOut = framesToProcessOut;
5185 frameCountIn = framesToProcessIn;
5201 if (consumeNullInput) {
5202 ma_node_process_pcm_frames_internal(pNode,
NULL, &frameCountIn, ppFramesOut, &frameCountOut);
5216 ma_node_process_pcm_frames_internal(pNode, (
const float**)ppFramesIn, &frameCountIn, ppFramesOut, &frameCountOut);
5228 if (consumeNullInput ==
MA_FALSE) {
5240 if (pFramesOut !=
NULL) {
5256 *pFramesRead = totalFramesRead + timeOffsetBeg;
5270 config.pDataSource = pDataSource;
5271 config.looping = looping;
5277 static void ma_data_source_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
5292 (void)pFrameCountIn;
5294 frameCount = *pFrameCountOut;
5304 *pFrameCountOut = (
ma_uint32)framesRead;
5309 ma_data_source_node_process_pcm_frames,
5323 if (pDataSourceNode ==
NULL) {
5329 if (pConfig ==
NULL) {
5345 baseConfig.
vtable = &g_ma_data_source_node_vtable;
5360 result =
ma_node_init(pNodeGraph, &baseConfig, pAllocationCallbacks, &pDataSourceNode->
base);
5378 if (pDataSourceNode ==
NULL) {
5389 if (pDataSourceNode ==
NULL) {
5406 inputChannels[0] = channels;
5407 outputChannels[0] = channels;
5408 outputChannels[1] = channels;
5412 config.nodeConfig.pInputChannels = inputChannels;
5413 config.nodeConfig.pOutputChannels = outputChannels;
5419 static void ma_splitter_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
5430 (void)pFrameCountIn;
5443 ma_splitter_node_process_pcm_frames,
5455 if (pSplitterNode ==
NULL) {
5461 if (pConfig ==
NULL) {
5475 baseConfig.
vtable = &g_ma_splitter_node_vtable;
5477 result =
ma_node_init(pNodeGraph, &baseConfig, pAllocationCallbacks, &pSplitterNode->
base);
5494 #ifndef MA_RESOURCE_MANAGER_PAGE_SIZE_IN_MILLISECONDS
5495 #define MA_RESOURCE_MANAGER_PAGE_SIZE_IN_MILLISECONDS 1000
5504 for (i = 0; i < 32; i += 1) {
5505 if ((x & (1 << i)) != 0) {
5523 for (iSample = 0; iSample <
count; iSample += 1) {
5535 for (iSample = 0; iSample <
count; iSample += 1) {
5536 pDst[iSample] =
ma_clip_s16(pDst[iSample] + pSrc[iSample]);
5547 for (iSample = 0; iSample <
count; iSample += 1) {
5549 pDst[iSample*3 + 0] = (
ma_uint8)((s & 0x000000FF) >> 0);
5550 pDst[iSample*3 + 1] = (
ma_uint8)((s & 0x0000FF00) >> 8);
5551 pDst[iSample*3 + 2] = (
ma_uint8)((s & 0x00FF0000) >> 16);
5562 for (iSample = 0; iSample <
count; iSample += 1) {
5563 pDst[iSample] =
ma_clip_s32(pDst[iSample] + pSrc[iSample]);
5567 static void ma_accumulate_and_clip_f32(
float* pDst,
const float* pSrc,
ma_uint64 count)
5574 for (iSample = 0; iSample <
count; iSample += 1) {
5575 pDst[iSample] =
ma_clip_f32(pDst[iSample] + pSrc[iSample]);
5588 for (iSample = 0; iSample <
count; iSample += 1) {
5600 for (iSample = 0; iSample <
count; iSample += 1) {
5612 for (iSample = 0; iSample <
count; iSample += 1) {
5614 pDst[iSample*3 + 0] = (
ma_uint8)((s & 0x000000FF) >> 0);
5615 pDst[iSample*3 + 1] = (
ma_uint8)((s & 0x0000FF00) >> 8);
5616 pDst[iSample*3 + 2] = (
ma_uint8)((s & 0x00FF0000) >> 16);
5627 for (iSample = 0; iSample <
count; iSample += 1) {
5632 static void ma_clip_samples_f32_ex(
float* pDst,
const float* pSrc,
ma_uint64 count)
5639 for (iSample = 0; iSample <
count; iSample += 1) {
5654 volumeFixed = ma_float_to_fixed_16(volume);
5656 for (iSample = 0; iSample <
count; iSample += 1) {
5657 pDst[iSample] =
ma_clip_u8(ma_apply_volume_unclipped_u8(pSrc[iSample], volumeFixed));
5669 volumeFixed = ma_float_to_fixed_16(volume);
5671 for (iSample = 0; iSample <
count; iSample += 1) {
5672 pDst[iSample] =
ma_clip_s16(ma_apply_volume_unclipped_s16(pSrc[iSample], volumeFixed));
5684 volumeFixed = ma_float_to_fixed_16(volume);
5686 for (iSample = 0; iSample <
count; iSample += 1) {
5688 pDst[iSample*3 + 0] = (
ma_uint8)((s & 0x000000FF) >> 0);
5689 pDst[iSample*3 + 1] = (
ma_uint8)((s & 0x0000FF00) >> 8);
5690 pDst[iSample*3 + 2] = (
ma_uint8)((s & 0x00FF0000) >> 16);
5702 volumeFixed = ma_float_to_fixed_16(volume);
5704 for (iSample = 0; iSample <
count; iSample += 1) {
5705 pDst[iSample] =
ma_clip_s32(ma_apply_volume_unclipped_s32(pSrc[iSample], volumeFixed));
5709 static void ma_volume_and_clip_samples_f32(
float* pDst,
const float* pSrc,
ma_uint64 count,
float volume)
5718 for (iSample = 0; iSample <
count; iSample += 1) {
5719 pDst[iSample] =
ma_clip_f32(ma_apply_volume_unclipped_f32(pSrc[iSample], volume));
5730 sampleCount = frameCount * channels;
5737 case ma_format_f32: ma_clip_samples_f32_ex((
float*)pDst, (
const float*)pSrc, sampleCount);
break;
5746 static void ma_volume_and_clip_pcm_frames(
void* pDst,
const void* pSrc,
ma_uint64 frameCount,
ma_format format,
ma_uint32 channels,
float volume)
5752 ma_clip_pcm_frames(pDst, pSrc, frameCount, format, channels);
5753 }
else if (volume == 0) {
5756 ma_uint64 sampleCount = frameCount * channels;
5763 case ma_format_f32: ma_volume_and_clip_samples_f32((
float*)pDst, (
const float*)pSrc, sampleCount, volume);
break;
5783 for (iSample = 0; iSample < sampleCount; iSample += 1) {
5795 for (iSample = 0; iSample < sampleCount; iSample += 1) {
5807 for (iSample = 0; iSample < sampleCount; iSample += 1) {
5809 pDst[iSample*3 + 0] = (
ma_uint8)((s & 0x000000FF) >> 0);
5810 pDst[iSample*3 + 1] = (
ma_uint8)((s & 0x0000FF00) >> 8);
5811 pDst[iSample*3 + 2] = (
ma_uint8)((s & 0x00FF0000) >> 16);
5822 for (iSample = 0; iSample < sampleCount; iSample += 1) {
5827 static void ma_clipped_accumulate_f32(
float* pDst,
const float* pSrc,
ma_uint64 sampleCount)
5834 for (iSample = 0; iSample < sampleCount; iSample += 1) {
5835 pDst[iSample] =
ma_clip_f32(pDst[iSample] + pSrc[iSample]);
5839 static void ma_clipped_accumulate_pcm_frames(
void* pDst,
const void* pSrc,
ma_uint64 frameCount,
ma_format format,
ma_uint32 channels)
5846 sampleCount = frameCount * channels;
5853 case ma_format_f32: ma_clipped_accumulate_f32((
float*)pDst, (
const float*)pSrc, sampleCount);
break;
5873 for (iSample = 0; iSample < sampleCount; iSample += 1) {
5885 for (iSample = 0; iSample < sampleCount; iSample += 1) {
5897 for (iSample = 0; iSample < sampleCount; iSample += 1) {
5909 for (iSample = 0; iSample < sampleCount; iSample += 1) {
5914 static void ma_unclipped_accumulate_f32(
float* pDst,
const float* pSrc,
ma_uint64 sampleCount)
5921 for (iSample = 0; iSample < sampleCount; iSample += 1) {
5922 pDst[iSample] = pDst[iSample] + pSrc[iSample];
5926 static void ma_unclipped_accumulate_pcm_frames(
void* pDst,
const void* pSrc,
ma_uint64 frameCount,
ma_format format,
ma_uint32 channels)
5933 sampleCount = frameCount * channels;
5940 case ma_format_f32: ma_unclipped_accumulate_f32((
float*)pDst, (
const float*)pSrc, sampleCount);
break;
5961 volumeFixed = ma_float_to_fixed_16(volume);
5963 for (iSample = 0; iSample <
count; iSample += 1) {
5976 volumeFixed = ma_float_to_fixed_16(volume);
5978 for (iSample = 0; iSample <
count; iSample += 1) {
5979 pDst[iSample] =
ma_clip_s16(pDst[iSample] + ma_apply_volume_unclipped_s16(pSrc[iSample], volumeFixed));
5991 volumeFixed = ma_float_to_fixed_16(volume);
5993 for (iSample = 0; iSample <
count; iSample += 1) {
5995 pDst[iSample*3 + 0] = (
ma_uint8)((s & 0x000000FF) >> 0);
5996 pDst[iSample*3 + 1] = (
ma_uint8)((s & 0x0000FF00) >> 8);
5997 pDst[iSample*3 + 2] = (
ma_uint8)((s & 0x00FF0000) >> 16);
6009 volumeFixed = ma_float_to_fixed_16(volume);
6011 for (iSample = 0; iSample <
count; iSample += 1) {
6012 dst[iSample] =
ma_clip_s32(dst[iSample] + ma_apply_volume_unclipped_s32(src[iSample], volumeFixed));
6016 static void ma_volume_and_accumulate_and_clip_f32(
float* pDst,
const float* pSrc,
ma_uint64 count,
float volume)
6023 for (iSample = 0; iSample <
count; iSample += 1) {
6024 pDst[iSample] =
ma_clip_f32(pDst[iSample] + ma_apply_volume_unclipped_f32(pSrc[iSample], volume));
6032 if (pDst ==
NULL || pSrc ==
NULL) {
6046 sampleCount = frameCount * channels;
6051 case ma_format_u8: ma_accumulate_and_clip_u8( pDst, pSrc, sampleCount);
break;
6052 case ma_format_s16: ma_accumulate_and_clip_s16(pDst, pSrc, sampleCount);
break;
6053 case ma_format_s24: ma_accumulate_and_clip_s24(pDst, pSrc, sampleCount);
break;
6054 case ma_format_s32: ma_accumulate_and_clip_s32(pDst, pSrc, sampleCount);
break;
6055 case ma_format_f32: ma_accumulate_and_clip_f32(pDst, pSrc, sampleCount);
break;
6063 case ma_format_u8: ma_volume_and_accumulate_and_clip_u8( pDst, pSrc, sampleCount, volume);
break;
6064 case ma_format_s16: ma_volume_and_accumulate_and_clip_s16(pDst, pSrc, sampleCount, volume);
break;
6065 case ma_format_s24: ma_volume_and_accumulate_and_clip_s24(pDst, pSrc, sampleCount, volume);
break;
6066 case ma_format_s32: ma_volume_and_accumulate_and_clip_s32(pDst, pSrc, sampleCount, volume);
break;
6067 case ma_format_f32: ma_volume_and_accumulate_and_clip_f32(pDst, pSrc, sampleCount, volume);
break;
6087 volumeFixed = ma_float_to_fixed_16(volume);
6089 for (iSample = 0; iSample < sampleCount; iSample += 1) {
6090 pDst[iSample] += ma_apply_volume_unclipped_u8(pSrc[iSample], volumeFixed);
6102 volumeFixed = ma_float_to_fixed_16(volume);
6104 for (iSample = 0; iSample < sampleCount; iSample += 1) {
6105 pDst[iSample] += ma_apply_volume_unclipped_s16(pSrc[iSample], volumeFixed);
6117 volumeFixed = ma_float_to_fixed_16(volume);
6119 for (iSample = 0; iSample < sampleCount; iSample += 1) {
6120 pDst[iSample] += ma_apply_volume_unclipped_s24(pSrc[iSample], volumeFixed);
6132 volumeFixed = ma_float_to_fixed_16(volume);
6134 for (iSample = 0; iSample < sampleCount; iSample += 1) {
6135 pDst[iSample] += ma_apply_volume_unclipped_s32(pSrc[iSample], volumeFixed);
6139 static void ma_mix_accumulation_buffers_f32(
float* pDst,
const float* pSrc,
ma_uint64 sampleCount,
float volume)
6146 for (iSample = 0; iSample < sampleCount; iSample += 1) {
6147 pDst[iSample] += ma_apply_volume_unclipped_f32(pSrc[iSample], volume);
6151 static void ma_mix_accumulation_buffers(
void* pDst,
const void* pSrc,
ma_uint64 frameCount,
ma_format formatIn,
ma_uint32 channelsIn,
float volume)
6158 sampleCount = frameCount * channelsIn;
6166 case ma_format_f32: ma_mix_accumulation_buffers_f32((
float*)pDst, (
const float*)pSrc, sampleCount, volume);
break;
6173 if (formatOut == formatIn && channelsOut == channelsIn) {
6175 ma_mix_accumulation_buffers(pDst, pSrc, frameCount, formatIn, channelsIn, volume);
6181 void* pRunningDst = pDst;
6182 const void* pRunningSrc = pSrc;
6184 while (totalFramesProcessed < frameCount) {
6185 ma_uint64 framesToProcess = frameCount - totalFramesProcessed;
6186 if (framesToProcess > clippedSrcBufferCapInFrames) {
6187 framesToProcess = clippedSrcBufferCapInFrames;
6191 ma_volume_and_clip_pcm_frames(clippedSrcBuffer, pRunningSrc, framesToProcess, formatIn, channelsIn, volume);
6194 ma_mix_pcm_frames_ex(pRunningDst, formatOut, channelsOut, clippedSrcBuffer, formatIn, channelsIn, framesToProcess, 1);
6196 totalFramesProcessed += framesToProcess;
6209 if (pAllocator ==
NULL) {
6224 if (pAllocator ==
NULL || pSlot ==
NULL) {
6230 for (iAttempt = 0; iAttempt < maxAttempts; iAttempt += 1) {
6243 if (oldBitfield == 0xFFFFFFFF) {
6247 bitOffset = ma_ffs_32(~oldBitfield);
6250 newBitfield = oldBitfield | (1 << bitOffset);
6259 slotIndex = (iGroup << 5) + bitOffset;
6262 pAllocator->
slots[slotIndex] += 1;
6265 *pSlot = ((
ma_uint64)pAllocator->
slots[slotIndex] << 32 | slotIndex);
6273 if (pAllocator->
count < capacity) {
6289 if (pAllocator ==
NULL) {
6293 iGroup = (slot & 0xFFFFFFFF) >> 5;
6294 iBit = (slot & 0xFFFFFFFF) & 31;
6302 while (pAllocator->
count > 0) {
6308 newBitfield = oldBitfield & ~(1 << iBit);
6322 #define MA_FENCE_COUNTER_MAX 0x7FFFFFFF
6328 if (pFence ==
NULL) {
6345 if (pFence ==
NULL) {
6356 if (pFence ==
NULL) {
6365 if (newCounter > MA_FENCE_COUNTER_MAX) {
6373 if (oldCounter == MA_FENCE_COUNTER_MAX) {
6386 if (pFence ==
NULL) {
6394 if (oldCounter == 0) {
6400 if (newCounter == 0) {
6406 if (oldCounter == 0) {
6419 if (pFence ==
NULL) {
6453 if (pNotification ==
NULL) {
6461 pNotificationCallbacks->
onSignal(pNotification);
6473 if (pNotificationPoll ==
NULL) {
6477 pNotificationPoll->
cb.
onSignal = ma_async_notification_poll__on_signal;
6485 if (pNotificationPoll ==
NULL) {
6502 if (pNotificationEvent ==
NULL) {
6506 pNotificationEvent->
cb.
onSignal = ma_async_notification_event__on_signal;
6518 if (pNotificationEvent ==
NULL) {
6528 if (pNotificationEvent ==
NULL) {
6537 if (pNotificationEvent ==
NULL) {
6552 return notifications;
6557 if (pPipelineNotifications ==
NULL) {
6567 if (pPipelineNotifications ==
NULL) {
6577 if (pPipelineNotifications ==
NULL) {
6587 #define MA_JOB_ID_NONE ~((ma_uint64)0)
6588 #define MA_JOB_SLOT_NONE (ma_uint16)(~0)
6602 return (
ma_uint16)((toc & 0xFFFF0000) >> 16);
6607 return ((
ma_uint64)ma_job_extract_refcount(toc) << 32) | (
ma_uint64)ma_job_extract_slot(toc);
6618 job.
next = MA_JOB_ID_NONE;
6629 if (pQueue ==
NULL) {
6634 pQueue->
flags = flags;
6648 pQueue->
jobs[ma_job_extract_slot(pQueue->
head)].
next = MA_JOB_ID_NONE;
6656 if (pQueue ==
NULL) {
6675 if (pQueue ==
NULL || pJob ==
NULL) {
6689 pQueue->
jobs[ma_job_extract_slot(slot)] = *pJob;
6692 pQueue->
jobs[ma_job_extract_slot(slot)].
next = MA_JOB_ID_NONE;
6696 tail = pQueue->
tail;
6697 next = pQueue->
jobs[ma_job_extract_slot(tail)].
next;
6699 if (ma_job_toc_to_allocation(tail) == ma_job_toc_to_allocation(pQueue->
tail)) {
6700 if (ma_job_extract_slot(next) == 0xFFFF) {
6726 if (pQueue ==
NULL || pJob ==
NULL) {
6737 head = pQueue->
head;
6738 tail = pQueue->
tail;
6739 next = pQueue->
jobs[ma_job_extract_slot(head)].
next;
6741 if (ma_job_toc_to_allocation(head) == ma_job_toc_to_allocation(pQueue->
head)) {
6742 if (ma_job_toc_to_allocation(head) == ma_job_toc_to_allocation(tail)) {
6743 if (ma_job_extract_slot(next) == 0xFFFF) {
6748 *pJob = pQueue->
jobs[ma_job_extract_slot(next)];
6773 if (pQueue ==
NULL || pJob ==
NULL) {
6784 #ifndef MA_DEFAULT_HASH_SEED
6785 #define MA_DEFAULT_HASH_SEED 42
6789 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
6790 #pragma GCC diagnostic push
6791 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
6796 return (x << r) | (x >> (32 - r));
6824 const int nblocks = len / 4;
6831 blocks = (
const ma_uint32 *)(data + nblocks*4);
6833 for(i = -nblocks; i; i++) {
6834 k1 = ma_hash_getblock(blocks,i);
6837 k1 = ma_rotl32(k1, 15);
6841 h1 = ma_rotl32(h1, 13);
6842 h1 = h1*5 + 0xe6546b64;
6846 tail = (
const ma_uint8*)(data + nblocks*4);
6850 case 3: k1 ^= tail[2] << 16;
6851 case 2: k1 ^= tail[1] << 8;
6852 case 1: k1 ^= tail[0];
6853 k1 *= c1; k1 = ma_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
6858 h1 = ma_hash_fmix32(h1);
6863 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
6864 #pragma GCC diagnostic push
6868 static ma_uint32 ma_hash_string_32(
const char* str)
6870 return ma_hash_32(str, (
int)strlen(str), MA_DEFAULT_HASH_SEED);
6873 static ma_uint32 ma_hash_string_w_32(
const wchar_t* str)
6875 return ma_hash_32(str, (
int)wcslen(str) *
sizeof(*str), MA_DEFAULT_HASH_SEED);
6892 while (pCurrentNode !=
NULL) {
6895 }
else if (hashedName32 < pCurrentNode->hashedName32) {
6896 pCurrentNode = pCurrentNode->
pChildLo;
6898 pCurrentNode = pCurrentNode->
pChildHi;
6902 *ppDataBufferNode = pCurrentNode;
6904 if (pCurrentNode ==
NULL) {
6919 *ppInsertPoint =
NULL;
6927 while (pCurrentNode !=
NULL) {
6932 if (hashedName32 < pCurrentNode->hashedName32) {
6937 pCurrentNode = pCurrentNode->
pChildLo;
6944 pCurrentNode = pCurrentNode->
pChildHi;
6950 *ppInsertPoint = pCurrentNode;
6962 if (pInsertPoint ==
NULL) {
6969 pInsertPoint->
pChildLo = pDataBufferNode;
6972 pInsertPoint->
pChildHi = pDataBufferNode;
6976 pDataBufferNode->
pParent = pInsertPoint;
6990 result = ma_resource_manager_data_buffer_node_insert_point(pResourceManager, pDataBufferNode->
hashedName32, &pInsertPoint);
6995 return ma_resource_manager_data_buffer_node_insert_at(pResourceManager, pDataBufferNode, pInsertPoint);
7005 pCurrentNode = pDataBufferNode;
7007 pCurrentNode = pCurrentNode->
pChildLo;
7010 return pCurrentNode;
7019 pCurrentNode = pDataBufferNode;
7021 pCurrentNode = pCurrentNode->
pChildHi;
7024 return pCurrentNode;
7032 return ma_resource_manager_data_buffer_node_find_min(pDataBufferNode->
pChildHi);
7040 return ma_resource_manager_data_buffer_node_find_max(pDataBufferNode->
pChildLo);
7096 pReplacementDataBufferNode = ma_resource_manager_data_buffer_node_find_inorder_successor(pDataBufferNode);
7109 if (pReplacementDataBufferNode->
pParent->
pChildLo == pReplacementDataBufferNode) {
7116 if (pReplacementDataBufferNode->
pParent->
pChildLo == pReplacementDataBufferNode) {
7140 pReplacementDataBufferNode->
pChildLo->
pParent = pReplacementDataBufferNode;
7143 pReplacementDataBufferNode->
pChildHi->
pParent = pReplacementDataBufferNode;
7162 result = ma_resource_manager_data_buffer_search(pResourceManager, hashedName32, &pDataBufferNode);
7167 return ma_resource_manager_data_buffer_remove(pResourceManager, pDataBufferNode);
7188 (void)pResourceManager;
7192 if (pNewRefCount !=
NULL) {
7193 *pNewRefCount = refCount;
7206 (void)pResourceManager;
7210 if (pNewRefCount !=
NULL) {
7211 *pNewRefCount = refCount;
7230 pDataBufferNode->
data.
decoded.totalFrameCount = 0;
7267 } ma_resource_manager_inline_notification;
7269 static ma_result ma_resource_manager_inline_notification_init(
ma_resource_manager* pResourceManager, ma_resource_manager_inline_notification* pNotification)
7274 pNotification->pResourceManager = pResourceManager;
7276 if (ma_resource_manager_is_threading_enabled(pResourceManager)) {
7283 static void ma_resource_manager_inline_notification_uninit(ma_resource_manager_inline_notification* pNotification)
7287 if (ma_resource_manager_is_threading_enabled(pNotification->pResourceManager)) {
7294 static void ma_resource_manager_inline_notification_wait(ma_resource_manager_inline_notification* pNotification)
7298 if (ma_resource_manager_is_threading_enabled(pNotification->pResourceManager)) {
7310 static void ma_resource_manager_inline_notification_wait_and_uninit(ma_resource_manager_inline_notification* pNotification)
7312 ma_resource_manager_inline_notification_wait(pNotification);
7313 ma_resource_manager_inline_notification_uninit(pNotification);
7317 static void ma_resource_manager_data_buffer_bst_lock(
ma_resource_manager* pResourceManager)
7321 if (ma_resource_manager_is_threading_enabled(pResourceManager)) {
7328 static void ma_resource_manager_data_buffer_bst_unlock(
ma_resource_manager* pResourceManager)
7332 if (ma_resource_manager_is_threading_enabled(pResourceManager)) {
7371 config.decodedChannels = 0;
7372 config.decodedSampleRate = 0;
7373 config.jobThreadCount = 1;
7385 if (pResourceManager ==
NULL) {
7391 if (pConfig ==
NULL) {
7399 pResourceManager->
config = *pConfig;
7466 if (ma_resource_manager_is_threading_enabled(pResourceManager)) {
7489 static void ma_resource_manager_delete_all_data_buffer_nodes(
ma_resource_manager* pResourceManager)
7496 ma_resource_manager_data_buffer_node_remove(pResourceManager, pDataBufferNode);
7499 ma_resource_manager_data_buffer_node_free(pResourceManager, pDataBufferNode);
7507 if (pResourceManager ==
NULL) {
7518 if (ma_resource_manager_is_threading_enabled(pResourceManager)) {
7525 ma_resource_manager_delete_all_data_buffer_nodes(pResourceManager);
7531 if (ma_resource_manager_is_threading_enabled(pResourceManager)) {
7537 if (pResourceManager->
config.
pLog == &pResourceManager->
log) {
7544 if (pResourceManager ==
NULL) {
7574 config = ma_resource_manager__init_decoder_config(pResourceManager);
7576 if (pFilePath !=
NULL) {
7601 result = ma_resource_manager_data_buffer_node_result(pDataBuffer->
pNode);
7611 switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->
pNode))
7649 if (pInitNotification !=
NULL) {
7653 if (pInitFence !=
NULL) {
7667 switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->
pNode))
7721 size_t dataSizeInBytes;
7730 if (pFilePath !=
NULL) {
7740 pDataBufferNode->
data.
encoded.sizeInBytes = dataSizeInBytes;
7760 if (pDecoder ==
NULL) {
7764 result = ma_resource_manager__init_decoder(pResourceManager, pFilePath, pFilePathW, pDecoder);
7777 if (totalFrameCount > 0) {
7790 if (pData ==
NULL) {
7801 pDataBufferNode->
data.
decoded.totalFrameCount = totalFrameCount;
7805 pDataBufferNode->
data.
decoded.decodedFrameCount = 0;
7825 *ppDecoder = pDecoder;
7842 pageSizeInFrames = MA_RESOURCE_MANAGER_PAGE_SIZE_IN_MILLISECONDS * (pDecoder->
outputSampleRate/1000);
7843 framesToTryReading = pageSizeInFrames;
7851 switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBufferNode))
7858 if (framesToTryReading > framesRemaining) {
7859 framesToTryReading = framesRemaining;
7869 if (framesRead > 0) {
7870 pDataBufferNode->
data.
decoded.decodedFrameCount += framesRead;
7885 if (framesRead > 0) {
7913 if (result ==
MA_SUCCESS && framesRead == 0) {
7925 ma_resource_manager_inline_notification initNotification;
7927 if (ppDataBufferNode !=
NULL) {
7928 *ppDataBufferNode =
NULL;
7931 if (pResourceManager ==
NULL || (pFilePath ==
NULL && pFilePathW ==
NULL && hashedName32 == 0)) {
7941 if (ma_resource_manager_is_threading_enabled(pResourceManager) ==
MA_FALSE) {
7945 if (hashedName32 == 0) {
7946 if (pFilePath !=
NULL) {
7947 hashedName32 = ma_hash_string_32(pFilePath);
7949 hashedName32 = ma_hash_string_w_32(pFilePathW);
7960 ma_resource_manager_data_buffer_bst_lock(pResourceManager);
7964 result = ma_resource_manager_data_buffer_node_insert_point(pResourceManager, hashedName32, &pInsertPoint);
7967 pDataBufferNode = pInsertPoint;
7969 result = ma_resource_manager_data_buffer_node_increment_ref(pResourceManager, pDataBufferNode,
NULL);
7982 if (pDataBufferNode ==
NULL) {
7991 if (pExistingData ==
NULL) {
7996 pDataBufferNode->
data = *pExistingData;
8001 result = ma_resource_manager_data_buffer_node_insert_at(pResourceManager, pDataBufferNode, pInsertPoint);
8015 char* pFilePathCopy =
NULL;
8016 wchar_t* pFilePathWCopy =
NULL;
8019 if (pFilePath !=
NULL) {
8025 if (pFilePathCopy ==
NULL && pFilePathWCopy ==
NULL) {
8031 ma_resource_manager_inline_notification_init(pResourceManager, &initNotification);
8040 job.
order = ma_resource_manager_data_buffer_node_next_execution_order(pDataBufferNode);
8069 ma_resource_manager_data_buffer_bst_unlock(pResourceManager);
8082 if (nodeAlreadyExists ==
MA_FALSE) {
8083 if (pFilePath ==
NULL && pFilePathW ==
NULL) {
8099 result = ma_resource_manager_data_buffer_node_init_supply_encoded(pResourceManager, pDataBufferNode, pFilePath, pFilePathW);
8106 result = ma_resource_manager_data_buffer_node_init_supply_decoded(pResourceManager, pDataBufferNode, pFilePath, pFilePathW, &pDecoder);
8114 result = ma_resource_manager_data_buffer_node_decode_next_page(pResourceManager, pDataBufferNode, pDecoder);
8138 ma_resource_manager_inline_notification_wait(&initNotification);
8150 if (nodeAlreadyExists ==
MA_FALSE) {
8151 ma_resource_manager_data_buffer_node_remove(pResourceManager, pDataBufferNode);
8162 ma_resource_manager_inline_notification_uninit(&initNotification);
8166 if (ppDataBufferNode !=
NULL) {
8167 *ppDataBufferNode = pDataBufferNode;
8179 if (pResourceManager ==
NULL) {
8183 if (pDataBufferNode ==
NULL) {
8184 if (pName ==
NULL && pNameW ==
NULL) {
8188 if (pName !=
NULL) {
8189 hashedName32 = ma_hash_string_32(pName);
8191 hashedName32 = ma_hash_string_w_32(pNameW);
8200 ma_resource_manager_data_buffer_bst_lock(pResourceManager);
8203 if (pDataBufferNode ==
NULL) {
8204 result = ma_resource_manager_data_buffer_node_search(pResourceManager, hashedName32, &pDataBufferNode);
8210 result = ma_resource_manager_data_buffer_node_decrement_ref(pResourceManager, pDataBufferNode, &refCount);
8215 if (refCount == 0) {
8216 result = ma_resource_manager_data_buffer_node_remove(pResourceManager, pDataBufferNode);
8222 ma_resource_manager_data_buffer_bst_unlock(pResourceManager);
8233 if (refCount == 0) {
8234 if (ma_resource_manager_data_buffer_node_result(pDataBufferNode) ==
MA_BUSY) {
8242 job.
order = ma_resource_manager_data_buffer_node_next_execution_order(pDataBufferNode);
8252 if (ma_resource_manager_is_threading_enabled(pResourceManager) ==
MA_FALSE) {
8253 while (ma_resource_manager_data_buffer_node_result(pDataBufferNode) ==
MA_BUSY) {
8265 ma_resource_manager_data_buffer_node_free(pResourceManager, pDataBufferNode);
8307 ma_resource_manager_data_buffer_cb__read_pcm_frames,
8308 ma_resource_manager_data_buffer_cb__seek_to_pcm_frame,
8311 ma_resource_manager_data_buffer_cb__get_data_format,
8312 ma_resource_manager_data_buffer_cb__get_cursor_in_pcm_frames,
8313 ma_resource_manager_data_buffer_cb__get_length_in_pcm_frames
8324 if (pNotifications !=
NULL) {
8325 notifications = *pNotifications;
8326 pNotifications =
NULL;
8331 if (pDataBuffer ==
NULL) {
8332 ma_pipeline_notifications_signal_all_notifications(¬ifications);
8339 if (ma_resource_manager_is_threading_enabled(pResourceManager) ==
MA_FALSE) {
8357 ma_pipeline_notifications_acquire_all_fences(¬ifications);
8360 result = ma_resource_manager_data_buffer_node_acquire(pResourceManager, pFilePath, pFilePathW, hashedName32, flags,
NULL, notifications.
init.
pFence, notifications.
done.
pFence, &pDataBufferNode);
8362 ma_pipeline_notifications_signal_all_notifications(¬ifications);
8367 dataSourceConfig.
vtable = &g_ma_resource_manager_data_buffer_vtable;
8371 ma_resource_manager_data_buffer_node_unacquire(pResourceManager, pDataBufferNode,
NULL,
NULL);
8372 ma_pipeline_notifications_signal_all_notifications(¬ifications);
8377 pDataBuffer->
pNode = pDataBufferNode;
8378 pDataBuffer->
flags = flags;
8382 if (async ==
MA_FALSE || ma_resource_manager_data_buffer_node_result(pDataBufferNode) ==
MA_SUCCESS) {
8384 result = ma_resource_manager_data_buffer_init_connector(pDataBuffer,
NULL,
NULL);
8387 ma_pipeline_notifications_signal_all_notifications(¬ifications);
8392 ma_resource_manager_inline_notification initNotification;
8395 ma_resource_manager_inline_notification_init(pResourceManager, &initNotification);
8406 ma_pipeline_notifications_acquire_all_fences(¬ifications);
8409 job.
order = ma_resource_manager_data_buffer_next_execution_order(pDataBuffer);
8423 ma_pipeline_notifications_release_all_fences(¬ifications);
8426 ma_resource_manager_inline_notification_wait(&initNotification);
8443 ma_resource_manager_inline_notification_uninit(&initNotification);
8448 ma_resource_manager_data_buffer_node_unacquire(pResourceManager, pDataBufferNode,
NULL,
NULL);
8453 ma_pipeline_notifications_release_all_fences(¬ifications);
8460 return ma_resource_manager_data_buffer_init_internal(pResourceManager, pFilePath,
NULL, 0, flags, pNotifications, pDataBuffer);
8465 return ma_resource_manager_data_buffer_init_internal(pResourceManager,
NULL, pFilePath, 0, flags, pNotifications, pDataBuffer);
8470 if (pExistingDataBuffer ==
NULL) {
8476 return ma_resource_manager_data_buffer_init_internal(pResourceManager,
NULL,
NULL, pExistingDataBuffer->
pNode->
hashedName32, pExistingDataBuffer->
flags,
NULL, pDataBuffer);
8484 ma_resource_manager_data_buffer_uninit_connector(pDataBuffer->
pResourceManager, pDataBuffer);
8499 if (pDataBuffer ==
NULL) {
8505 return ma_resource_manager_data_buffer_uninit_internal(pDataBuffer);
8512 ma_resource_manager_inline_notification notification;
8521 result = ma_resource_manager_inline_notification_init(pDataBuffer->
pResourceManager, ¬ification);
8527 job.
order = ma_resource_manager_data_buffer_next_execution_order(pDataBuffer);
8534 ma_resource_manager_inline_notification_uninit(¬ification);
8538 ma_resource_manager_inline_notification_wait_and_uninit(¬ification);
8552 if (pFramesRead !=
NULL) {
8588 isDecodedBufferBusy = (ma_resource_manager_data_buffer_node_result(pDataBuffer->
pNode) ==
MA_BUSY);
8592 if (frameCount > availableFrames) {
8593 frameCount = availableFrames;
8602 if (frameCount == 0) {
8612 if (frameCount > 0) {
8613 result =
ma_data_source_read_pcm_frames(ma_resource_manager_data_buffer_get_connector(pDataBuffer), pFramesOut, frameCount, &framesRead, isLooping);
8621 if (ma_resource_manager_data_buffer_node_result(pDataBuffer->
pNode) ==
MA_BUSY) {
8626 if (isDecodedBufferBusy) {
8630 if (pFramesRead !=
NULL) {
8631 *pFramesRead = framesRead;
8667 switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->
pNode))
8708 if (pDataBuffer ==
NULL || pCursor ==
NULL) {
8714 switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->
pNode))
8748 if (pDataBuffer ==
NULL || pLength ==
NULL) {
8761 if (pDataBuffer ==
NULL) {
8770 if (pDataBuffer ==
NULL) {
8781 if (pIsLooping ==
NULL) {
8787 if (pDataBuffer ==
NULL) {
8798 if (pAvailableFrames ==
NULL) {
8802 *pAvailableFrames = 0;
8804 if (pDataBuffer ==
NULL) {
8809 if (ma_resource_manager_data_buffer_node_result(pDataBuffer->
pNode) ==
MA_BUSY) {
8816 switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->
pNode))
8836 *pAvailableFrames = 0;
8853 return ma_resource_manager_data_buffer_node_acquire(pResourceManager, pFilePath,
NULL, 0, flags,
NULL,
NULL,
NULL,
NULL);
8858 return ma_resource_manager_data_buffer_node_acquire(pResourceManager,
NULL, pFilePath, 0, flags,
NULL,
NULL,
NULL,
NULL);
8864 return ma_resource_manager_data_buffer_node_acquire(pResourceManager, pName, pNameW, 0, 0, pExistingData,
NULL,
NULL,
NULL);
8872 data.
decoded.totalFrameCount = frameCount;
8874 data.
decoded.channels = channels;
8875 data.
decoded.sampleRate = sampleRate;
8877 return ma_resource_manager_register_data(pResourceManager, pName, pNameW, &data);
8882 return ma_resource_manager_register_decoded_data_internal(pResourceManager, pName,
NULL, pData, frameCount, format, channels, sampleRate);
8887 return ma_resource_manager_register_decoded_data_internal(pResourceManager,
NULL, pName, pData, frameCount, format, channels, sampleRate);
8891 static ma_result ma_resource_manager_register_encoded_data_internal(
ma_resource_manager* pResourceManager,
const char* pName,
const wchar_t* pNameW,
const void* pData,
size_t sizeInBytes)
8896 data.
encoded.sizeInBytes = sizeInBytes;
8898 return ma_resource_manager_register_data(pResourceManager, pName, pNameW, &data);
8903 return ma_resource_manager_register_encoded_data_internal(pResourceManager, pName,
NULL, pData, sizeInBytes);
8908 return ma_resource_manager_register_encoded_data_internal(pResourceManager,
NULL, pName, pData, sizeInBytes);
8924 return ma_resource_manager_data_buffer_node_unacquire(pResourceManager,
NULL, pName,
NULL);
8929 return ma_resource_manager_data_buffer_node_unacquire(pResourceManager,
NULL,
NULL, pName);
8989 ma_resource_manager_data_stream_cb__read_pcm_frames,
8990 ma_resource_manager_data_stream_cb__seek_to_pcm_frame,
8991 ma_resource_manager_data_stream_cb__map,
8992 ma_resource_manager_data_stream_cb__unmap,
8993 ma_resource_manager_data_stream_cb__get_data_format,
8994 ma_resource_manager_data_stream_cb__get_cursor_in_pcm_frames,
8995 ma_resource_manager_data_stream_cb__get_length_in_pcm_frames
9002 char* pFilePathCopy =
NULL;
9003 wchar_t* pFilePathWCopy =
NULL;
9006 ma_resource_manager_inline_notification waitNotification;
9009 if (pNotifications !=
NULL) {
9010 notifications = *pNotifications;
9011 pNotifications =
NULL;
9016 if (pDataStream ==
NULL) {
9017 ma_pipeline_notifications_signal_all_notifications(¬ifications);
9024 dataSourceConfig.
vtable = &g_ma_resource_manager_data_stream_vtable;
9028 ma_pipeline_notifications_signal_all_notifications(¬ifications);
9033 pDataStream->
flags = flags;
9036 if (pResourceManager ==
NULL || (pFilePath ==
NULL && pFilePathW ==
NULL)) {
9037 ma_pipeline_notifications_signal_all_notifications(¬ifications);
9044 if (pFilePath !=
NULL) {
9050 if (pFilePathCopy ==
NULL && pFilePathWCopy ==
NULL) {
9051 ma_pipeline_notifications_signal_all_notifications(¬ifications);
9060 waitBeforeReturning =
MA_TRUE;
9061 ma_resource_manager_inline_notification_init(pResourceManager, &waitNotification);
9064 ma_pipeline_notifications_acquire_all_fences(¬ifications);
9068 job.
order = ma_resource_manager_data_stream_next_execution_order(pDataStream);
9076 ma_pipeline_notifications_signal_all_notifications(¬ifications);
9077 ma_pipeline_notifications_release_all_fences(¬ifications);
9079 if (waitBeforeReturning) {
9080 ma_resource_manager_inline_notification_uninit(&waitNotification);
9089 if (waitBeforeReturning) {
9090 ma_resource_manager_inline_notification_wait_and_uninit(&waitNotification);
9104 return ma_resource_manager_data_stream_init_internal(pResourceManager, pFilePath,
NULL, flags, pNotifications, pDataStream);
9109 return ma_resource_manager_data_stream_init_internal(pResourceManager,
NULL, pFilePath, flags, pNotifications, pDataStream);
9114 ma_resource_manager_inline_notification freeEvent;
9117 if (pDataStream ==
NULL) {
9128 ma_resource_manager_inline_notification_init(pDataStream->
pResourceManager, &freeEvent);
9131 job.
order = ma_resource_manager_data_stream_next_execution_order(pDataStream);
9138 ma_resource_manager_inline_notification_wait_and_uninit(&freeEvent);
9156 MA_ASSERT(pageIndex == 0 || pageIndex == 1);
9165 ma_uint64 totalFramesReadForThisPage = 0;
9166 void* pPageData = ma_resource_manager_data_stream_get_page_data_pointer(pDataStream, pageIndex, 0);
9168 pageSizeInFrames = ma_resource_manager_data_stream_get_page_size_in_frames(pDataStream);
9173 while (totalFramesReadForThisPage < pageSizeInFrames) {
9177 framesRemaining = pageSizeInFrames - totalFramesReadForThisPage;
9179 totalFramesReadForThisPage += framesRead;
9182 if (framesRead < framesRemaining) {
9194 if (totalFramesReadForThisPage < pageSizeInFrames) {
9208 for (iPage = 0; iPage < 2; iPage += 1) {
9209 ma_resource_manager_data_stream_fill_page(pDataStream, iPage);
9221 if (pFramesRead !=
NULL) {
9228 if (pDataStream ==
NULL) {
9237 if (ma_resource_manager_data_stream_seek_counter(pDataStream) > 0) {
9244 totalFramesProcessed = 0;
9245 while (totalFramesProcessed < frameCount) {
9246 void* pMappedFrames;
9249 mappedFrameCount = frameCount - totalFramesProcessed;
9256 if (pFramesOut !=
NULL) {
9260 totalFramesProcessed += mappedFrameCount;
9268 if (pFramesRead !=
NULL) {
9269 *pFramesRead = totalFramesProcessed;
9283 if (pFrameCount !=
NULL) {
9284 frameCount = *pFrameCount;
9287 if (ppFramesOut !=
NULL) {
9288 *ppFramesOut =
NULL;
9291 if (pDataStream ==
NULL || ppFramesOut ==
NULL || pFrameCount ==
NULL) {
9300 if (ma_resource_manager_data_stream_seek_counter(pDataStream) > 0) {
9306 framesAvailable = 0;
9315 framesAvailable = currentPageFrameCount - pDataStream->
relativeCursor;
9319 if (framesAvailable == 0) {
9320 if (ma_resource_manager_data_stream_is_decoder_at_end(pDataStream)) {
9329 if (frameCount > framesAvailable) {
9330 frameCount = framesAvailable;
9334 *pFrameCount = frameCount;
9358 if (pDataStream ==
NULL) {
9367 if (frameCount > 0xFFFFFFFF) {
9371 pageSizeInFrames = ma_resource_manager_data_stream_get_page_size_in_frames(pDataStream);
9380 if (newRelativeCursor >= pageSizeInFrames) {
9381 newRelativeCursor -= pageSizeInFrames;
9385 job.
order = ma_resource_manager_data_stream_next_execution_order(pDataStream);
9413 if (pDataStream ==
NULL) {
9425 ma_resource_manager_data_stream_set_absolute_cursor(pDataStream, frameIndex);
9445 job.
order = ma_resource_manager_data_stream_next_execution_order(pDataStream);
9456 if (pFormat !=
NULL) {
9460 if (pChannels !=
NULL) {
9464 if (pSampleRate !=
NULL) {
9468 if (pDataStream ==
NULL) {
9485 if (pCursor ==
NULL) {
9494 if (pDataStream ==
NULL) {
9511 if (pLength ==
NULL) {
9522 if (pDataStream ==
NULL) {
9527 return streamResult;
9535 if (*pLength == 0) {
9544 if (pDataStream ==
NULL) {
9553 if (pDataStream ==
NULL) {
9564 if (pIsLooping ==
NULL) {
9570 if (pDataStream ==
NULL) {
9586 if (pAvailableFrames ==
NULL) {
9590 *pAvailableFrames = 0;
9592 if (pDataStream ==
NULL) {
9600 availableFrames = 0;
9608 *pAvailableFrames = availableFrames;
9615 if (pDataSource ==
NULL) {
9621 if (pResourceManager ==
NULL) {
9625 pDataSource->
flags = flags;
9634 result = ma_resource_manager_data_source_preinit(pResourceManager, flags, pDataSource);
9651 result = ma_resource_manager_data_source_preinit(pResourceManager, flags, pDataSource);
9668 if (pExistingDataSource ==
NULL) {
9672 result = ma_resource_manager_data_source_preinit(pResourceManager, pExistingDataSource->
flags, pDataSource);
9687 if (pDataSource ==
NULL) {
9702 if (pFramesRead !=
NULL) {
9706 if (pDataSource ==
NULL) {
9719 if (pDataSource ==
NULL) {
9732 if (pDataSource ==
NULL) {
9745 if (pDataSource ==
NULL) {
9758 if (pDataSource ==
NULL) {
9771 if (pDataSource ==
NULL) {
9784 if (pDataSource ==
NULL) {
9797 if (pDataSource ==
NULL) {
9810 if (pDataSource ==
NULL) {
9823 if (pDataSource ==
NULL || pIsLooping ==
NULL) {
9836 if (pAvailableFrames ==
NULL) {
9840 *pAvailableFrames = 0;
9842 if (pDataSource ==
NULL) {
9856 if (pResourceManager ==
NULL) {
9871 if (pResourceManager ==
NULL) {
9890 result = ma_resource_manager_data_buffer_node_result(pJob->
loadDataBufferNode.pDataBufferNode);
9924 ma_job pageDataBufferNodeJob;
9957 pageDataBufferNodeJob.
order = ma_resource_manager_data_buffer_node_next_execution_order(pJob->
loadDataBufferNode.pDataBufferNode);
10032 ma_resource_manager_data_buffer_node_free(pResourceManager, pJob->
freeDataBufferNode.pDataBufferNode);
10056 result = ma_resource_manager_data_buffer_node_result(pJob->
pageDataBufferNode.pDataBufferNode);
10074 newJob.
order = ma_resource_manager_data_buffer_node_next_execution_order(pJob->
pageDataBufferNode.pDataBufferNode);
10158 result = ma_resource_manager_data_buffer_node_result(pJob->
loadDataBuffer.pDataBuffer->pNode);
10202 ma_resource_manager_data_buffer_uninit_internal(pJob->
freeDataBuffer.pDataBuffer);
10271 ma_resource_manager_data_stream_fill_pages(pDataStream);
10356 ma_resource_manager_data_stream_fill_page(pDataStream, pJob->
pageDataStream.pageIndex);
10391 ma_resource_manager_data_stream_fill_pages(pDataStream);
10403 if (pResourceManager ==
NULL || pJob ==
NULL) {
10415 case MA_JOB_LOAD_DATA_BUFFER:
return ma_resource_manager_process_job__load_data_buffer(pResourceManager, pJob);
10416 case MA_JOB_FREE_DATA_BUFFER:
return ma_resource_manager_process_job__free_data_buffer(pResourceManager, pJob);
10419 case MA_JOB_LOAD_DATA_STREAM:
return ma_resource_manager_process_job__load_data_stream(pResourceManager, pJob);
10420 case MA_JOB_FREE_DATA_STREAM:
return ma_resource_manager_process_job__free_data_stream(pResourceManager, pJob);
10421 case MA_JOB_PAGE_DATA_STREAM:
return ma_resource_manager_process_job__page_data_stream(pResourceManager, pJob);
10422 case MA_JOB_SEEK_DATA_STREAM:
return ma_resource_manager_process_job__seek_data_stream(pResourceManager, pJob);
10436 if (pResourceManager ==
NULL) {
10459 config.channels = channels;
10469 if (pPanner ==
NULL) {
10475 if (pConfig ==
NULL) {
10482 pPanner->
pan = pConfig->
pan;
10487 static void ma_stereo_balance_pcm_frames_f32(
float* pFramesOut,
const float* pFramesIn,
ma_uint64 frameCount,
float pan)
10492 float factor = 1.0f - pan;
10493 if (pFramesOut == pFramesIn) {
10494 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
10495 pFramesOut[iFrame*2 + 0] = pFramesIn[iFrame*2 + 0] * factor;
10498 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
10499 pFramesOut[iFrame*2 + 0] = pFramesIn[iFrame*2 + 0] * factor;
10500 pFramesOut[iFrame*2 + 1] = pFramesIn[iFrame*2 + 1];
10504 float factor = 1.0f + pan;
10505 if (pFramesOut == pFramesIn) {
10506 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
10507 pFramesOut[iFrame*2 + 1] = pFramesIn[iFrame*2 + 1] * factor;
10510 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
10511 pFramesOut[iFrame*2 + 0] = pFramesIn[iFrame*2 + 0];
10512 pFramesOut[iFrame*2 + 1] = pFramesIn[iFrame*2 + 1] * factor;
10518 static void ma_stereo_balance_pcm_frames(
void* pFramesOut,
const void* pFramesIn,
ma_uint64 frameCount,
ma_format format,
float pan)
10522 if (pFramesOut == pFramesIn) {
10532 case ma_format_f32: ma_stereo_balance_pcm_frames_f32((
float*)pFramesOut, (
float*)pFramesIn, frameCount, pan);
break;
10543 static void ma_stereo_pan_pcm_frames_f32(
float* pFramesOut,
const float* pFramesIn,
ma_uint64 frameCount,
float pan)
10548 float factorL0 = 1.0f - pan;
10549 float factorL1 = 0.0f + pan;
10551 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
10552 float sample0 = (pFramesIn[iFrame*2 + 0] * factorL0);
10553 float sample1 = (pFramesIn[iFrame*2 + 0] * factorL1) + pFramesIn[iFrame*2 + 1];
10555 pFramesOut[iFrame*2 + 0] = sample0;
10556 pFramesOut[iFrame*2 + 1] = sample1;
10559 float factorR0 = 0.0f - pan;
10560 float factorR1 = 1.0f + pan;
10562 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
10563 float sample0 = pFramesIn[iFrame*2 + 0] + (pFramesIn[iFrame*2 + 1] * factorR0);
10564 float sample1 = (pFramesIn[iFrame*2 + 1] * factorR1);
10566 pFramesOut[iFrame*2 + 0] = sample0;
10567 pFramesOut[iFrame*2 + 1] = sample1;
10572 static void ma_stereo_pan_pcm_frames(
void* pFramesOut,
const void* pFramesIn,
ma_uint64 frameCount,
ma_format format,
float pan)
10576 if (pFramesOut == pFramesIn) {
10586 case ma_format_f32: ma_stereo_pan_pcm_frames_f32((
float*)pFramesOut, (
float*)pFramesIn, frameCount, pan);
break;
10598 if (pPanner ==
NULL || pFramesOut ==
NULL || pFramesIn ==
NULL) {
10605 ma_stereo_balance_pcm_frames(pFramesOut, pFramesIn, frameCount, pPanner->
format, pPanner->
pan);
10607 ma_stereo_pan_pcm_frames(pFramesOut, pFramesIn, frameCount, pPanner->
format, pPanner->
pan);
10624 if (pPanner ==
NULL) {
10628 pPanner->
mode = mode;
10633 if (pPanner ==
NULL) {
10649 config.channels = channels;
10650 config.sampleRate = sampleRate;
10658 if (pFader ==
NULL) {
10664 if (pConfig ==
NULL) {
10673 pFader->
config = *pConfig;
10684 if (pFader ==
NULL) {
10709 const float* pFramesInF32 = (
const float*)pFramesIn;
10710 float* pFramesOutF32 = (
float*)pFramesOut;
10712 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
10716 for (iChannel = 0; iChannel < pFader->
config.
channels; iChannel += 1) {
10733 if (pFader ==
NULL) {
10737 if (pFormat !=
NULL) {
10741 if (pChannels !=
NULL) {
10745 if (pSampleRate !=
NULL) {
10752 if (pFader ==
NULL) {
10757 if (volumeBeg < 0) {
10769 if (pFader ==
NULL) {
10801 return ma_vec3f_init_3f(
10810 return ma_vec3f_init_3f(
10819 return a.
x*b.
x + a.
y*b.
y + a.
z*b.
z;
10824 return ma_vec3f_dot(v, v);
10829 return (
float)
ma_sqrtd(ma_vec3f_len2(v));
10834 return ma_vec3f_len(ma_vec3f_sub(a, b));
10840 float l = ma_vec3f_len(v);
10842 return ma_vec3f_init_3f(0, 0, 0);
10855 return ma_vec3f_init_3f(
10865 #ifndef MA_DEFAULT_SPEED_OF_SOUND
10866 #define MA_DEFAULT_SPEED_OF_SOUND 343.3f
10874 { 0.0f, 0.0f, -1.0f },
10875 { 0.0f, 0.0f, -1.0f },
10876 {-0.7071f, 0.0f, -0.7071f },
10877 {+0.7071f, 0.0f, -0.7071f },
10878 { 0.0f, 0.0f, -1.0f },
10879 { 0.0f, 0.0f, -1.0f },
10880 {-0.7071f, 0.0f, +0.7071f },
10881 {+0.7071f, 0.0f, +0.7071f },
10882 {-0.3162f, 0.0f, -0.9487f },
10883 {+0.3162f, 0.0f, -0.9487f },
10884 { 0.0f, 0.0f, +1.0f },
10885 {-1.0f, 0.0f, 0.0f },
10886 {+1.0f, 0.0f, 0.0f },
10887 { 0.0f, +1.0f, 0.0f },
10888 {-0.5774f, +0.5774f, -0.5774f },
10889 { 0.0f, +0.7071f, -0.7071f },
10890 {+0.5774f, +0.5774f, -0.5774f },
10891 {-0.5774f, +0.5774f, +0.5774f },
10892 { 0.0f, +0.7071f, +0.7071f },
10893 {+0.5774f, +0.5774f, +0.5774f },
10894 { 0.0f, 0.0f, -1.0f },
10895 { 0.0f, 0.0f, -1.0f },
10896 { 0.0f, 0.0f, -1.0f },
10897 { 0.0f, 0.0f, -1.0f },
10898 { 0.0f, 0.0f, -1.0f },
10899 { 0.0f, 0.0f, -1.0f },
10900 { 0.0f, 0.0f, -1.0f },
10901 { 0.0f, 0.0f, -1.0f },
10902 { 0.0f, 0.0f, -1.0f },
10903 { 0.0f, 0.0f, -1.0f },
10904 { 0.0f, 0.0f, -1.0f },
10905 { 0.0f, 0.0f, -1.0f },
10906 { 0.0f, 0.0f, -1.0f },
10907 { 0.0f, 0.0f, -1.0f },
10908 { 0.0f, 0.0f, -1.0f },
10909 { 0.0f, 0.0f, -1.0f },
10910 { 0.0f, 0.0f, -1.0f },
10911 { 0.0f, 0.0f, -1.0f },
10912 { 0.0f, 0.0f, -1.0f },
10913 { 0.0f, 0.0f, -1.0f },
10914 { 0.0f, 0.0f, -1.0f },
10915 { 0.0f, 0.0f, -1.0f },
10916 { 0.0f, 0.0f, -1.0f },
10917 { 0.0f, 0.0f, -1.0f },
10918 { 0.0f, 0.0f, -1.0f },
10919 { 0.0f, 0.0f, -1.0f },
10920 { 0.0f, 0.0f, -1.0f },
10921 { 0.0f, 0.0f, -1.0f },
10922 { 0.0f, 0.0f, -1.0f },
10923 { 0.0f, 0.0f, -1.0f },
10924 { 0.0f, 0.0f, -1.0f },
10925 { 0.0f, 0.0f, -1.0f }
10931 return ma_vec3f_init_3f(0, 0, -1);
10933 return g_maChannelDirections[channel];
10939 static float ma_attenuation_inverse(
float distance,
float minDistance,
float maxDistance,
float rolloff)
10941 if (minDistance >= maxDistance) {
10945 return minDistance / (minDistance + rolloff * (
ma_clamp(distance, minDistance, maxDistance) - minDistance));
10948 static float ma_attenuation_linear(
float distance,
float minDistance,
float maxDistance,
float rolloff)
10950 if (minDistance >= maxDistance) {
10954 return 1 - rolloff * (
ma_clamp(distance, minDistance, maxDistance) - minDistance) / (maxDistance - minDistance);
10957 static float ma_attenuation_exponential(
float distance,
float minDistance,
float maxDistance,
float rolloff)
10959 if (minDistance >= maxDistance) {
10963 return (
float)
ma_powd(
ma_clamp(distance, minDistance, maxDistance) / minDistance, -rolloff);
10976 static float ma_doppler_pitch(
ma_vec3f relativePosition,
ma_vec3f sourceVelocity,
ma_vec3f listenVelocity,
float speedOfSound,
float dopplerFactor)
10982 len = ma_vec3f_len(relativePosition);
10993 vls = ma_vec3f_dot(relativePosition, listenVelocity) / len;
10994 vss = ma_vec3f_dot(relativePosition, sourceVelocity) / len;
10996 vls =
ma_min(vls, speedOfSound / dopplerFactor);
10997 vss =
ma_min(vss, speedOfSound / dopplerFactor);
10999 return (speedOfSound - dopplerFactor*vls) / (speedOfSound - dopplerFactor*vss);
11003 static void ma_get_default_channel_map_for_spatializer(
ma_uint32 channelCount,
ma_channel* pChannelMap)
11012 if (channelCount == 2) {
11026 config.channelsOut = channelsOut;
11029 config.worldUp = ma_vec3f_init_3f(0, 1, 0);
11030 config.coneInnerAngleInRadians = 6.283185f;
11031 config.coneOuterAngleInRadians = 6.283185f;
11032 config.coneOuterGain = 0;
11033 config.speedOfSound = 343.3f;
11041 size_t sizeInBytes;
11042 size_t channelMapOutOffset;
11043 } ma_spatializer_listener_heap_layout;
11051 if (pConfig ==
NULL) {
11059 pHeapLayout->sizeInBytes = 0;
11062 pHeapLayout->channelMapOutOffset = pHeapLayout->sizeInBytes;
11072 ma_spatializer_listener_heap_layout heapLayout;
11074 if (pHeapSizeInBytes ==
NULL) {
11078 *pHeapSizeInBytes = 0;
11080 result = ma_spatializer_listener_get_heap_layout(pConfig, &heapLayout);
11085 *pHeapSizeInBytes = heapLayout.sizeInBytes;
11093 ma_spatializer_listener_heap_layout heapLayout;
11095 if (pListener ==
NULL) {
11101 result = ma_spatializer_listener_get_heap_layout(pConfig, &heapLayout);
11106 pListener->
_pHeap = pHeap;
11107 pListener->
config = *pConfig;
11108 pListener->
position = ma_vec3f_init_3f(0, 0, 0);
11109 pListener->
direction = ma_vec3f_init_3f(0, 0, -1);
11110 pListener->
velocity = ma_vec3f_init_3f(0, 0, 0);
11134 size_t heapSizeInBytes;
11142 if (heapSizeInBytes > 0) {
11143 pHeap =
ma_malloc(heapSizeInBytes, pAllocationCallbacks);
11144 if (pHeap ==
NULL) {
11153 ma_free(pHeap, pAllocationCallbacks);
11163 if (pListener ==
NULL) {
11174 if (pListener ==
NULL) {
11183 if (pListener ==
NULL) {
11194 if (pListener ==
NULL) {
11198 if (pInnerAngleInRadians !=
NULL) {
11202 if (pOuterAngleInRadians !=
NULL) {
11206 if (pOuterGain !=
NULL) {
11213 if (pListener ==
NULL) {
11217 pListener->
position = ma_vec3f_init_3f(x, y, z);
11222 if (pListener ==
NULL) {
11223 return ma_vec3f_init_3f(0, 0, 0);
11231 if (pListener ==
NULL) {
11235 pListener->
direction = ma_vec3f_init_3f(x, y, z);
11240 if (pListener ==
NULL) {
11241 return ma_vec3f_init_3f(0, 0, -1);
11249 if (pListener ==
NULL) {
11253 pListener->
velocity = ma_vec3f_init_3f(x, y, z);
11258 if (pListener ==
NULL) {
11259 return ma_vec3f_init_3f(0, 0, 0);
11267 if (pListener ==
NULL) {
11276 if (pListener ==
NULL) {
11285 if (pListener ==
NULL) {
11294 if (pListener ==
NULL) {
11295 return ma_vec3f_init_3f(0, 1, 0);
11309 config.channelsIn = channelsIn;
11310 config.channelsOut = channelsOut;
11320 config.coneInnerAngleInRadians = 6.283185f;
11321 config.coneOuterAngleInRadians = 6.283185f;
11322 config.coneOuterGain = 0.0f;
11323 config.dopplerFactor = 1;
11324 config.gainSmoothTimeInFrames = 360;
11349 size_t sizeInBytes;
11350 size_t channelMapInOffset;
11351 size_t newChannelGainsOffset;
11352 size_t gainerOffset;
11353 } ma_spatializer_heap_layout;
11363 if (pConfig ==
NULL) {
11367 result = ma_spatializer_validate_config(pConfig);
11372 pHeapLayout->sizeInBytes = 0;
11377 pHeapLayout->channelMapInOffset = pHeapLayout->sizeInBytes;
11382 pHeapLayout->newChannelGainsOffset = pHeapLayout->sizeInBytes;
11387 size_t gainerHeapSizeInBytes;
11390 gainerConfig = ma_spatializer_gainer_config_init(pConfig);
11397 pHeapLayout->gainerOffset = pHeapLayout->sizeInBytes;
11398 pHeapLayout->sizeInBytes +=
ma_align_64(gainerHeapSizeInBytes);
11407 ma_spatializer_heap_layout heapLayout;
11409 if (pHeapSizeInBytes ==
NULL) {
11413 *pHeapSizeInBytes = 0;
11415 result = ma_spatializer_get_heap_layout(pConfig, &heapLayout);
11420 *pHeapSizeInBytes = heapLayout.sizeInBytes;
11429 ma_spatializer_heap_layout heapLayout;
11432 if (pSpatializer ==
NULL) {
11438 if (pConfig ==
NULL || pHeap ==
NULL) {
11442 result = ma_spatializer_get_heap_layout(pConfig, &heapLayout);
11447 pSpatializer->
_pHeap = pHeap;
11448 pSpatializer->
config = *pConfig;
11449 pSpatializer->
position = ma_vec3f_init_3f(0, 0, 0);
11450 pSpatializer->
direction = ma_vec3f_init_3f(0, 0, -1);
11451 pSpatializer->
velocity = ma_vec3f_init_3f(0, 0, 0);
11469 gainerConfig = ma_spatializer_gainer_config_init(pConfig);
11482 size_t heapSizeInBytes;
11491 if (heapSizeInBytes > 0) {
11492 pHeap =
ma_malloc(heapSizeInBytes, pAllocationCallbacks);
11493 if (pHeap ==
NULL) {
11502 ma_free(pHeap, pAllocationCallbacks);
11512 if (pSpatializer ==
NULL) {
11523 static float ma_calculate_angular_gain(
ma_vec3f dirA,
ma_vec3f dirB,
float coneInnerAngleInRadians,
float coneOuterAngleInRadians,
float coneOuterGain)
11537 if (coneInnerAngleInRadians < 6.283185f) {
11538 float angularGain = 1;
11539 float cutoffInner = (float)
ma_cosd(coneInnerAngleInRadians*0.5f);
11540 float cutoffOuter = (float)
ma_cosd(coneOuterAngleInRadians*0.5f);
11543 d = ma_vec3f_dot(dirA, dirB);
11545 if (d > cutoffInner) {
11550 if (d > cutoffOuter) {
11552 angularGain =
ma_mix_f32(coneOuterGain, 1, (d - cutoffOuter) / (cutoffInner - cutoffOuter));
11555 angularGain = coneOuterGain;
11560 return angularGain;
11572 if (pSpatializer ==
NULL) {
11600 float speedOfSound;
11601 float distance = 0;
11611 if (pListener !=
NULL) {
11612 listenerVel = pListener->
velocity;
11615 listenerVel = ma_vec3f_init_3f(0, 0, 0);
11616 speedOfSound = MA_DEFAULT_SPEED_OF_SOUND;
11621 relativePos = pSpatializer->
position;
11639 axisZ = ma_vec3f_normalize(pListener->
direction);
11640 axisX = ma_vec3f_normalize(ma_vec3f_cross(axisZ, pListener->
config.
worldUp));
11648 if (ma_vec3f_len2(axisX) == 0) {
11649 axisX = ma_vec3f_init_3f(1, 0, 0);
11652 axisY = ma_vec3f_cross(axisX, axisZ);
11660 axisX = ma_vec3f_neg(axisX);
11664 m[0][0] = axisX.
x; m[1][0] = axisX.
y; m[2][0] = axisX.
z; m[3][0] = -ma_vec3f_dot(axisX, pListener->
position);
11665 m[0][1] = axisY.
x; m[1][1] = axisY.
y; m[2][1] = axisY.
z; m[3][1] = -ma_vec3f_dot(axisY, pListener->
position);
11666 m[0][2] = -axisZ.
x; m[1][2] = -axisZ.
y; m[2][2] = -axisZ.
z; m[3][2] = -ma_vec3f_dot(ma_vec3f_neg(axisZ), pListener->
position);
11667 m[0][3] = 0; m[1][3] = 0; m[2][3] = 0; m[3][3] = 1;
11675 relativePos.
x = m[0][0] * v.
x + m[1][0] * v.
y + m[2][0] * v.
z + m[3][0] * 1;
11676 relativePos.
y = m[0][1] * v.
x + m[1][1] * v.
y + m[2][1] * v.
z + m[3][1] * 1;
11677 relativePos.
z = m[0][2] * v.
x + m[1][2] * v.
y + m[2][2] * v.
z + m[3][2] * 1;
11684 relativeDir.
x = m[0][0] * v.
x + m[1][0] * v.
y + m[2][0] * v.
z;
11685 relativeDir.
y = m[0][1] * v.
x + m[1][1] * v.
y + m[2][1] * v.
z;
11686 relativeDir.
z = m[0][2] * v.
x + m[1][2] * v.
y + m[2][2] * v.
z;
11689 distance = ma_vec3f_len(relativePos);
11713 if (distance > 0.001f) {
11714 float distanceInv = 1/distance;
11715 relativePosNormalized = relativePos;
11716 relativePosNormalized.
x *= distanceInv;
11717 relativePosNormalized.
y *= distanceInv;
11718 relativePosNormalized.
z *= distanceInv;
11721 relativePosNormalized = ma_vec3f_init_3f(0, 0, 0);
11736 if (distance > 0) {
11746 float listenerInnerAngle;
11747 float listenerOuterAngle;
11748 float listenerOuterGain;
11751 listenerDirection = ma_vec3f_init_3f(0, 0, -1);
11753 listenerDirection = ma_vec3f_init_3f(0, 0, +1);
11760 gain *= ma_calculate_angular_gain(listenerDirection, relativePosNormalized, listenerInnerAngle, listenerOuterAngle, listenerOuterGain);
11791 for (iChannel = 0; iChannel < channelsOut; iChannel += 1) {
11796 ma_channel_map_apply_f32((
float*)pFramesOut, pChannelMapOut, channelsOut, (
const float*)pFramesIn, pChannelMapIn, channelsIn, frameCount,
ma_channel_mix_mode_rectangular);
11802 if (distance > 0) {
11804 float distanceInv = 1/distance;
11805 unitPos.
x *= distanceInv;
11806 unitPos.
y *= distanceInv;
11807 unitPos.
z *= distanceInv;
11809 for (iChannel = 0; iChannel < channelsOut; iChannel += 1) {
11815 d = ma_vec3f_dot(unitPos, ma_get_channel_direction(channelOut));
11862 d = (
d + 1) * 0.5f;
11875 channelGainsOut[iChannel] *=
d;
11906 if (pSpatializer ==
NULL) {
11915 if (pSpatializer ==
NULL) {
11924 if (pSpatializer ==
NULL) {
11933 if (pSpatializer ==
NULL) {
11942 if (pSpatializer ==
NULL) {
11951 if (pSpatializer ==
NULL) {
11960 if (pSpatializer ==
NULL) {
11969 if (pSpatializer ==
NULL) {
11978 if (pSpatializer ==
NULL) {
11987 if (pSpatializer ==
NULL) {
11996 if (pSpatializer ==
NULL) {
12005 if (pSpatializer ==
NULL) {
12014 if (pSpatializer ==
NULL) {
12023 if (pSpatializer ==
NULL) {
12032 if (pSpatializer ==
NULL) {
12041 if (pSpatializer ==
NULL) {
12050 if (pSpatializer ==
NULL) {
12061 if (pSpatializer ==
NULL) {
12065 if (pInnerAngleInRadians !=
NULL) {
12069 if (pOuterAngleInRadians !=
NULL) {
12073 if (pOuterGain !=
NULL) {
12080 if (pSpatializer ==
NULL) {
12089 if (pSpatializer ==
NULL) {
12098 if (pSpatializer ==
NULL) {
12102 pSpatializer->
position = ma_vec3f_init_3f(x, y, z);
12107 if (pSpatializer ==
NULL) {
12108 return ma_vec3f_init_3f(0, 0, 0);
12116 if (pSpatializer ==
NULL) {
12120 pSpatializer->
direction = ma_vec3f_init_3f(x, y, z);
12125 if (pSpatializer ==
NULL) {
12126 return ma_vec3f_init_3f(0, 0, -1);
12134 if (pSpatializer ==
NULL) {
12138 pSpatializer->
velocity = ma_vec3f_init_3f(x, y, z);
12143 if (pSpatializer ==
NULL) {
12144 return ma_vec3f_init_3f(0, 0, 0);
12158 #define MA_SEEK_TARGET_NONE (~(ma_uint64)0)
12165 config.pEngine = pEngine;
12174 static void ma_engine_node_update_pitch_if_required(
ma_engine_node* pEngineNode)
12183 if (pEngineNode->
oldPitch != newPitch) {
12193 if (isUpdateRequired) {
12216 if (ma_engine_node_is_pitching_enabled(pEngineNode)) {
12219 return outputFrameCount;
12223 static void ma_engine_node_process_pcm_frames__general(
ma_engine_node* pEngineNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
12236 frameCountIn = *pFrameCountIn;
12237 frameCountOut = *pFrameCountOut;
12242 totalFramesProcessedIn = 0;
12243 totalFramesProcessedOut = 0;
12245 isPitchingEnabled = ma_engine_node_is_pitching_enabled(pEngineNode);
12247 isSpatializationEnabled = ma_engine_node_is_spatialization_enabled(pEngineNode);
12248 isPanningEnabled = pEngineNode->
panner.
pan != 0 && channelsOut != 1;
12251 while (totalFramesProcessedOut < frameCountOut) {
12271 const float* pRunningFramesIn;
12272 float* pRunningFramesOut;
12273 float* pWorkingBuffer;
12282 framesAvailableIn = frameCountIn - totalFramesProcessedIn;
12283 framesAvailableOut = frameCountOut - totalFramesProcessedOut;
12288 if (channelsIn == channelsOut) {
12290 pWorkingBuffer = pRunningFramesOut;
12293 pWorkingBuffer = temp;
12294 if (framesAvailableOut > tempCapInFrames) {
12295 framesAvailableOut = tempCapInFrames;
12300 if (isPitchingEnabled) {
12301 ma_uint64 resampleFrameCountIn = framesAvailableIn;
12302 ma_uint64 resampleFrameCountOut = framesAvailableOut;
12305 isWorkingBufferValid =
MA_TRUE;
12307 framesJustProcessedIn = (
ma_uint32)resampleFrameCountIn;
12308 framesJustProcessedOut = (
ma_uint32)resampleFrameCountOut;
12310 framesJustProcessedIn = framesAvailableIn;
12311 framesJustProcessedOut = framesAvailableOut;
12315 if (isFadingEnabled) {
12316 if (isWorkingBufferValid) {
12320 isWorkingBufferValid =
MA_TRUE;
12328 if (isWorkingBufferValid ==
MA_FALSE) {
12329 pWorkingBuffer = (
float*)pRunningFramesIn;
12333 if (isSpatializationEnabled) {
12349 if (channelsIn == channelsOut) {
12361 if (isPanningEnabled) {
12366 totalFramesProcessedIn += framesJustProcessedIn;
12367 totalFramesProcessedOut += framesJustProcessedOut;
12370 if (framesJustProcessedOut == 0) {
12376 *pFrameCountIn = totalFramesProcessedIn;
12377 *pFrameCountOut = totalFramesProcessedOut;
12380 static void ma_engine_node_process_pcm_frames__sound(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
12385 ma_uint32 frameCount = *pFrameCountOut;
12394 (void)pFrameCountIn;
12399 *pFrameCountOut = 0;
12404 if (pSound->
seekTarget != MA_SEEK_TARGET_NONE) {
12422 ma_engine_node_update_pitch_if_required(&pSound->
engineNode);
12433 while (totalFramesRead < frameCount) {
12434 ma_uint32 framesRemaining = frameCount - totalFramesRead;
12439 const float* pRunningFramesIn;
12440 float* pRunningFramesOut;
12446 framesToRead = (
ma_uint32)ma_engine_node_get_required_input_frame_count(&pSound->
engineNode, framesRemaining);
12447 if (framesToRead > tempCapInFrames) {
12448 framesToRead = tempCapInFrames;
12460 frameCountIn = (
ma_uint32)framesJustRead;
12461 frameCountOut = framesRemaining;
12466 pRunningFramesIn = (
float*)temp;
12467 ma_engine_node_process_pcm_frames__general(&pSound->
engineNode, &pRunningFramesIn, &frameCountIn, &pRunningFramesOut, &frameCountOut);
12474 pRunningFramesIn = tempf32;
12475 ma_engine_node_process_pcm_frames__general(&pSound->
engineNode, &pRunningFramesIn, &frameCountIn, &pRunningFramesOut, &frameCountOut);
12479 MA_ASSERT(frameCountIn == framesJustRead);
12480 totalFramesRead += (
ma_uint32)frameCountOut;
12488 *pFrameCountOut = totalFramesRead;
12491 static void ma_engine_node_process_pcm_frames__group(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
12500 ma_engine_node_update_pitch_if_required((
ma_engine_node*)pNode);
12503 ma_engine_node_process_pcm_frames__general((
ma_engine_node*)pNode, ppFramesIn, pFrameCountIn, ppFramesOut, pFrameCountOut);
12511 ma_engine_node_update_pitch_if_required((
ma_engine_node*)pNode);
12513 result = ma_engine_node_get_required_input_frame_count((
ma_engine_node*)pNode, outputFrameCount);
12514 if (result > 0xFFFFFFFF) {
12515 result = 0xFFFFFFFF;
12524 ma_engine_node_process_pcm_frames__sound,
12533 ma_engine_node_process_pcm_frames__group,
12534 ma_engine_node_get_required_input_frame_count__group,
12549 baseNodeConfig.
vtable = &g_ma_engine_node_vtable__sound;
12554 baseNodeConfig.
vtable = &g_ma_engine_node_vtable__group;
12558 return baseNodeConfig;
12568 size_t sizeInBytes;
12569 size_t baseNodeOffset;
12570 size_t spatializerOffset;
12571 } ma_engine_node_heap_layout;
12576 size_t tempHeapSize;
12586 if (pConfig ==
NULL) {
12594 pHeapLayout->sizeInBytes = 0;
12601 baseNodeConfig = ma_engine_node_base_node_config_init(pConfig);
12610 pHeapLayout->baseNodeOffset = pHeapLayout->sizeInBytes;
12611 pHeapLayout->sizeInBytes +=
ma_align_64(tempHeapSize);
12615 spatializerConfig = ma_engine_node_spatializer_config_init(&baseNodeConfig);
12622 pHeapLayout->spatializerOffset = pHeapLayout->sizeInBytes;
12623 pHeapLayout->sizeInBytes +=
ma_align_64(tempHeapSize);
12632 ma_engine_node_heap_layout heapLayout;
12634 if (pHeapSizeInBytes ==
NULL) {
12638 *pHeapSizeInBytes = 0;
12640 result = ma_engine_node_get_heap_layout(pConfig, &heapLayout);
12645 *pHeapSizeInBytes = heapLayout.sizeInBytes;
12653 ma_engine_node_heap_layout heapLayout;
12662 if (pEngineNode ==
NULL) {
12668 result = ma_engine_node_get_heap_layout(pConfig, &heapLayout);
12677 pEngineNode->
_pHeap = pHeap;
12680 pEngineNode->
pitch = 1;
12693 baseNodeConfig = ma_engine_node_base_node_config_init(pConfig);
12734 spatializerConfig = ma_engine_node_spatializer_config_init(&baseNodeConfig);
12759 error0:
return result;
12765 size_t heapSizeInBytes;
12773 if (heapSizeInBytes > 0) {
12774 pHeap =
ma_malloc(heapSizeInBytes, pAllocationCallbacks);
12775 if (pHeap ==
NULL) {
12784 ma_free(pHeap, pAllocationCallbacks);
12835 config.listenerCount = 1;
12841 static void ma_engine_data_callback_internal(
ma_device* pDevice,
void* pFramesOut,
const void* pFramesIn,
ma_uint32 frameCount)
12859 #
if !defined(MA_NO_RESOURCE_MANAGER) && defined(MA_EMSCRIPTEN)
12880 if (pEngine !=
NULL) {
12885 if (pConfig !=
NULL) {
12886 engineConfig = *pConfig;
12909 deviceConfig.
dataCallback = ma_engine_data_callback_internal;
12919 contextConfig.
pLog = engineConfig.
pLog;
12922 #ifndef MA_NO_RESOURCE_MANAGER
12949 pEngine->
pLog = engineConfig.
pLog;
12974 for (iListener = 0; iListener < engineConfig.
listenerCount; iListener += 1) {
12990 if (gainSmoothTimeInMilliseconds == 0) {
12991 gainSmoothTimeInMilliseconds = 8;
12999 #ifndef MA_NO_RESOURCE_MANAGER
13011 resourceManagerConfig.
pLog = pEngine->
pLog;
13019 #if defined(MA_EMSCRIPTEN)
13052 #ifndef MA_NO_RESOURCE_MANAGER
13059 for (iListener = 0; iListener < pEngine->
listenerCount; iListener += 1) {
13075 if (pEngine ==
NULL) {
13095 if (pSoundToDelete ==
NULL) {
13113 #ifndef MA_NO_RESOURCE_MANAGER
13130 if (pEngine ==
NULL) {
13139 if (pEngine ==
NULL) {
13144 return pEngine->
pLog;
13172 if (pEngine ==
NULL) {
13188 if (pEngine ==
NULL) {
13204 if (pEngine ==
NULL) {
13218 if (pEngine ==
NULL) {
13227 if (pEngine ==
NULL) {
13237 if (pEngine ==
NULL) {
13254 iListenerClosest = 0;
13255 for (iListener = 0; iListener < pEngine->
listenerCount; iListener += 1) {
13256 float len2 = ma_vec3f_len2(ma_vec3f_sub(pEngine->
listeners[iListener].
position, ma_vec3f_init_3f(absolutePosX, absolutePosY, absolutePosZ)));
13257 if (closestLen2 > len2) {
13258 closestLen2 = len2;
13259 iListenerClosest = iListener;
13264 return iListenerClosest;
13279 return ma_vec3f_init_3f(0, 0, 0);
13297 return ma_vec3f_init_3f(0, 0, -1);
13315 return ma_vec3f_init_3f(0, 0, 0);
13332 if (pInnerAngleInRadians !=
NULL) {
13333 *pInnerAngleInRadians = 0;
13336 if (pOuterAngleInRadians !=
NULL) {
13337 *pOuterAngleInRadians = 0;
13340 if (pOuterGain !=
NULL) {
13359 return ma_vec3f_init_3f(0, 1, 0);
13366 #ifndef MA_NO_RESOURCE_MANAGER
13373 if (pEngine ==
NULL || pFilePath ==
NULL) {
13378 if (pNode ==
NULL) {
13380 nodeInputBusIndex = 0;
13405 pSound = pNextSound;
13411 if (pSound !=
NULL) {
13434 if (pSound !=
NULL) {
13487 return ma_engine_play_sound_ex(pEngine, pFilePath, pGroup, 0);
13494 if (pSound ==
NULL) {
13501 if (pEngine ==
NULL) {
13518 if (pConfig ==
NULL) {
13577 #ifndef MA_NO_RESOURCE_MANAGER
13629 result = ma_sound_init_from_data_source_internal(pEngine, &
config, pSound);
13645 config.pFilePath = pFilePath;
13647 config.pInitialAttachment = pGroup;
13648 config.pDoneFence = pDoneFence;
13655 config.pFilePathW = pFilePath;
13657 config.pInitialAttachment = pGroup;
13658 config.pDoneFence = pDoneFence;
13667 result = ma_sound_preinit(pEngine, pSound);
13672 if (pExistingSound ==
NULL) {
13699 config.pInitialAttachment = pGroup;
13701 result = ma_sound_init_from_data_source_internal(pEngine, &
config, pSound);
13716 config.pDataSource = pDataSource;
13718 config.pInitialAttachment = pGroup;
13726 result = ma_sound_preinit(pEngine, pSound);
13731 if (pConfig ==
NULL) {
13736 #ifndef MA_NO_RESOURCE_MANAGER
13738 return ma_sound_init_from_file_internal(pEngine, pConfig, pSound);
13748 return ma_sound_init_from_data_source_internal(pEngine, pConfig, pSound);
13754 if (pSound ==
NULL) {
13765 #ifndef MA_NO_RESOURCE_MANAGER
13778 if (pSound ==
NULL) {
13787 if (pSound ==
NULL) {
13796 if (pSound ==
NULL) {
13824 if (pSound ==
NULL) {
13836 if (pSound ==
NULL) {
13853 if (pSound ==
NULL) {
13862 if (pSound ==
NULL) {
13871 if (pSound ==
NULL) {
13880 if (pSound ==
NULL) {
13898 if (pSound ==
NULL) {
13907 if (pSound ==
NULL) {
13916 if (pSound ==
NULL) {
13917 return ma_vec3f_init_3f(0, 0, 0);
13925 if (pSound ==
NULL) {
13934 if (pSound ==
NULL) {
13935 return ma_vec3f_init_3f(0, 0, 0);
13943 if (pSound ==
NULL) {
13952 if (pSound ==
NULL) {
13953 return ma_vec3f_init_3f(0, 0, 0);
13961 if (pSound ==
NULL) {
13970 if (pSound ==
NULL) {
13979 if (pSound ==
NULL) {
13988 if (pSound ==
NULL) {
13997 if (pSound ==
NULL) {
14006 if (pSound ==
NULL) {
14015 if (pSound ==
NULL) {
14024 if (pSound ==
NULL) {
14033 if (pSound ==
NULL) {
14042 if (pSound ==
NULL) {
14051 if (pSound ==
NULL) {
14060 if (pSound ==
NULL) {
14069 if (pSound ==
NULL) {
14078 if (pSound ==
NULL) {
14087 if (pSound ==
NULL) {
14096 if (pInnerAngleInRadians !=
NULL) {
14097 *pInnerAngleInRadians = 0;
14100 if (pOuterAngleInRadians !=
NULL) {
14101 *pOuterAngleInRadians = 0;
14104 if (pOuterGain !=
NULL) {
14113 if (pSound ==
NULL) {
14122 if (pSound ==
NULL) {
14132 if (pSound ==
NULL) {
14141 if (pSound ==
NULL) {
14150 if (pSound ==
NULL) {
14159 if (pSound ==
NULL) {
14168 if (pSound ==
NULL) {
14177 if (pSound ==
NULL) {
14186 if (pSound ==
NULL) {
14195 if (pSound ==
NULL) {
14204 if (pSound ==
NULL) {
14213 if (pSound ==
NULL) {
14230 #ifndef MA_NO_RESOURCE_MANAGER
14239 if (pSound ==
NULL) {
14253 if (pSound ==
NULL) {
14267 if (pSound ==
NULL) {
14280 #ifndef MA_NO_RESOURCE_MANAGER
14300 if (pSound ==
NULL) {
14306 if (pFormat !=
NULL) {
14310 if (pChannels !=
NULL) {
14314 if (pSampleRate !=
NULL) {
14326 if (pSound ==
NULL) {
14340 if (pSound ==
NULL) {
14357 config.pInitialAttachment = pParentGroup;
14365 if (pGroup ==
NULL) {
14371 if (pConfig ==
NULL) {
14376 soundConfig = *pConfig;
14554 ma_sound_set_cone(pGroup, innerAngleInRadians, outerAngleInRadians, outerGain);
14559 ma_sound_get_cone(pGroup, pInnerAngleInRadians, pOuterAngleInRadians, pOuterGain);
14633 static void ma_biquad_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
14638 (void)pFrameCountIn;
14645 ma_biquad_node_process_pcm_frames,
14657 if (pNode ==
NULL) {
14663 if (pConfig ==
NULL) {
14677 baseNodeConfig.
vtable = &g_ma_biquad_node_vtable;
14681 result =
ma_node_init(pNodeGraph, &baseNodeConfig, pAllocationCallbacks, pNode);
14718 static void ma_lpf_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
14723 (void)pFrameCountIn;
14730 ma_lpf_node_process_pcm_frames,
14742 if (pNode ==
NULL) {
14748 if (pConfig ==
NULL) {
14762 baseNodeConfig.
vtable = &g_ma_lpf_node_vtable;
14766 result =
ma_node_init(pNodeGraph, &baseNodeConfig, pAllocationCallbacks, pNode);
14803 static void ma_hpf_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
14808 (void)pFrameCountIn;
14815 ma_hpf_node_process_pcm_frames,
14827 if (pNode ==
NULL) {
14833 if (pConfig ==
NULL) {
14847 baseNodeConfig.
vtable = &g_ma_hpf_node_vtable;
14851 result =
ma_node_init(pNodeGraph, &baseNodeConfig, pAllocationCallbacks, pNode);
14889 static void ma_bpf_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
14894 (void)pFrameCountIn;
14901 ma_bpf_node_process_pcm_frames,
14913 if (pNode ==
NULL) {
14919 if (pConfig ==
NULL) {
14933 baseNodeConfig.
vtable = &g_ma_bpf_node_vtable;
14937 result =
ma_node_init(pNodeGraph, &baseNodeConfig, pAllocationCallbacks, pNode);
14974 static void ma_notch_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
14979 (void)pFrameCountIn;
14986 ma_notch_node_process_pcm_frames,
14998 if (pNode ==
NULL) {
15004 if (pConfig ==
NULL) {
15018 baseNodeConfig.
vtable = &g_ma_notch_node_vtable;
15022 result =
ma_node_init(pNodeGraph, &baseNodeConfig, pAllocationCallbacks, pNode);
15059 static void ma_peak_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
15064 (void)pFrameCountIn;
15071 ma_peak_node_process_pcm_frames,
15083 if (pNode ==
NULL) {
15089 if (pConfig ==
NULL) {
15104 baseNodeConfig.
vtable = &g_ma_peak_node_vtable;
15108 result =
ma_node_init(pNodeGraph, &baseNodeConfig, pAllocationCallbacks, pNode);
15145 static void ma_loshelf_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
15150 (void)pFrameCountIn;
15157 ma_loshelf_node_process_pcm_frames,
15169 if (pNode ==
NULL) {
15175 if (pConfig ==
NULL) {
15189 baseNodeConfig.
vtable = &g_ma_loshelf_node_vtable;
15193 result =
ma_node_init(pNodeGraph, &baseNodeConfig, pAllocationCallbacks, pNode);
15230 static void ma_hishelf_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
15235 (void)pFrameCountIn;
15242 ma_hishelf_node_process_pcm_frames,
15254 if (pNode ==
NULL) {
15260 if (pConfig ==
NULL) {
15274 baseNodeConfig.
vtable = &g_ma_hishelf_node_vtable;
15278 result =
ma_node_init(pNodeGraph, &baseNodeConfig, pAllocationCallbacks, pNode);
15310 config.channels = channels;
15311 config.sampleRate = sampleRate;
15312 config.delayInFrames = delayInFrames;
15324 if (pDelay ==
NULL) {
15330 if (pConfig ==
NULL) {
15334 if (pConfig->
decay < 0 || pConfig->
decay > 1) {
15338 pDelay->
config = *pConfig;
15354 if (pDelay ==
NULL) {
15365 float* pFramesOutF32 = (
float*)pFramesOut;
15366 const float* pFramesInF32 = (
const float*)pFramesIn;
15368 if (pDelay ==
NULL || pFramesOut ==
NULL || pFramesIn ==
NULL) {
15372 for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
15373 for (iChannel = 0; iChannel < pDelay->
config.
channels; iChannel += 1) {
15406 if (pDelay ==
NULL) {
15415 if (pDelay ==
NULL) {
15424 if (pDelay ==
NULL) {
15433 if (pDelay ==
NULL) {
15442 if (pDelay ==
NULL) {
15451 if (pDelay ==
NULL) {
15472 static void ma_delay_node_process_pcm_frames(
ma_node* pNode,
const float** ppFramesIn,
ma_uint32* pFrameCountIn,
float** ppFramesOut,
ma_uint32* pFrameCountOut)
15476 (void)pFrameCountIn;
15483 ma_delay_node_process_pcm_frames,
15495 if (pDelayNode ==
NULL) {
15507 baseConfig.
vtable = &g_ma_delay_node_vtable;
15522 if (pDelayNode ==
NULL) {
15533 if (pDelayNode ==
NULL) {
15542 if (pDelayNode ==
NULL) {
15551 if (pDelayNode ==
NULL) {
15560 if (pDelayNode ==
NULL) {
15569 if (pDelayNode ==
NULL) {
15578 if (pDelayNode ==
NULL) {