From 99d99680efe2a36dc1c5dc6f246dd3720fdd8eee Mon Sep 17 00:00:00 2001 From: David Reid Date: Wed, 15 Jul 2020 18:33:48 +1000 Subject: [PATCH] Update dr_wav. --- extras/dr_wav.h | 111 ++++++++++++++++++++++++++++++++++++------------ miniaudio.h | 91 +++++++++++++++++++++++++++------------ 2 files changed, 147 insertions(+), 55 deletions(-) diff --git a/extras/dr_wav.h b/extras/dr_wav.h index f2404d10..2fb30a47 100644 --- a/extras/dr_wav.h +++ b/extras/dr_wav.h @@ -1,6 +1,6 @@ /* WAV audio loader and writer. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_wav - v0.12.6 - 2020-06-23 +dr_wav - v0.12.7 - 2020-07-15 David Reid - mackron@gmail.com @@ -144,7 +144,7 @@ extern "C" { #define DRWAV_VERSION_MAJOR 0 #define DRWAV_VERSION_MINOR 12 -#define DRWAV_VERSION_REVISION 6 +#define DRWAV_VERSION_REVISION 7 #define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION) #include /* For size_t. */ @@ -2225,6 +2225,52 @@ static drwav_uint64 drwav__data_chunk_size_w64(drwav_uint64 dataChunkSize) } +static size_t drwav__write(drwav* pWav, const void* pData, size_t dataSize) +{ + DRWAV_ASSERT(pWav != NULL); + DRWAV_ASSERT(pWav->onWrite != NULL); + + /* Generic write. Assumes no byte reordering required. */ + return pWav->onWrite(pWav->pUserData, pData, dataSize); +} + +static size_t drwav__write_u16ne_to_le(drwav* pWav, drwav_uint16 value) +{ + DRWAV_ASSERT(pWav != NULL); + DRWAV_ASSERT(pWav->onWrite != NULL); + + if (!drwav__is_little_endian()) { + value = drwav__bswap16(value); + } + + return drwav__write(pWav, &value, 2); +} + +static size_t drwav__write_u32ne_to_le(drwav* pWav, drwav_uint32 value) +{ + DRWAV_ASSERT(pWav != NULL); + DRWAV_ASSERT(pWav->onWrite != NULL); + + if (!drwav__is_little_endian()) { + value = drwav__bswap32(value); + } + + return drwav__write(pWav, &value, 4); +} + +static size_t drwav__write_u64ne_to_le(drwav* pWav, drwav_uint64 value) +{ + DRWAV_ASSERT(pWav != NULL); + DRWAV_ASSERT(pWav->onWrite != NULL); + + if (!drwav__is_little_endian()) { + value = drwav__bswap64(value); + } + + return drwav__write(pWav, &value, 8); +} + + static drwav_bool32 drwav_preinit_write(drwav* pWav, const drwav_data_format* pFormat, drwav_bool32 isSequential, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks) { if (pWav == NULL || onWrite == NULL) { @@ -2298,45 +2344,45 @@ static drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_data_for /* "RIFF" chunk. */ if (pFormat->container == drwav_container_riff) { drwav_uint32 chunkSizeRIFF = 36 + (drwav_uint32)initialDataChunkSize; /* +36 = "RIFF"+[RIFF Chunk Size]+"WAVE" + [sizeof "fmt " chunk] */ - runningPos += pWav->onWrite(pWav->pUserData, "RIFF", 4); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeRIFF, 4); - runningPos += pWav->onWrite(pWav->pUserData, "WAVE", 4); + runningPos += drwav__write(pWav, "RIFF", 4); + runningPos += drwav__write_u32ne_to_le(pWav, chunkSizeRIFF); + runningPos += drwav__write(pWav, "WAVE", 4); } else { drwav_uint64 chunkSizeRIFF = 80 + 24 + initialDataChunkSize; /* +24 because W64 includes the size of the GUID and size fields. */ - runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_RIFF, 16); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeRIFF, 8); - runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_WAVE, 16); + runningPos += drwav__write(pWav, drwavGUID_W64_RIFF, 16); + runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeRIFF); + runningPos += drwav__write(pWav, drwavGUID_W64_WAVE, 16); } /* "fmt " chunk. */ if (pFormat->container == drwav_container_riff) { chunkSizeFMT = 16; - runningPos += pWav->onWrite(pWav->pUserData, "fmt ", 4); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeFMT, 4); + runningPos += drwav__write(pWav, "fmt ", 4); + runningPos += drwav__write_u32ne_to_le(pWav, (drwav_uint32)chunkSizeFMT); } else { chunkSizeFMT = 40; - runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_FMT, 16); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeFMT, 8); + runningPos += drwav__write(pWav, drwavGUID_W64_FMT, 16); + runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeFMT); } - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.formatTag, 2); - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.channels, 2); - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.sampleRate, 4); - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.avgBytesPerSec, 4); - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.blockAlign, 2); - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.bitsPerSample, 2); + runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.formatTag); + runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.channels); + runningPos += drwav__write_u32ne_to_le(pWav, pWav->fmt.sampleRate); + runningPos += drwav__write_u32ne_to_le(pWav, pWav->fmt.avgBytesPerSec); + runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.blockAlign); + runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.bitsPerSample); pWav->dataChunkDataPos = runningPos; /* "data" chunk. */ if (pFormat->container == drwav_container_riff) { drwav_uint32 chunkSizeDATA = (drwav_uint32)initialDataChunkSize; - runningPos += pWav->onWrite(pWav->pUserData, "data", 4); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeDATA, 4); + runningPos += drwav__write(pWav, "data", 4); + runningPos += drwav__write_u32ne_to_le(pWav, chunkSizeDATA); } else { drwav_uint64 chunkSizeDATA = 24 + initialDataChunkSize; /* +24 because W64 includes the size of the GUID and size fields. */ - runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_DATA, 16); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeDATA, 8); + runningPos += drwav__write(pWav, drwavGUID_W64_DATA, 16); + runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeDATA); } @@ -3316,7 +3362,7 @@ DRWAV_API drwav_result drwav_uninit(drwav* pWav) if (paddingSize > 0) { drwav_uint64 paddingData = 0; - pWav->onWrite(pWav->pUserData, &paddingData, paddingSize); + drwav__write(pWav, &paddingData, paddingSize); /* Byte order does not matter for this. */ } /* @@ -3328,25 +3374,25 @@ DRWAV_API drwav_result drwav_uninit(drwav* pWav) /* The "RIFF" chunk size. */ if (pWav->onSeek(pWav->pUserData, 4, drwav_seek_origin_start)) { drwav_uint32 riffChunkSize = drwav__riff_chunk_size_riff(pWav->dataChunkDataSize); - pWav->onWrite(pWav->pUserData, &riffChunkSize, 4); + drwav__write_u32ne_to_le(pWav, riffChunkSize); } /* the "data" chunk size. */ if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 4, drwav_seek_origin_start)) { drwav_uint32 dataChunkSize = drwav__data_chunk_size_riff(pWav->dataChunkDataSize); - pWav->onWrite(pWav->pUserData, &dataChunkSize, 4); + drwav__write_u32ne_to_le(pWav, dataChunkSize); } } else { /* The "RIFF" chunk size. */ if (pWav->onSeek(pWav->pUserData, 16, drwav_seek_origin_start)) { drwav_uint64 riffChunkSize = drwav__riff_chunk_size_w64(pWav->dataChunkDataSize); - pWav->onWrite(pWav->pUserData, &riffChunkSize, 8); + drwav__write_u64ne_to_le(pWav, riffChunkSize); } /* The "data" chunk size. */ if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 16, drwav_seek_origin_start)) { drwav_uint64 dataChunkSize = drwav__data_chunk_size_w64(pWav->dataChunkDataSize); - pWav->onWrite(pWav->pUserData, &dataChunkSize, 8); + drwav__write_u64ne_to_le(pWav, dataChunkSize); } } } @@ -4797,7 +4843,12 @@ DRWAV_API void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t samp } for (i = 0; i < sampleCount; ++i) { - double x = (double)(((drwav_int32)(((drwav_uint32)(pIn[i*3+0]) << 8) | ((drwav_uint32)(pIn[i*3+1]) << 16) | ((drwav_uint32)(pIn[i*3+2])) << 24)) >> 8); + double x; + drwav_uint32 a = ((drwav_uint32)(pIn[i*3+0]) << 8); + drwav_uint32 b = ((drwav_uint32)(pIn[i*3+1]) << 16); + drwav_uint32 c = ((drwav_uint32)(pIn[i*3+2]) << 24); + + x = (double)((drwav_int32)(a | b | c) >> 8); *pOut++ = (float)(x * 0.00000011920928955078125); } } @@ -5875,6 +5926,10 @@ two different ways to initialize a drwav object. /* REVISION HISTORY ================ +v0.12.7 - 2020-07-15 + - Fix some bugs on big-endian architectures. + - Fix an error in s24 to f32 conversion. + v0.12.6 - 2020-06-23 - Change drwav_read_*() to allow NULL to be passed in as the output buffer which is equivalent to a forward seek. - Fix a buffer overflow when trying to decode invalid IMA-ADPCM files. diff --git a/miniaudio.h b/miniaudio.h index dac49a9a..af2c9028 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -42167,7 +42167,7 @@ extern "C" { #define DRWAV_XSTRINGIFY(x) DRWAV_STRINGIFY(x) #define DRWAV_VERSION_MAJOR 0 #define DRWAV_VERSION_MINOR 12 -#define DRWAV_VERSION_REVISION 6 +#define DRWAV_VERSION_REVISION 7 #define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION) #include #ifdef _MSC_VER @@ -47570,6 +47570,39 @@ static drwav_uint64 drwav__data_chunk_size_w64(drwav_uint64 dataChunkSize) { return 24 + dataChunkSize; } +static size_t drwav__write(drwav* pWav, const void* pData, size_t dataSize) +{ + DRWAV_ASSERT(pWav != NULL); + DRWAV_ASSERT(pWav->onWrite != NULL); + return pWav->onWrite(pWav->pUserData, pData, dataSize); +} +static size_t drwav__write_u16ne_to_le(drwav* pWav, drwav_uint16 value) +{ + DRWAV_ASSERT(pWav != NULL); + DRWAV_ASSERT(pWav->onWrite != NULL); + if (!drwav__is_little_endian()) { + value = drwav__bswap16(value); + } + return drwav__write(pWav, &value, 2); +} +static size_t drwav__write_u32ne_to_le(drwav* pWav, drwav_uint32 value) +{ + DRWAV_ASSERT(pWav != NULL); + DRWAV_ASSERT(pWav->onWrite != NULL); + if (!drwav__is_little_endian()) { + value = drwav__bswap32(value); + } + return drwav__write(pWav, &value, 4); +} +static size_t drwav__write_u64ne_to_le(drwav* pWav, drwav_uint64 value) +{ + DRWAV_ASSERT(pWav != NULL); + DRWAV_ASSERT(pWav->onWrite != NULL); + if (!drwav__is_little_endian()) { + value = drwav__bswap64(value); + } + return drwav__write(pWav, &value, 8); +} static drwav_bool32 drwav_preinit_write(drwav* pWav, const drwav_data_format* pFormat, drwav_bool32 isSequential, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks) { if (pWav == NULL || onWrite == NULL) { @@ -47618,39 +47651,39 @@ static drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_data_for pWav->dataChunkDataSizeTargetWrite = initialDataChunkSize; if (pFormat->container == drwav_container_riff) { drwav_uint32 chunkSizeRIFF = 36 + (drwav_uint32)initialDataChunkSize; - runningPos += pWav->onWrite(pWav->pUserData, "RIFF", 4); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeRIFF, 4); - runningPos += pWav->onWrite(pWav->pUserData, "WAVE", 4); + runningPos += drwav__write(pWav, "RIFF", 4); + runningPos += drwav__write_u32ne_to_le(pWav, chunkSizeRIFF); + runningPos += drwav__write(pWav, "WAVE", 4); } else { drwav_uint64 chunkSizeRIFF = 80 + 24 + initialDataChunkSize; - runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_RIFF, 16); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeRIFF, 8); - runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_WAVE, 16); + runningPos += drwav__write(pWav, drwavGUID_W64_RIFF, 16); + runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeRIFF); + runningPos += drwav__write(pWav, drwavGUID_W64_WAVE, 16); } if (pFormat->container == drwav_container_riff) { chunkSizeFMT = 16; - runningPos += pWav->onWrite(pWav->pUserData, "fmt ", 4); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeFMT, 4); + runningPos += drwav__write(pWav, "fmt ", 4); + runningPos += drwav__write_u32ne_to_le(pWav, (drwav_uint32)chunkSizeFMT); } else { chunkSizeFMT = 40; - runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_FMT, 16); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeFMT, 8); + runningPos += drwav__write(pWav, drwavGUID_W64_FMT, 16); + runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeFMT); } - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.formatTag, 2); - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.channels, 2); - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.sampleRate, 4); - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.avgBytesPerSec, 4); - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.blockAlign, 2); - runningPos += pWav->onWrite(pWav->pUserData, &pWav->fmt.bitsPerSample, 2); + runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.formatTag); + runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.channels); + runningPos += drwav__write_u32ne_to_le(pWav, pWav->fmt.sampleRate); + runningPos += drwav__write_u32ne_to_le(pWav, pWav->fmt.avgBytesPerSec); + runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.blockAlign); + runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.bitsPerSample); pWav->dataChunkDataPos = runningPos; if (pFormat->container == drwav_container_riff) { drwav_uint32 chunkSizeDATA = (drwav_uint32)initialDataChunkSize; - runningPos += pWav->onWrite(pWav->pUserData, "data", 4); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeDATA, 4); + runningPos += drwav__write(pWav, "data", 4); + runningPos += drwav__write_u32ne_to_le(pWav, chunkSizeDATA); } else { drwav_uint64 chunkSizeDATA = 24 + initialDataChunkSize; - runningPos += pWav->onWrite(pWav->pUserData, drwavGUID_W64_DATA, 16); - runningPos += pWav->onWrite(pWav->pUserData, &chunkSizeDATA, 8); + runningPos += drwav__write(pWav, drwavGUID_W64_DATA, 16); + runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeDATA); } if (pFormat->container == drwav_container_riff) { if (runningPos != 20 + chunkSizeFMT + 8) { @@ -48478,26 +48511,26 @@ DRWAV_API drwav_result drwav_uninit(drwav* pWav) } if (paddingSize > 0) { drwav_uint64 paddingData = 0; - pWav->onWrite(pWav->pUserData, &paddingData, paddingSize); + drwav__write(pWav, &paddingData, paddingSize); } if (pWav->onSeek && !pWav->isSequentialWrite) { if (pWav->container == drwav_container_riff) { if (pWav->onSeek(pWav->pUserData, 4, drwav_seek_origin_start)) { drwav_uint32 riffChunkSize = drwav__riff_chunk_size_riff(pWav->dataChunkDataSize); - pWav->onWrite(pWav->pUserData, &riffChunkSize, 4); + drwav__write_u32ne_to_le(pWav, riffChunkSize); } if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 4, drwav_seek_origin_start)) { drwav_uint32 dataChunkSize = drwav__data_chunk_size_riff(pWav->dataChunkDataSize); - pWav->onWrite(pWav->pUserData, &dataChunkSize, 4); + drwav__write_u32ne_to_le(pWav, dataChunkSize); } } else { if (pWav->onSeek(pWav->pUserData, 16, drwav_seek_origin_start)) { drwav_uint64 riffChunkSize = drwav__riff_chunk_size_w64(pWav->dataChunkDataSize); - pWav->onWrite(pWav->pUserData, &riffChunkSize, 8); + drwav__write_u64ne_to_le(pWav, riffChunkSize); } if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 16, drwav_seek_origin_start)) { drwav_uint64 dataChunkSize = drwav__data_chunk_size_w64(pWav->dataChunkDataSize); - pWav->onWrite(pWav->pUserData, &dataChunkSize, 8); + drwav__write_u64ne_to_le(pWav, dataChunkSize); } } } @@ -49578,7 +49611,11 @@ DRWAV_API void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t samp return; } for (i = 0; i < sampleCount; ++i) { - double x = (double)(((drwav_int32)(((drwav_uint32)(pIn[i*3+0]) << 8) | ((drwav_uint32)(pIn[i*3+1]) << 16) | ((drwav_uint32)(pIn[i*3+2])) << 24)) >> 8); + double x; + drwav_uint32 a = ((drwav_uint32)(pIn[i*3+0]) << 8); + drwav_uint32 b = ((drwav_uint32)(pIn[i*3+1]) << 16); + drwav_uint32 c = ((drwav_uint32)(pIn[i*3+2]) << 24); + x = (double)((drwav_int32)(a | b | c) >> 8); *pOut++ = (float)(x * 0.00000011920928955078125); } }