diff --git a/miniaudio.h b/miniaudio.h index 1a561a66..8371b822 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -63796,6 +63796,7 @@ MA_API void ma_audio_ring_buffer_unmap_consume(ma_audio_ring_buffer* pRingBuffer MA_API ma_result ma_audio_ring_buffer_write_pcm_frames(ma_audio_ring_buffer* pRingBuffer, const void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten) { void* pMappedBuffer; + ma_uint32 mappedFrameCount; if (pFramesWritten != NULL) { *pFramesWritten = 0; @@ -63805,20 +63806,35 @@ MA_API ma_result ma_audio_ring_buffer_write_pcm_frames(ma_audio_ring_buffer* pRi return MA_INVALID_ARGS; } - frameCount = ma_ring_buffer_map_produce(&pRingBuffer->rb, frameCount, &pMappedBuffer); + mappedFrameCount = ma_ring_buffer_map_produce(&pRingBuffer->rb, frameCount, &pMappedBuffer); { - size_t bytesToCopy = (size_t)frameCount * ma_get_bytes_per_frame(pRingBuffer->format, pRingBuffer->channels); + /* + When pFramesWritten is null it means the caller has no way of knowing how many frames were actually written. The most + practical thing to do in this case is to treat it as all or nothing. + */ + if (pFramesWritten == NULL && mappedFrameCount != frameCount) { + mappedFrameCount = 0; + } + + if (mappedFrameCount > 0) { + size_t bytesToCopy = (size_t)mappedFrameCount * ma_get_bytes_per_frame(pRingBuffer->format, pRingBuffer->channels); - if (pFrames != NULL) { - MA_COPY_MEMORY(pMappedBuffer, pFrames, bytesToCopy); - } else { - MA_ZERO_MEMORY(pMappedBuffer, bytesToCopy); + if (pFrames != NULL) { + MA_COPY_MEMORY(pMappedBuffer, pFrames, bytesToCopy); + } else { + MA_ZERO_MEMORY(pMappedBuffer, bytesToCopy); + } } } - ma_ring_buffer_unmap_produce(&pRingBuffer->rb, frameCount); + ma_ring_buffer_unmap_produce(&pRingBuffer->rb, mappedFrameCount); if (pFramesWritten != NULL) { - *pFramesWritten = frameCount; + *pFramesWritten = mappedFrameCount; + } else { + /* When pFramesWritten is null we need to treat it as all or nothing. */ + if (mappedFrameCount != frameCount) { + return MA_NO_SPACE; + } } return MA_SUCCESS; @@ -63827,6 +63843,7 @@ MA_API ma_result ma_audio_ring_buffer_write_pcm_frames(ma_audio_ring_buffer* pRi MA_API ma_result ma_audio_ring_buffer_read_pcm_frames(ma_audio_ring_buffer* pRingBuffer, void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesRead) { void* pMappedBuffer; + ma_uint32 mappedFrameCount; if (pFramesRead != NULL) { *pFramesRead = 0; @@ -63836,18 +63853,33 @@ MA_API ma_result ma_audio_ring_buffer_read_pcm_frames(ma_audio_ring_buffer* pRin return MA_INVALID_ARGS; } - frameCount = ma_ring_buffer_map_consume(&pRingBuffer->rb, frameCount, &pMappedBuffer); + mappedFrameCount = ma_ring_buffer_map_consume(&pRingBuffer->rb, frameCount, &pMappedBuffer); { - size_t bytesToCopy = (size_t)frameCount * ma_get_bytes_per_frame(pRingBuffer->format, pRingBuffer->channels); + /* + When pFramesRead is null it means the caller has no way of knowing how many frames were actually read. The most + practical thing to do in this case is to treat it as all or nothing. + */ + if (pFramesRead == NULL && mappedFrameCount != frameCount) { + mappedFrameCount = 0; + } - if (pFrames != NULL) { - MA_COPY_MEMORY(pFrames, pMappedBuffer, bytesToCopy); + if (mappedFrameCount > 0) { + size_t bytesToCopy = (size_t)mappedFrameCount * ma_get_bytes_per_frame(pRingBuffer->format, pRingBuffer->channels); + + if (pFrames != NULL) { + MA_COPY_MEMORY(pFrames, pMappedBuffer, bytesToCopy); + } } } - ma_ring_buffer_unmap_consume(&pRingBuffer->rb, frameCount); + ma_ring_buffer_unmap_consume(&pRingBuffer->rb, mappedFrameCount); if (pFramesRead != NULL) { - *pFramesRead = frameCount; + *pFramesRead = mappedFrameCount; + } else { + /* When pFramesRead is null we need to treat it as all or nothing. */ + if (mappedFrameCount != frameCount) { + return MA_NO_DATA_AVAILABLE; + } } return MA_SUCCESS;