mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-24 01:04:02 +02:00
Add some APIs to data sources:
* ma_data_source_get_cursor_in_pcm_frames() * ma_data_source_get_length_in_pcm_frames() When the data source has no notion of a cursor or length, these return MA_NOT_IMPLEMENTED to let the caller know about it. This is returned when a custom data source leaves these functions unimplemented. ma_decoder, ma_audio_buffer, ma_waveform and ma_noise have all been updated to support these new functions.
This commit is contained in:
+102
@@ -5244,6 +5244,8 @@ typedef struct
|
|||||||
ma_result (* onMap)(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
|
ma_result (* onMap)(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
|
||||||
ma_result (* onUnmap)(ma_data_source* pDataSource, ma_uint64 frameCount);
|
ma_result (* onUnmap)(ma_data_source* pDataSource, ma_uint64 frameCount);
|
||||||
ma_result (* onGetDataFormat)(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
|
ma_result (* onGetDataFormat)(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
|
||||||
|
ma_result (* onGetCursor)(ma_data_source* pDataSource, ma_uint64* pCursor);
|
||||||
|
ma_result (* onGetLength)(ma_data_source* pDataSource, ma_uint64* pLength);
|
||||||
} ma_data_source_callbacks;
|
} ma_data_source_callbacks;
|
||||||
|
|
||||||
MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead, ma_bool32 loop); /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
|
MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead, ma_bool32 loop); /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
|
||||||
@@ -5252,6 +5254,8 @@ MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, m
|
|||||||
MA_API ma_result ma_data_source_map(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount);
|
MA_API ma_result ma_data_source_map(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount);
|
||||||
MA_API ma_result ma_data_source_unmap(ma_data_source* pDataSource, ma_uint64 frameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
|
MA_API ma_result ma_data_source_unmap(ma_data_source* pDataSource, ma_uint64 frameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
|
||||||
MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
|
MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
|
||||||
|
MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor);
|
||||||
|
MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength); /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -41315,6 +41319,48 @@ MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_
|
|||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor)
|
||||||
|
{
|
||||||
|
ma_data_source_callbacks* pCallbacks = (ma_data_source_callbacks*)pDataSource;
|
||||||
|
|
||||||
|
if (pCursor == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCursor = 0;
|
||||||
|
|
||||||
|
if (pCallbacks == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCallbacks->onGetCursor == NULL) {
|
||||||
|
return MA_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pCallbacks->onGetCursor(pDataSource, pCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength)
|
||||||
|
{
|
||||||
|
ma_data_source_callbacks* pCallbacks = (ma_data_source_callbacks*)pDataSource;
|
||||||
|
|
||||||
|
if (pLength == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
pLength = 0;
|
||||||
|
|
||||||
|
if (pCallbacks == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCallbacks->onGetLength == NULL) {
|
||||||
|
return MA_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pCallbacks->onGetLength(pDataSource, pLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MA_API ma_audio_buffer_config ma_audio_buffer_config_init(ma_format format, ma_uint32 channels, ma_uint64 sizeInFrames, const void* pData, const ma_allocation_callbacks* pAllocationCallbacks)
|
MA_API ma_audio_buffer_config ma_audio_buffer_config_init(ma_format format, ma_uint32 channels, ma_uint64 sizeInFrames, const void* pData, const ma_allocation_callbacks* pAllocationCallbacks)
|
||||||
@@ -41373,6 +41419,24 @@ static ma_result ma_audio_buffer__data_source_on_get_data_format(ma_data_source*
|
|||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ma_result ma_audio_buffer__data_source_on_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
|
||||||
|
{
|
||||||
|
ma_audio_buffer* pAudioBuffer = (ma_audio_buffer*)pDataSource;
|
||||||
|
|
||||||
|
*pCursor = pAudioBuffer->cursor;
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ma_result ma_audio_buffer__data_source_on_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
|
||||||
|
{
|
||||||
|
ma_audio_buffer* pAudioBuffer = (ma_audio_buffer*)pDataSource;
|
||||||
|
|
||||||
|
*pLength = pAudioBuffer->sizeInFrames;
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static ma_result ma_audio_buffer_init_ex(const ma_audio_buffer_config* pConfig, ma_bool32 doCopy, ma_audio_buffer* pAudioBuffer)
|
static ma_result ma_audio_buffer_init_ex(const ma_audio_buffer_config* pConfig, ma_bool32 doCopy, ma_audio_buffer* pAudioBuffer)
|
||||||
{
|
{
|
||||||
if (pAudioBuffer == NULL) {
|
if (pAudioBuffer == NULL) {
|
||||||
@@ -41394,6 +41458,8 @@ static ma_result ma_audio_buffer_init_ex(const ma_audio_buffer_config* pConfig,
|
|||||||
pAudioBuffer->ds.onMap = ma_audio_buffer__data_source_on_map;
|
pAudioBuffer->ds.onMap = ma_audio_buffer__data_source_on_map;
|
||||||
pAudioBuffer->ds.onUnmap = ma_audio_buffer__data_source_on_unmap;
|
pAudioBuffer->ds.onUnmap = ma_audio_buffer__data_source_on_unmap;
|
||||||
pAudioBuffer->ds.onGetDataFormat = ma_audio_buffer__data_source_on_get_data_format;
|
pAudioBuffer->ds.onGetDataFormat = ma_audio_buffer__data_source_on_get_data_format;
|
||||||
|
pAudioBuffer->ds.onGetCursor = ma_audio_buffer__data_source_on_get_cursor;
|
||||||
|
pAudioBuffer->ds.onGetLength = ma_audio_buffer__data_source_on_get_length;
|
||||||
pAudioBuffer->format = pConfig->format;
|
pAudioBuffer->format = pConfig->format;
|
||||||
pAudioBuffer->channels = pConfig->channels;
|
pAudioBuffer->channels = pConfig->channels;
|
||||||
pAudioBuffer->cursor = 0;
|
pAudioBuffer->cursor = 0;
|
||||||
@@ -44433,6 +44499,27 @@ static ma_result ma_decoder__data_source_on_get_data_format(ma_data_source* pDat
|
|||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ma_result ma_decoder__data_source_on_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
|
||||||
|
{
|
||||||
|
ma_decoder* pDecoder = (ma_decoder*)pDataSource;
|
||||||
|
|
||||||
|
*pCursor = pDecoder->readPointerInPCMFrames;
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ma_result ma_decoder__data_source_on_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
|
||||||
|
{
|
||||||
|
ma_decoder* pDecoder = (ma_decoder*)pDataSource;
|
||||||
|
|
||||||
|
*pLength = ma_decoder_get_length_in_pcm_frames(pDecoder);
|
||||||
|
if (*pLength == 0) {
|
||||||
|
return MA_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static ma_result ma_decoder__preinit(ma_decoder_read_proc onRead, ma_decoder_seek_proc onSeek, void* pUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
|
static ma_result ma_decoder__preinit(ma_decoder_read_proc onRead, ma_decoder_seek_proc onSeek, void* pUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
|
||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
@@ -44452,6 +44539,8 @@ static ma_result ma_decoder__preinit(ma_decoder_read_proc onRead, ma_decoder_see
|
|||||||
pDecoder->ds.onRead = ma_decoder__data_source_on_read;
|
pDecoder->ds.onRead = ma_decoder__data_source_on_read;
|
||||||
pDecoder->ds.onSeek = ma_decoder__data_source_on_seek;
|
pDecoder->ds.onSeek = ma_decoder__data_source_on_seek;
|
||||||
pDecoder->ds.onGetDataFormat = ma_decoder__data_source_on_get_data_format;
|
pDecoder->ds.onGetDataFormat = ma_decoder__data_source_on_get_data_format;
|
||||||
|
pDecoder->ds.onGetCursor = ma_decoder__data_source_on_get_cursor;
|
||||||
|
pDecoder->ds.onGetLength = ma_decoder__data_source_on_get_length;
|
||||||
|
|
||||||
pDecoder->onRead = onRead;
|
pDecoder->onRead = onRead;
|
||||||
pDecoder->onSeek = onSeek;
|
pDecoder->onSeek = onSeek;
|
||||||
@@ -46220,6 +46309,15 @@ static ma_result ma_waveform__data_source_on_get_data_format(ma_data_source* pDa
|
|||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ma_result ma_waveform__data_source_on_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
|
||||||
|
{
|
||||||
|
ma_waveform* pWaveform = (ma_waveform*)pDataSource;
|
||||||
|
|
||||||
|
*pCursor = (ma_uint64)(pWaveform->time / pWaveform->advance);
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
MA_API ma_result ma_waveform_init(const ma_waveform_config* pConfig, ma_waveform* pWaveform)
|
MA_API ma_result ma_waveform_init(const ma_waveform_config* pConfig, ma_waveform* pWaveform)
|
||||||
{
|
{
|
||||||
if (pWaveform == NULL) {
|
if (pWaveform == NULL) {
|
||||||
@@ -46230,6 +46328,8 @@ MA_API ma_result ma_waveform_init(const ma_waveform_config* pConfig, ma_waveform
|
|||||||
pWaveform->ds.onRead = ma_waveform__data_source_on_read;
|
pWaveform->ds.onRead = ma_waveform__data_source_on_read;
|
||||||
pWaveform->ds.onSeek = ma_waveform__data_source_on_seek;
|
pWaveform->ds.onSeek = ma_waveform__data_source_on_seek;
|
||||||
pWaveform->ds.onGetDataFormat = ma_waveform__data_source_on_get_data_format;
|
pWaveform->ds.onGetDataFormat = ma_waveform__data_source_on_get_data_format;
|
||||||
|
pWaveform->ds.onGetCursor = ma_waveform__data_source_on_get_cursor;
|
||||||
|
pWaveform->ds.onGetLength = NULL; /* Intentionally set to NULL since there's no notion of a length in waveforms. */
|
||||||
pWaveform->config = *pConfig;
|
pWaveform->config = *pConfig;
|
||||||
pWaveform->advance = 1.0 / pWaveform->config.sampleRate;
|
pWaveform->advance = 1.0 / pWaveform->config.sampleRate;
|
||||||
pWaveform->time = 0;
|
pWaveform->time = 0;
|
||||||
@@ -46619,6 +46719,8 @@ MA_API ma_result ma_noise_init(const ma_noise_config* pConfig, ma_noise* pNoise)
|
|||||||
pNoise->ds.onRead = ma_noise__data_source_on_read;
|
pNoise->ds.onRead = ma_noise__data_source_on_read;
|
||||||
pNoise->ds.onSeek = ma_noise__data_source_on_seek; /* <-- No-op for noise. */
|
pNoise->ds.onSeek = ma_noise__data_source_on_seek; /* <-- No-op for noise. */
|
||||||
pNoise->ds.onGetDataFormat = ma_noise__data_source_on_get_data_format;
|
pNoise->ds.onGetDataFormat = ma_noise__data_source_on_get_data_format;
|
||||||
|
pNoise->ds.onGetCursor = NULL; /* No notion of a cursor for noise. */
|
||||||
|
pNoise->ds.onGetLength = NULL; /* No notion of a length for noise. */
|
||||||
pNoise->config = *pConfig;
|
pNoise->config = *pConfig;
|
||||||
ma_lcg_seed(&pNoise->lcg, pConfig->seed);
|
ma_lcg_seed(&pNoise->lcg, pConfig->seed);
|
||||||
|
|
||||||
|
|||||||
@@ -594,7 +594,9 @@ struct ma_resource_manager_data_stream
|
|||||||
ma_uint32 flags; /* The flags that were passed used to initialize the stream. */
|
ma_uint32 flags; /* The flags that were passed used to initialize the stream. */
|
||||||
ma_decoder decoder; /* Used for filling pages with data. This is only ever accessed by the job thread. The public API should never touch this. */
|
ma_decoder decoder; /* Used for filling pages with data. This is only ever accessed by the job thread. The public API should never touch this. */
|
||||||
ma_bool32 isDecoderInitialized; /* Required for determining whether or not the decoder should be uninitialized in MA_JOB_FREE_DATA_STREAM. */
|
ma_bool32 isDecoderInitialized; /* Required for determining whether or not the decoder should be uninitialized in MA_JOB_FREE_DATA_STREAM. */
|
||||||
|
ma_uint64 totalLengthInPCMFrames; /* This is calculated when first loaded by the MA_JOB_LOAD_DATA_STREAM. */
|
||||||
ma_uint32 relativeCursor; /* The playback cursor, relative to the current page. Only ever accessed by the public API. Never accessed by the job thread. */
|
ma_uint32 relativeCursor; /* The playback cursor, relative to the current page. Only ever accessed by the public API. Never accessed by the job thread. */
|
||||||
|
ma_uint64 absoluteCursor; /* The playback cursor, in absolute position starting from the start of the file. */
|
||||||
ma_uint32 currentPageIndex; /* Toggles between 0 and 1. Index 0 is the first half of pPageData. Index 1 is the second half. Only ever accessed by the public API. Never accessed by the job thread. */
|
ma_uint32 currentPageIndex; /* Toggles between 0 and 1. Index 0 is the first half of pPageData. Index 1 is the second half. Only ever accessed by the public API. Never accessed by the job thread. */
|
||||||
ma_uint32 executionCounter; /* For allocating execution orders for jobs. */
|
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_uint32 executionPointer; /* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */
|
||||||
@@ -666,6 +668,8 @@ MA_API ma_result ma_resource_manager_data_buffer_seek_to_pcm_frame(ma_resource_m
|
|||||||
MA_API ma_result ma_resource_manager_data_buffer_map(ma_resource_manager_data_buffer* pDataBuffer, void** ppFramesOut, ma_uint64* pFrameCount);
|
MA_API ma_result ma_resource_manager_data_buffer_map(ma_resource_manager_data_buffer* pDataBuffer, void** ppFramesOut, ma_uint64* pFrameCount);
|
||||||
MA_API ma_result ma_resource_manager_data_buffer_unmap(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64 frameCount);
|
MA_API ma_result ma_resource_manager_data_buffer_unmap(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64 frameCount);
|
||||||
MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_manager_data_buffer* pDataBuffer, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
|
MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_manager_data_buffer* pDataBuffer, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
|
||||||
|
MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pCursor);
|
||||||
|
MA_API ma_result ma_resource_manager_data_buffer_get_length_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pLength);
|
||||||
MA_API ma_result ma_resource_manager_data_buffer_result(const ma_resource_manager_data_buffer* pDataBuffer);
|
MA_API ma_result ma_resource_manager_data_buffer_result(const ma_resource_manager_data_buffer* pDataBuffer);
|
||||||
MA_API ma_result ma_resource_manager_data_buffer_set_looping(ma_resource_manager_data_buffer* pDataBuffer, ma_bool32 isLooping);
|
MA_API ma_result ma_resource_manager_data_buffer_set_looping(ma_resource_manager_data_buffer* pDataBuffer, ma_bool32 isLooping);
|
||||||
MA_API ma_result ma_resource_manager_data_buffer_get_looping(const ma_resource_manager_data_buffer* pDataBuffer, ma_bool32* pIsLooping);
|
MA_API ma_result ma_resource_manager_data_buffer_get_looping(const ma_resource_manager_data_buffer* pDataBuffer, ma_bool32* pIsLooping);
|
||||||
@@ -679,6 +683,8 @@ MA_API ma_result ma_resource_manager_data_stream_seek_to_pcm_frame(ma_resource_m
|
|||||||
MA_API ma_result ma_resource_manager_data_stream_map(ma_resource_manager_data_stream* pDataStream, void** ppFramesOut, ma_uint64* pFrameCount);
|
MA_API ma_result ma_resource_manager_data_stream_map(ma_resource_manager_data_stream* pDataStream, void** ppFramesOut, ma_uint64* pFrameCount);
|
||||||
MA_API ma_result ma_resource_manager_data_stream_unmap(ma_resource_manager_data_stream* pDataStream, ma_uint64 frameCount);
|
MA_API ma_result ma_resource_manager_data_stream_unmap(ma_resource_manager_data_stream* pDataStream, ma_uint64 frameCount);
|
||||||
MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_manager_data_stream* pDataStream, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
|
MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_manager_data_stream* pDataStream, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
|
||||||
|
MA_API ma_result ma_resource_manager_data_stream_get_cursor_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pCursor);
|
||||||
|
MA_API ma_result ma_resource_manager_data_stream_get_length_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pLength);
|
||||||
MA_API ma_result ma_resource_manager_data_stream_result(const ma_resource_manager_data_stream* pDataStream);
|
MA_API ma_result ma_resource_manager_data_stream_result(const ma_resource_manager_data_stream* pDataStream);
|
||||||
MA_API ma_result ma_resource_manager_data_stream_set_looping(ma_resource_manager_data_stream* pDataStream, ma_bool32 isLooping);
|
MA_API ma_result ma_resource_manager_data_stream_set_looping(ma_resource_manager_data_stream* pDataStream, ma_bool32 isLooping);
|
||||||
MA_API ma_result ma_resource_manager_data_stream_get_looping(const ma_resource_manager_data_stream* pDataStream, ma_bool32* pIsLooping);
|
MA_API ma_result ma_resource_manager_data_stream_get_looping(const ma_resource_manager_data_stream* pDataStream, ma_bool32* pIsLooping);
|
||||||
@@ -692,6 +698,8 @@ MA_API ma_result ma_resource_manager_data_source_seek_to_pcm_frame(ma_resource_m
|
|||||||
MA_API ma_result ma_resource_manager_data_source_map(ma_resource_manager_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount);
|
MA_API ma_result ma_resource_manager_data_source_map(ma_resource_manager_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount);
|
||||||
MA_API ma_result ma_resource_manager_data_source_unmap(ma_resource_manager_data_source* pDataSource, ma_uint64 frameCount);
|
MA_API ma_result ma_resource_manager_data_source_unmap(ma_resource_manager_data_source* pDataSource, ma_uint64 frameCount);
|
||||||
MA_API ma_result ma_resource_manager_data_source_get_data_format(ma_resource_manager_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
|
MA_API ma_result ma_resource_manager_data_source_get_data_format(ma_resource_manager_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
|
||||||
|
MA_API ma_result ma_resource_manager_data_source_get_cursor_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pCursor);
|
||||||
|
MA_API ma_result ma_resource_manager_data_source_get_length_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pLength);
|
||||||
MA_API ma_result ma_resource_manager_data_source_result(const ma_resource_manager_data_source* pDataSource);
|
MA_API ma_result ma_resource_manager_data_source_result(const ma_resource_manager_data_source* pDataSource);
|
||||||
MA_API ma_result ma_resource_manager_data_source_set_looping(ma_resource_manager_data_source* pDataSource, ma_bool32 isLooping);
|
MA_API ma_result ma_resource_manager_data_source_set_looping(ma_resource_manager_data_source* pDataSource, ma_bool32 isLooping);
|
||||||
MA_API ma_result ma_resource_manager_data_source_get_looping(const ma_resource_manager_data_source* pDataSource, ma_bool32* pIsLooping);
|
MA_API ma_result ma_resource_manager_data_source_get_looping(const ma_resource_manager_data_source* pDataSource, ma_bool32* pIsLooping);
|
||||||
@@ -2603,6 +2611,43 @@ MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_man
|
|||||||
return ma_data_source_get_data_format(ma_resource_manager_data_buffer_get_connector(pDataBuffer), pFormat, pChannels, pSampleRate);
|
return ma_data_source_get_data_format(ma_resource_manager_data_buffer_get_connector(pDataBuffer), pFormat, pChannels, pSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pCursor)
|
||||||
|
{
|
||||||
|
/* We cannot be using the data source after it's been uninitialized. */
|
||||||
|
MA_ASSERT(pDataBuffer->pNode->result != MA_UNAVAILABLE);
|
||||||
|
|
||||||
|
if (pDataBuffer == NULL || pCursor == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pCursor = pDataBuffer->cursor;
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_resource_manager_data_buffer_get_length_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pLength)
|
||||||
|
{
|
||||||
|
/* We cannot be using the data source after it's been uninitialized. */
|
||||||
|
MA_ASSERT(pDataBuffer->pNode->result != MA_UNAVAILABLE);
|
||||||
|
|
||||||
|
if (pDataBuffer == NULL || pLength == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDataBuffer->connectorType == ma_resource_manager_data_buffer_connector_unknown) {
|
||||||
|
return MA_BUSY; /* Still loading. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDataBuffer->connectorType == ma_resource_manager_data_buffer_connector_buffer) {
|
||||||
|
*pLength = pDataBuffer->pNode->data.decoded.frameCount;
|
||||||
|
} else {
|
||||||
|
/* TODO: This needs to change. This is too inefficient to be used generally because it may involve scanning the entire file. */
|
||||||
|
*pLength = ma_decoder_get_length_in_pcm_frames(&pDataBuffer->connector.decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
MA_API ma_result ma_resource_manager_data_buffer_result(const ma_resource_manager_data_buffer* pDataBuffer)
|
MA_API ma_result ma_resource_manager_data_buffer_result(const ma_resource_manager_data_buffer* pDataBuffer)
|
||||||
{
|
{
|
||||||
if (pDataBuffer == NULL) {
|
if (pDataBuffer == NULL) {
|
||||||
@@ -3122,6 +3167,9 @@ MA_API ma_result ma_resource_manager_data_stream_unmap(ma_resource_manager_data_
|
|||||||
|
|
||||||
pageSizeInFrames = ma_resource_manager_data_stream_get_page_size_in_frames(pDataStream);
|
pageSizeInFrames = ma_resource_manager_data_stream_get_page_size_in_frames(pDataStream);
|
||||||
|
|
||||||
|
/* The absolute cursor needs to be updated. */
|
||||||
|
pDataStream->absoluteCursor += frameCount;
|
||||||
|
|
||||||
/* Here is where we need to check if we need to load a new page, and if so, post a job to load it. */
|
/* Here is where we need to check if we need to load a new page, and if so, post a job to load it. */
|
||||||
newRelativeCursor = pDataStream->relativeCursor + (ma_uint32)frameCount;
|
newRelativeCursor = pDataStream->relativeCursor + (ma_uint32)frameCount;
|
||||||
|
|
||||||
@@ -3208,6 +3256,49 @@ MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_man
|
|||||||
return ma_data_source_get_data_format(&pDataStream->decoder, pFormat, pChannels, pSampleRate);
|
return ma_data_source_get_data_format(&pDataStream->decoder, pFormat, pChannels, pSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_resource_manager_data_stream_get_cursor_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pCursor)
|
||||||
|
{
|
||||||
|
/* We cannot be using the data source after it's been uninitialized. */
|
||||||
|
MA_ASSERT(pDataStream->result != MA_UNAVAILABLE);
|
||||||
|
|
||||||
|
if (pDataStream == NULL || pCursor == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDataStream->result != MA_SUCCESS) {
|
||||||
|
return MA_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pCursor = pDataStream->absoluteCursor;
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_resource_manager_data_stream_get_length_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pLength)
|
||||||
|
{
|
||||||
|
/* We cannot be using the data source after it's been uninitialized. */
|
||||||
|
MA_ASSERT(pDataStream->result != MA_UNAVAILABLE);
|
||||||
|
|
||||||
|
if (pDataStream == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDataStream->result != MA_SUCCESS) {
|
||||||
|
return MA_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
We most definitely do not want to be calling ma_decoder_get_length_in_pcm_frames() directly. Instead we want to use a cached value that we
|
||||||
|
calculated when we initialized it on the job thread.
|
||||||
|
*/
|
||||||
|
*pLength = pDataStream->totalLengthInPCMFrames;
|
||||||
|
if (*pLength == 0) {
|
||||||
|
return MA_NOT_IMPLEMENTED; /* Some decoders may not have a known length. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
MA_API ma_result ma_resource_manager_data_stream_result(const ma_resource_manager_data_stream* pDataStream)
|
MA_API ma_result ma_resource_manager_data_stream_result(const ma_resource_manager_data_stream* pDataStream)
|
||||||
{
|
{
|
||||||
if (pDataStream == NULL) {
|
if (pDataStream == NULL) {
|
||||||
@@ -3375,6 +3466,32 @@ MA_API ma_result ma_resource_manager_data_source_get_data_format(ma_resource_man
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_resource_manager_data_source_get_cursor_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pCursor)
|
||||||
|
{
|
||||||
|
if (pDataSource == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pDataSource->flags & MA_DATA_SOURCE_FLAG_STREAM) != 0) {
|
||||||
|
return ma_resource_manager_data_stream_get_cursor_in_pcm_frames(&pDataSource->stream, pCursor);
|
||||||
|
} else {
|
||||||
|
return ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(&pDataSource->buffer, pCursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_resource_manager_data_source_get_length_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pLength)
|
||||||
|
{
|
||||||
|
if (pDataSource == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pDataSource->flags & MA_DATA_SOURCE_FLAG_STREAM) != 0) {
|
||||||
|
return ma_resource_manager_data_stream_get_length_in_pcm_frames(&pDataSource->stream, pLength);
|
||||||
|
} else {
|
||||||
|
return ma_resource_manager_data_buffer_get_length_in_pcm_frames(&pDataSource->buffer, pLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MA_API ma_result ma_resource_manager_data_source_result(const ma_resource_manager_data_source* pDataSource)
|
MA_API ma_result ma_resource_manager_data_source_result(const ma_resource_manager_data_source* pDataSource)
|
||||||
{
|
{
|
||||||
if (pDataSource == NULL) {
|
if (pDataSource == NULL) {
|
||||||
@@ -3868,6 +3985,13 @@ static ma_result ma_resource_manager_process_job__load_data_stream(ma_resource_m
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Retrieve the total length of the file before marking the decoder are loaded. */
|
||||||
|
pDataStream->totalLengthInPCMFrames = ma_decoder_get_length_in_pcm_frames(&pDataStream->decoder);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Only mark the decoder as initialized when the length of the decoder has been retrieved because that can possibly require a scan over the whole file
|
||||||
|
and we don't want to have another thread trying to access the decoder while it's scanning.
|
||||||
|
*/
|
||||||
pDataStream->isDecoderInitialized = MA_TRUE;
|
pDataStream->isDecoderInitialized = MA_TRUE;
|
||||||
|
|
||||||
/* We have the decoder so we can now initialize our page buffer. */
|
/* We have the decoder so we can now initialize our page buffer. */
|
||||||
|
|||||||
Reference in New Issue
Block a user