Browse Source

Update dr_wav to f69c5fcf97

pull/150/head
Steve Russell 1 month ago
parent
commit
3cb4e593e9
2 changed files with 121 additions and 7566 deletions
  1. +1
    -7498
      src/dr_wav.c
  2. +120
    -68
      src/dr_wav.h

+ 1
- 7498
src/dr_wav.c
File diff suppressed because it is too large
View File


+ 120
- 68
src/dr_wav.h View File

@@ -1,10 +1,6 @@
/* /*
WAV audio loader and writer. Choice of public domain or MIT-0. See license statements at the end of this file. WAV audio loader and writer. Choice of public domain or MIT-0. See license statements at the end of this file.
<<<<<<< HEAD
dr_wav - v0.13.17 - TBD
=======
dr_wav - v0.13.16 - 2024-02-27
>>>>>>> e80c373575b337720703a41691536272b21b554c
dr_wav - v0.14.0 - TBD


David Reid - mackron@gmail.com David Reid - mackron@gmail.com


@@ -150,12 +146,8 @@ 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
<<<<<<< HEAD
#define DRWAV_VERSION_REVISION 17
=======
#define DRWAV_VERSION_REVISION 16
>>>>>>> e80c373575b337720703a41691536272b21b554c
#define DRWAV_VERSION_MINOR 14
#define DRWAV_VERSION_REVISION 0
#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> /* For size_t. */ #include <stddef.h> /* For size_t. */
@@ -184,7 +176,7 @@ typedef unsigned int drwav_uint32;
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#endif #endif
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__)
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) || defined(__powerpc64__)
typedef drwav_uint64 drwav_uintptr; typedef drwav_uint64 drwav_uintptr;
#else #else
typedef drwav_uint32 drwav_uintptr; typedef drwav_uint32 drwav_uintptr;
@@ -563,11 +555,11 @@ typedef struct
/* See drwav_smpl_loop_type. */ /* See drwav_smpl_loop_type. */
drwav_uint32 type; drwav_uint32 type;


/* The byte offset of the first sample to be played in the loop. */
drwav_uint32 firstSampleByteOffset;
/* The offset of the first sample to be played in the loop. */
drwav_uint32 firstSampleOffset;


/* The byte offset into the audio data of the last sample to be played in the loop. */
drwav_uint32 lastSampleByteOffset;
/* The offset into the audio data of the last sample to be played in the loop. */
drwav_uint32 lastSampleOffset;


/* A value to represent that playback should occur at a point between samples. This value ranges from 0 to UINT32_MAX. Where a value of 0 means no fraction, and a value of (UINT32_MAX / 2) would mean half a sample. */ /* A value to represent that playback should occur at a point between samples. This value ranges from 0 to UINT32_MAX. Where a value of 0 means no fraction, and a value of (UINT32_MAX / 2) would mean half a sample. */
drwav_uint32 sampleFraction; drwav_uint32 sampleFraction;
@@ -645,8 +637,8 @@ typedef struct
/* Set to 0 for uncompressed formats. Else the last byte in compressed wave data where decompression can begin to find the value of the corresponding sample value. */ /* Set to 0 for uncompressed formats. Else the last byte in compressed wave data where decompression can begin to find the value of the corresponding sample value. */
drwav_uint32 blockStart; drwav_uint32 blockStart;


/* For uncompressed formats this is the byte offset of the cue point into the audio data. For compressed formats this is relative to the block specified with blockStart. */
drwav_uint32 sampleByteOffset;
/* For uncompressed formats this is the offset of the cue point into the audio data. For compressed formats this is relative to the block specified with blockStart. */
drwav_uint32 sampleOffset;
} drwav_cue_point; } drwav_cue_point;


typedef struct typedef struct
@@ -1330,8 +1322,6 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b);
#endif #endif
#endif /* dr_wav_h */ #endif /* dr_wav_h */


<<<<<<< HEAD
=======


/************************************************************************************************************************************************************ /************************************************************************************************************************************************************
************************************************************************************************************************************************************ ************************************************************************************************************************************************************
@@ -1394,7 +1384,7 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b);
#define DRWAV_MAX_SIMD_VECTOR_SIZE 32 #define DRWAV_MAX_SIMD_VECTOR_SIZE 32


/* Architecture Detection */ /* Architecture Detection */
#if defined(__x86_64__) || defined(_M_X64)
#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
#define DRWAV_X64 #define DRWAV_X64
#elif defined(__i386) || defined(_M_IX86) #elif defined(__i386) || defined(_M_IX86)
#define DRWAV_X86 #define DRWAV_X86
@@ -2106,7 +2096,7 @@ DRWAV_PRIVATE drwav_uint8* drwav__metadata_get_memory(drwav__metadata_parser* pP
pParser->pDataCursor += align - modulo; pParser->pDataCursor += align - modulo;
} }
} }
pResult = pParser->pDataCursor; pResult = pParser->pDataCursor;


/* /*
@@ -2199,12 +2189,12 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_smpl_to_metadata_obj(drwav__metadata_pars
bytesJustRead = drwav__metadata_parser_read(pParser, smplLoopData, sizeof(smplLoopData), &totalBytesRead); bytesJustRead = drwav__metadata_parser_read(pParser, smplLoopData, sizeof(smplLoopData), &totalBytesRead);


if (bytesJustRead == sizeof(smplLoopData)) { if (bytesJustRead == sizeof(smplLoopData)) {
pMetadata->data.smpl.pLoops[iSampleLoop].cuePointId = drwav_bytes_to_u32(smplLoopData + 0);
pMetadata->data.smpl.pLoops[iSampleLoop].type = drwav_bytes_to_u32(smplLoopData + 4);
pMetadata->data.smpl.pLoops[iSampleLoop].firstSampleByteOffset = drwav_bytes_to_u32(smplLoopData + 8);
pMetadata->data.smpl.pLoops[iSampleLoop].lastSampleByteOffset = drwav_bytes_to_u32(smplLoopData + 12);
pMetadata->data.smpl.pLoops[iSampleLoop].sampleFraction = drwav_bytes_to_u32(smplLoopData + 16);
pMetadata->data.smpl.pLoops[iSampleLoop].playCount = drwav_bytes_to_u32(smplLoopData + 20);
pMetadata->data.smpl.pLoops[iSampleLoop].cuePointId = drwav_bytes_to_u32(smplLoopData + 0);
pMetadata->data.smpl.pLoops[iSampleLoop].type = drwav_bytes_to_u32(smplLoopData + 4);
pMetadata->data.smpl.pLoops[iSampleLoop].firstSampleOffset = drwav_bytes_to_u32(smplLoopData + 8);
pMetadata->data.smpl.pLoops[iSampleLoop].lastSampleOffset = drwav_bytes_to_u32(smplLoopData + 12);
pMetadata->data.smpl.pLoops[iSampleLoop].sampleFraction = drwav_bytes_to_u32(smplLoopData + 16);
pMetadata->data.smpl.pLoops[iSampleLoop].playCount = drwav_bytes_to_u32(smplLoopData + 20);
} else { } else {
break; break;
} }
@@ -2264,7 +2254,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_cue_to_metadata_obj(drwav__metadata_parse
pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[3] = cuePointData[11]; pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[3] = cuePointData[11];
pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart = drwav_bytes_to_u32(cuePointData + 12); pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart = drwav_bytes_to_u32(cuePointData + 12);
pMetadata->data.cue.pCuePoints[iCuePoint].blockStart = drwav_bytes_to_u32(cuePointData + 16); pMetadata->data.cue.pCuePoints[iCuePoint].blockStart = drwav_bytes_to_u32(cuePointData + 16);
pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset = drwav_bytes_to_u32(cuePointData + 20);
pMetadata->data.cue.pCuePoints[iCuePoint].sampleOffset = drwav_bytes_to_u32(cuePointData + 20);
} else { } else {
break; break;
} }
@@ -2417,7 +2407,7 @@ DRWAV_PRIVATE drwav_result drwav_buffer_reader_read(drwav_buffer_reader* pReader
size_t bytesRemaining; size_t bytesRemaining;


DRWAV_ASSERT(pReader != NULL); DRWAV_ASSERT(pReader != NULL);
if (pBytesRead != NULL) { if (pBytesRead != NULL) {
*pBytesRead = 0; *pBytesRead = 0;
} }
@@ -2497,7 +2487,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_bext_to_metadata_obj(drwav__metadata_pars
size_t 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_buffer_reader reader; drwav_buffer_reader reader;
drwav_uint32 timeReferenceLow; drwav_uint32 timeReferenceLow;
@@ -2559,7 +2549,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_list_label_or_note_to_metadata_obj(drwav_
drwav_uint64 totalBytesRead = 0; drwav_uint64 totalBytesRead = 0;
size_t bytesJustRead = drwav__metadata_parser_read(pParser, cueIDBuffer, sizeof(cueIDBuffer), &totalBytesRead); size_t bytesJustRead = drwav__metadata_parser_read(pParser, cueIDBuffer, sizeof(cueIDBuffer), &totalBytesRead);


DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);
DRWAV_ASSERT(pParser->stage == drwav__metadata_parser_stage_read);


if (bytesJustRead == sizeof(cueIDBuffer)) { if (bytesJustRead == sizeof(cueIDBuffer)) {
drwav_uint32 sizeIncludingNullTerminator; drwav_uint32 sizeIncludingNullTerminator;
@@ -2731,7 +2721,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser*
} }
} else { } else {
/* Loop count in header does not match the size of the chunk. */ /* Loop count in header does not match the size of the chunk. */
}
}
} }
} else { } else {
bytesRead = drwav__read_smpl_to_metadata_obj(pParser, pChunkHeader, &pParser->pMetadata[pParser->metadataCursor]); bytesRead = drwav__read_smpl_to_metadata_obj(pParser, pChunkHeader, &pParser->pMetadata[pParser->metadataCursor]);
@@ -3352,7 +3342,7 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
if (((pWav->container == drwav_container_riff || pWav->container == drwav_container_rifx || pWav->container == drwav_container_rf64) && drwav_fourcc_equal(header.id.fourcc, "data")) || if (((pWav->container == drwav_container_riff || pWav->container == drwav_container_rifx || pWav->container == drwav_container_rf64) && drwav_fourcc_equal(header.id.fourcc, "data")) ||
((pWav->container == drwav_container_w64) && drwav_guid_equal(header.id.guid, drwavGUID_W64_DATA))) { ((pWav->container == drwav_container_w64) && drwav_guid_equal(header.id.guid, drwavGUID_W64_DATA))) {
foundChunk_data = DRWAV_TRUE; foundChunk_data = DRWAV_TRUE;
pWav->dataChunkDataPos = cursor; pWav->dataChunkDataPos = cursor;


if (pWav->container != drwav_container_rf64) { /* The data chunk size for RF64 will always be set to 0xFFFFFFFF here. It was set to it's true value earlier. */ if (pWav->container != drwav_container_rf64) { /* The data chunk size for RF64 will always be set to 0xFFFFFFFF here. It was set to it's true value earlier. */
@@ -3442,7 +3432,7 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
return DRWAV_FALSE; return DRWAV_FALSE;
} }


channels = drwav_bytes_to_u16_ex (commData + 0, pWav->container); channels = drwav_bytes_to_u16_ex (commData + 0, pWav->container);
frameCount = drwav_bytes_to_u32_ex (commData + 2, pWav->container); frameCount = drwav_bytes_to_u32_ex (commData + 2, pWav->container);
sampleSizeInBits = drwav_bytes_to_u16_ex (commData + 6, pWav->container); sampleSizeInBits = drwav_bytes_to_u16_ex (commData + 6, pWav->container);
@@ -3475,12 +3465,15 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
compressionFormat = DR_WAVE_FORMAT_MULAW; compressionFormat = DR_WAVE_FORMAT_MULAW;
} else if (drwav_fourcc_equal(type, "ima4")) { } else if (drwav_fourcc_equal(type, "ima4")) {
compressionFormat = DR_WAVE_FORMAT_DVI_ADPCM; compressionFormat = DR_WAVE_FORMAT_DVI_ADPCM;
sampleSizeInBits = 4;
sampleSizeInBits = 4;


/* /*
I haven't been able to figure out how to get correct decoding for IMA ADPCM. Until this is figured out I haven't been able to figure out how to get correct decoding for IMA ADPCM. Until this is figured out
we'll need to abort when we encounter such an encoding. Advice welcome! we'll need to abort when we encounter such an encoding. Advice welcome!
*/ */
(void)compressionFormat;
(void)sampleSizeInBits;

return DRWAV_FALSE; return DRWAV_FALSE;
} else { } else {
return DRWAV_FALSE; /* Unknown or unsupported compression format. Need to abort. */ return DRWAV_FALSE; /* Unknown or unsupported compression format. Need to abort. */
@@ -3517,7 +3510,7 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on


/* In AIFF, samples are padded to 8 byte boundaries. We need to round up our bits per sample here. */ /* In AIFF, samples are padded to 8 byte boundaries. We need to round up our bits per sample here. */
fmt.bitsPerSample += (fmt.bitsPerSample & 7); fmt.bitsPerSample += (fmt.bitsPerSample & 7);


/* If the form type is AIFC there will be some additional data in the chunk. We need to seek past it. */ /* If the form type is AIFC there will be some additional data in the chunk. We need to seek past it. */
if (isAIFCFormType) { if (isAIFCFormType) {
@@ -3543,20 +3536,46 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
return DRWAV_FALSE; return DRWAV_FALSE;
} }


/* We need to seek forward by the offset. */
/* The position of the audio data starts at an offset. */
offset = drwav_bytes_to_u32_ex(offsetAndBlockSizeData + 0, pWav->container); offset = drwav_bytes_to_u32_ex(offsetAndBlockSizeData + 0, pWav->container);
if (drwav__seek_forward(pWav->onSeek, offset, pWav->pUserData) == DRWAV_FALSE) {
return DRWAV_FALSE;
}
cursor += offset;
pWav->dataChunkDataPos = cursor + offset;


pWav->dataChunkDataPos = cursor;
/* The data chunk size needs to be reduced by the offset or else seeking will break. */
dataChunkSize = chunkSize; dataChunkSize = chunkSize;
if (dataChunkSize > offset) {
dataChunkSize -= offset;
} else {
dataChunkSize = 0;
}


/* If we're running in sequential mode, or we're not reading metadata, we have enough now that we can get out of the loop. */
if (sequential || !isProcessingMetadata) {
break; /* No need to keep reading beyond the data chunk. */
if (sequential) {
if (foundChunk_fmt) { /* <-- Name is misleading, but will be set to true if the COMM chunk has been parsed. */
/*
Getting here means we're opening in sequential mode and we've found the SSND (data) and COMM (fmt) chunks. We need
to get out of the loop here or else we'll end up going past the data chunk and will have no way of getting back to
it since we're not allowed to seek backwards.

One subtle detail here is that there is an offset with the SSND chunk. We need to make sure we seek past this offset
so we're left sitting on the first byte of actual audio data.
*/
if (drwav__seek_forward(pWav->onSeek, offset, pWav->pUserData) == DRWAV_FALSE) {
return DRWAV_FALSE;
}
cursor += offset;

break;
} else {
/*
Getting here means the COMM chunk was not found. In sequential mode, if we haven't yet found the COMM chunk
we'll need to abort because we can't be doing a backwards seek back to the SSND chunk in order to read the
data. For this reason, this configuration of AIFF files are not supported with sequential mode.
*/
return DRWAV_FALSE;
}
} else { } else {
chunkSize += header.paddingSize; /* <-- Make sure we seek past the padding. */
chunkSize -= sizeof(offsetAndBlockSizeData); /* <-- This was read earlier. */

if (drwav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData) == DRWAV_FALSE) { if (drwav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData) == DRWAV_FALSE) {
break; break;
} }
@@ -3567,7 +3586,6 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
} }





/* Getting here means it's not a chunk that we care about internally, but might need to be handled as metadata by the caller. */ /* Getting here means it's not a chunk that we care about internally, but might need to be handled as metadata by the caller. */
if (isProcessingMetadata) { if (isProcessingMetadata) {
drwav__metadata_process_chunk(&metadataParser, &header, drwav_metadata_type_all_including_unknown); drwav__metadata_process_chunk(&metadataParser, &header, drwav_metadata_type_all_including_unknown);
@@ -3659,6 +3677,10 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on




/* At this point we should be sitting on the first byte of the raw audio data. */ /* At this point we should be sitting on the first byte of the raw audio data. */
if (drwav__seek_from_start(pWav->onSeek, pWav->dataChunkDataPos, pWav->pUserData) == DRWAV_FALSE) {
drwav_free(pWav->pMetadata, &pWav->allocationCallbacks);
return DRWAV_FALSE;
}


/* /*
I've seen a WAV file in the wild where a RIFF-ecapsulated file has the size of it's "RIFF" and I've seen a WAV file in the wild where a RIFF-ecapsulated file has the size of it's "RIFF" and
@@ -3680,18 +3702,30 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
} }
} }


if (drwav__seek_from_start(pWav->onSeek, pWav->dataChunkDataPos, pWav->pUserData) == DRWAV_FALSE) {
drwav_free(pWav->pMetadata, &pWav->allocationCallbacks);
return DRWAV_FALSE;
}


pWav->fmt = fmt; pWav->fmt = fmt;
pWav->sampleRate = fmt.sampleRate; pWav->sampleRate = fmt.sampleRate;
pWav->channels = fmt.channels; pWav->channels = fmt.channels;
pWav->bitsPerSample = fmt.bitsPerSample; pWav->bitsPerSample = fmt.bitsPerSample;
pWav->bytesRemaining = dataChunkSize;
pWav->translatedFormatTag = translatedFormatTag; pWav->translatedFormatTag = translatedFormatTag;

/*
I've had a report where files would start glitching after seeking. The reason for this is the data
chunk is not a clean multiple of the PCM frame size in bytes. Where this becomes a problem is when
seeking, because the number of bytes remaining in the data chunk is used to calculate the current
byte position. If this byte position is not aligned to the number of bytes in a PCM frame, it will
result in the seek not being cleanly positioned at the start of the PCM frame thereby resulting in
all decoded frames after that being corrupted.

To address this, we need to round the data chunk size down to the nearest multiple of the frame size.
*/
if (!drwav__is_compressed_format_tag(translatedFormatTag)) {
drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
if (bytesPerFrame > 0) {
dataChunkSize -= (dataChunkSize % bytesPerFrame);
}
}

pWav->bytesRemaining = dataChunkSize;
pWav->dataChunkDataSize = dataChunkSize; pWav->dataChunkDataSize = dataChunkSize;


if (sampleCountFromFactChunk != 0) { if (sampleCountFromFactChunk != 0) {
@@ -4005,8 +4039,8 @@ DRWAV_PRIVATE size_t drwav__write_or_count_metadata(drwav* pWav, drwav_metadata*
for (iLoop = 0; iLoop < pMetadata->data.smpl.sampleLoopCount; ++iLoop) { for (iLoop = 0; iLoop < pMetadata->data.smpl.sampleLoopCount; ++iLoop) {
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].cuePointId); bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].cuePointId);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].type); bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].type);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].firstSampleByteOffset);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].lastSampleByteOffset);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].firstSampleOffset);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].lastSampleOffset);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].sampleFraction); bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].sampleFraction);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].playCount); bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].playCount);
} }
@@ -4046,7 +4080,7 @@ DRWAV_PRIVATE size_t drwav__write_or_count_metadata(drwav* pWav, drwav_metadata*
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId, 4); bytesWritten += drwav__write_or_count(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId, 4);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart); bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].blockStart); bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].blockStart);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset);
bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].sampleOffset);
} }
} break; } break;


@@ -4205,7 +4239,7 @@ DRWAV_PRIVATE size_t drwav__write_or_count_metadata(drwav* pWav, drwav_metadata*


if (pMetadata->data.labelOrNote.stringLength > 0) { if (pMetadata->data.labelOrNote.stringLength > 0) {
chunkSize += pMetadata->data.labelOrNote.stringLength + 1; chunkSize += pMetadata->data.labelOrNote.stringLength + 1;
}
}
} break; } break;


case drwav_metadata_type_list_labelled_cue_region: case drwav_metadata_type_list_labelled_cue_region:
@@ -4714,7 +4748,7 @@ DRWAV_PRIVATE drwav_result drwav_result_from_errno(int e)
#ifdef ENOSYS #ifdef ENOSYS
case ENOSYS: return DRWAV_NOT_IMPLEMENTED; case ENOSYS: return DRWAV_NOT_IMPLEMENTED;
#endif #endif
#ifdef ENOTEMPTY
#if defined(ENOTEMPTY) && ENOTEMPTY != EEXIST /* In AIX, ENOTEMPTY and EEXIST use the same value. */
case ENOTEMPTY: return DRWAV_DIRECTORY_NOT_EMPTY; case ENOTEMPTY: return DRWAV_DIRECTORY_NOT_EMPTY;
#endif #endif
#ifdef ELOOP #ifdef ELOOP
@@ -5189,7 +5223,7 @@ DRWAV_PRIVATE drwav_bool32 drwav_init_file__internal_FILE(drwav* pWav, FILE* pFi
fclose(pFile); fclose(pFile);
return result; return result;
} }
result = drwav_init__internal(pWav, onChunk, pChunkUserData, flags); result = drwav_init__internal(pWav, onChunk, pChunkUserData, flags);
if (result != DRWAV_TRUE) { if (result != DRWAV_TRUE) {
fclose(pFile); fclose(pFile);
@@ -6111,6 +6145,13 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav
{ {
drwav_uint64 totalFramesRead = 0; drwav_uint64 totalFramesRead = 0;


static drwav_int32 adaptationTable[] = {
230, 230, 230, 230, 307, 409, 512, 614,
768, 614, 512, 409, 307, 230, 230, 230
};
static drwav_int32 coeff1Table[] = { 256, 512, 0, 192, 240, 460, 392 };
static drwav_int32 coeff2Table[] = { 0, -256, 0, 64, 0, -208, -232 };

DRWAV_ASSERT(pWav != NULL); DRWAV_ASSERT(pWav != NULL);
DRWAV_ASSERT(framesToRead > 0); DRWAV_ASSERT(framesToRead > 0);


@@ -6136,6 +6177,11 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav
pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][0]; pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][0];
pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[0][1]; pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[0][1];
pWav->msadpcm.cachedFrameCount = 2; pWav->msadpcm.cachedFrameCount = 2;

/* The predictor is used as an index into coeff1Table so we'll need to validate to ensure it never overflows. */
if (pWav->msadpcm.predictor[0] >= drwav_countof(coeff1Table)) {
return totalFramesRead; /* Invalid file. */
}
} else { } else {
/* Stereo. */ /* Stereo. */
drwav_uint8 header[14]; drwav_uint8 header[14];
@@ -6158,6 +6204,11 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav
pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][1]; pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][1];
pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[1][1]; pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[1][1];
pWav->msadpcm.cachedFrameCount = 2; pWav->msadpcm.cachedFrameCount = 2;

/* The predictor is used as an index into coeff1Table so we'll need to validate to ensure it never overflows. */
if (pWav->msadpcm.predictor[0] >= drwav_countof(coeff1Table) || pWav->msadpcm.predictor[1] >= drwav_countof(coeff2Table)) {
return totalFramesRead; /* Invalid file. */
}
} }
} }


@@ -6191,13 +6242,6 @@ DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav
if (pWav->msadpcm.bytesRemainingInBlock == 0) { if (pWav->msadpcm.bytesRemainingInBlock == 0) {
continue; continue;
} else { } else {
static drwav_int32 adaptationTable[] = {
230, 230, 230, 230, 307, 409, 512, 614,
768, 614, 512, 409, 307, 230, 230, 230
};
static drwav_int32 coeff1Table[] = { 256, 512, 0, 192, 240, 460, 392 };
static drwav_int32 coeff2Table[] = { 0, -256, 0, 64, 0, -208, -232 };

drwav_uint8 nibbles; drwav_uint8 nibbles;
drwav_int32 nibble0; drwav_int32 nibble0;
drwav_int32 nibble1; drwav_int32 nibble1;
@@ -8360,6 +8404,15 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b)
/* /*
REVISION HISTORY REVISION HISTORY
================ ================
v0.14.0 - TBD
- API CHANGE: The `firstSampleByteOffset`, `lastSampleByteOffset` and `sampleByteOffset` members of `drwav_cue_point` have been renamed to `firstSampleOffset`, `lastSampleOffset` and `sampleOffset`, respectively.
- Fix a static analysis warning.
- Fix compilation for AIX OS.

v0.13.17 - 2024-12-17
- Fix a possible crash when reading from MS-ADPCM encoded files.
- Improve detection of ARM64EC

v0.13.16 - 2024-02-27 v0.13.16 - 2024-02-27
- Fix a Wdouble-promotion warning. - Fix a Wdouble-promotion warning.


@@ -8823,4 +8876,3 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
>>>>>>> e80c373575b337720703a41691536272b21b554c

Loading…
Cancel
Save