mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-24 09:14:04 +02:00
Add some APIs for ma_audio_buffer and ma_decoder.
* ma_audio_buffer_get_available_frames() * ma_decoder_get_available_frames()
This commit is contained in:
+81
-12
@@ -5288,7 +5288,7 @@ MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer
|
||||
MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount);
|
||||
MA_API ma_result ma_audio_buffer_unmap(ma_audio_buffer* pAudioBuffer, 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_at_end(ma_audio_buffer* pAudioBuffer);
|
||||
|
||||
MA_API ma_result ma_audio_buffer_get_available_frames(ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames);
|
||||
|
||||
|
||||
|
||||
@@ -5407,7 +5407,8 @@ struct ma_decoder
|
||||
ma_decoder_read_proc onRead;
|
||||
ma_decoder_seek_proc onSeek;
|
||||
void* pUserData;
|
||||
ma_uint64 readPointer; /* Used for returning back to a previous position after analysing the stream or whatnot. */
|
||||
ma_uint64 readPointerInBytes; /* In internal encoded data. */
|
||||
ma_uint64 readPointerInPCMFrames; /* In output sample rate. Used for keeping track of how many frames are available for decoding. */
|
||||
ma_format internalFormat;
|
||||
ma_uint32 internalChannels;
|
||||
ma_uint32 internalSampleRate;
|
||||
@@ -5511,6 +5512,17 @@ This is not thread safe without your own synchronization.
|
||||
*/
|
||||
MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 frameIndex);
|
||||
|
||||
/*
|
||||
Retrieves the number of frames that can be read before reaching the end.
|
||||
|
||||
This calls `ma_decoder_get_length_in_pcm_frames()` so you need to be aware of the rules for that function, in
|
||||
particular ensuring you do not call it on streams of an undefined length, such as internet radio.
|
||||
|
||||
If the total length of the decoder cannot be retrieved, such as with Vorbis decoders, `MA_NOT_IMPLEMENTED` will be
|
||||
returned.
|
||||
*/
|
||||
MA_API ma_result ma_decoder_get_available_frames(ma_decoder* pDecoder, ma_uint64* pAvailableFrames);
|
||||
|
||||
/*
|
||||
Helper for opening and decoding a file into a heap allocated block of memory. Free the returned pointer with ma_free(). On input,
|
||||
pConfig should be set to what you want. On output it will be set to what you got.
|
||||
@@ -41616,6 +41628,27 @@ MA_API ma_result ma_audio_buffer_at_end(ma_audio_buffer* pAudioBuffer)
|
||||
return pAudioBuffer->cursor == pAudioBuffer->sizeInFrames;
|
||||
}
|
||||
|
||||
MA_API ma_result ma_audio_buffer_get_available_frames(ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames)
|
||||
{
|
||||
if (pAvailableFrames == NULL) {
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
*pAvailableFrames = 0;
|
||||
|
||||
if (pAudioBuffer == NULL) {
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (pAudioBuffer->sizeInFrames <= pAudioBuffer->cursor) {
|
||||
*pAvailableFrames = 0;
|
||||
} else {
|
||||
*pAvailableFrames = pAudioBuffer->sizeInFrames - pAudioBuffer->cursor;
|
||||
}
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************************************************************************
|
||||
@@ -43427,7 +43460,7 @@ static size_t ma_decoder_read_bytes(ma_decoder* pDecoder, void* pBufferOut, size
|
||||
MA_ASSERT(pBufferOut != NULL);
|
||||
|
||||
bytesRead = pDecoder->onRead(pDecoder, pBufferOut, bytesToRead);
|
||||
pDecoder->readPointer += bytesRead;
|
||||
pDecoder->readPointerInBytes += bytesRead;
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
@@ -43441,9 +43474,9 @@ static ma_bool32 ma_decoder_seek_bytes(ma_decoder* pDecoder, int byteOffset, ma_
|
||||
wasSuccessful = pDecoder->onSeek(pDecoder, byteOffset, origin);
|
||||
if (wasSuccessful) {
|
||||
if (origin == ma_seek_origin_start) {
|
||||
pDecoder->readPointer = (ma_uint64)byteOffset;
|
||||
pDecoder->readPointerInBytes = (ma_uint64)byteOffset;
|
||||
} else {
|
||||
pDecoder->readPointer += byteOffset;
|
||||
pDecoder->readPointerInBytes += byteOffset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45609,17 +45642,15 @@ MA_API ma_uint64 ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesO
|
||||
|
||||
/* Fast path. */
|
||||
if (pDecoder->converter.isPassthrough) {
|
||||
return pDecoder->onReadPCMFrames(pDecoder, pFramesOut, frameCount);
|
||||
}
|
||||
|
||||
totalFramesReadOut = pDecoder->onReadPCMFrames(pDecoder, pFramesOut, frameCount);
|
||||
} else {
|
||||
/*
|
||||
Getting here means we need to do data conversion. If we're seeking forward and are _not_ doing resampling we can run this in a fast path. If we're doing resampling we
|
||||
need to run through each sample because we need to ensure it's internal cache is updated.
|
||||
*/
|
||||
if (pFramesOut == NULL && pDecoder->converter.hasResampler == MA_FALSE) {
|
||||
return pDecoder->onReadPCMFrames(pDecoder, NULL, frameCount); /* All decoder backends must support passing in NULL for the output buffer. */
|
||||
}
|
||||
|
||||
totalFramesReadOut = pDecoder->onReadPCMFrames(pDecoder, NULL, frameCount); /* All decoder backends must support passing in NULL for the output buffer. */
|
||||
} else {
|
||||
/* Slow path. Need to run everything through the data converter. */
|
||||
totalFramesReadOut = 0;
|
||||
totalFramesReadIn = 0;
|
||||
@@ -45670,6 +45701,10 @@ MA_API ma_uint64 ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesO
|
||||
break; /* We're done. */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pDecoder->readPointerInPCMFrames += totalFramesReadOut;
|
||||
|
||||
return totalFramesReadOut;
|
||||
}
|
||||
@@ -45681,6 +45716,7 @@ MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 fr
|
||||
}
|
||||
|
||||
if (pDecoder->onSeekToPCMFrame) {
|
||||
ma_result result;
|
||||
ma_uint64 internalFrameIndex;
|
||||
if (pDecoder->internalSampleRate == pDecoder->outputSampleRate) {
|
||||
internalFrameIndex = frameIndex;
|
||||
@@ -45688,13 +45724,44 @@ MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 fr
|
||||
internalFrameIndex = ma_calculate_frame_count_after_resampling(pDecoder->internalSampleRate, pDecoder->outputSampleRate, frameIndex);
|
||||
}
|
||||
|
||||
return pDecoder->onSeekToPCMFrame(pDecoder, internalFrameIndex);
|
||||
result = pDecoder->onSeekToPCMFrame(pDecoder, internalFrameIndex);
|
||||
if (result == MA_SUCCESS) {
|
||||
pDecoder->readPointerInPCMFrames = frameIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/* Should never get here, but if we do it means onSeekToPCMFrame was not set by the backend. */
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
MA_API ma_result ma_decoder_get_available_frames(ma_decoder* pDecoder, ma_uint64* pAvailableFrames)
|
||||
{
|
||||
ma_uint64 totalFrameCount;
|
||||
|
||||
if (pAvailableFrames == NULL) {
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
*pAvailableFrames = 0;
|
||||
|
||||
if (pDecoder == NULL) {
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
totalFrameCount = ma_decoder_get_length_in_pcm_frames(pDecoder);
|
||||
if (totalFrameCount == 0) {
|
||||
return MA_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (totalFrameCount <= pDecoder->readPointerInPCMFrames) {
|
||||
*pAvailableFrames = 0;
|
||||
} else {
|
||||
*pAvailableFrames = totalFrameCount - pDecoder->readPointerInPCMFrames;
|
||||
}
|
||||
|
||||
return MA_SUCCESS; /* No frames available. */
|
||||
}
|
||||
|
||||
|
||||
static ma_result ma_decoder__full_decode_and_uninit(ma_decoder* pDecoder, ma_decoder_config* pConfigOut, ma_uint64* pFrameCountOut, void** ppPCMFramesOut)
|
||||
{
|
||||
@@ -62292,6 +62359,8 @@ v0.10.16 - TBD
|
||||
- Fix a bug in ma_data_source_read_pcm_frames() where looping doesn't work.
|
||||
- Fix some compilation warnings on Windows when both DirectSound and WinMM are disabled.
|
||||
- Fix some compilation warnings when no decoders are enabled.
|
||||
- Add ma_audio_buffer_get_available_frames()
|
||||
- Add ma_decoder_get_available_frames()
|
||||
- Updates to documentation.
|
||||
|
||||
v0.10.15 - 2020-07-15
|
||||
|
||||
Reference in New Issue
Block a user