Commit 8686f52e authored by David Reid's avatar David Reid

Version 0.10.43

parent cc99951f
/* /*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
miniaudio - v0.10.42 - 2021-08-22 miniaudio - v0.10.43 - 2021-12-10
David Reid - mackron@gmail.com David Reid - mackron@gmail.com
...@@ -2624,7 +2624,7 @@ typedef unsigned char c89atomic_bool; ...@@ -2624,7 +2624,7 @@ typedef unsigned char c89atomic_bool;
#define C89ATOMIC_X64 #define C89ATOMIC_X64
#elif defined(__i386) || defined(_M_IX86) #elif defined(__i386) || defined(_M_IX86)
#define C89ATOMIC_X86 #define C89ATOMIC_X86
#elif defined(__arm__) || defined(_M_ARM) #elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
#define C89ATOMIC_ARM #define C89ATOMIC_ARM
#endif #endif
#if defined(_MSC_VER) #if defined(_MSC_VER)
...@@ -13863,10 +13863,11 @@ static ma_result ma_context_enumerate_devices__alsa(ma_context* pContext, ma_enu ...@@ -13863,10 +13863,11 @@ static ma_result ma_context_enumerate_devices__alsa(ma_context* pContext, ma_enu
/* /*
Some devices are both playback and capture, but they are only enumerated by ALSA once. We need to fire the callback Some devices are both playback and capture, but they are only enumerated by ALSA once. We need to fire the callback
again for the other device type in this case. We do this for known devices. again for the other device type in this case. We do this for known devices and where the IOID hint is NULL, which
means both Input and Output.
*/ */
if (cbResult) { if (cbResult) {
if (ma_is_common_device_name__alsa(NAME)) { if (ma_is_common_device_name__alsa(NAME) || IOID == NULL) {
if (deviceType == ma_device_type_playback) { if (deviceType == ma_device_type_playback) {
if (!ma_is_capture_device_blacklisted__alsa(NAME)) { if (!ma_is_capture_device_blacklisted__alsa(NAME)) {
cbResult = callback(pContext, ma_device_type_capture, &deviceInfo, pUserData); cbResult = callback(pContext, ma_device_type_capture, &deviceInfo, pUserData);
...@@ -14684,7 +14685,7 @@ static ma_result ma_device_wait_write__alsa(ma_device* pDevice) ...@@ -14684,7 +14685,7 @@ static ma_result ma_device_wait_write__alsa(ma_device* pDevice)
static ma_result ma_device_read__alsa(ma_device* pDevice, void* pFramesOut, ma_uint32 frameCount, ma_uint32* pFramesRead) static ma_result ma_device_read__alsa(ma_device* pDevice, void* pFramesOut, ma_uint32 frameCount, ma_uint32* pFramesRead)
{ {
ma_snd_pcm_sframes_t resultALSA; ma_snd_pcm_sframes_t resultALSA = 0;
MA_ASSERT(pDevice != NULL); MA_ASSERT(pDevice != NULL);
MA_ASSERT(pFramesOut != NULL); MA_ASSERT(pFramesOut != NULL);
...@@ -14738,7 +14739,7 @@ static ma_result ma_device_read__alsa(ma_device* pDevice, void* pFramesOut, ma_u ...@@ -14738,7 +14739,7 @@ static ma_result ma_device_read__alsa(ma_device* pDevice, void* pFramesOut, ma_u
static ma_result ma_device_write__alsa(ma_device* pDevice, const void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten) static ma_result ma_device_write__alsa(ma_device* pDevice, const void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten)
{ {
ma_snd_pcm_sframes_t resultALSA; ma_snd_pcm_sframes_t resultALSA = 0;
MA_ASSERT(pDevice != NULL); MA_ASSERT(pDevice != NULL);
MA_ASSERT(pFrames != NULL); MA_ASSERT(pFrames != NULL);
...@@ -16935,7 +16936,7 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi ...@@ -16935,7 +16936,7 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi
attr = *pActualAttr; attr = *pActualAttr;
} }
pDescriptorPlayback->periodCount = attr.maxlength / attr.tlength; pDescriptorPlayback->periodCount = ma_max(attr.maxlength / attr.tlength, 1);
pDescriptorPlayback->periodSizeInFrames = attr.maxlength / ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels) / pDescriptorPlayback->periodCount; pDescriptorPlayback->periodSizeInFrames = attr.maxlength / ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels) / pDescriptorPlayback->periodCount;
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[PulseAudio] Playback actual attr: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d, fragsize=%d; internalPeriodSizeInFrames=%d\n", attr.maxlength, attr.tlength, attr.prebuf, attr.minreq, attr.fragsize, pDescriptorPlayback->periodSizeInFrames); ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "[PulseAudio] Playback actual attr: maxlength=%d, tlength=%d, prebuf=%d, minreq=%d, fragsize=%d; internalPeriodSizeInFrames=%d\n", attr.maxlength, attr.tlength, attr.prebuf, attr.minreq, attr.fragsize, pDescriptorPlayback->periodSizeInFrames);
...@@ -25770,7 +25771,7 @@ static ma_result ma_device_init_by_type__webaudio(ma_device* pDevice, const ma_d ...@@ -25770,7 +25771,7 @@ static ma_result ma_device_init_by_type__webaudio(ma_device* pDevice, const ma_d
var isCapture = $3; var isCapture = $3;
var pDevice = $4; var pDevice = $4;
if (typeof(miniaudio) === 'undefined') { if (typeof(window.miniaudio) === 'undefined') {
return -1; /* Context not initialized. */ return -1; /* Context not initialized. */
} }
...@@ -26067,8 +26068,8 @@ static ma_result ma_context_init__webaudio(ma_context* pContext, const ma_contex ...@@ -26067,8 +26068,8 @@ static ma_result ma_context_init__webaudio(ma_context* pContext, const ma_contex
return 0; /* Web Audio not supported. */ return 0; /* Web Audio not supported. */
} }
if (typeof(miniaudio) === 'undefined') { if (typeof(window.miniaudio) === 'undefined') {
miniaudio = {}; window.miniaudio = {};
miniaudio.devices = []; /* Device cache for mapping devices to indexes for JavaScript/C interop. */ miniaudio.devices = []; /* Device cache for mapping devices to indexes for JavaScript/C interop. */
miniaudio.track_device = function(device) { miniaudio.track_device = function(device) {
...@@ -39463,7 +39464,7 @@ extern "C" { ...@@ -39463,7 +39464,7 @@ extern "C" {
#define DRWAV_XSTRINGIFY(x) DRWAV_STRINGIFY(x) #define DRWAV_XSTRINGIFY(x) DRWAV_STRINGIFY(x)
#define DRWAV_VERSION_MAJOR 0 #define DRWAV_VERSION_MAJOR 0
#define DRWAV_VERSION_MINOR 13 #define DRWAV_VERSION_MINOR 13
#define DRWAV_VERSION_REVISION 1 #define DRWAV_VERSION_REVISION 4
#define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION) #define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION)
#include <stddef.h> #include <stddef.h>
typedef signed char drwav_int8; typedef signed char drwav_int8;
...@@ -46323,6 +46324,7 @@ code below please report the bug to the respective repository for the relevant p ...@@ -46323,6 +46324,7 @@ code below please report the bug to the respective repository for the relevant p
#define drwav_min(a, b) (((a) < (b)) ? (a) : (b)) #define drwav_min(a, b) (((a) < (b)) ? (a) : (b))
#define drwav_max(a, b) (((a) > (b)) ? (a) : (b)) #define drwav_max(a, b) (((a) > (b)) ? (a) : (b))
#define drwav_clamp(x, lo, hi) (drwav_max((lo), drwav_min((hi), (x)))) #define drwav_clamp(x, lo, hi) (drwav_max((lo), drwav_min((hi), (x))))
#define drwav_offset_ptr(p, offset) (((drwav_uint8*)(p)) + (offset))
#define DRWAV_MAX_SIMD_VECTOR_SIZE 64 #define DRWAV_MAX_SIMD_VECTOR_SIZE 64
#if defined(__x86_64__) || defined(_M_X64) #if defined(__x86_64__) || defined(_M_X64)
#define DRWAV_X64 #define DRWAV_X64
...@@ -46566,6 +46568,9 @@ static DRWAV_INLINE void drwav__bswap_samples_pcm(void* pSamples, drwav_uint64 s ...@@ -46566,6 +46568,9 @@ static DRWAV_INLINE void drwav__bswap_samples_pcm(void* pSamples, drwav_uint64 s
{ {
switch (bytesPerSample) switch (bytesPerSample)
{ {
case 1:
{
} break;
case 2: case 2:
{ {
drwav__bswap_samples_s16((drwav_int16*)pSamples, sampleCount); drwav__bswap_samples_s16((drwav_int16*)pSamples, sampleCount);
...@@ -46976,12 +46981,13 @@ DRWAV_PRIVATE size_t drwav__metadata_parser_read(drwav__metadata_parser* pParser ...@@ -46976,12 +46981,13 @@ DRWAV_PRIVATE size_t drwav__metadata_parser_read(drwav__metadata_parser* pParser
return pParser->onRead(pParser->pReadSeekUserData, pBufferOut, bytesToRead); return pParser->onRead(pParser->pReadSeekUserData, pBufferOut, bytesToRead);
} }
} }
DRWAV_PRIVATE drwav_uint64 drwav__read_smpl_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata) DRWAV_PRIVATE drwav_uint64 drwav__read_smpl_to_metadata_obj(drwav__metadata_parser* pParser, const drwav_chunk_header* pChunkHeader, drwav_metadata* pMetadata)
{ {
drwav_uint8 smplHeaderData[DRWAV_SMPL_BYTES]; drwav_uint8 smplHeaderData[DRWAV_SMPL_BYTES];
drwav_uint64 totalBytesRead = 0; drwav_uint64 totalBytesRead = 0;
size_t bytesJustRead = drwav__metadata_parser_read(pParser, smplHeaderData, sizeof(smplHeaderData), &totalBytesRead); size_t bytesJustRead = drwav__metadata_parser_read(pParser, smplHeaderData, sizeof(smplHeaderData), &totalBytesRead);
DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read); DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);
DRWAV_ASSERT(pChunkHeader != NULL);
if (bytesJustRead == sizeof(smplHeaderData)) { if (bytesJustRead == sizeof(smplHeaderData)) {
drwav_uint32 iSampleLoop; drwav_uint32 iSampleLoop;
pMetadata->type = drwav_metadata_type_smpl; pMetadata->type = drwav_metadata_type_smpl;
...@@ -46994,30 +47000,32 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_smpl_to_metadata_obj(drwav__metadata_pars ...@@ -46994,30 +47000,32 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_smpl_to_metadata_obj(drwav__metadata_pars
pMetadata->data.smpl.smpteOffset = drwav_bytes_to_u32(smplHeaderData + 24); pMetadata->data.smpl.smpteOffset = drwav_bytes_to_u32(smplHeaderData + 24);
pMetadata->data.smpl.sampleLoopCount = drwav_bytes_to_u32(smplHeaderData + 28); pMetadata->data.smpl.sampleLoopCount = drwav_bytes_to_u32(smplHeaderData + 28);
pMetadata->data.smpl.samplerSpecificDataSizeInBytes = drwav_bytes_to_u32(smplHeaderData + 32); pMetadata->data.smpl.samplerSpecificDataSizeInBytes = drwav_bytes_to_u32(smplHeaderData + 32);
pMetadata->data.smpl.pLoops = (drwav_smpl_loop*)drwav__metadata_get_memory(pParser, sizeof(drwav_smpl_loop) * pMetadata->data.smpl.sampleLoopCount, DRWAV_METADATA_ALIGNMENT); if (pMetadata->data.smpl.sampleLoopCount == (pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES) {
for (iSampleLoop = 0; iSampleLoop < pMetadata->data.smpl.sampleLoopCount; ++iSampleLoop) { pMetadata->data.smpl.pLoops = (drwav_smpl_loop*)drwav__metadata_get_memory(pParser, sizeof(drwav_smpl_loop) * pMetadata->data.smpl.sampleLoopCount, DRWAV_METADATA_ALIGNMENT);
drwav_uint8 smplLoopData[DRWAV_SMPL_LOOP_BYTES]; for (iSampleLoop = 0; iSampleLoop < pMetadata->data.smpl.sampleLoopCount; ++iSampleLoop) {
bytesJustRead = drwav__metadata_parser_read(pParser, smplLoopData, sizeof(smplLoopData), &totalBytesRead); drwav_uint8 smplLoopData[DRWAV_SMPL_LOOP_BYTES];
if (bytesJustRead == sizeof(smplLoopData)) { bytesJustRead = drwav__metadata_parser_read(pParser, smplLoopData, sizeof(smplLoopData), &totalBytesRead);
pMetadata->data.smpl.pLoops[iSampleLoop].cuePointId = drwav_bytes_to_u32(smplLoopData + 0); if (bytesJustRead == sizeof(smplLoopData)) {
pMetadata->data.smpl.pLoops[iSampleLoop].type = drwav_bytes_to_u32(smplLoopData + 4); pMetadata->data.smpl.pLoops[iSampleLoop].cuePointId = drwav_bytes_to_u32(smplLoopData + 0);
pMetadata->data.smpl.pLoops[iSampleLoop].firstSampleByteOffset = drwav_bytes_to_u32(smplLoopData + 8); pMetadata->data.smpl.pLoops[iSampleLoop].type = drwav_bytes_to_u32(smplLoopData + 4);
pMetadata->data.smpl.pLoops[iSampleLoop].lastSampleByteOffset = drwav_bytes_to_u32(smplLoopData + 12); pMetadata->data.smpl.pLoops[iSampleLoop].firstSampleByteOffset = drwav_bytes_to_u32(smplLoopData + 8);
pMetadata->data.smpl.pLoops[iSampleLoop].sampleFraction = drwav_bytes_to_u32(smplLoopData + 16); pMetadata->data.smpl.pLoops[iSampleLoop].lastSampleByteOffset = drwav_bytes_to_u32(smplLoopData + 12);
pMetadata->data.smpl.pLoops[iSampleLoop].playCount = drwav_bytes_to_u32(smplLoopData + 20); pMetadata->data.smpl.pLoops[iSampleLoop].sampleFraction = drwav_bytes_to_u32(smplLoopData + 16);
} else { pMetadata->data.smpl.pLoops[iSampleLoop].playCount = drwav_bytes_to_u32(smplLoopData + 20);
break; } else {
break;
}
}
if (pMetadata->data.smpl.samplerSpecificDataSizeInBytes > 0) {
pMetadata->data.smpl.pSamplerSpecificData = drwav__metadata_get_memory(pParser, pMetadata->data.smpl.samplerSpecificDataSizeInBytes, 1);
DRWAV_ASSERT(pMetadata->data.smpl.pSamplerSpecificData != NULL);
drwav__metadata_parser_read(pParser, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes, &totalBytesRead);
} }
}
if (pMetadata->data.smpl.samplerSpecificDataSizeInBytes > 0) {
pMetadata->data.smpl.pSamplerSpecificData = drwav__metadata_get_memory(pParser, pMetadata->data.smpl.samplerSpecificDataSizeInBytes, 1);
DRWAV_ASSERT(pMetadata->data.smpl.pSamplerSpecificData != NULL);
bytesJustRead = drwav__metadata_parser_read(pParser, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes, &totalBytesRead);
} }
} }
return totalBytesRead; return totalBytesRead;
} }
DRWAV_PRIVATE drwav_uint64 drwav__read_cue_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata) DRWAV_PRIVATE drwav_uint64 drwav__read_cue_to_metadata_obj(drwav__metadata_parser* pParser, const drwav_chunk_header* pChunkHeader, drwav_metadata* pMetadata)
{ {
drwav_uint8 cueHeaderSectionData[DRWAV_CUE_BYTES]; drwav_uint8 cueHeaderSectionData[DRWAV_CUE_BYTES];
drwav_uint64 totalBytesRead = 0; drwav_uint64 totalBytesRead = 0;
...@@ -47026,25 +47034,27 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_cue_to_metadata_obj(drwav__metadata_parse ...@@ -47026,25 +47034,27 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_cue_to_metadata_obj(drwav__metadata_parse
if (bytesJustRead == sizeof(cueHeaderSectionData)) { if (bytesJustRead == sizeof(cueHeaderSectionData)) {
pMetadata->type = drwav_metadata_type_cue; pMetadata->type = drwav_metadata_type_cue;
pMetadata->data.cue.cuePointCount = drwav_bytes_to_u32(cueHeaderSectionData); pMetadata->data.cue.cuePointCount = drwav_bytes_to_u32(cueHeaderSectionData);
pMetadata->data.cue.pCuePoints = (drwav_cue_point*)drwav__metadata_get_memory(pParser, sizeof(drwav_cue_point) * pMetadata->data.cue.cuePointCount, DRWAV_METADATA_ALIGNMENT); if (pMetadata->data.cue.cuePointCount == (pChunkHeader->sizeInBytes - DRWAV_CUE_BYTES) / DRWAV_CUE_POINT_BYTES) {
DRWAV_ASSERT(pMetadata->data.cue.pCuePoints != NULL); pMetadata->data.cue.pCuePoints = (drwav_cue_point*)drwav__metadata_get_memory(pParser, sizeof(drwav_cue_point) * pMetadata->data.cue.cuePointCount, DRWAV_METADATA_ALIGNMENT);
if (pMetadata->data.cue.cuePointCount > 0) { DRWAV_ASSERT(pMetadata->data.cue.pCuePoints != NULL);
drwav_uint32 iCuePoint; if (pMetadata->data.cue.cuePointCount > 0) {
for (iCuePoint = 0; iCuePoint < pMetadata->data.cue.cuePointCount; ++iCuePoint) { drwav_uint32 iCuePoint;
drwav_uint8 cuePointData[DRWAV_CUE_POINT_BYTES]; for (iCuePoint = 0; iCuePoint < pMetadata->data.cue.cuePointCount; ++iCuePoint) {
bytesJustRead = drwav__metadata_parser_read(pParser, cuePointData, sizeof(cuePointData), &totalBytesRead); drwav_uint8 cuePointData[DRWAV_CUE_POINT_BYTES];
if (bytesJustRead == sizeof(cuePointData)) { bytesJustRead = drwav__metadata_parser_read(pParser, cuePointData, sizeof(cuePointData), &totalBytesRead);
pMetadata->data.cue.pCuePoints[iCuePoint].id = drwav_bytes_to_u32(cuePointData + 0); if (bytesJustRead == sizeof(cuePointData)) {
pMetadata->data.cue.pCuePoints[iCuePoint].playOrderPosition = drwav_bytes_to_u32(cuePointData + 4); pMetadata->data.cue.pCuePoints[iCuePoint].id = drwav_bytes_to_u32(cuePointData + 0);
pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[0] = cuePointData[8]; pMetadata->data.cue.pCuePoints[iCuePoint].playOrderPosition = drwav_bytes_to_u32(cuePointData + 4);
pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[1] = cuePointData[9]; pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[0] = cuePointData[8];
pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[2] = cuePointData[10]; pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[1] = cuePointData[9];
pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[3] = cuePointData[11]; pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[2] = cuePointData[10];
pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart = drwav_bytes_to_u32(cuePointData + 12); pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[3] = cuePointData[11];
pMetadata->data.cue.pCuePoints[iCuePoint].blockStart = drwav_bytes_to_u32(cuePointData + 16); pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart = drwav_bytes_to_u32(cuePointData + 12);
pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset = drwav_bytes_to_u32(cuePointData + 20); pMetadata->data.cue.pCuePoints[iCuePoint].blockStart = drwav_bytes_to_u32(cuePointData + 16);
} else { pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset = drwav_bytes_to_u32(cuePointData + 20);
break; } else {
break;
}
} }
} }
} }
...@@ -47086,7 +47096,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_acid_to_metadata_obj(drwav__metadata_pars ...@@ -47086,7 +47096,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_acid_to_metadata_obj(drwav__metadata_pars
} }
return bytesRead; return bytesRead;
} }
DRWAV_PRIVATE size_t drwav__strlen_clamped(char* str, size_t maxToRead) DRWAV_PRIVATE size_t drwav__strlen_clamped(const char* str, size_t maxToRead)
{ {
size_t result = 0; size_t result = 0;
while (*str++ && result < maxToRead) { while (*str++ && result < maxToRead) {
...@@ -47094,7 +47104,7 @@ DRWAV_PRIVATE size_t drwav__strlen_clamped(char* str, size_t maxToRead) ...@@ -47094,7 +47104,7 @@ DRWAV_PRIVATE size_t drwav__strlen_clamped(char* str, size_t maxToRead)
} }
return result; return result;
} }
DRWAV_PRIVATE char* drwav__metadata_copy_string(drwav__metadata_parser* pParser, char* str, size_t maxToRead) DRWAV_PRIVATE char* drwav__metadata_copy_string(drwav__metadata_parser* pParser, const char* str, size_t maxToRead)
{ {
size_t len = drwav__strlen_clamped(str, maxToRead); size_t len = drwav__strlen_clamped(str, maxToRead);
if (len) { if (len) {
...@@ -47107,58 +47117,134 @@ DRWAV_PRIVATE char* drwav__metadata_copy_string(drwav__metadata_parser* pParser, ...@@ -47107,58 +47117,134 @@ DRWAV_PRIVATE char* drwav__metadata_copy_string(drwav__metadata_parser* pParser,
return NULL; return NULL;
} }
} }
typedef struct
{
const void* pBuffer;
size_t sizeInBytes;
size_t cursor;
} drwav_buffer_reader;
DRWAV_PRIVATE drwav_result drwav_buffer_reader_init(const void* pBuffer, size_t sizeInBytes, drwav_buffer_reader* pReader)
{
DRWAV_ASSERT(pBuffer != NULL);
DRWAV_ASSERT(pReader != NULL);
DRWAV_ZERO_OBJECT(pReader);
pReader->pBuffer = pBuffer;
pReader->sizeInBytes = sizeInBytes;
pReader->cursor = 0;
return DRWAV_SUCCESS;
}
DRWAV_PRIVATE const void* drwav_buffer_reader_ptr(const drwav_buffer_reader* pReader)
{
DRWAV_ASSERT(pReader != NULL);
return drwav_offset_ptr(pReader->pBuffer, pReader->cursor);
}
DRWAV_PRIVATE drwav_result drwav_buffer_reader_seek(drwav_buffer_reader* pReader, size_t bytesToSeek)
{
DRWAV_ASSERT(pReader != NULL);
if (pReader->cursor + bytesToSeek > pReader->sizeInBytes) {
return DRWAV_BAD_SEEK;
}
pReader->cursor += bytesToSeek;
return DRWAV_SUCCESS;
}
DRWAV_PRIVATE drwav_result drwav_buffer_reader_read(drwav_buffer_reader* pReader, void* pDst, size_t bytesToRead, size_t* pBytesRead)
{
drwav_result result = DRWAV_SUCCESS;
size_t bytesRemaining;
DRWAV_ASSERT(pReader != NULL);
if (pBytesRead != NULL) {
*pBytesRead = 0;
}
bytesRemaining = (pReader->sizeInBytes - pReader->cursor);
if (bytesToRead > bytesRemaining) {
bytesToRead = bytesRemaining;
}
if (pDst == NULL) {
result = drwav_buffer_reader_seek(pReader, bytesToRead);
} else {
DRWAV_COPY_MEMORY(pDst, drwav_buffer_reader_ptr(pReader), bytesToRead);
pReader->cursor += bytesToRead;
}
DRWAV_ASSERT(pReader->cursor <= pReader->sizeInBytes);
if (result == DRWAV_SUCCESS) {
if (pBytesRead != NULL) {
*pBytesRead = bytesToRead;
}
}
return DRWAV_SUCCESS;
}
DRWAV_PRIVATE drwav_result drwav_buffer_reader_read_u16(drwav_buffer_reader* pReader, drwav_uint16* pDst)
{
drwav_result result;
size_t bytesRead;
drwav_uint8 data[2];
DRWAV_ASSERT(pReader != NULL);
DRWAV_ASSERT(pDst != NULL);
*pDst = 0;
result = drwav_buffer_reader_read(pReader, data, sizeof(*pDst), &bytesRead);
if (result != DRWAV_SUCCESS || bytesRead != sizeof(*pDst)) {
return result;
}
*pDst = drwav_bytes_to_u16(data);
return DRWAV_SUCCESS;
}
DRWAV_PRIVATE drwav_result drwav_buffer_reader_read_u32(drwav_buffer_reader* pReader, drwav_uint32* pDst)
{
drwav_result result;
size_t bytesRead;
drwav_uint8 data[4];
DRWAV_ASSERT(pReader != NULL);
DRWAV_ASSERT(pDst != NULL);
*pDst = 0;
result = drwav_buffer_reader_read(pReader, data, sizeof(*pDst), &bytesRead);
if (result != DRWAV_SUCCESS || bytesRead != sizeof(*pDst)) {
return result;
}
*pDst = drwav_bytes_to_u32(data);
return DRWAV_SUCCESS;
}
DRWAV_PRIVATE drwav_uint64 drwav__read_bext_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata, drwav_uint64 chunkSize) DRWAV_PRIVATE drwav_uint64 drwav__read_bext_to_metadata_obj(drwav__metadata_parser* pParser, drwav_metadata* pMetadata, drwav_uint64 chunkSize)
{ {
drwav_uint8 bextData[DRWAV_BEXT_BYTES]; drwav_uint8 bextData[DRWAV_BEXT_BYTES];
drwav_uint64 bytesRead = drwav__metadata_parser_read(pParser, bextData, sizeof(bextData), NULL); size_t bytesRead = drwav__metadata_parser_read(pParser, bextData, sizeof(bextData), NULL);
DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read); DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);
if (bytesRead == sizeof(bextData)) { if (bytesRead == sizeof(bextData)) {
drwav_uint8* pReadPointer; drwav_buffer_reader reader;
drwav_uint32 timeReferenceLow; drwav_uint32 timeReferenceLow;
drwav_uint32 timeReferenceHigh; drwav_uint32 timeReferenceHigh;
size_t extraBytes; size_t extraBytes;
pMetadata->type = drwav_metadata_type_bext; pMetadata->type = drwav_metadata_type_bext;
pReadPointer = bextData; if (drwav_buffer_reader_init(bextData, bytesRead, &reader) == DRWAV_SUCCESS) {
pMetadata->data.bext.pDescription = drwav__metadata_copy_string(pParser, (char*)(pReadPointer), DRWAV_BEXT_DESCRIPTION_BYTES); pMetadata->data.bext.pDescription = drwav__metadata_copy_string(pParser, (const char*)drwav_buffer_reader_ptr(&reader), DRWAV_BEXT_DESCRIPTION_BYTES);
pReadPointer += DRWAV_BEXT_DESCRIPTION_BYTES; drwav_buffer_reader_seek(&reader, DRWAV_BEXT_DESCRIPTION_BYTES);
pMetadata->data.bext.pOriginatorName = drwav__metadata_copy_string(pParser, (char*)(pReadPointer), DRWAV_BEXT_ORIGINATOR_NAME_BYTES); pMetadata->data.bext.pOriginatorName = drwav__metadata_copy_string(pParser, (const char*)drwav_buffer_reader_ptr(&reader), DRWAV_BEXT_ORIGINATOR_NAME_BYTES);
pReadPointer += DRWAV_BEXT_ORIGINATOR_NAME_BYTES; drwav_buffer_reader_seek(&reader, DRWAV_BEXT_ORIGINATOR_NAME_BYTES);
pMetadata->data.bext.pOriginatorReference = drwav__metadata_copy_string(pParser, (char*)(pReadPointer), DRWAV_BEXT_ORIGINATOR_REF_BYTES); pMetadata->data.bext.pOriginatorReference = drwav__metadata_copy_string(pParser, (const char*)drwav_buffer_reader_ptr(&reader), DRWAV_BEXT_ORIGINATOR_REF_BYTES);
pReadPointer += DRWAV_BEXT_ORIGINATOR_REF_BYTES; drwav_buffer_reader_seek(&reader, DRWAV_BEXT_ORIGINATOR_REF_BYTES);
memcpy(pReadPointer, pMetadata->data.bext.pOriginationDate, sizeof(pMetadata->data.bext.pOriginationDate)); drwav_buffer_reader_read(&reader, pMetadata->data.bext.pOriginationDate, sizeof(pMetadata->data.bext.pOriginationDate), NULL);
pReadPointer += sizeof(pMetadata->data.bext.pOriginationDate); drwav_buffer_reader_read(&reader, pMetadata->data.bext.pOriginationTime, sizeof(pMetadata->data.bext.pOriginationTime), NULL);
memcpy(pReadPointer, pMetadata->data.bext.pOriginationTime, sizeof(pMetadata->data.bext.pOriginationTime)); drwav_buffer_reader_read_u32(&reader, &timeReferenceLow);
pReadPointer += sizeof(pMetadata->data.bext.pOriginationTime); drwav_buffer_reader_read_u32(&reader, &timeReferenceHigh);
timeReferenceLow = drwav_bytes_to_u32(pReadPointer); pMetadata->data.bext.timeReference = ((drwav_uint64)timeReferenceHigh << 32) + timeReferenceLow;
pReadPointer += sizeof(drwav_uint32); drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.version);
timeReferenceHigh = drwav_bytes_to_u32(pReadPointer); pMetadata->data.bext.pUMID = drwav__metadata_get_memory(pParser, DRWAV_BEXT_UMID_BYTES, 1);
pReadPointer += sizeof(drwav_uint32); drwav_buffer_reader_read(&reader, pMetadata->data.bext.pUMID, DRWAV_BEXT_UMID_BYTES, NULL);
pMetadata->data.bext.timeReference = ((drwav_uint64)timeReferenceHigh << 32) + timeReferenceLow; drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.loudnessValue);
pMetadata->data.bext.version = drwav_bytes_to_u16(pReadPointer); drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.loudnessRange);
pReadPointer += sizeof(drwav_uint16); drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.maxTruePeakLevel);
pMetadata->data.bext.pUMID = drwav__metadata_get_memory(pParser, DRWAV_BEXT_UMID_BYTES, 1); drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.maxMomentaryLoudness);
memcpy(pMetadata->data.bext.pUMID, pReadPointer, DRWAV_BEXT_UMID_BYTES); drwav_buffer_reader_read_u16(&reader, &pMetadata->data.bext.maxShortTermLoudness);
pReadPointer += DRWAV_BEXT_UMID_BYTES; DRWAV_ASSERT((drwav_offset_ptr(drwav_buffer_reader_ptr(&reader), DRWAV_BEXT_RESERVED_BYTES)) == (bextData + DRWAV_BEXT_BYTES));
pMetadata->data.bext.loudnessValue = drwav_bytes_to_u16(pReadPointer); extraBytes = (size_t)(chunkSize - DRWAV_BEXT_BYTES);
pReadPointer += sizeof(drwav_uint16); if (extraBytes > 0) {
pMetadata->data.bext.loudnessRange = drwav_bytes_to_u16(pReadPointer); pMetadata->data.bext.pCodingHistory = (char*)drwav__metadata_get_memory(pParser, extraBytes + 1, 1);
pReadPointer += sizeof(drwav_uint16); DRWAV_ASSERT(pMetadata->data.bext.pCodingHistory != NULL);
pMetadata->data.bext.maxTruePeakLevel = drwav_bytes_to_u16(pReadPointer); bytesRead += drwav__metadata_parser_read(pParser, pMetadata->data.bext.pCodingHistory, extraBytes, NULL);
pReadPointer += sizeof(drwav_uint16); pMetadata->data.bext.codingHistorySize = (drwav_uint32)strlen(pMetadata->data.bext.pCodingHistory);
pMetadata->data.bext.maxMomentaryLoudness = drwav_bytes_to_u16(pReadPointer); } else {
pReadPointer += sizeof(drwav_uint16); pMetadata->data.bext.pCodingHistory = NULL;
pMetadata->data.bext.maxShortTermLoudness = drwav_bytes_to_u16(pReadPointer); pMetadata->data.bext.codingHistorySize = 0;
pReadPointer += sizeof(drwav_uint16); }
DRWAV_ASSERT((pReadPointer + DRWAV_BEXT_RESERVED_BYTES) == (bextData + DRWAV_BEXT_BYTES));
extraBytes = (size_t)(chunkSize - DRWAV_BEXT_BYTES);
if (extraBytes > 0) {
pMetadata->data.bext.pCodingHistory = (char*)drwav__metadata_get_memory(pParser, extraBytes + 1, 1);
DRWAV_ASSERT(pMetadata->data.bext.pCodingHistory != NULL);
bytesRead += drwav__metadata_parser_read(pParser, pMetadata->data.bext.pCodingHistory, extraBytes, NULL);
pMetadata->data.bext.codingHistorySize = (drwav_uint32)strlen(pMetadata->data.bext.pCodingHistory);
} else {
pMetadata->data.bext.pCodingHistory = NULL;
pMetadata->data.bext.codingHistorySize = 0;
} }
} }
return bytesRead; return bytesRead;
...@@ -47178,7 +47264,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_list_label_or_note_to_metadata_obj(drwav_ ...@@ -47178,7 +47264,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_list_label_or_note_to_metadata_obj(drwav_
pMetadata->data.labelOrNote.stringLength = sizeIncludingNullTerminator - 1; pMetadata->data.labelOrNote.stringLength = sizeIncludingNullTerminator - 1;
pMetadata->data.labelOrNote.pString = (char*)drwav__metadata_get_memory(pParser, sizeIncludingNullTerminator, 1); pMetadata->data.labelOrNote.pString = (char*)drwav__metadata_get_memory(pParser, sizeIncludingNullTerminator, 1);
DRWAV_ASSERT(pMetadata->data.labelOrNote.pString != NULL); DRWAV_ASSERT(pMetadata->data.labelOrNote.pString != NULL);
bytesJustRead = drwav__metadata_parser_read(pParser, pMetadata->data.labelOrNote.pString, sizeIncludingNullTerminator, &totalBytesRead); drwav__metadata_parser_read(pParser, pMetadata->data.labelOrNote.pString, sizeIncludingNullTerminator, &totalBytesRead);
} else { } else {
pMetadata->data.labelOrNote.stringLength = 0; pMetadata->data.labelOrNote.stringLength = 0;
pMetadata->data.labelOrNote.pString = NULL; pMetadata->data.labelOrNote.pString = NULL;
...@@ -47210,7 +47296,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_list_labelled_cue_region_to_metadata_obj( ...@@ -47210,7 +47296,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_list_labelled_cue_region_to_metadata_obj(
pMetadata->data.labelledCueRegion.stringLength = sizeIncludingNullTerminator - 1; pMetadata->data.labelledCueRegion.stringLength = sizeIncludingNullTerminator - 1;
pMetadata->data.labelledCueRegion.pString = (char*)drwav__metadata_get_memory(pParser, sizeIncludingNullTerminator, 1); pMetadata->data.labelledCueRegion.pString = (char*)drwav__metadata_get_memory(pParser, sizeIncludingNullTerminator, 1);
DRWAV_ASSERT(pMetadata->data.labelledCueRegion.pString != NULL); DRWAV_ASSERT(pMetadata->data.labelledCueRegion.pString != NULL);
bytesJustRead = drwav__metadata_parser_read(pParser, pMetadata->data.labelledCueRegion.pString, sizeIncludingNullTerminator, &totalBytesRead); drwav__metadata_parser_read(pParser, pMetadata->data.labelledCueRegion.pString, sizeIncludingNullTerminator, &totalBytesRead);
} else { } else {
pMetadata->data.labelledCueRegion.stringLength = 0; pMetadata->data.labelledCueRegion.stringLength = 0;
pMetadata->data.labelledCueRegion.pString = NULL; pMetadata->data.labelledCueRegion.pString = NULL;
...@@ -47276,11 +47362,11 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_unknown_chunk(drwav__metadata ...@@ -47276,11 +47362,11 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_unknown_chunk(drwav__metadata
} }
return bytesRead; return bytesRead;
} }
DRWAV_PRIVATE drwav_bool32 drwav__chunk_matches(drwav_uint64 allowedMetadataTypes, const drwav_uint8* pChunkID, drwav_metadata_type type, const char* pID) DRWAV_PRIVATE drwav_bool32 drwav__chunk_matches(drwav_metadata_type allowedMetadataTypes, const drwav_uint8* pChunkID, drwav_metadata_type type, const char* pID)
{ {
return (allowedMetadataTypes & type) && drwav_fourcc_equal(pChunkID, pID); return (allowedMetadataTypes & type) && drwav_fourcc_equal(pChunkID, pID);
} }
DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser* pParser, const drwav_chunk_header* pChunkHeader, drwav_uint64 allowedMetadataTypes) DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser* pParser, const drwav_chunk_header* pChunkHeader, drwav_metadata_type allowedMetadataTypes)
{ {
const drwav_uint8 *pChunkID = pChunkHeader->id.fourcc; const drwav_uint8 *pChunkID = pChunkHeader->id.fourcc;
drwav_uint64 bytesRead = 0; drwav_uint64 bytesRead = 0;
...@@ -47296,16 +47382,21 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser* ...@@ -47296,16 +47382,21 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser*
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &bytesRead); bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &bytesRead);
if (bytesJustRead == sizeof(buffer)) { if (bytesJustRead == sizeof(buffer)) {
drwav_uint32 loopCount = drwav_bytes_to_u32(buffer); drwav_uint32 loopCount = drwav_bytes_to_u32(buffer);
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &bytesRead); drwav_uint64 calculatedLoopCount;
if (bytesJustRead == sizeof(buffer)) { calculatedLoopCount = (pChunkHeader->sizeInBytes - DRWAV_SMPL_BYTES) / DRWAV_SMPL_LOOP_BYTES;
drwav_uint32 samplerSpecificDataSizeInBytes = drwav_bytes_to_u32(buffer); if (calculatedLoopCount == loopCount) {
pParser->metadataCount += 1; bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &bytesRead);
drwav__metadata_request_extra_memory_for_stage_2(pParser, sizeof(drwav_smpl_loop) * loopCount, DRWAV_METADATA_ALIGNMENT); if (bytesJustRead == sizeof(buffer)) {
drwav__metadata_request_extra_memory_for_stage_2(pParser, samplerSpecificDataSizeInBytes, 1); drwav_uint32 samplerSpecificDataSizeInBytes = drwav_bytes_to_u32(buffer);
pParser->metadataCount += 1;
drwav__metadata_request_extra_memory_for_stage_2(pParser, sizeof(drwav_smpl_loop) * loopCount, DRWAV_METADATA_ALIGNMENT);
drwav__metadata_request_extra_memory_for_stage_2(pParser, samplerSpecificDataSizeInBytes, 1);
}
} else {
} }
} }
} else { } else {
bytesRead = drwav__read_smpl_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor]); bytesRead = drwav__read_smpl_to_metadata_obj(pParser, pChunkHeader, &pParser->pMetadata[pParser->metadataCursor]);
if (bytesRead == pChunkHeader->sizeInBytes) { if (bytesRead == pChunkHeader->sizeInBytes) {
pParser->metadataCursor += 1; pParser->metadataCursor += 1;
} else { } else {
...@@ -47347,7 +47438,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser* ...@@ -47347,7 +47438,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser*
cueCount = (size_t)(pChunkHeader->sizeInBytes - DRWAV_CUE_BYTES) / DRWAV_CUE_POINT_BYTES; cueCount = (size_t)(pChunkHeader->sizeInBytes - DRWAV_CUE_BYTES) / DRWAV_CUE_POINT_BYTES;
drwav__metadata_request_extra_memory_for_stage_2(pParser, sizeof(drwav_cue_point) * cueCount, DRWAV_METADATA_ALIGNMENT); drwav__metadata_request_extra_memory_for_stage_2(pParser, sizeof(drwav_cue_point) * cueCount, DRWAV_METADATA_ALIGNMENT);
} else { } else {
bytesRead = drwav__read_cue_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor]); bytesRead = drwav__read_cue_to_metadata_obj(pParser, pChunkHeader, &pParser->pMetadata[pParser->metadataCursor]);
if (bytesRead == pChunkHeader->sizeInBytes) { if (bytesRead == pChunkHeader->sizeInBytes) {
pParser->metadataCursor += 1; pParser->metadataCursor += 1;
} else { } else {
...@@ -47462,7 +47553,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser* ...@@ -47462,7 +47553,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser*
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_album); subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_album);
} else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_tracknumber, "ITRK")) { } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_tracknumber, "ITRK")) {
subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_tracknumber); subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_tracknumber);
} else if (allowedMetadataTypes & drwav_metadata_type_unknown) { } else if ((allowedMetadataTypes & drwav_metadata_type_unknown) != 0) {
subchunkBytesRead = drwav__metadata_process_unknown_chunk(pParser, subchunkId, subchunkDataSize, listType); subchunkBytesRead = drwav__metadata_process_unknown_chunk(pParser, subchunkId, subchunkDataSize, listType);
} }
bytesRead += subchunkBytesRead; bytesRead += subchunkBytesRead;
...@@ -47481,18 +47572,25 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser* ...@@ -47481,18 +47572,25 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser*
bytesRead += 1; bytesRead += 1;
} }
} }
} else if (allowedMetadataTypes & drwav_metadata_type_unknown) { } else if ((allowedMetadataTypes & drwav_metadata_type_unknown) != 0) {
bytesRead = drwav__metadata_process_unknown_chunk(pParser, pChunkID, pChunkHeader->sizeInBytes, drwav_metadata_location_top_level); bytesRead = drwav__metadata_process_unknown_chunk(pParser, pChunkID, pChunkHeader->sizeInBytes, drwav_metadata_location_top_level);
} }
return bytesRead; return bytesRead;
} }
DRWAV_PRIVATE drwav_uint32 drwav_get_bytes_per_pcm_frame(drwav* pWav) DRWAV_PRIVATE drwav_uint32 drwav_get_bytes_per_pcm_frame(drwav* pWav)
{ {
drwav_uint32 bytesPerFrame;
if ((pWav->bitsPerSample & 0x7) == 0) { if ((pWav->bitsPerSample & 0x7) == 0) {
return (pWav->bitsPerSample * pWav->fmt.channels) >> 3; bytesPerFrame = (pWav->bitsPerSample * pWav->fmt.channels) >> 3;
} else { } else {
return pWav->fmt.blockAlign; bytesPerFrame = pWav->fmt.blockAlign;
}
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ALAW || pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
if (bytesPerFrame != pWav->fmt.channels) {
return 0;
}
} }
return bytesPerFrame;
} }
DRWAV_API drwav_uint16 drwav_fmt_get_format(const drwav_fmt* pFMT) DRWAV_API drwav_uint16 drwav_fmt_get_format(const drwav_fmt* pFMT)
{ {
...@@ -47773,7 +47871,11 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on ...@@ -47773,7 +47871,11 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
if (sampleCountFromFactChunk != 0) { if (sampleCountFromFactChunk != 0) {
pWav->totalPCMFrameCount = sampleCountFromFactChunk; pWav->totalPCMFrameCount = sampleCountFromFactChunk;
} else { } else {
pWav->totalPCMFrameCount = dataChunkSize / drwav_get_bytes_per_pcm_frame(pWav); drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame == 0) {
return DRWAV_FALSE;
}
pWav->totalPCMFrameCount = dataChunkSize / bytesPerFrame;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
drwav_uint64 totalBlockHeaderSizeInBytes; drwav_uint64 totalBlockHeaderSizeInBytes;
drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign; drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
...@@ -47799,6 +47901,9 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on ...@@ -47799,6 +47901,9 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
return DRWAV_FALSE; return DRWAV_FALSE;
} }
} }
if (drwav_get_bytes_per_pcm_frame(pWav) == 0) {
return DRWAV_FALSE;
}
#ifdef DR_WAV_LIBSNDFILE_COMPAT #ifdef DR_WAV_LIBSNDFILE_COMPAT
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign; drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
...@@ -49300,6 +49405,7 @@ DRWAV_API drwav_result drwav_uninit(drwav* pWav) ...@@ -49300,6 +49405,7 @@ DRWAV_API drwav_result drwav_uninit(drwav* pWav)
DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut) DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut)
{ {
size_t bytesRead; size_t bytesRead;
drwav_uint32 bytesPerFrame;
if (pWav == NULL || bytesToRead == 0) { if (pWav == NULL || bytesToRead == 0) {
return 0; return 0;
} }
...@@ -49309,6 +49415,10 @@ DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOu ...@@ -49309,6 +49415,10 @@ DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOu
if (bytesToRead == 0) { if (bytesToRead == 0) {
return 0; return 0;
} }
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame == 0) {
return 0;
}
if (pBufferOut != NULL) { if (pBufferOut != NULL) {
bytesRead = pWav->onRead(pWav->pUserData, pBufferOut, bytesToRead); bytesRead = pWav->onRead(pWav->pUserData, pBufferOut, bytesToRead);
} else { } else {
...@@ -49337,7 +49447,7 @@ DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOu ...@@ -49337,7 +49447,7 @@ DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOu
} }
} }
} }
pWav->readCursorInPCMFrames += bytesRead / drwav_get_bytes_per_pcm_frame(pWav); pWav->readCursorInPCMFrames += bytesRead / bytesPerFrame;
pWav->bytesRemaining -= bytesRead; pWav->bytesRemaining -= bytesRead;
return bytesRead; return bytesRead;
} }
...@@ -49368,7 +49478,11 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 frames ...@@ -49368,7 +49478,11 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 frames
{ {
drwav_uint64 framesRead = drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut); drwav_uint64 framesRead = drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
if (pBufferOut != NULL) { if (pBufferOut != NULL) {
drwav__bswap_samples(pBufferOut, framesRead*pWav->channels, drwav_get_bytes_per_pcm_frame(pWav)/pWav->channels, pWav->translatedFormatTag); drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame == 0) {
return 0;
}
drwav__bswap_samples(pBufferOut, framesRead*pWav->channels, bytesPerFrame/pWav->channels, pWav->translatedFormatTag);
} }
return framesRead; return framesRead;
} }
...@@ -49448,10 +49562,15 @@ DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetF ...@@ -49448,10 +49562,15 @@ DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetF
drwav_uint64 currentBytePos; drwav_uint64 currentBytePos;
drwav_uint64 targetBytePos; drwav_uint64 targetBytePos;
drwav_uint64 offset; drwav_uint64 offset;
totalSizeInBytes = pWav->totalPCMFrameCount * drwav_get_bytes_per_pcm_frame(pWav); drwav_uint32 bytesPerFrame;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame == 0) {
return DRWAV_FALSE;
}
totalSizeInBytes = pWav->totalPCMFrameCount * bytesPerFrame;
DRWAV_ASSERT(totalSizeInBytes >= pWav->bytesRemaining); DRWAV_ASSERT(totalSizeInBytes >= pWav->bytesRemaining);
currentBytePos = totalSizeInBytes - pWav->bytesRemaining; currentBytePos = totalSizeInBytes - pWav->bytesRemaining;
targetBytePos = targetFrameIndex * drwav_get_bytes_per_pcm_frame(pWav); targetBytePos = targetFrameIndex * bytesPerFrame;
if (currentBytePos < targetBytePos) { if (currentBytePos < targetBytePos) {
offset = (targetBytePos - currentBytePos); offset = (targetBytePos - currentBytePos);
} else { } else {
...@@ -49465,7 +49584,7 @@ DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetF ...@@ -49465,7 +49584,7 @@ DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetF
if (!pWav->onSeek(pWav->pUserData, offset32, drwav_seek_origin_current)) { if (!pWav->onSeek(pWav->pUserData, offset32, drwav_seek_origin_current)) {
return DRWAV_FALSE; return DRWAV_FALSE;
} }
pWav->readCursorInPCMFrames += offset32 / drwav_get_bytes_per_pcm_frame(pWav); pWav->readCursorInPCMFrames += offset32 / bytesPerFrame;
pWav->bytesRemaining -= offset32; pWav->bytesRemaining -= offset32;
offset -= offset32; offset -= offset32;
} }
...@@ -49551,6 +49670,9 @@ DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 frame ...@@ -49551,6 +49670,9 @@ DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 frame
bytesWritten = 0; bytesWritten = 0;
pRunningData = (const drwav_uint8*)pData; pRunningData = (const drwav_uint8*)pData;
bytesPerSample = drwav_get_bytes_per_pcm_frame(pWav) / pWav->channels; bytesPerSample = drwav_get_bytes_per_pcm_frame(pWav) / pWav->channels;
if (bytesPerSample == 0) {
return 0;
}
while (bytesToWrite > 0) { while (bytesToWrite > 0) {
drwav_uint8 temp[4096]; drwav_uint8 temp[4096];
drwav_uint32 sampleCount; drwav_uint32 sampleCount;
...@@ -49749,7 +49871,7 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uin ...@@ -49749,7 +49871,7 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uin
return totalFramesRead; return totalFramesRead;
} }
pWav->ima.predictor[0] = drwav_bytes_to_s16(header + 0); pWav->ima.predictor[0] = drwav_bytes_to_s16(header + 0);
pWav->ima.stepIndex[0] = header[2]; pWav->ima.stepIndex[0] = drwav_clamp(header[2], 0, (drwav_int32)drwav_countof(stepTable)-1);
pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[0]; pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[0];
pWav->ima.cachedFrameCount = 1; pWav->ima.cachedFrameCount = 1;
} else { } else {
...@@ -49764,9 +49886,9 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uin ...@@ -49764,9 +49886,9 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uin
return totalFramesRead; return totalFramesRead;
} }
pWav->ima.predictor[0] = drwav_bytes_to_s16(header + 0); pWav->ima.predictor[0] = drwav_bytes_to_s16(header + 0);
pWav->ima.stepIndex[0] = header[2]; pWav->ima.stepIndex[0] = drwav_clamp(header[2], 0, (drwav_int32)drwav_countof(stepTable)-1);
pWav->ima.predictor[1] = drwav_bytes_to_s16(header + 4); pWav->ima.predictor[1] = drwav_bytes_to_s16(header + 4);
pWav->ima.stepIndex[1] = header[6]; pWav->ima.stepIndex[1] = drwav_clamp(header[6], 0, (drwav_int32)drwav_countof(stepTable)-1);
pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 2] = pWav->ima.predictor[0]; pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 2] = pWav->ima.predictor[0];
pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[1]; pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[1];
pWav->ima.cachedFrameCount = 1; pWav->ima.cachedFrameCount = 1;
...@@ -49880,7 +50002,7 @@ static DRWAV_INLINE drwav_int16 drwav__mulaw_to_s16(drwav_uint8 sampleIn) ...@@ -49880,7 +50002,7 @@ static DRWAV_INLINE drwav_int16 drwav__mulaw_to_s16(drwav_uint8 sampleIn)
} }
DRWAV_PRIVATE void drwav__pcm_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample) DRWAV_PRIVATE void drwav__pcm_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
{ {
unsigned int i; size_t i;
if (bytesPerSample == 1) { if (bytesPerSample == 1) {
drwav_u8_to_s16(pOut, pIn, totalSampleCount); drwav_u8_to_s16(pOut, pIn, totalSampleCount);
return; return;
...@@ -49932,8 +50054,10 @@ DRWAV_PRIVATE void drwav__ieee_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, ...@@ -49932,8 +50054,10 @@ DRWAV_PRIVATE void drwav__ieee_to_s16(drwav_int16* pOut, const drwav_uint8* pIn,
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame; drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
if ((pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 16) || pBufferOut == NULL) { if ((pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 16) || pBufferOut == NULL) {
return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
} }
...@@ -49941,14 +50065,25 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_uin ...@@ -49941,14 +50065,25 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_uin
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav__pcm_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
DRWAV_ASSERT(DRWAV_FALSE);
break;
}
drwav__pcm_to_s16(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
...@@ -49957,8 +50092,10 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_uin ...@@ -49957,8 +50092,10 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_uin
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame; drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
if (pBufferOut == NULL) { if (pBufferOut == NULL) {
return drwav_read_pcm_frames(pWav, framesToRead, NULL); return drwav_read_pcm_frames(pWav, framesToRead, NULL);
} }
...@@ -49966,14 +50103,25 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_ui ...@@ -49966,14 +50103,25 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_ui
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav__ieee_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
DRWAV_ASSERT(DRWAV_FALSE);
break;
}
drwav__ieee_to_s16(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
...@@ -49982,8 +50130,10 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_ui ...@@ -49982,8 +50130,10 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_ui
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame; drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
if (pBufferOut == NULL) { if (pBufferOut == NULL) {
return drwav_read_pcm_frames(pWav, framesToRead, NULL); return drwav_read_pcm_frames(pWav, framesToRead, NULL);
} }
...@@ -49991,14 +50141,25 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_ui ...@@ -49991,14 +50141,25 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_ui
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav_alaw_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels)); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
DRWAV_ASSERT(DRWAV_FALSE);
break;
}
drwav_alaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead);
pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
...@@ -50007,8 +50168,10 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_ui ...@@ -50007,8 +50168,10 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_ui
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int16* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame; drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
if (pBufferOut == NULL) { if (pBufferOut == NULL) {
return drwav_read_pcm_frames(pWav, framesToRead, NULL); return drwav_read_pcm_frames(pWav, framesToRead, NULL);
} }
...@@ -50016,14 +50179,25 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav* pWav, drwav_u ...@@ -50016,14 +50179,25 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav* pWav, drwav_u
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav_mulaw_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels)); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
DRWAV_ASSERT(DRWAV_FALSE);
break;
}
drwav_mulaw_to_s16(pBufferOut, sampleData, (size_t)samplesRead);
pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
...@@ -50204,49 +50378,50 @@ DRWAV_PRIVATE void drwav__ieee_to_f32(float* pOut, const drwav_uint8* pIn, size_ ...@@ -50204,49 +50378,50 @@ DRWAV_PRIVATE void drwav__ieee_to_f32(float* pOut, const drwav_uint8* pIn, size_
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__pcm(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__pcm(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav); drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav__pcm_to_f32(pBufferOut, sampleData, (size_t)framesRead*pWav->channels, bytesPerFrame/pWav->channels); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
framesToRead -= framesRead; if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
totalFramesRead += framesRead; DRWAV_ASSERT(DRWAV_FALSE);
}
return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__msadpcm(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{
drwav_uint64 totalFramesRead = 0;
drwav_int16 samples16[2048];
while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
if (framesRead == 0) {
break; break;
} }
drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels)); drwav__pcm_to_f32(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
pBufferOut += framesRead*pWav->channels; pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
return totalFramesRead; return totalFramesRead;
} }
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ima(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__msadpcm_ima(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{ {
drwav_uint64 totalFramesRead = 0; drwav_uint64 totalFramesRead;
drwav_int16 samples16[2048]; drwav_int16 samples16[2048];
totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels);
drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToReadThisIteration, samples16);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels)); drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
pBufferOut += framesRead*pWav->channels; pBufferOut += framesRead*pWav->channels;
framesToRead -= framesRead; framesToRead -= framesRead;
...@@ -50257,8 +50432,10 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ima(drwav* pWav, drwav_uin ...@@ -50257,8 +50432,10 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ima(drwav* pWav, drwav_uin
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame; drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT && pWav->bitsPerSample == 32) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT && pWav->bitsPerSample == 32) {
return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
} }
...@@ -50266,14 +50443,25 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_ui ...@@ -50266,14 +50443,25 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_ui
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav__ieee_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
DRWAV_ASSERT(DRWAV_FALSE);
break;
}
drwav__ieee_to_f32(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
...@@ -50282,19 +50470,33 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_ui ...@@ -50282,19 +50470,33 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_ui
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav); drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav_alaw_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels)); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
DRWAV_ASSERT(DRWAV_FALSE);
break;
}
drwav_alaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead);
pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
...@@ -50303,19 +50505,33 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav* pWav, drwav_ui ...@@ -50303,19 +50505,33 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav* pWav, drwav_ui
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__mulaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__mulaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav); drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav_mulaw_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels)); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
DRWAV_ASSERT(DRWAV_FALSE);
break;
}
drwav_mulaw_to_f32(pBufferOut, sampleData, (size_t)samplesRead);
pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
...@@ -50335,8 +50551,8 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 frame ...@@ -50335,8 +50551,8 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 frame
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
return drwav_read_pcm_frames_f32__pcm(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames_f32__pcm(pWav, framesToRead, pBufferOut);
} }
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
return drwav_read_pcm_frames_f32__msadpcm(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames_f32__msadpcm_ima(pWav, framesToRead, pBufferOut);
} }
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
return drwav_read_pcm_frames_f32__ieee(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames_f32__ieee(pWav, framesToRead, pBufferOut);
...@@ -50347,9 +50563,6 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 frame ...@@ -50347,9 +50563,6 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 frame
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
return drwav_read_pcm_frames_f32__mulaw(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames_f32__mulaw(pWav, framesToRead, pBufferOut);
} }
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
return drwav_read_pcm_frames_f32__ima(pWav, framesToRead, pBufferOut);
}
return 0; return 0;
} }
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut) DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
...@@ -50506,8 +50719,10 @@ DRWAV_PRIVATE void drwav__ieee_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, ...@@ -50506,8 +50719,10 @@ DRWAV_PRIVATE void drwav__ieee_to_s32(drwav_int32* pOut, const drwav_uint8* pIn,
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__pcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame; drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 32) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 32) {
return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
} }
...@@ -50515,44 +50730,41 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__pcm(drwav* pWav, drwav_uin ...@@ -50515,44 +50730,41 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__pcm(drwav* pWav, drwav_uin
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav__pcm_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
framesToRead -= framesRead; if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
totalFramesRead += framesRead; DRWAV_ASSERT(DRWAV_FALSE);
}
return totalFramesRead;
}
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__msadpcm(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{
drwav_uint64 totalFramesRead = 0;
drwav_int16 samples16[2048];
while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
if (framesRead == 0) {
break; break;
} }
drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels)); drwav__pcm_to_s32(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
pBufferOut += framesRead*pWav->channels; pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
return totalFramesRead; return totalFramesRead;
} }
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ima(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__msadpcm_ima(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{ {
drwav_uint64 totalFramesRead = 0; drwav_uint64 totalFramesRead = 0;
drwav_int16 samples16[2048]; drwav_int16 samples16[2048];
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels);
drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToReadThisIteration, samples16);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels)); drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels));
pBufferOut += framesRead*pWav->channels; pBufferOut += framesRead*pWav->channels;
framesToRead -= framesRead; framesToRead -= framesRead;
...@@ -50563,19 +50775,33 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ima(drwav* pWav, drwav_uin ...@@ -50563,19 +50775,33 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ima(drwav* pWav, drwav_uin
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ieee(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav); drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav__ieee_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
DRWAV_ASSERT(DRWAV_FALSE);
break;
}
drwav__ieee_to_s32(pBufferOut, sampleData, (size_t)samplesRead, bytesPerSample);
pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
...@@ -50584,19 +50810,33 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ieee(drwav* pWav, drwav_ui ...@@ -50584,19 +50810,33 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ieee(drwav* pWav, drwav_ui
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav); drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav_alaw_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels)); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
DRWAV_ASSERT(DRWAV_FALSE);
break;
}
drwav_alaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead);
pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
...@@ -50605,19 +50845,33 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav* pWav, drwav_ui ...@@ -50605,19 +50845,33 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav* pWav, drwav_ui
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut) DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__mulaw(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
{ {
drwav_uint64 totalFramesRead; drwav_uint64 totalFramesRead;
drwav_uint8 sampleData[4096]; drwav_uint8 sampleData[4096] = {0};
drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav); drwav_uint32 bytesPerFrame;
drwav_uint32 bytesPerSample;
drwav_uint64 samplesRead;
bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame == 0) { if (bytesPerFrame == 0) {
return 0; return 0;
} }
bytesPerSample = bytesPerFrame / pWav->channels;
if (bytesPerSample == 0 || (bytesPerFrame % pWav->channels) != 0) {
return 0;
}
totalFramesRead = 0; totalFramesRead = 0;
while (framesToRead > 0) { while (framesToRead > 0) {
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData); drwav_uint64 framesToReadThisIteration = drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame);
drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, framesToReadThisIteration, sampleData);
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
drwav_mulaw_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels)); DRWAV_ASSERT(framesRead <= framesToReadThisIteration);
pBufferOut += framesRead*pWav->channels; samplesRead = framesRead * pWav->channels;
if ((samplesRead * bytesPerSample) > sizeof(sampleData)) {
DRWAV_ASSERT(DRWAV_FALSE);
break;
}
drwav_mulaw_to_s32(pBufferOut, sampleData, (size_t)samplesRead);
pBufferOut += samplesRead;
framesToRead -= framesRead; framesToRead -= framesRead;
totalFramesRead += framesRead; totalFramesRead += framesRead;
} }
...@@ -50637,8 +50891,8 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 frame ...@@ -50637,8 +50891,8 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 frame
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
return drwav_read_pcm_frames_s32__pcm(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames_s32__pcm(pWav, framesToRead, pBufferOut);
} }
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM || pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
return drwav_read_pcm_frames_s32__msadpcm(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames_s32__msadpcm_ima(pWav, framesToRead, pBufferOut);
} }
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) {
return drwav_read_pcm_frames_s32__ieee(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames_s32__ieee(pWav, framesToRead, pBufferOut);
...@@ -50649,9 +50903,6 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 frame ...@@ -50649,9 +50903,6 @@ DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint64 frame
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_MULAW) {
return drwav_read_pcm_frames_s32__mulaw(pWav, framesToRead, pBufferOut); return drwav_read_pcm_frames_s32__mulaw(pWav, framesToRead, pBufferOut);
} }
if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
return drwav_read_pcm_frames_s32__ima(pWav, framesToRead, pBufferOut);
}
return 0; return 0;
} }
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32le(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut) DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32le(drwav* pWav, drwav_uint64 framesToRead, drwav_int32* pBufferOut)
/* /*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
miniaudio - v0.10.42 - 2021-08-22 miniaudio - v0.10.43 - 2021-12-10
David Reid - mackron@gmail.com David Reid - mackron@gmail.com
...@@ -20,7 +20,7 @@ extern "C" { ...@@ -20,7 +20,7 @@ extern "C" {
#define MA_VERSION_MAJOR 0 #define MA_VERSION_MAJOR 0
#define MA_VERSION_MINOR 10 #define MA_VERSION_MINOR 10
#define MA_VERSION_REVISION 42 #define MA_VERSION_REVISION 43
#define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION) #define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION)
#if defined(_MSC_VER) && !defined(__clang__) #if defined(_MSC_VER) && !defined(__clang__)
......
/* /*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
miniaudio - v0.10.43 - TBD miniaudio - v0.10.43 - 2021-12-10
David Reid - mackron@gmail.com David Reid - mackron@gmail.com
...@@ -69690,8 +69690,8 @@ The following miscellaneous changes have also been made. ...@@ -69690,8 +69690,8 @@ The following miscellaneous changes have also been made.
/* /*
REVISION HISTORY REVISION HISTORY
================ ================
v0.10.43 - TBD v0.10.43 - 2021-12-10
- ALSA: Fix use of uninitialized variables - ALSA: Fix use of uninitialized variables.
- ALSA: Fix enumeration of devices that support both playback and capture. - ALSA: Fix enumeration of devices that support both playback and capture.
- PulseAudio: Fix a possible division by zero. - PulseAudio: Fix a possible division by zero.
- WebAudio: Fix errors in strict mode. - WebAudio: Fix errors in strict mode.
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