diff --git a/research/miniaudio_engine.h b/research/miniaudio_engine.h index 9e19ab4a..67379091 100644 --- a/research/miniaudio_engine.h +++ b/research/miniaudio_engine.h @@ -1367,7 +1367,7 @@ struct ma_resource_manager_data_buffer ma_uint32 flags; /* The flags that were passed used to initialize the buffer. */ ma_uint32 executionCounter; /* For allocating execution orders for jobs. */ ma_uint32 executionPointer; /* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */ - ma_uint64 cursorInPCMFrames; /* Only updated by the public API. Never written nor read from the job thread. */ + ma_uint64 seekTargetInPCMFrames; /* Only updated by the public API. Never written nor read from the job thread. */ ma_bool32 seekToCursorOnNextRead; /* On the next read we need to seek to the frame cursor. */ MA_ATOMIC ma_result result; /* Keeps track of a result of decoding. Set to MA_BUSY while the buffer is still loading. Set to MA_SUCCESS when loading is finished successfully. Otherwise set to some other code. */ MA_ATOMIC ma_bool32 isLooping; /* Can be read and written by different threads at the same time. Must be used atomically. */ @@ -7445,7 +7445,7 @@ MA_API ma_result ma_resource_manager_data_buffer_read_pcm_frames(ma_resource_man if (pDataBuffer->seekToCursorOnNextRead) { pDataBuffer->seekToCursorOnNextRead = MA_FALSE; - result = ma_data_source_seek_to_pcm_frame(ma_resource_manager_data_buffer_get_connector(pDataBuffer), pDataBuffer->cursorInPCMFrames); + result = ma_data_source_seek_to_pcm_frame(ma_resource_manager_data_buffer_get_connector(pDataBuffer), pDataBuffer->seekTargetInPCMFrames); if (result != MA_SUCCESS) { return result; } @@ -7457,45 +7457,42 @@ MA_API ma_result ma_resource_manager_data_buffer_read_pcm_frames(ma_resource_man */ if (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_decoded) { ma_uint64 availableFrames; + + isDecodedBufferBusy = (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY); + if (ma_resource_manager_data_buffer_get_available_frames(pDataBuffer, &availableFrames) == MA_SUCCESS) { /* Don't try reading more than the available frame count. */ if (frameCount > availableFrames) { frameCount = availableFrames; - isDecodedBufferBusy = (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY); - - if (!isDecodedBufferBusy && availableFrames == 0) { - result = MA_AT_END; - } + } else { + isDecodedBufferBusy = MA_FALSE; /* We have enough frames available in the buffer to avoid a MA_BUSY status. */ } } } - if (result == MA_SUCCESS) { - result = ma_resource_manager_data_buffer_get_looping(pDataBuffer, &isLooping); - if (result != MA_SUCCESS) { - return result; - } + result = ma_resource_manager_data_buffer_get_looping(pDataBuffer, &isLooping); + if (result != MA_SUCCESS) { + return result; + } - result = ma_data_source_read_pcm_frames(ma_resource_manager_data_buffer_get_connector(pDataBuffer), pFramesOut, frameCount, &framesRead, isLooping); - pDataBuffer->cursorInPCMFrames += framesRead; + result = ma_data_source_read_pcm_frames(ma_resource_manager_data_buffer_get_connector(pDataBuffer), pFramesOut, frameCount, &framesRead, isLooping); - /* - If we returned MA_AT_END, but the node is still loading, we don't want to return that code or else the caller will interpret the sound - as at the end and terminate decoding. - */ - if (result == MA_AT_END) { - if (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY) { - result = MA_BUSY; - } - } - - if (isDecodedBufferBusy) { + /* + If we returned MA_AT_END, but the node is still loading, we don't want to return that code or else the caller will interpret the sound + as at the end and terminate decoding. + */ + if (result == MA_AT_END) { + if (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY) { result = MA_BUSY; } + } - if (pFramesRead != NULL) { - *pFramesRead = framesRead; - } + if (isDecodedBufferBusy) { + result = MA_BUSY; + } + + if (pFramesRead != NULL) { + *pFramesRead = framesRead; } return result; @@ -7510,7 +7507,7 @@ MA_API ma_result ma_resource_manager_data_buffer_seek_to_pcm_frame(ma_resource_m /* If we haven't yet got a connector we need to abort. */ if (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_unknown) { - pDataBuffer->cursorInPCMFrames = frameIndex; + pDataBuffer->seekTargetInPCMFrames = frameIndex; pDataBuffer->seekToCursorOnNextRead = MA_TRUE; return MA_BUSY; /* Still loading. */ } @@ -7520,7 +7517,7 @@ MA_API ma_result ma_resource_manager_data_buffer_seek_to_pcm_frame(ma_resource_m return result; } - pDataBuffer->cursorInPCMFrames = frameIndex; + pDataBuffer->seekTargetInPCMFrames = ~(ma_uint64)0; /* <-- For identification purposes. */ pDataBuffer->seekToCursorOnNextRead = MA_FALSE; return MA_SUCCESS; @@ -7576,9 +7573,35 @@ MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_res return MA_INVALID_ARGS; } - *pCursor = pDataBuffer->cursorInPCMFrames; + *pCursor = 0; - return MA_SUCCESS; + switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode)) + { + case ma_resource_manager_data_supply_type_encoded: + { + return ma_decoder_get_cursor_in_pcm_frames(&pDataBuffer->connector.decoder, pCursor); + }; + + case ma_resource_manager_data_supply_type_decoded: + { + return ma_audio_buffer_get_cursor_in_pcm_frames(&pDataBuffer->connector.buffer, pCursor); + }; + + case ma_resource_manager_data_supply_type_decoded_paged: + { + return ma_paged_audio_buffer_get_cursor_in_pcm_frames(&pDataBuffer->connector.pagedBuffer, pCursor); + }; + + case ma_resource_manager_data_supply_type_unknown: + { + return MA_BUSY; + }; + + default: + { + return MA_INVALID_ARGS; + } + } } MA_API ma_result ma_resource_manager_data_buffer_get_length_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pLength) @@ -7663,19 +7686,16 @@ MA_API ma_result ma_resource_manager_data_buffer_get_available_frames(ma_resourc case ma_resource_manager_data_supply_type_decoded: { - if (pDataBuffer->pNode->data.decoded.decodedFrameCount > pDataBuffer->cursorInPCMFrames) { - *pAvailableFrames = pDataBuffer->pNode->data.decoded.decodedFrameCount - pDataBuffer->cursorInPCMFrames; - } else { - *pAvailableFrames = 0; - } - - return MA_SUCCESS; + return ma_audio_buffer_get_available_frames(&pDataBuffer->connector.buffer, pAvailableFrames); }; case ma_resource_manager_data_supply_type_decoded_paged: { - if (pDataBuffer->pNode->data.decodedPaged.decodedFrameCount > pDataBuffer->cursorInPCMFrames) { - *pAvailableFrames = pDataBuffer->pNode->data.decodedPaged.decodedFrameCount - pDataBuffer->cursorInPCMFrames; + ma_uint64 cursor; + ma_paged_audio_buffer_get_cursor_in_pcm_frames(&pDataBuffer->connector.pagedBuffer, &cursor); + + if (pDataBuffer->pNode->data.decodedPaged.decodedFrameCount > cursor) { + *pAvailableFrames = pDataBuffer->pNode->data.decodedPaged.decodedFrameCount - cursor; } else { *pAvailableFrames = 0; }