Commit d3d98ee3 authored by David Reid's avatar David Reid

Add ma_audio_buffer_ref.

This is a data source whose backing data is an application-controlled
pointer. No data is copied. It's a way of efficiently wrapping a raw
buffer and using it as a data source.
parent aeb51a8e
...@@ -5812,6 +5812,29 @@ MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSo ...@@ -5812,6 +5812,29 @@ MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSo
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. */ 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
{
ma_data_source_callbacks ds;
ma_format format;
ma_uint32 channels;
ma_uint64 cursor;
ma_uint64 sizeInFrames;
const void* pData;
} ma_audio_buffer_ref;
MA_API ma_result ma_audio_buffer_ref_init(ma_format format, ma_uint32 channels, ma_audio_buffer_ref* pAudioBufferRef);
MA_API ma_result ma_audio_buffer_ref_reset(ma_audio_buffer_ref* pAudioBufferRef, const void* pData, ma_uint64 sizeInFrames);
MA_API ma_uint64 ma_audio_buffer_ref_read_pcm_frames(ma_audio_buffer_ref* pAudioBufferRef, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
MA_API ma_result ma_audio_buffer_ref_seek_to_pcm_frame(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameIndex);
MA_API ma_result ma_audio_buffer_ref_map(ma_audio_buffer_ref* pAudioBufferRef, void** ppFramesOut, ma_uint64* pFrameCount);
MA_API ma_result ma_audio_buffer_ref_unmap(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
MA_API ma_result ma_audio_buffer_ref_at_end(ma_audio_buffer_ref* pAudioBufferRef);
MA_API ma_result ma_audio_buffer_ref_get_available_frames(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pAvailableFrames);
typedef struct typedef struct
{ {
ma_format format; ma_format format;
...@@ -5825,12 +5848,7 @@ MA_API ma_audio_buffer_config ma_audio_buffer_config_init(ma_format format, ma_u ...@@ -5825,12 +5848,7 @@ MA_API ma_audio_buffer_config ma_audio_buffer_config_init(ma_format format, ma_u
typedef struct typedef struct
{ {
ma_data_source_callbacks ds; ma_audio_buffer_ref ref;
ma_format format;
ma_uint32 channels;
ma_uint64 cursor;
ma_uint64 sizeInFrames;
const void* pData;
ma_allocation_callbacks allocationCallbacks; ma_allocation_callbacks allocationCallbacks;
ma_bool32 ownsData; /* Used to control whether or not miniaudio owns the data buffer. If set to true, pData will be freed in ma_audio_buffer_uninit(). */ ma_bool32 ownsData; /* Used to control whether or not miniaudio owns the data buffer. If set to true, pData will be freed in ma_audio_buffer_uninit(). */
ma_uint8 _pExtraData[1]; /* For allocating a buffer with the memory located directly after the other memory of the structure. */ ma_uint8 _pExtraData[1]; /* For allocating a buffer with the memory located directly after the other memory of the structure. */
...@@ -43315,24 +43333,10 @@ MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSo ...@@ -43315,24 +43333,10 @@ MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSo
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_audio_buffer_config config;
MA_ZERO_OBJECT(&config);
config.format = format;
config.channels = channels;
config.sizeInFrames = sizeInFrames;
config.pData = pData;
ma_allocation_callbacks_init_copy(&config.allocationCallbacks, pAllocationCallbacks);
return config; static ma_result ma_audio_buffer_ref__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
}
static ma_result ma_audio_buffer__data_source_on_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{ {
ma_uint64 framesRead = ma_audio_buffer_read_pcm_frames((ma_audio_buffer*)pDataSource, pFramesOut, frameCount, MA_FALSE); ma_uint64 framesRead = ma_audio_buffer_ref_read_pcm_frames((ma_audio_buffer_ref*)pDataSource, pFramesOut, frameCount, MA_FALSE);
if (pFramesRead != NULL) { if (pFramesRead != NULL) {
*pFramesRead = framesRead; *pFramesRead = framesRead;
...@@ -43345,52 +43349,247 @@ static ma_result ma_audio_buffer__data_source_on_read(ma_data_source* pDataSourc ...@@ -43345,52 +43349,247 @@ static ma_result ma_audio_buffer__data_source_on_read(ma_data_source* pDataSourc
return MA_SUCCESS; return MA_SUCCESS;
} }
static ma_result ma_audio_buffer__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex) static ma_result ma_audio_buffer_ref__data_source_on_seek(ma_data_source* pDataSource, ma_uint64 frameIndex)
{ {
return ma_audio_buffer_seek_to_pcm_frame((ma_audio_buffer*)pDataSource, frameIndex); return ma_audio_buffer_ref_seek_to_pcm_frame((ma_audio_buffer_ref*)pDataSource, frameIndex);
} }
static ma_result ma_audio_buffer__data_source_on_map(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount) static ma_result ma_audio_buffer_ref__data_source_on_map(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount)
{ {
return ma_audio_buffer_map((ma_audio_buffer*)pDataSource, ppFramesOut, pFrameCount); return ma_audio_buffer_ref_map((ma_audio_buffer_ref*)pDataSource, ppFramesOut, pFrameCount);
} }
static ma_result ma_audio_buffer__data_source_on_unmap(ma_data_source* pDataSource, ma_uint64 frameCount) static ma_result ma_audio_buffer_ref__data_source_on_unmap(ma_data_source* pDataSource, ma_uint64 frameCount)
{ {
return ma_audio_buffer_unmap((ma_audio_buffer*)pDataSource, frameCount); return ma_audio_buffer_ref_unmap((ma_audio_buffer_ref*)pDataSource, frameCount);
} }
static ma_result ma_audio_buffer__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate) static ma_result ma_audio_buffer_ref__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate)
{ {
ma_audio_buffer* pAudioBuffer = (ma_audio_buffer*)pDataSource; ma_audio_buffer_ref* pAudioBufferRef = (ma_audio_buffer_ref*)pDataSource;
*pFormat = pAudioBuffer->format; *pFormat = pAudioBufferRef->format;
*pChannels = pAudioBuffer->channels; *pChannels = pAudioBufferRef->channels;
*pSampleRate = 0; /* There is no notion of a sample rate with audio buffers. */ *pSampleRate = 0; /* There is no notion of a sample rate with audio buffers. */
return MA_SUCCESS; return MA_SUCCESS;
} }
static ma_result ma_audio_buffer__data_source_on_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor) static ma_result ma_audio_buffer_ref__data_source_on_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor)
{
ma_audio_buffer_ref* pAudioBufferRef = (ma_audio_buffer_ref*)pDataSource;
*pCursor = pAudioBufferRef->cursor;
return MA_SUCCESS;
}
static ma_result ma_audio_buffer_ref__data_source_on_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
{
ma_audio_buffer_ref* pAudioBufferRef = (ma_audio_buffer_ref*)pDataSource;
*pLength = pAudioBufferRef->sizeInFrames;
return MA_SUCCESS;
}
MA_API ma_result ma_audio_buffer_ref_init(ma_format format, ma_uint32 channels, ma_audio_buffer_ref* pAudioBufferRef)
{
if (pAudioBufferRef == NULL) {
return MA_INVALID_ARGS;
}
MA_ZERO_OBJECT(pAudioBufferRef);
pAudioBufferRef->ds.onRead = ma_audio_buffer_ref__data_source_on_read;
pAudioBufferRef->ds.onSeek = ma_audio_buffer_ref__data_source_on_seek;
pAudioBufferRef->ds.onMap = ma_audio_buffer_ref__data_source_on_map;
pAudioBufferRef->ds.onUnmap = ma_audio_buffer_ref__data_source_on_unmap;
pAudioBufferRef->ds.onGetDataFormat = ma_audio_buffer_ref__data_source_on_get_data_format;
pAudioBufferRef->ds.onGetCursor = ma_audio_buffer_ref__data_source_on_get_cursor;
pAudioBufferRef->ds.onGetLength = ma_audio_buffer_ref__data_source_on_get_length;
pAudioBufferRef->format = format;
pAudioBufferRef->channels = channels;
pAudioBufferRef->cursor = 0;
pAudioBufferRef->sizeInFrames = 0;
pAudioBufferRef->pData = NULL;
return MA_SUCCESS;
}
MA_API ma_result ma_audio_buffer_ref_reset(ma_audio_buffer_ref* pAudioBufferRef, const void* pData, ma_uint64 sizeInFrames)
{
if (pAudioBufferRef == NULL) {
return MA_INVALID_ARGS;
}
pAudioBufferRef->cursor = 0;
pAudioBufferRef->sizeInFrames = sizeInFrames;
pAudioBufferRef->pData = pData;
return MA_SUCCESS;
}
MA_API ma_uint64 ma_audio_buffer_ref_read_pcm_frames(ma_audio_buffer_ref* pAudioBufferRef, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop)
{ {
ma_audio_buffer* pAudioBuffer = (ma_audio_buffer*)pDataSource; ma_uint64 totalFramesRead = 0;
if (pAudioBufferRef == NULL) {
return 0;
}
if (frameCount == 0) {
return 0;
}
while (totalFramesRead < frameCount) {
ma_uint64 framesAvailable = pAudioBufferRef->sizeInFrames - pAudioBufferRef->cursor;
ma_uint64 framesRemaining = frameCount - totalFramesRead;
ma_uint64 framesToRead;
framesToRead = framesRemaining;
if (framesToRead > framesAvailable) {
framesToRead = framesAvailable;
}
if (pFramesOut != NULL) {
ma_copy_pcm_frames(pFramesOut, ma_offset_ptr(pAudioBufferRef->pData, pAudioBufferRef->cursor * ma_get_bytes_per_frame(pAudioBufferRef->format, pAudioBufferRef->channels)), framesToRead, pAudioBufferRef->format, pAudioBufferRef->channels);
}
totalFramesRead += framesToRead;
pAudioBufferRef->cursor += framesToRead;
if (pAudioBufferRef->cursor == pAudioBufferRef->sizeInFrames) {
if (loop) {
pAudioBufferRef->cursor = 0;
} else {
break; /* We've reached the end and we're not looping. Done. */
}
}
*pCursor = pAudioBuffer->cursor; MA_ASSERT(pAudioBufferRef->cursor < pAudioBufferRef->sizeInFrames);
}
return totalFramesRead;
}
MA_API ma_result ma_audio_buffer_ref_seek_to_pcm_frame(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameIndex)
{
if (pAudioBufferRef == NULL) {
return MA_INVALID_ARGS;
}
if (frameIndex > pAudioBufferRef->sizeInFrames) {
return MA_INVALID_ARGS;
}
pAudioBufferRef->cursor = (size_t)frameIndex;
return MA_SUCCESS; return MA_SUCCESS;
} }
static ma_result ma_audio_buffer__data_source_on_get_length(ma_data_source* pDataSource, ma_uint64* pLength) MA_API ma_result ma_audio_buffer_ref_map(ma_audio_buffer_ref* pAudioBufferRef, void** ppFramesOut, ma_uint64* pFrameCount)
{ {
ma_audio_buffer* pAudioBuffer = (ma_audio_buffer*)pDataSource; ma_uint64 framesAvailable;
ma_uint64 frameCount = 0;
*pLength = pAudioBuffer->sizeInFrames; if (ppFramesOut != NULL) {
*ppFramesOut = NULL; /* Safety. */
}
if (pFrameCount != NULL) {
frameCount = *pFrameCount;
*pFrameCount = 0; /* Safety. */
}
if (pAudioBufferRef == NULL || ppFramesOut == NULL || pFrameCount == NULL) {
return MA_INVALID_ARGS;
}
framesAvailable = pAudioBufferRef->sizeInFrames - pAudioBufferRef->cursor;
if (frameCount > framesAvailable) {
frameCount = framesAvailable;
}
*ppFramesOut = ma_offset_ptr(pAudioBufferRef->pData, pAudioBufferRef->cursor * ma_get_bytes_per_frame(pAudioBufferRef->format, pAudioBufferRef->channels));
*pFrameCount = frameCount;
return MA_SUCCESS; return MA_SUCCESS;
} }
MA_API ma_result ma_audio_buffer_ref_unmap(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameCount)
{
ma_uint64 framesAvailable;
if (pAudioBufferRef == NULL) {
return MA_INVALID_ARGS;
}
framesAvailable = pAudioBufferRef->sizeInFrames - pAudioBufferRef->cursor;
if (frameCount > framesAvailable) {
return MA_INVALID_ARGS; /* The frame count was too big. This should never happen in an unmapping. Need to make sure the caller is aware of this. */
}
pAudioBufferRef->cursor += frameCount;
if (pAudioBufferRef->cursor == pAudioBufferRef->sizeInFrames) {
return MA_AT_END; /* Successful. Need to tell the caller that the end has been reached so that it can loop if desired. */
} else {
return MA_SUCCESS;
}
}
MA_API ma_result ma_audio_buffer_ref_at_end(ma_audio_buffer_ref* pAudioBufferRef)
{
if (pAudioBufferRef == NULL) {
return MA_FALSE;
}
return pAudioBufferRef->cursor == pAudioBufferRef->sizeInFrames;
}
MA_API ma_result ma_audio_buffer_ref_get_available_frames(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pAvailableFrames)
{
if (pAvailableFrames == NULL) {
return MA_INVALID_ARGS;
}
*pAvailableFrames = 0;
if (pAudioBufferRef == NULL) {
return MA_INVALID_ARGS;
}
if (pAudioBufferRef->sizeInFrames <= pAudioBufferRef->cursor) {
*pAvailableFrames = 0;
} else {
*pAvailableFrames = pAudioBufferRef->sizeInFrames - pAudioBufferRef->cursor;
}
return MA_SUCCESS;
}
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_audio_buffer_config config;
MA_ZERO_OBJECT(&config);
config.format = format;
config.channels = channels;
config.sizeInFrames = sizeInFrames;
config.pData = pData;
ma_allocation_callbacks_init_copy(&config.allocationCallbacks, pAllocationCallbacks);
return config;
}
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)
{ {
ma_result result;
if (pAudioBuffer == NULL) { if (pAudioBuffer == NULL) {
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
...@@ -43405,25 +43604,18 @@ static ma_result ma_audio_buffer_init_ex(const ma_audio_buffer_config* pConfig, ...@@ -43405,25 +43604,18 @@ static ma_result ma_audio_buffer_init_ex(const ma_audio_buffer_config* pConfig,
return MA_INVALID_ARGS; /* Not allowing buffer sizes of 0 frames. */ return MA_INVALID_ARGS; /* Not allowing buffer sizes of 0 frames. */
} }
pAudioBuffer->ds.onRead = ma_audio_buffer__data_source_on_read; result = ma_audio_buffer_ref_init(pConfig->format, pConfig->channels, &pAudioBuffer->ref);
pAudioBuffer->ds.onSeek = ma_audio_buffer__data_source_on_seek; if (result != MA_SUCCESS) {
pAudioBuffer->ds.onMap = ma_audio_buffer__data_source_on_map; return result;
pAudioBuffer->ds.onUnmap = ma_audio_buffer__data_source_on_unmap; }
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->channels = pConfig->channels;
pAudioBuffer->cursor = 0;
pAudioBuffer->sizeInFrames = pConfig->sizeInFrames;
pAudioBuffer->pData = NULL; /* Set properly later. */
ma_allocation_callbacks_init_copy(&pAudioBuffer->allocationCallbacks, &pConfig->allocationCallbacks); ma_allocation_callbacks_init_copy(&pAudioBuffer->allocationCallbacks, &pConfig->allocationCallbacks);
if (doCopy) { if (doCopy) {
ma_uint64 allocationSizeInBytes; ma_uint64 allocationSizeInBytes;
void* pData; void* pData;
allocationSizeInBytes = pAudioBuffer->sizeInFrames * ma_get_bytes_per_frame(pAudioBuffer->format, pAudioBuffer->channels); allocationSizeInBytes = pConfig->sizeInFrames * ma_get_bytes_per_frame(pConfig->format, pConfig->channels);
if (allocationSizeInBytes > MA_SIZE_MAX) { if (allocationSizeInBytes > MA_SIZE_MAX) {
return MA_OUT_OF_MEMORY; /* Too big. */ return MA_OUT_OF_MEMORY; /* Too big. */
} }
...@@ -43434,15 +43626,15 @@ static ma_result ma_audio_buffer_init_ex(const ma_audio_buffer_config* pConfig, ...@@ -43434,15 +43626,15 @@ static ma_result ma_audio_buffer_init_ex(const ma_audio_buffer_config* pConfig,
} }
if (pConfig->pData != NULL) { if (pConfig->pData != NULL) {
ma_copy_pcm_frames(pData, pConfig->pData, pAudioBuffer->sizeInFrames, pAudioBuffer->format, pAudioBuffer->channels); ma_copy_pcm_frames(pData, pConfig->pData, pConfig->sizeInFrames, pConfig->format, pConfig->channels);
} else { } else {
ma_silence_pcm_frames(pData, pAudioBuffer->sizeInFrames, pAudioBuffer->format, pAudioBuffer->channels); ma_silence_pcm_frames(pData, pConfig->sizeInFrames, pConfig->format, pConfig->channels);
} }
pAudioBuffer->pData = pData; ma_audio_buffer_ref_reset(&pAudioBuffer->ref, pData, pConfig->sizeInFrames);
pAudioBuffer->ownsData = MA_TRUE; pAudioBuffer->ownsData = MA_TRUE;
} else { } else {
pAudioBuffer->pData = pConfig->pData; ma_audio_buffer_ref_reset(&pAudioBuffer->ref, pConfig->pData, pConfig->sizeInFrames);
pAudioBuffer->ownsData = MA_FALSE; pAudioBuffer->ownsData = MA_FALSE;
} }
...@@ -43455,13 +43647,12 @@ static void ma_audio_buffer_uninit_ex(ma_audio_buffer* pAudioBuffer, ma_bool32 d ...@@ -43455,13 +43647,12 @@ static void ma_audio_buffer_uninit_ex(ma_audio_buffer* pAudioBuffer, ma_bool32 d
return; return;
} }
if (pAudioBuffer->ownsData && pAudioBuffer->pData != &pAudioBuffer->_pExtraData[0]) { if (pAudioBuffer->ownsData && pAudioBuffer->ref.pData != &pAudioBuffer->_pExtraData[0]) {
ma__free_from_callbacks((void*)pAudioBuffer->pData, &pAudioBuffer->allocationCallbacks); /* Naugty const cast, but OK in this case since we've guarded it with the ownsData check. */ ma__free_from_callbacks((void*)pAudioBuffer->ref.pData, &pAudioBuffer->allocationCallbacks); /* Naugty const cast, but OK in this case since we've guarded it with the ownsData check. */
} }
if (doFree) { if (doFree) {
ma_allocation_callbacks allocationCallbacks = pAudioBuffer->allocationCallbacks; ma__free_from_callbacks(pAudioBuffer, &pAudioBuffer->allocationCallbacks);
ma__free_from_callbacks(pAudioBuffer, &allocationCallbacks);
} }
} }
...@@ -43536,45 +43727,11 @@ MA_API void ma_audio_buffer_uninit_and_free(ma_audio_buffer* pAudioBuffer) ...@@ -43536,45 +43727,11 @@ MA_API void ma_audio_buffer_uninit_and_free(ma_audio_buffer* pAudioBuffer)
MA_API ma_uint64 ma_audio_buffer_read_pcm_frames(ma_audio_buffer* pAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop) MA_API ma_uint64 ma_audio_buffer_read_pcm_frames(ma_audio_buffer* pAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop)
{ {
ma_uint64 totalFramesRead = 0;
if (pAudioBuffer == NULL) { if (pAudioBuffer == NULL) {
return 0; return 0;
} }
if (frameCount == 0) { return ma_audio_buffer_ref_read_pcm_frames(&pAudioBuffer->ref, pFramesOut, frameCount, loop);
return 0;
}
while (totalFramesRead < frameCount) {
ma_uint64 framesAvailable = pAudioBuffer->sizeInFrames - pAudioBuffer->cursor;
ma_uint64 framesRemaining = frameCount - totalFramesRead;
ma_uint64 framesToRead;
framesToRead = framesRemaining;
if (framesToRead > framesAvailable) {
framesToRead = framesAvailable;
}
if (pFramesOut != NULL) {
ma_copy_pcm_frames(pFramesOut, ma_offset_ptr(pAudioBuffer->pData, pAudioBuffer->cursor * ma_get_bytes_per_frame(pAudioBuffer->format, pAudioBuffer->channels)), framesToRead, pAudioBuffer->format, pAudioBuffer->channels);
}
totalFramesRead += framesToRead;
pAudioBuffer->cursor += framesToRead;
if (pAudioBuffer->cursor == pAudioBuffer->sizeInFrames) {
if (loop) {
pAudioBuffer->cursor = 0;
} else {
break; /* We've reached the end and we're not looping. Done. */
}
}
MA_ASSERT(pAudioBuffer->cursor < pAudioBuffer->sizeInFrames);
}
return totalFramesRead;
} }
MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer, ma_uint64 frameIndex) MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer, ma_uint64 frameIndex)
...@@ -43583,64 +43740,33 @@ MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer ...@@ -43583,64 +43740,33 @@ MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
if (frameIndex > pAudioBuffer->sizeInFrames) { return ma_audio_buffer_ref_seek_to_pcm_frame(&pAudioBuffer->ref, frameIndex);
return MA_INVALID_ARGS;
}
pAudioBuffer->cursor = (size_t)frameIndex;
return MA_SUCCESS;
} }
MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount) MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount)
{ {
ma_uint64 framesAvailable;
ma_uint64 frameCount = 0;
if (ppFramesOut != NULL) { if (ppFramesOut != NULL) {
*ppFramesOut = NULL; /* Safety. */ *ppFramesOut = NULL; /* Safety. */
} }
if (pFrameCount != NULL) { if (pAudioBuffer == NULL) {
frameCount = *pFrameCount; if (pFrameCount != NULL) {
*pFrameCount = 0; /* Safety. */ *pFrameCount = 0;
} }
if (pAudioBuffer == NULL || ppFramesOut == NULL || pFrameCount == NULL) {
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
framesAvailable = pAudioBuffer->sizeInFrames - pAudioBuffer->cursor; return ma_audio_buffer_ref_map(&pAudioBuffer->ref, ppFramesOut, pFrameCount);
if (frameCount > framesAvailable) {
frameCount = framesAvailable;
}
*ppFramesOut = ma_offset_ptr(pAudioBuffer->pData, pAudioBuffer->cursor * ma_get_bytes_per_frame(pAudioBuffer->format, pAudioBuffer->channels));
*pFrameCount = frameCount;
return MA_SUCCESS;
} }
MA_API ma_result ma_audio_buffer_unmap(ma_audio_buffer* pAudioBuffer, ma_uint64 frameCount) MA_API ma_result ma_audio_buffer_unmap(ma_audio_buffer* pAudioBuffer, ma_uint64 frameCount)
{ {
ma_uint64 framesAvailable;
if (pAudioBuffer == NULL) { if (pAudioBuffer == NULL) {
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
framesAvailable = pAudioBuffer->sizeInFrames - pAudioBuffer->cursor; return ma_audio_buffer_ref_unmap(&pAudioBuffer->ref, frameCount);
if (frameCount > framesAvailable) {
return MA_INVALID_ARGS; /* The frame count was too big. This should never happen in an unmapping. Need to make sure the caller is aware of this. */
}
pAudioBuffer->cursor += frameCount;
if (pAudioBuffer->cursor == pAudioBuffer->sizeInFrames) {
return MA_AT_END; /* Successful. Need to tell the caller that the end has been reached so that it can loop if desired. */
} else {
return MA_SUCCESS;
}
} }
MA_API ma_result ma_audio_buffer_at_end(ma_audio_buffer* pAudioBuffer) MA_API ma_result ma_audio_buffer_at_end(ma_audio_buffer* pAudioBuffer)
...@@ -43649,7 +43775,7 @@ MA_API ma_result ma_audio_buffer_at_end(ma_audio_buffer* pAudioBuffer) ...@@ -43649,7 +43775,7 @@ MA_API ma_result ma_audio_buffer_at_end(ma_audio_buffer* pAudioBuffer)
return MA_FALSE; return MA_FALSE;
} }
return pAudioBuffer->cursor == pAudioBuffer->sizeInFrames; return ma_audio_buffer_ref_at_end(&pAudioBuffer->ref);
} }
MA_API ma_result ma_audio_buffer_get_available_frames(ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames) MA_API ma_result ma_audio_buffer_get_available_frames(ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames)
...@@ -43664,13 +43790,7 @@ MA_API ma_result ma_audio_buffer_get_available_frames(ma_audio_buffer* pAudioBuf ...@@ -43664,13 +43790,7 @@ MA_API ma_result ma_audio_buffer_get_available_frames(ma_audio_buffer* pAudioBuf
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
if (pAudioBuffer->sizeInFrames <= pAudioBuffer->cursor) { return ma_audio_buffer_ref_get_available_frames(&pAudioBuffer->ref, pAvailableFrames);
*pAvailableFrames = 0;
} else {
*pAvailableFrames = pAudioBuffer->sizeInFrames - pAudioBuffer->cursor;
}
return MA_SUCCESS;
} }
...@@ -5531,7 +5531,7 @@ static ma_result ma_resource_manager_data_buffer_init_connector(ma_resource_mana ...@@ -5531,7 +5531,7 @@ static ma_result ma_resource_manager_data_buffer_init_connector(ma_resource_mana
config = ma_audio_buffer_config_init(pDataBuffer->pNode->data.decoded.format, pDataBuffer->pNode->data.decoded.channels, pDataBuffer->pNode->data.decoded.frameCount, pDataBuffer->pNode->data.encoded.pData, NULL); config = ma_audio_buffer_config_init(pDataBuffer->pNode->data.decoded.format, pDataBuffer->pNode->data.decoded.channels, pDataBuffer->pNode->data.decoded.frameCount, pDataBuffer->pNode->data.encoded.pData, NULL);
result = ma_audio_buffer_init(&config, &pDataBuffer->connector.buffer); result = ma_audio_buffer_init(&config, &pDataBuffer->connector.buffer);
pDataBuffer->lengthInPCMFrames = pDataBuffer->connector.buffer.sizeInFrames; pDataBuffer->lengthInPCMFrames = pDataBuffer->connector.buffer.ref.sizeInFrames;
} else { } else {
ma_decoder_config configOut; ma_decoder_config configOut;
configOut = ma_decoder_config_init(pDataBuffer->pResourceManager->config.decodedFormat, pDataBuffer->pResourceManager->config.decodedChannels, pDataBuffer->pResourceManager->config.decodedSampleRate); configOut = ma_decoder_config_init(pDataBuffer->pResourceManager->config.decodedFormat, pDataBuffer->pResourceManager->config.decodedChannels, pDataBuffer->pResourceManager->config.decodedSampleRate);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment