Update external libraries.

This commit is contained in:
David Reid
2019-10-07 08:34:42 +10:00
parent 154bb46bab
commit 268abad8d2
4 changed files with 520 additions and 308 deletions
+151 -151
View File
@@ -1,6 +1,6 @@
/*
FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
dr_flac - v0.12.1 - 2019-09-29
dr_flac - v0.12.2 - 2019-10-07
David Reid - mackron@gmail.com
*/
@@ -1256,9 +1256,6 @@ typedef drflac_int32 drflac_result;
#define DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE 10
#define drflac_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
#define drflac_assert DRFLAC_ASSERT
#define drflac_copy_memory DRFLAC_COPY_MEMORY
#define drflac_zero_memory DRFLAC_ZERO_MEMORY
/* CPU caps. */
@@ -1564,7 +1561,7 @@ static DRFLAC_INLINE drflac_uint8 drflac_crc8(drflac_uint8 crc, drflac_uint32 da
0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
};
drflac_assert(count <= 32);
DRFLAC_ASSERT(count <= 32);
wholeBytes = count >> 3;
leftoverBits = count - (wholeBytes*8);
@@ -1653,7 +1650,7 @@ static DRFLAC_INLINE drflac_uint16 drflac_crc16__32bit(drflac_uint16 crc, drflac
0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
};
drflac_assert(count <= 64);
DRFLAC_ASSERT(count <= 64);
wholeBytes = count >> 3;
leftoverBits = count & 7;
@@ -1688,7 +1685,7 @@ static DRFLAC_INLINE drflac_uint16 drflac_crc16__64bit(drflac_uint16 crc, drflac
0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
};
drflac_assert(count <= 64);
DRFLAC_ASSERT(count <= 64);
wholeBytes = count >> 3;
leftoverBits = count & 7;
@@ -1770,7 +1767,7 @@ static DRFLAC_INLINE void drflac__update_crc16(drflac_bs* bs)
static DRFLAC_INLINE drflac_uint16 drflac__flush_crc16(drflac_bs* bs)
{
/* We should never be flushing in a situation where we are not aligned on a byte boundary. */
drflac_assert((DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7) == 0);
DRFLAC_ASSERT((DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7) == 0);
/*
The bits that were read from the L1 cache need to be accumulated. The number of bytes needing to be accumulated is determined
@@ -1883,7 +1880,7 @@ static drflac_bool32 drflac__reload_cache(drflac_bs* bs)
return DRFLAC_FALSE;
}
drflac_assert(bytesRead < DRFLAC_CACHE_L1_SIZE_BYTES(bs));
DRFLAC_ASSERT(bytesRead < DRFLAC_CACHE_L1_SIZE_BYTES(bs));
bs->consumedBits = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8;
bs->cache = drflac__be2host__cache_line(bs->unalignedCache);
@@ -1914,10 +1911,10 @@ static void drflac__reset_cache(drflac_bs* bs)
static DRFLAC_INLINE drflac_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, drflac_uint32* pResultOut)
{
drflac_assert(bs != NULL);
drflac_assert(pResultOut != NULL);
drflac_assert(bitCount > 0);
drflac_assert(bitCount <= 32);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResultOut != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 32);
if (bs->consumedBits == DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
if (!drflac__reload_cache(bs)) {
@@ -1971,10 +1968,10 @@ static drflac_bool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, dr
drflac_uint32 result;
drflac_uint32 signbit;
drflac_assert(bs != NULL);
drflac_assert(pResult != NULL);
drflac_assert(bitCount > 0);
drflac_assert(bitCount <= 32);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResult != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 32);
if (!drflac__read_uint32(bs, bitCount, &result)) {
return DRFLAC_FALSE;
@@ -1993,8 +1990,8 @@ static drflac_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, d
drflac_uint32 resultHi;
drflac_uint32 resultLo;
drflac_assert(bitCount <= 64);
drflac_assert(bitCount > 32);
DRFLAC_ASSERT(bitCount <= 64);
DRFLAC_ASSERT(bitCount > 32);
if (!drflac__read_uint32(bs, bitCount - 32, &resultHi)) {
return DRFLAC_FALSE;
@@ -2016,7 +2013,7 @@ static drflac_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, dr
drflac_uint64 result;
drflac_uint64 signbit;
drflac_assert(bitCount <= 64);
DRFLAC_ASSERT(bitCount <= 64);
if (!drflac__read_uint64(bs, bitCount, &result)) {
return DRFLAC_FALSE;
@@ -2034,10 +2031,10 @@ static drflac_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, d
{
drflac_uint32 result;
drflac_assert(bs != NULL);
drflac_assert(pResult != NULL);
drflac_assert(bitCount > 0);
drflac_assert(bitCount <= 16);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResult != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 16);
if (!drflac__read_uint32(bs, bitCount, &result)) {
return DRFLAC_FALSE;
@@ -2052,10 +2049,10 @@ static drflac_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, dr
{
drflac_int32 result;
drflac_assert(bs != NULL);
drflac_assert(pResult != NULL);
drflac_assert(bitCount > 0);
drflac_assert(bitCount <= 16);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResult != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 16);
if (!drflac__read_int32(bs, bitCount, &result)) {
return DRFLAC_FALSE;
@@ -2070,10 +2067,10 @@ static drflac_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, dr
{
drflac_uint32 result;
drflac_assert(bs != NULL);
drflac_assert(pResult != NULL);
drflac_assert(bitCount > 0);
drflac_assert(bitCount <= 8);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResult != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 8);
if (!drflac__read_uint32(bs, bitCount, &result)) {
return DRFLAC_FALSE;
@@ -2087,10 +2084,10 @@ static drflac_bool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, drf
{
drflac_int32 result;
drflac_assert(bs != NULL);
drflac_assert(pResult != NULL);
drflac_assert(bitCount > 0);
drflac_assert(bitCount <= 8);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pResult != NULL);
DRFLAC_ASSERT(bitCount > 0);
DRFLAC_ASSERT(bitCount <= 8);
if (!drflac__read_int32(bs, bitCount, &result)) {
return DRFLAC_FALSE;
@@ -2150,7 +2147,7 @@ static drflac_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek)
bitsToSeek = 0; /* <-- Necessary for the assert below. */
}
drflac_assert(bitsToSeek == 0);
DRFLAC_ASSERT(bitsToSeek == 0);
return DRFLAC_TRUE;
}
}
@@ -2159,7 +2156,7 @@ static drflac_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek)
/* This function moves the bit streamer to the first bit after the sync code (bit 15 of the of the frame header). It will also update the CRC-16. */
static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs)
{
drflac_assert(bs != NULL);
DRFLAC_ASSERT(bs != NULL);
/*
The sync code is always aligned to 8 bits. This is convenient for us because it means we can do byte-aligned movements. The first
@@ -2379,8 +2376,8 @@ static DRFLAC_INLINE drflac_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs,
static drflac_bool32 drflac__seek_to_byte(drflac_bs* bs, drflac_uint64 offsetFromStart)
{
drflac_assert(bs != NULL);
drflac_assert(offsetFromStart > 0);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(offsetFromStart > 0);
/*
Seeking from the start is not quite as trivial as it sounds because the onSeek callback takes a signed 32-bit integer (which
@@ -2426,9 +2423,9 @@ static drflac_result drflac__read_utf8_coded_number(drflac_bs* bs, drflac_uint64
int byteCount;
int i;
drflac_assert(bs != NULL);
drflac_assert(pNumberOut != NULL);
drflac_assert(pCRCOut != NULL);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(pNumberOut != NULL);
DRFLAC_ASSERT(pCRCOut != NULL);
crc = *pCRCOut;
@@ -2463,7 +2460,7 @@ static drflac_result drflac__read_utf8_coded_number(drflac_bs* bs, drflac_uint64
}
/* Read extra bytes. */
drflac_assert(byteCount > 1);
DRFLAC_ASSERT(byteCount > 1);
result = (drflac_uint64)(utf8[0] & (0xFF >> (byteCount + 1)));
for (i = 1; i < byteCount; ++i) {
@@ -2493,7 +2490,7 @@ static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_32(drflac_uint32
{
drflac_int32 prediction = 0;
drflac_assert(order <= 32);
DRFLAC_ASSERT(order <= 32);
/* 32-bit version. */
@@ -2541,7 +2538,7 @@ static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_64(drflac_uint32
{
drflac_int64 prediction;
drflac_assert(order <= 32);
DRFLAC_ASSERT(order <= 32);
/* 64-bit version. */
@@ -2728,9 +2725,9 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(drfla
{
drflac_uint32 i;
drflac_assert(bs != NULL);
drflac_assert(count > 0);
drflac_assert(pSamplesOut != NULL);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
for (i = 0; i < count; ++i) {
drflac_uint32 zeroCounter = 0;
@@ -2817,7 +2814,7 @@ static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac
drflac_uint32 riceParamPart;
drflac_uint32 riceLength;
drflac_assert(riceParam > 0); /* <-- riceParam should never be 0. drflac__read_rice_parts__param_equals_zero() should be used instead for this case. */
DRFLAC_ASSERT(riceParam > 0); /* <-- riceParam should never be 0. drflac__read_rice_parts__param_equals_zero() should be used instead for this case. */
riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam);
@@ -2927,7 +2924,7 @@ static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x1(drflac_bs* bs, drf
/* Before reloading the cache we need to grab the size in bits of the low part. */
riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits;
drflac_assert(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
DRFLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
/* Now reload the cache. */
if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
@@ -3036,7 +3033,7 @@ static DRFLAC_INLINE drflac_bool32 drflac__seek_rice_parts(drflac_bs* bs, drflac
/* Before reloading the cache we need to grab the size in bits of the low part. */
drflac_uint32 riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits;
drflac_assert(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
DRFLAC_ASSERT(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32);
/* Now reload the cache. */
if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
@@ -3110,9 +3107,9 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar_zeroorde
drflac_uint32 riceParamMask;
drflac_uint32 i;
drflac_assert(bs != NULL);
drflac_assert(count > 0);
drflac_assert(pSamplesOut != NULL);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
(void)bitsPerSample;
(void)order;
@@ -3156,9 +3153,9 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar(drflac_b
const drflac_int32* pSamplesOutEnd;
drflac_uint32 i;
drflac_assert(bs != NULL);
drflac_assert(count > 0);
drflac_assert(pSamplesOut != NULL);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
if (order == 0) {
return drflac__decode_samples_with_residual__rice__scalar_zeroorder(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
@@ -3543,7 +3540,7 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41_64(drflac
const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
drflac_assert(order <= 12);
DRFLAC_ASSERT(order <= 12);
riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
riceParamMask128 = _mm_set1_epi32(riceParamMask);
@@ -3710,9 +3707,9 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41_64(drflac
static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
{
drflac_assert(bs != NULL);
drflac_assert(count > 0);
drflac_assert(pSamplesOut != NULL);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
/* In my testing the order is rarely > 12, so in this case I'm going to simplify the SSE implementation by only handling order <= 12. */
if (order > 0 && order <= 12) {
@@ -4198,9 +4195,9 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__neon_64(drflac_
static drflac_bool32 drflac__decode_samples_with_residual__rice__neon(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
{
drflac_assert(bs != NULL);
drflac_assert(count > 0);
drflac_assert(pSamplesOut != NULL);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
/* In my testing the order is rarely > 12, so in this case I'm going to simplify the NEON implementation by only handling order <= 12. */
if (order > 0 && order <= 12) {
@@ -4241,8 +4238,8 @@ static drflac_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, drflac_
{
drflac_uint32 i;
drflac_assert(bs != NULL);
drflac_assert(count > 0);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
for (i = 0; i < count; ++i) {
if (!drflac__seek_rice_parts(bs, riceParam)) {
@@ -4257,10 +4254,10 @@ static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs*
{
drflac_uint32 i;
drflac_assert(bs != NULL);
drflac_assert(count > 0);
drflac_assert(unencodedBitsPerSample <= 31); /* <-- unencodedBitsPerSample is a 5 bit number, so cannot exceed 31. */
drflac_assert(pSamplesOut != NULL);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(unencodedBitsPerSample <= 31); /* <-- unencodedBitsPerSample is a 5 bit number, so cannot exceed 31. */
DRFLAC_ASSERT(pSamplesOut != NULL);
for (i = 0; i < count; ++i) {
if (unencodedBitsPerSample > 0) {
@@ -4294,9 +4291,9 @@ static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_
drflac_uint32 samplesInPartition;
drflac_uint32 partitionsRemaining;
drflac_assert(bs != NULL);
drflac_assert(blockSize != 0);
drflac_assert(pDecodedSamples != NULL); /* <-- Should we allow NULL, in which case we just seek past the residual rather than do a full decode? */
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(blockSize != 0);
DRFLAC_ASSERT(pDecodedSamples != NULL); /* <-- Should we allow NULL, in which case we just seek past the residual rather than do a full decode? */
if (!drflac__read_uint8(bs, 2, &residualMethod)) {
return DRFLAC_FALSE;
@@ -4389,8 +4386,8 @@ static drflac_bool32 drflac__read_and_seek_residual(drflac_bs* bs, drflac_uint32
drflac_uint32 samplesInPartition;
drflac_uint32 partitionsRemaining;
drflac_assert(bs != NULL);
drflac_assert(blockSize != 0);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(blockSize != 0);
if (!drflac__read_uint8(bs, 2, &residualMethod)) {
return DRFLAC_FALSE;
@@ -4561,7 +4558,7 @@ static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 bl
return DRFLAC_FALSE;
}
drflac_zero_memory(coefficients, sizeof(coefficients));
DRFLAC_ZERO_MEMORY(coefficients, sizeof(coefficients));
for (i = 0; i < lpcOrder; ++i) {
if (!drflac__read_int32(bs, lpcPrecision, coefficients + i)) {
return DRFLAC_FALSE;
@@ -4581,8 +4578,8 @@ static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs* bs, drflac_u
const drflac_uint32 sampleRateTable[12] = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1}; /* -1 = reserved. */
drflac_assert(bs != NULL);
drflac_assert(header != NULL);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(header != NULL);
/* Keep looping until we find a valid sync code. */
for (;;) {
@@ -4801,8 +4798,8 @@ static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame,
drflac_subframe* pSubframe;
drflac_uint32 subframeBitsPerSample;
drflac_assert(bs != NULL);
drflac_assert(frame != NULL);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(frame != NULL);
pSubframe = frame->subframes + subframeIndex;
if (!drflac__read_subframe_header(bs, pSubframe)) {
@@ -4858,8 +4855,8 @@ static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, i
drflac_subframe* pSubframe;
drflac_uint32 subframeBitsPerSample;
drflac_assert(bs != NULL);
drflac_assert(frame != NULL);
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(frame != NULL);
pSubframe = frame->subframes + subframeIndex;
if (!drflac__read_subframe_header(bs, pSubframe)) {
@@ -4950,7 +4947,7 @@ static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignm
{
drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2};
drflac_assert(channelAssignment <= 10);
DRFLAC_ASSERT(channelAssignment <= 10);
return lookup[channelAssignment];
}
@@ -4965,7 +4962,7 @@ static drflac_result drflac__decode_flac_frame(drflac* pFlac)
#endif
/* This function should be called while the stream is sitting on the first byte after the frame header. */
drflac_zero_memory(pFlac->currentFLACFrame.subframes, sizeof(pFlac->currentFLACFrame.subframes));
DRFLAC_ZERO_MEMORY(pFlac->currentFLACFrame.subframes, sizeof(pFlac->currentFLACFrame.subframes));
/* The frame block size must never be larger than the maximum block size defined by the FLAC stream. */
if (pFlac->currentFLACFrame.header.blockSizeInPCMFrames > pFlac->maxBlockSizeInPCMFrames) {
@@ -5050,7 +5047,7 @@ static drflac_result drflac__seek_flac_frame(drflac* pFlac)
static drflac_bool32 drflac__read_and_decode_next_flac_frame(drflac* pFlac)
{
drflac_assert(pFlac != NULL);
DRFLAC_ASSERT(pFlac != NULL);
for (;;) {
drflac_result result;
@@ -5077,7 +5074,7 @@ static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac* pFlac, drf
drflac_uint64 firstPCMFrame;
drflac_uint64 lastPCMFrame;
drflac_assert(pFlac != NULL);
DRFLAC_ASSERT(pFlac != NULL);
firstPCMFrame = pFlac->currentFLACFrame.header.pcmFrameNumber;
if (firstPCMFrame == 0) {
@@ -5101,11 +5098,11 @@ static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac)
{
drflac_bool32 result;
drflac_assert(pFlac != NULL);
DRFLAC_ASSERT(pFlac != NULL);
result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFLACFramePosInBytes);
drflac_zero_memory(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
pFlac->currentPCMFrame = 0;
return result;
@@ -5114,7 +5111,7 @@ static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac)
static DRFLAC_INLINE drflac_result drflac__seek_to_next_flac_frame(drflac* pFlac)
{
/* This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section. */
drflac_assert(pFlac != NULL);
DRFLAC_ASSERT(pFlac != NULL);
return drflac__seek_flac_frame(pFlac);
}
@@ -5150,7 +5147,7 @@ static drflac_bool32 drflac__seek_to_pcm_frame__brute_force(drflac* pFlac, drfla
drflac_bool32 isMidFrame = DRFLAC_FALSE;
drflac_uint64 runningPCMFrameCount;
drflac_assert(pFlac != NULL);
DRFLAC_ASSERT(pFlac != NULL);
/* If we are seeking forward we start from the current position. Otherwise we need to start all the way from the start of the file. */
if (pcmFrameIndex >= pFlac->currentPCMFrame) {
@@ -5266,10 +5263,10 @@ location.
static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac* pFlac, drflac_uint64 targetByte, drflac_uint64 rangeLo, drflac_uint64 rangeHi, drflac_uint64* pLastSuccessfulSeekOffset)
{
drflac_assert(pFlac != NULL);
drflac_assert(pLastSuccessfulSeekOffset != NULL);
drflac_assert(targetByte >= rangeLo);
drflac_assert(targetByte <= rangeHi);
DRFLAC_ASSERT(pFlac != NULL);
DRFLAC_ASSERT(pLastSuccessfulSeekOffset != NULL);
DRFLAC_ASSERT(targetByte >= rangeLo);
DRFLAC_ASSERT(targetByte <= rangeHi);
*pLastSuccessfulSeekOffset = pFlac->firstFLACFramePosInBytes;
@@ -5289,7 +5286,7 @@ static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac* pFla
/* Getting here should mean that we have seeked to an appropriate byte. */
/* Clear the details of the FLAC frame so we don't misreport data. */
drflac_zero_memory(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
DRFLAC_ZERO_MEMORY(&pFlac->currentFLACFrame, sizeof(pFlac->currentFLACFrame));
/*
Now seek to the next FLAC frame. We need to decode the entire frame (not just the header) because it's possible for the header to incorrectly pass the
@@ -5319,7 +5316,7 @@ static drflac_bool32 drflac__seek_to_approximate_flac_frame_to_byte(drflac* pFla
/* The current PCM frame needs to be updated based on the frame we just seeked to. */
drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &pFlac->currentPCMFrame, NULL);
drflac_assert(targetByte <= rangeHi);
DRFLAC_ASSERT(targetByte <= rangeHi);
*pLastSuccessfulSeekOffset = targetByte;
return DRFLAC_TRUE;
@@ -5477,7 +5474,7 @@ static drflac_bool32 drflac__seek_to_pcm_frame__seek_table(drflac* pFlac, drflac
drflac_uint32 iSeekpoint;
drflac_assert(pFlac != NULL);
DRFLAC_ASSERT(pFlac != NULL);
if (pFlac->pSeekpoints == NULL || pFlac->seekpointCount == 0) {
return DRFLAC_FALSE;
@@ -5721,7 +5718,7 @@ drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData,
pStreamInfo->channels = (drflac_uint8 )((importantProps & (((drflac_uint64)0x0000000E << 16) << 24)) >> 41) + 1;
pStreamInfo->bitsPerSample = (drflac_uint8 )((importantProps & (((drflac_uint64)0x0000001F << 16) << 20)) >> 36) + 1;
pStreamInfo->totalPCMFrameCount = ((importantProps & ((((drflac_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF)));
drflac_copy_memory(pStreamInfo->md5, md5, sizeof(md5));
DRFLAC_COPY_MEMORY(pStreamInfo->md5, md5, sizeof(md5));
return DRFLAC_TRUE;
}
@@ -5993,7 +5990,7 @@ drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_s
pRunningData = (const char*)pRawData;
pRunningDataEnd = (const char*)pRawData + blockSize;
drflac_copy_memory(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128;
DRFLAC_COPY_MEMORY(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128;
metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(const drflac_uint64*)pRunningData); pRunningData += 8;
metadata.data.cuesheet.isCD = (pRunningData[0] & 0x80) != 0; pRunningData += 259;
metadata.data.cuesheet.trackCount = pRunningData[0]; pRunningData += 1;
@@ -6380,7 +6377,7 @@ drflac_result drflac_ogg__read_page_header_after_capture_pattern(drflac_read_pro
drflac_uint8 data[23];
drflac_uint32 i;
drflac_assert(*pCRC32 == DRFLAC_OGG_CAPTURE_PATTERN_CRC32);
DRFLAC_ASSERT(*pCRC32 == DRFLAC_OGG_CAPTURE_PATTERN_CRC32);
if (onRead(pUserData, data, 23) != 23) {
return DRFLAC_END_OF_STREAM;
@@ -6389,10 +6386,10 @@ drflac_result drflac_ogg__read_page_header_after_capture_pattern(drflac_read_pro
pHeader->structureVersion = data[0];
pHeader->headerType = data[1];
drflac_copy_memory(&pHeader->granulePosition, &data[ 2], 8);
drflac_copy_memory(&pHeader->serialNumber, &data[10], 4);
drflac_copy_memory(&pHeader->sequenceNumber, &data[14], 4);
drflac_copy_memory(&pHeader->checksum, &data[18], 4);
DRFLAC_COPY_MEMORY(&pHeader->granulePosition, &data[ 2], 8);
DRFLAC_COPY_MEMORY(&pHeader->serialNumber, &data[10], 4);
DRFLAC_COPY_MEMORY(&pHeader->sequenceNumber, &data[14], 4);
DRFLAC_COPY_MEMORY(&pHeader->checksum, &data[18], 4);
pHeader->segmentCount = data[22];
/* Calculate the CRC. Note that for the calculation the checksum part of the page needs to be set to 0. */
@@ -6673,15 +6670,15 @@ static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytes
drflac_uint8* pRunningBufferOut = (drflac_uint8*)bufferOut;
size_t bytesRead = 0;
drflac_assert(oggbs != NULL);
drflac_assert(pRunningBufferOut != NULL);
DRFLAC_ASSERT(oggbs != NULL);
DRFLAC_ASSERT(pRunningBufferOut != NULL);
/* Reading is done page-by-page. If we've run out of bytes in the page we need to move to the next one. */
while (bytesRead < bytesToRead) {
size_t bytesRemainingToRead = bytesToRead - bytesRead;
if (oggbs->bytesRemainingInPage >= bytesRemainingToRead) {
drflac_copy_memory(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), bytesRemainingToRead);
DRFLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), bytesRemainingToRead);
bytesRead += bytesRemainingToRead;
oggbs->bytesRemainingInPage -= (drflac_uint32)bytesRemainingToRead;
break;
@@ -6689,13 +6686,13 @@ static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytes
/* If we get here it means some of the requested data is contained in the next pages. */
if (oggbs->bytesRemainingInPage > 0) {
drflac_copy_memory(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), oggbs->bytesRemainingInPage);
DRFLAC_COPY_MEMORY(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), oggbs->bytesRemainingInPage);
bytesRead += oggbs->bytesRemainingInPage;
pRunningBufferOut += oggbs->bytesRemainingInPage;
oggbs->bytesRemainingInPage = 0;
}
drflac_assert(bytesRemainingToRead > 0);
DRFLAC_ASSERT(bytesRemainingToRead > 0);
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) {
break; /* Failed to go to the next page. Might have simply hit the end of the stream. */
}
@@ -6709,8 +6706,8 @@ static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_see
drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
int bytesSeeked = 0;
drflac_assert(oggbs != NULL);
drflac_assert(offset >= 0); /* <-- Never seek backwards. */
DRFLAC_ASSERT(oggbs != NULL);
DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
/* Seeking is always forward which makes things a lot simpler. */
if (origin == drflac_seek_origin_start) {
@@ -6725,11 +6722,11 @@ static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_see
return drflac__on_seek_ogg(pUserData, offset, drflac_seek_origin_current);
}
drflac_assert(origin == drflac_seek_origin_current);
DRFLAC_ASSERT(origin == drflac_seek_origin_current);
while (bytesSeeked < offset) {
int bytesRemainingToSeek = offset - bytesSeeked;
drflac_assert(bytesRemainingToSeek >= 0);
DRFLAC_ASSERT(bytesRemainingToSeek >= 0);
if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) {
bytesSeeked += bytesRemainingToSeek;
@@ -6744,7 +6741,7 @@ static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_see
oggbs->bytesRemainingInPage = 0;
}
drflac_assert(bytesRemainingToSeek > 0);
DRFLAC_ASSERT(bytesRemainingToSeek > 0);
if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) {
/* Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch. */
return DRFLAC_FALSE;
@@ -6763,7 +6760,7 @@ drflac_bool32 drflac_ogg__seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFram
drflac_uint64 runningFrameBytePos;
drflac_uint64 runningPCMFrameCount;
drflac_assert(oggbs != NULL);
DRFLAC_ASSERT(oggbs != NULL);
originalBytePos = oggbs->currentBytePos; /* For recovery. Points to the OggS identifier. */
@@ -7079,7 +7076,7 @@ drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onR
return DRFLAC_FALSE;
}
drflac_zero_memory(pInit, sizeof(*pInit));
DRFLAC_ZERO_MEMORY(pInit, sizeof(*pInit));
pInit->onRead = onRead;
pInit->onSeek = onSeek;
pInit->onMeta = onMeta;
@@ -7115,7 +7112,7 @@ drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onR
flags = header[1];
drflac_copy_memory(&headerSize, header+2, 4);
DRFLAC_COPY_MEMORY(&headerSize, header+2, 4);
headerSize = drflac__unsynchsafe_32(drflac__be2host_32(headerSize));
if (flags & 0x10) {
headerSize += 10;
@@ -7157,10 +7154,10 @@ drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onR
void drflac__init_from_info(drflac* pFlac, drflac_init_info* pInit)
{
drflac_assert(pFlac != NULL);
drflac_assert(pInit != NULL);
DRFLAC_ASSERT(pFlac != NULL);
DRFLAC_ASSERT(pInit != NULL);
drflac_zero_memory(pFlac, sizeof(*pFlac));
DRFLAC_ZERO_MEMORY(pFlac, sizeof(*pFlac));
pFlac->bs = pInit->bs;
pFlac->onMeta = pInit->onMeta;
pFlac->pUserDataMD = pInit->pUserDataMD;
@@ -7240,7 +7237,7 @@ drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_p
allocationSize += sizeof(drflac_oggbs);
}
drflac_zero_memory(&oggbs, sizeof(oggbs));
DRFLAC_ZERO_MEMORY(&oggbs, sizeof(oggbs));
if (init.container == drflac_container_ogg) {
oggbs.onRead = onRead;
oggbs.onSeek = onSeek;
@@ -7388,7 +7385,7 @@ static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t byt
static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
{
drflac_assert(offset >= 0); /* <-- Never seek backwards. */
DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
return fseek((FILE*)pUserData, offset, (origin == drflac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
}
@@ -7455,8 +7452,8 @@ static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t by
drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
size_t bytesRemaining;
drflac_assert(memoryStream != NULL);
drflac_assert(memoryStream->dataSize >= memoryStream->currentReadPos);
DRFLAC_ASSERT(memoryStream != NULL);
DRFLAC_ASSERT(memoryStream->dataSize >= memoryStream->currentReadPos);
bytesRemaining = memoryStream->dataSize - memoryStream->currentReadPos;
if (bytesToRead > bytesRemaining) {
@@ -7464,7 +7461,7 @@ static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t by
}
if (bytesToRead > 0) {
drflac_copy_memory(bufferOut, memoryStream->data + memoryStream->currentReadPos, bytesToRead);
DRFLAC_COPY_MEMORY(bufferOut, memoryStream->data + memoryStream->currentReadPos, bytesToRead);
memoryStream->currentReadPos += bytesToRead;
}
@@ -7475,8 +7472,8 @@ static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_
{
drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
drflac_assert(memoryStream != NULL);
drflac_assert(offset >= 0); /* <-- Never seek backwards. */
DRFLAC_ASSERT(memoryStream != NULL);
DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
if (offset > (drflac_int64)memoryStream->dataSize) {
return DRFLAC_FALSE;
@@ -7600,7 +7597,7 @@ void drflac_close(drflac* pFlac)
/* Need to clean up Ogg streams a bit differently due to the way the bit streaming is chained. */
if (pFlac->container == drflac_container_ogg) {
drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
drflac_assert(pFlac->bs.onRead == drflac__on_read_ogg);
DRFLAC_ASSERT(pFlac->bs.onRead == drflac__on_read_ogg);
if (oggbs->onRead == drflac__on_read_stdio) {
fclose((FILE*)oggbs->pUserData);
@@ -7679,7 +7676,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__sse2(drf
drflac_int32 shift1;
drflac_uint64 i;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -7716,7 +7713,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__neon(drf
int32x4_t shift0_4;
int32x4_t shift1_4;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -7837,7 +7834,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__sse2(dr
drflac_int32 shift1;
drflac_uint64 i;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -7874,7 +7871,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__neon(dr
int32x4_t shift0_4;
int32x4_t shift1_4;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -8061,7 +8058,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__sse2(drfl
drflac_uint64 frameCount4;
int shift;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -8137,7 +8134,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__neon(drfl
int32x4_t wbpsShift1_4; /* wbps = Wasted Bits Per Sample */
int32x4_t one4;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -8514,7 +8511,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__sse2(drf
drflac_int32 shift1;
drflac_uint64 i;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -8556,7 +8553,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__neon(drf
int32x4_t shift0_4;
int32x4_t shift1_4;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -8699,7 +8696,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__sse2(dr
drflac_int32 shift1;
drflac_uint64 i;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -8741,7 +8738,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__neon(dr
int32x4_t shift0_4;
int32x4_t shift1_4;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -8954,7 +8951,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__sse2(drfl
drflac_uint64 frameCount4;
drflac_int32 shift;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -9033,7 +9030,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__neon(drfl
int32x4_t wbpsShift0_4; /* wbps = Wasted Bits Per Sample */
int32x4_t wbpsShift1_4; /* wbps = Wasted Bits Per Sample */
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -9418,7 +9415,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__sse2(drf
drflac_uint64 i;
__m128 factor;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -9459,7 +9456,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__neon(drf
int32x4_t shift0_4;
int32x4_t shift1_4;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -9589,7 +9586,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__sse2(dr
drflac_uint64 i;
__m128 factor;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -9630,7 +9627,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__neon(dr
int32x4_t shift0_4;
int32x4_t shift1_4;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -9827,7 +9824,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__sse2(drfl
drflac_int32 shift;
__m128 factor128;
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -9918,7 +9915,7 @@ static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__neon(drfl
int32x4_t wbps0_4; /* Wasted Bits Per Sample */
int32x4_t wbps1_4; /* Wasted Bits Per Sample */
drflac_assert(pFlac->bitsPerSample <= 24);
DRFLAC_ASSERT(pFlac->bitsPerSample <= 24);
frameCount4 = frameCount >> 2;
@@ -10347,7 +10344,7 @@ static type* drflac__full_read_and_close_ ## extension (drflac* pFlac, unsigned
type* pSampleData = NULL; \
drflac_uint64 totalPCMFrameCount; \
\
drflac_assert(pFlac != NULL); \
DRFLAC_ASSERT(pFlac != NULL); \
\
totalPCMFrameCount = pFlac->totalPCMFrameCount; \
\
@@ -10377,13 +10374,13 @@ static type* drflac__full_read_and_close_ ## extension (drflac* pFlac, unsigned
pSampleData = pNewSampleData; \
} \
\
drflac_copy_memory(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \
DRFLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \
totalPCMFrameCount += pcmFramesRead; \
} \
\
/* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to \
protect those ears from random noise! */ \
drflac_zero_memory(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \
DRFLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \
} else { \
drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type); \
if (dataSize > DRFLAC_SIZE_MAX) { \
@@ -10695,7 +10692,7 @@ drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter,
offsetLo = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
cuesheetTrack.offset = offsetLo | (offsetHi << 32);
cuesheetTrack.trackNumber = pRunningData[0]; pRunningData += 1;
drflac_copy_memory(cuesheetTrack.ISRC, pRunningData, sizeof(cuesheetTrack.ISRC)); pRunningData += 12;
DRFLAC_COPY_MEMORY(cuesheetTrack.ISRC, pRunningData, sizeof(cuesheetTrack.ISRC)); pRunningData += 12;
cuesheetTrack.isAudio = (pRunningData[0] & 0x80) != 0;
cuesheetTrack.preEmphasis = (pRunningData[0] & 0x40) != 0; pRunningData += 14;
cuesheetTrack.indexCount = pRunningData[0]; pRunningData += 1;
@@ -10720,6 +10717,9 @@ drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter,
/*
REVISION HISTORY
================
v0.12.2 - 2019-10-07
- Internal code clean up.
v0.12.1 - 2019-09-29
- Fix some Clang Static Analyzer warnings.
- Fix an unused variable warning.
+335 -122
View File
@@ -1,6 +1,6 @@
/*
MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
dr_mp3 - v0.4.7 - 2019-07-28
dr_mp3 - v0.5.0 - 2019-10-07
David Reid - mackron@gmail.com
@@ -8,6 +8,71 @@ Based off minimp3 (https://github.com/lieff/minimp3) which is where the real wor
differences between minimp3 and dr_mp3.
*/
/*
RELEASE NOTES - v0.5.0
=======================
Version 0.5.0 has breaking API changes.
Improved Client-Defined Memory Allocation
-----------------------------------------
The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The
existing system of DRMP3_MALLOC, DRMP3_REALLOC and DRMP3_FREE are still in place and will be used by default when no custom
allocation callbacks are specified.
To use the new system, you pass in a pointer to a drmp3_allocation_callbacks object to drmp3_init() and family, like this:
void* my_malloc(size_t sz, void* pUserData)
{
return malloc(sz);
}
void* my_realloc(void* p, size_t sz, void* pUserData)
{
return realloc(p, sz);
}
void my_free(void* p, void* pUserData)
{
free(p);
}
...
drmp3_allocation_callbacks allocationCallbacks;
allocationCallbacks.pUserData = &myData;
allocationCallbacks.onMalloc = my_malloc;
allocationCallbacks.onRealloc = my_realloc;
allocationCallbacks.onFree = my_free;
drmp3_init_file(&mp3, "my_file.wav", NULL, &allocationCallbacks);
The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines.
Passing in null for the allocation callbacks object will cause dr_wav to use defaults which is the same as DRMP3_MALLOC,
DRMP3_REALLOC and DRMP3_FREE and the equivalent of how it worked in previous versions.
Every API that opens a drmp3 object now takes this extra parameter. These include the following:
drmp3_init()
drmp3_init_file()
drmp3_init_memory()
drmp3_open_and_read_pcm_frames_f32()
drmp3_open_and_read_pcm_frames_s16()
drmp3_open_memory_and_read_pcm_frames_f32()
drmp3_open_memory_and_read_pcm_frames_s16()
drmp3_open_file_and_read_pcm_frames_f32()
drmp3_open_file_and_read_pcm_frames_s16()
Renamed APIs
------------
The following APIs have been renamed for consistency with other dr_* libraries and to make it clear that they return PCM frame
counts rather than sample counts.
drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32()
drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16()
drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32()
drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16()
drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32()
drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16()
*/
/*
USAGE
=====
@@ -42,8 +107,8 @@ You do not need to do any annoying memory management when reading PCM frames - t
any number of PCM frames in each call to drmp3_read_pcm_frames_f32() and it will return as many PCM frames as it can, up to the
requested amount.
You can also decode an entire file in one go with drmp3_open_and_read_f32(), drmp3_open_memory_and_read_f32() and
drmp3_open_file_and_read_f32().
You can also decode an entire file in one go with drmp3_open_and_read_pcm_frames_f32(), drmp3_open_memory_and_read_pcm_frames_f32() and
drmp3_open_file_and_read_pcm_frames_f32().
OPTIONS
@@ -95,13 +160,22 @@ typedef drmp3_uint32 drmp3_bool32;
#define DRMP3_MAX_SAMPLES_PER_FRAME (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2)
#ifdef _MSC_VER
#define DRMP3_INLINE __forceinline
#define DRMP3_INLINE __forceinline
#elif defined(__GNUC__)
/*
I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
I am using "__inline__" only when we're compiling in strict ANSI mode.
*/
#if defined(__STRICT_ANSI__)
#define DRMP3_INLINE __inline__ __attribute__((always_inline))
#else
#define DRMP3_INLINE inline __attribute__((always_inline))
#endif
#else
#ifdef __GNUC__
#define DRMP3_INLINE __inline__ __attribute__((always_inline))
#else
#define DRMP3_INLINE
#endif
#define DRMP3_INLINE
#endif
/*
@@ -229,6 +303,14 @@ will be either drmp3_seek_origin_start or drmp3_seek_origin_current.
*/
typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin);
typedef struct
{
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} drmp3_allocation_callbacks;
typedef struct
{
drmp3_uint32 outputChannels;
@@ -244,6 +326,7 @@ typedef struct
drmp3_read_proc onRead;
drmp3_seek_proc onSeek;
void* pUserData;
drmp3_allocation_callbacks allocationCallbacks;
drmp3_uint32 mp3FrameChannels; /* The number of channels in the currently loaded MP3 frame. Internal use only. */
drmp3_uint32 mp3FrameSampleRate; /* The sample rate of the currently loaded MP3 frame. Internal use only. */
drmp3_uint32 pcmFramesConsumedInMP3Frame;
@@ -279,7 +362,7 @@ Close the loader with drmp3_uninit().
See also: drmp3_init_file(), drmp3_init_memory(), drmp3_uninit()
*/
drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_config* pConfig);
drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_config* pConfig, const drmp3_allocation_callbacks* pAllocationCallbacks);
/*
Initializes an MP3 decoder from a block of memory.
@@ -289,7 +372,7 @@ the lifetime of the drmp3 object.
The buffer should contain the contents of the entire MP3 file.
*/
drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_config* pConfig);
drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_config* pConfig, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_MP3_NO_STDIO
/*
@@ -299,7 +382,7 @@ This holds the internal FILE object until drmp3_uninit() is called. Keep this in
objects because the operating system may restrict the number of file handles an application can have open at
any given time.
*/
drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* filePath, const drmp3_config* pConfig);
drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* filePath, const drmp3_config* pConfig, const drmp3_allocation_callbacks* pAllocationCallbacks);
#endif
/*
@@ -377,21 +460,21 @@ pConfig is both an input and output. On input it contains what you want. On outp
Free the returned pointer with drmp3_free().
*/
float* drmp3_open_and_read_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount);
drmp3_int16* drmp3_open_and_read_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount);
float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
float* drmp3_open_memory_and_read_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount);
drmp3_int16* drmp3_open_memory_and_read_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount);
float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifndef DR_MP3_NO_STDIO
float* drmp3_open_file_and_read_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount);
drmp3_int16* drmp3_open_file_and_read_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount);
float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
#endif
/*
Frees any memory that was allocated by a public drmp3 API.
*/
void drmp3_free(void* p);
void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks);
#ifdef __cplusplus
}
@@ -2260,13 +2343,6 @@ void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, int num_samples)
#define DRMP3_FREE(p) free((p))
#endif
#define drmp3_assert DRMP3_ASSERT
#define drmp3_copy_memory DRMP3_COPY_MEMORY
#define drmp3_zero_memory DRMP3_ZERO_MEMORY
#define drmp3_zero_object DRMP3_ZERO_OBJECT
#define drmp3_malloc DRMP3_MALLOC
#define drmp3_realloc DRMP3_REALLOC
#define drmp3_countof(x) (sizeof(x) / sizeof(x[0]))
#define drmp3_max(x, y) (((x) > (y)) ? (x) : (y))
#define drmp3_min(x, y) (((x) < (y)) ? (x) : (y))
@@ -2286,10 +2362,105 @@ static void drmp3_blend_f32(float* pOut, float* pInA, float* pInB, float factor,
}
}
static void* drmp3__malloc_default(size_t sz, void* pUserData)
{
(void)pUserData;
return DRMP3_MALLOC(sz);
}
static void* drmp3__realloc_default(void* p, size_t sz, void* pUserData)
{
(void)pUserData;
return DRMP3_REALLOC(p, sz);
}
static void drmp3__free_default(void* p, void* pUserData)
{
(void)pUserData;
DRMP3_FREE(p);
}
static void* drmp3__malloc_from_callbacks(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
if (pAllocationCallbacks == NULL) {
return NULL;
}
if (pAllocationCallbacks->onMalloc != NULL) {
return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
}
/* Try using realloc(). */
if (pAllocationCallbacks->onRealloc != NULL) {
return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
}
return NULL;
}
static void* drmp3__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
if (pAllocationCallbacks == NULL) {
return NULL;
}
if (pAllocationCallbacks->onRealloc != NULL) {
return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
}
/* Try emulating realloc() in terms of malloc()/free(). */
if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
void* p2;
p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
if (p2 == NULL) {
return NULL;
}
DRMP3_COPY_MEMORY(p2, p, szOld);
pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
return p2;
}
return NULL;
}
static void drmp3__free_from_callbacks(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
if (p == NULL || pAllocationCallbacks == NULL) {
return;
}
if (pAllocationCallbacks->onFree != NULL) {
pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
}
}
drmp3_allocation_callbacks drmp3_copy_allocation_callbacks_or_defaults(const drmp3_allocation_callbacks* pAllocationCallbacks)
{
if (pAllocationCallbacks != NULL) {
/* Copy. */
return *pAllocationCallbacks;
} else {
/* Defaults. */
drmp3_allocation_callbacks allocationCallbacks;
allocationCallbacks.pUserData = NULL;
allocationCallbacks.onMalloc = drmp3__malloc_default;
allocationCallbacks.onRealloc = drmp3__realloc_default;
allocationCallbacks.onFree = drmp3__free_default;
return allocationCallbacks;
}
}
void drmp3_src_cache_init(drmp3_src* pSRC, drmp3_src_cache* pCache)
{
drmp3_assert(pSRC != NULL);
drmp3_assert(pCache != NULL);
DRMP3_ASSERT(pSRC != NULL);
DRMP3_ASSERT(pCache != NULL);
pCache->pSRC = pSRC;
pCache->cachedFrameCount = 0;
@@ -2301,11 +2472,11 @@ drmp3_uint64 drmp3_src_cache_read_frames(drmp3_src_cache* pCache, drmp3_uint64 f
drmp3_uint32 channels;
drmp3_uint64 totalFramesRead = 0;
drmp3_assert(pCache != NULL);
drmp3_assert(pCache->pSRC != NULL);
drmp3_assert(pCache->pSRC->onRead != NULL);
drmp3_assert(frameCount > 0);
drmp3_assert(pFramesOut != NULL);
DRMP3_ASSERT(pCache != NULL);
DRMP3_ASSERT(pCache->pSRC != NULL);
DRMP3_ASSERT(pCache->pSRC->onRead != NULL);
DRMP3_ASSERT(frameCount > 0);
DRMP3_ASSERT(pFramesOut != NULL);
channels = pCache->pSRC->config.channels;
@@ -2318,7 +2489,7 @@ drmp3_uint64 drmp3_src_cache_read_frames(drmp3_src_cache* pCache, drmp3_uint64 f
framesToReadFromMemory = framesRemainingInMemory;
}
drmp3_copy_memory(pFramesOut, pCache->pCachedFrames + pCache->iNextFrame*channels, (drmp3_uint32)(framesToReadFromMemory * channels * sizeof(float)));
DRMP3_COPY_MEMORY(pFramesOut, pCache->pCachedFrames + pCache->iNextFrame*channels, (drmp3_uint32)(framesToReadFromMemory * channels * sizeof(float)));
pCache->iNextFrame += (drmp3_uint32)framesToReadFromMemory;
totalFramesRead += framesToReadFromMemory;
@@ -2329,7 +2500,7 @@ drmp3_uint64 drmp3_src_cache_read_frames(drmp3_src_cache* pCache, drmp3_uint64 f
/* At this point there are still more frames to read from the client, so we'll need to reload the cache with fresh data. */
drmp3_assert(frameCount > 0);
DRMP3_ASSERT(frameCount > 0);
pFramesOut += framesToReadFromMemory * channels;
pCache->iNextFrame = 0;
@@ -2362,7 +2533,7 @@ drmp3_bool32 drmp3_src_init(const drmp3_src_config* pConfig, drmp3_src_read_proc
return DRMP3_FALSE;
}
drmp3_zero_object(pSRC);
DRMP3_ZERO_OBJECT(pSRC);
if (pConfig == NULL || onRead == NULL) {
return DRMP3_FALSE;
@@ -2445,9 +2616,9 @@ drmp3_uint64 drmp3_src_read_frames(drmp3_src* pSRC, drmp3_uint64 frameCount, voi
drmp3_uint64 drmp3_src_read_frames_passthrough(drmp3_src* pSRC, drmp3_uint64 frameCount, void* pFramesOut, drmp3_bool32 flush)
{
drmp3_assert(pSRC != NULL);
drmp3_assert(frameCount > 0);
drmp3_assert(pFramesOut != NULL);
DRMP3_ASSERT(pSRC != NULL);
DRMP3_ASSERT(frameCount > 0);
DRMP3_ASSERT(pFramesOut != NULL);
(void)flush; /* Passthrough need not care about flushing. */
return pSRC->onRead(pSRC, frameCount, pFramesOut, pSRC->pUserData);
@@ -2458,9 +2629,9 @@ drmp3_uint64 drmp3_src_read_frames_linear(drmp3_src* pSRC, drmp3_uint64 frameCou
double factor;
drmp3_uint64 totalFramesRead;
drmp3_assert(pSRC != NULL);
drmp3_assert(frameCount > 0);
drmp3_assert(pFramesOut != NULL);
DRMP3_ASSERT(pSRC != NULL);
DRMP3_ASSERT(frameCount > 0);
DRMP3_ASSERT(pFramesOut != NULL);
/* For linear SRC, the bin is only 2 frames: 1 prior, 1 future. */
@@ -2549,7 +2720,7 @@ static size_t drmp3__on_read(drmp3* pMP3, void* pBufferOut, size_t bytesToRead)
static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin origin)
{
drmp3_assert(offset >= 0);
DRMP3_ASSERT(offset >= 0);
if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) {
return DRMP3_FALSE;
@@ -2603,8 +2774,8 @@ static drmp3_uint64 drmp3_read_src(drmp3_src* pSRC, drmp3_uint64 frameCount, voi
float* pFramesOutF = (float*)pFramesOut;
drmp3_uint64 totalFramesRead = 0;
drmp3_assert(pMP3 != NULL);
drmp3_assert(pMP3->onRead != NULL);
DRMP3_ASSERT(pMP3 != NULL);
DRMP3_ASSERT(pMP3->onRead != NULL);
while (frameCount > 0) {
/* Read from the in-memory buffer first. */
@@ -2669,7 +2840,7 @@ static drmp3_uint64 drmp3_read_src(drmp3_src* pSRC, drmp3_uint64 frameCount, voi
break;
}
drmp3_assert(pMP3->pcmFramesRemainingInMP3Frame == 0);
DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0);
/*
At this point we have exhausted our in-memory buffer so we need to re-fill. Note that the sample rate may have changed
@@ -2686,7 +2857,7 @@ static drmp3_uint64 drmp3_read_src(drmp3_src* pSRC, drmp3_uint64 frameCount, voi
static drmp3_bool32 drmp3_init_src(drmp3* pMP3)
{
drmp3_src_config srcConfig;
drmp3_zero_object(&srcConfig);
DRMP3_ZERO_OBJECT(&srcConfig);
srcConfig.sampleRateIn = DR_MP3_DEFAULT_SAMPLE_RATE;
srcConfig.sampleRateOut = pMP3->sampleRate;
srcConfig.channels = pMP3->channels;
@@ -2703,8 +2874,8 @@ static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPC
{
drmp3_uint32 pcmFramesRead = 0;
drmp3_assert(pMP3 != NULL);
drmp3_assert(pMP3->onRead != NULL);
DRMP3_ASSERT(pMP3 != NULL);
DRMP3_ASSERT(pMP3->onRead != NULL);
if (pMP3->atEnd) {
return 0;
@@ -2720,14 +2891,17 @@ static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPC
if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) {
drmp3_uint8* pNewData;
size_t newDataCap;
pMP3->dataCapacity = DRMP3_DATA_CHUNK_SIZE;
pNewData = (drmp3_uint8*)drmp3_realloc(pMP3->pData, pMP3->dataCapacity);
newDataCap = DRMP3_DATA_CHUNK_SIZE;
pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
if (pNewData == NULL) {
return 0; /* Out of memory. */
}
pMP3->pData = pNewData;
pMP3->dataCapacity = newDataCap;
}
bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
@@ -2784,16 +2958,19 @@ static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPC
/* Need more data. minimp3 recommends doing data submission in 16K chunks. */
if (pMP3->dataCapacity == pMP3->dataSize) {
drmp3_uint8* pNewData;
/* No room. Expand. */
pMP3->dataCapacity += DRMP3_DATA_CHUNK_SIZE;
pNewData = (drmp3_uint8*)drmp3_realloc(pMP3->pData, pMP3->dataCapacity);
drmp3_uint8* pNewData;
size_t newDataCap;
newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE;
pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
if (pNewData == NULL) {
return 0; /* Out of memory. */
}
pMP3->pData = pNewData;
pMP3->dataCapacity = newDataCap;
}
/* Fill in a chunk. */
@@ -2812,7 +2989,7 @@ static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPC
static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3)
{
drmp3_assert(pMP3 != NULL);
DRMP3_ASSERT(pMP3 != NULL);
return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames, DRMP3_FALSE);
}
@@ -2821,7 +2998,7 @@ static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3)
{
drmp3_uint32 pcmFrameCount;
drmp3_assert(pMP3 != NULL);
DRMP3_ASSERT(pMP3 != NULL);
pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL);
if (pcmFrameCount == 0) {
@@ -2837,12 +3014,12 @@ static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3)
}
#endif
drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_config* pConfig)
drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_config* pConfig, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
drmp3_config config;
drmp3_assert(pMP3 != NULL);
drmp3_assert(onRead != NULL);
DRMP3_ASSERT(pMP3 != NULL);
DRMP3_ASSERT(onRead != NULL);
/* This function assumes the output object has already been reset to 0. Do not do that here, otherwise things will break. */
drmp3dec_init(&pMP3->decoder);
@@ -2851,7 +3028,7 @@ drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek
if (pConfig != NULL) {
config = *pConfig;
} else {
drmp3_zero_object(&config);
DRMP3_ZERO_OBJECT(&config);
}
pMP3->channels = config.outputChannels;
@@ -2866,6 +3043,11 @@ drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek
pMP3->onRead = onRead;
pMP3->onSeek = onSeek;
pMP3->pUserData = pUserData;
pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) {
return DRMP3_FALSE; /* Invalid allocation callbacks. */
}
/*
We need a sample rate converter for converting the sample rate from the MP3 frames to the requested output sample rate. Note that if
@@ -2884,14 +3066,14 @@ drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek
return DRMP3_TRUE;
}
drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_config* pConfig)
drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_config* pConfig, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
if (pMP3 == NULL || onRead == NULL) {
return DRMP3_FALSE;
}
drmp3_zero_object(pMP3);
return drmp3_init_internal(pMP3, onRead, onSeek, pUserData, pConfig);
DRMP3_ZERO_OBJECT(pMP3);
return drmp3_init_internal(pMP3, onRead, onSeek, pUserData, pConfig, pAllocationCallbacks);
}
@@ -2900,8 +3082,8 @@ static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t by
drmp3* pMP3 = (drmp3*)pUserData;
size_t bytesRemaining;
drmp3_assert(pMP3 != NULL);
drmp3_assert(pMP3->memory.dataSize >= pMP3->memory.currentReadPos);
DRMP3_ASSERT(pMP3 != NULL);
DRMP3_ASSERT(pMP3->memory.dataSize >= pMP3->memory.currentReadPos);
bytesRemaining = pMP3->memory.dataSize - pMP3->memory.currentReadPos;
if (bytesToRead > bytesRemaining) {
@@ -2909,7 +3091,7 @@ static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t by
}
if (bytesToRead > 0) {
drmp3_copy_memory(pBufferOut, pMP3->memory.pData + pMP3->memory.currentReadPos, bytesToRead);
DRMP3_COPY_MEMORY(pBufferOut, pMP3->memory.pData + pMP3->memory.currentReadPos, bytesToRead);
pMP3->memory.currentReadPos += bytesToRead;
}
@@ -2920,7 +3102,7 @@ static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3
{
drmp3* pMP3 = (drmp3*)pUserData;
drmp3_assert(pMP3 != NULL);
DRMP3_ASSERT(pMP3 != NULL);
if (origin == drmp3_seek_origin_current) {
if (byteOffset > 0) {
@@ -2946,13 +3128,13 @@ static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3
return DRMP3_TRUE;
}
drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_config* pConfig)
drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_config* pConfig, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
if (pMP3 == NULL) {
return DRMP3_FALSE;
}
drmp3_zero_object(pMP3);
DRMP3_ZERO_OBJECT(pMP3);
if (pData == NULL || dataSize == 0) {
return DRMP3_FALSE;
@@ -2962,7 +3144,7 @@ drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize,
pMP3->memory.dataSize = dataSize;
pMP3->memory.currentReadPos = 0;
return drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, pMP3, pConfig);
return drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, pMP3, pConfig, pAllocationCallbacks);
}
@@ -2979,7 +3161,7 @@ static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek
return fseek((FILE*)pUserData, offset, (origin == drmp3_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
}
drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* filePath, const drmp3_config* pConfig)
drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* filePath, const drmp3_config* pConfig, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
FILE* pFile;
#if defined(_MSC_VER) && _MSC_VER >= 1400
@@ -2993,7 +3175,7 @@ drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* filePath, const drmp3_conf
}
#endif
return drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pConfig);
return drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pConfig, pAllocationCallbacks);
}
#endif
@@ -3009,7 +3191,7 @@ void drmp3_uninit(drmp3* pMP3)
}
#endif
drmp3_free(pMP3->pData);
drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);
}
drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut)
@@ -3082,7 +3264,7 @@ drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, d
void drmp3_reset(drmp3* pMP3)
{
drmp3_assert(pMP3 != NULL);
DRMP3_ASSERT(pMP3 != NULL);
pMP3->pcmFramesConsumedInMP3Frame = 0;
pMP3->pcmFramesRemainingInMP3Frame = 0;
@@ -3103,8 +3285,8 @@ void drmp3_reset(drmp3* pMP3)
drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3)
{
drmp3_assert(pMP3 != NULL);
drmp3_assert(pMP3->onSeek != NULL);
DRMP3_ASSERT(pMP3 != NULL);
DRMP3_ASSERT(pMP3->onSeek != NULL);
/* Seek to the start of the stream to begin with. */
if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) {
@@ -3189,7 +3371,7 @@ drmp3_bool32 drmp3_seek_forward_by_pcm_frames__brute_force(drmp3* pMP3, drmp3_ui
drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 frameIndex)
{
drmp3_assert(pMP3 != NULL);
DRMP3_ASSERT(pMP3 != NULL);
if (frameIndex == pMP3->currentPCMFrame) {
return DRMP3_TRUE;
@@ -3206,7 +3388,7 @@ drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 fram
}
}
drmp3_assert(frameIndex >= pMP3->currentPCMFrame);
DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame);
return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame));
}
@@ -3214,7 +3396,7 @@ drmp3_bool32 drmp3_find_closest_seek_point(drmp3* pMP3, drmp3_uint64 frameIndex,
{
drmp3_uint32 iSeekPoint;
drmp3_assert(pSeekPointIndex != NULL);
DRMP3_ASSERT(pSeekPointIndex != NULL);
*pSeekPointIndex = 0;
@@ -3241,9 +3423,9 @@ drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint64 frame
drmp3_uint16 iMP3Frame;
drmp3_uint64 leftoverFrames;
drmp3_assert(pMP3 != NULL);
drmp3_assert(pMP3->pSeekPoints != NULL);
drmp3_assert(pMP3->seekPointCount > 0);
DRMP3_ASSERT(pMP3 != NULL);
DRMP3_ASSERT(pMP3->pSeekPoints != NULL);
DRMP3_ASSERT(pMP3->seekPointCount > 0);
/* If there is no prior seekpoint it means the target PCM frame comes before the first seek point. Just assume a seekpoint at the start of the file in this case. */
if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) {
@@ -3365,7 +3547,7 @@ drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3Fr
}
srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate;
drmp3_assert(srcRatio > 0);
DRMP3_ASSERT(srcRatio > 0);
pcmFramesInCurrentMP3FrameOutF = totalPCMFrameCountFractionalPart + (pcmFramesInCurrentMP3FrameIn / srcRatio);
pcmFramesInCurrentMP3FrameOut = (drmp3_uint32)pcmFramesInCurrentMP3FrameOutF;
@@ -3420,7 +3602,7 @@ void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFram
drmp3_uint32 pcmFrameCountOut;
srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate;
drmp3_assert(srcRatio > 0);
DRMP3_ASSERT(srcRatio > 0);
pcmFrameCountOutF = *pRunningPCMFrameCountFractionalPart + (pcmFrameCountIn / srcRatio);
pcmFrameCountOut = (drmp3_uint32)pcmFrameCountOutF;
@@ -3498,7 +3680,7 @@ drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCo
drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
/* The byte position of the next frame will be the stream's cursor position, minus whatever is sitting in the buffer. */
drmp3_assert(pMP3->streamCursor >= pMP3->dataSize);
DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
mp3FrameInfo[iMP3Frame].bytePos = pMP3->streamCursor - pMP3->dataSize;
mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount;
@@ -3601,7 +3783,7 @@ float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_
float* pFrames = NULL;
float temp[4096];
drmp3_assert(pMP3 != NULL);
DRMP3_ASSERT(pMP3 != NULL);
for (;;) {
drmp3_uint64 framesToReadRightNow = drmp3_countof(temp) / pMP3->channels;
@@ -3612,29 +3794,33 @@ float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_
/* Reallocate the output buffer if there's not enough room. */
if (framesCapacity < totalFramesRead + framesJustRead) {
drmp3_uint64 oldFramesBufferSize;
drmp3_uint64 newFramesBufferSize;
drmp3_uint64 newFramesCap;
float* pNewFrames;
framesCapacity *= 2;
if (framesCapacity < totalFramesRead + framesJustRead) {
framesCapacity = totalFramesRead + framesJustRead;
newFramesCap = framesCapacity * 2;
if (newFramesCap < totalFramesRead + framesJustRead) {
newFramesCap = totalFramesRead + framesJustRead;
}
newFramesBufferSize = framesCapacity*pMP3->channels*sizeof(float);
oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float);
newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(float);
if (newFramesBufferSize > DRMP3_SIZE_MAX) {
break;
}
pNewFrames = (float*)drmp3_realloc(pFrames, (size_t)newFramesBufferSize);
pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
if (pNewFrames == NULL) {
drmp3_free(pFrames);
drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
break;
}
pFrames = pNewFrames;
framesCapacity = newFramesCap;
}
drmp3_copy_memory(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
totalFramesRead += framesJustRead;
/* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
@@ -3664,7 +3850,7 @@ drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig,
drmp3_int16* pFrames = NULL;
drmp3_int16 temp[4096];
drmp3_assert(pMP3 != NULL);
DRMP3_ASSERT(pMP3 != NULL);
for (;;) {
drmp3_uint64 framesToReadRightNow = drmp3_countof(temp) / pMP3->channels;
@@ -3676,28 +3862,31 @@ drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig,
/* Reallocate the output buffer if there's not enough room. */
if (framesCapacity < totalFramesRead + framesJustRead) {
drmp3_uint64 newFramesBufferSize;
drmp3_uint64 oldFramesBufferSize;
drmp3_uint64 newFramesCap;
drmp3_int16* pNewFrames;
framesCapacity *= 2;
if (framesCapacity < totalFramesRead + framesJustRead) {
framesCapacity = totalFramesRead + framesJustRead;
newFramesCap = framesCapacity * 2;
if (newFramesCap < totalFramesRead + framesJustRead) {
newFramesCap = totalFramesRead + framesJustRead;
}
newFramesBufferSize = framesCapacity*pMP3->channels*sizeof(drmp3_int16);
oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16);
newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(drmp3_int16);
if (newFramesBufferSize > DRMP3_SIZE_MAX) {
break;
}
pNewFrames = (drmp3_int16*)drmp3_realloc(pFrames, (size_t)newFramesBufferSize);
pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
if (pNewFrames == NULL) {
drmp3_free(pFrames);
drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
break;
}
pFrames = pNewFrames;
}
drmp3_copy_memory(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16)));
DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16)));
totalFramesRead += framesJustRead;
/* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
@@ -3721,20 +3910,20 @@ drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig,
}
float* drmp3_open_and_read_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
drmp3 mp3;
if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pConfig)) {
if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pConfig, pAllocationCallbacks)) {
return NULL;
}
return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
}
drmp3_int16* drmp3_open_and_read_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
drmp3 mp3;
if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pConfig)) {
if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pConfig, pAllocationCallbacks)) {
return NULL;
}
@@ -3742,20 +3931,20 @@ drmp3_int16* drmp3_open_and_read_s16(drmp3_read_proc onRead, drmp3_seek_proc onS
}
float* drmp3_open_memory_and_read_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
drmp3 mp3;
if (!drmp3_init_memory(&mp3, pData, dataSize, pConfig)) {
if (!drmp3_init_memory(&mp3, pData, dataSize, pConfig, pAllocationCallbacks)) {
return NULL;
}
return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
}
drmp3_int16* drmp3_open_memory_and_read_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
drmp3 mp3;
if (!drmp3_init_memory(&mp3, pData, dataSize, pConfig)) {
if (!drmp3_init_memory(&mp3, pData, dataSize, pConfig, pAllocationCallbacks)) {
return NULL;
}
@@ -3764,20 +3953,20 @@ drmp3_int16* drmp3_open_memory_and_read_s16(const void* pData, size_t dataSize,
#ifndef DR_MP3_NO_STDIO
float* drmp3_open_file_and_read_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
drmp3 mp3;
if (!drmp3_init_file(&mp3, filePath, pConfig)) {
if (!drmp3_init_file(&mp3, filePath, pConfig, pAllocationCallbacks)) {
return NULL;
}
return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
}
drmp3_int16* drmp3_open_file_and_read_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
drmp3 mp3;
if (!drmp3_init_file(&mp3, filePath, pConfig)) {
if (!drmp3_init_file(&mp3, filePath, pConfig, pAllocationCallbacks)) {
return NULL;
}
@@ -3785,9 +3974,13 @@ drmp3_int16* drmp3_open_file_and_read_s16(const char* filePath, drmp3_config* pC
}
#endif
void drmp3_free(void* p)
void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
DRMP3_FREE(p);
if (pAllocationCallbacks != NULL) {
drmp3__free_from_callbacks(p, pAllocationCallbacks);
} else {
drmp3__free_default(p, NULL);
}
}
#endif /*DR_MP3_IMPLEMENTATION*/
@@ -3810,6 +4003,26 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3
/*
REVISION HISTORY
================
v0.5.0 - 2019-10-07
- API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
- drmp3_init()
- drmp3_init_file()
- drmp3_init_memory()
- drmp3_open_and_read_pcm_frames_f32()
- drmp3_open_and_read_pcm_frames_s16()
- drmp3_open_memory_and_read_pcm_frames_f32()
- drmp3_open_memory_and_read_pcm_frames_s16()
- drmp3_open_file_and_read_pcm_frames_f32()
- drmp3_open_file_and_read_pcm_frames_s16()
- API CHANGE: Renamed the following APIs:
- drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32()
- drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16()
- drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32()
- drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16()
- drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32()
- drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16()
v0.4.7 - 2019-07-28
- Fix a compiler error.
@@ -3828,9 +4041,9 @@ v0.4.3 - 2019-05-05
DR_MP3_DEFAULT_CHANNELS or DR_MP3_DEFAULT_SAMPLE_RATE.
- Add s16 reading APIs
- drmp3_read_pcm_frames_s16
- drmp3_open_memory_and_read_s16
- drmp3_open_and_read_s16
- drmp3_open_file_and_read_s16
- drmp3_open_memory_and_read_pcm_frames_s16
- drmp3_open_and_read_pcm_frames_s16
- drmp3_open_file_and_read_pcm_frames_s16
- Add drmp3_get_mp3_and_pcm_frame_count() to the public header section.
- Add support for C89.
- Change license to choice of public domain or MIT-0.
@@ -3845,9 +4058,9 @@ v0.4.0 - 2018-12-16
- API CHANGE: Rename some APIs:
- drmp3_read_f32 -> to drmp3_read_pcm_frames_f32
- drmp3_seek_to_frame -> drmp3_seek_to_pcm_frame
- drmp3_open_and_decode_f32 -> drmp3_open_and_read_f32
- drmp3_open_and_decode_memory_f32 -> drmp3_open_memory_and_read_f32
- drmp3_open_and_decode_file_f32 -> drmp3_open_file_and_read_f32
- drmp3_open_and_decode_f32 -> drmp3_open_and_read_pcm_frames_f32
- drmp3_open_and_decode_memory_f32 -> drmp3_open_memory_and_read_pcm_frames_f32
- drmp3_open_and_decode_file_f32 -> drmp3_open_file_and_read_pcm_frames_f32
- Add drmp3_get_pcm_frame_count().
- Add drmp3_get_mp3_frame_count().
- Improve seeking performance.
+32 -33
View File
@@ -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.11.0 - 2019-10-06
dr_wav - v0.11.1 - 2019-10-07
David Reid - mackron@gmail.com
*/
@@ -16,7 +16,7 @@ The main change with this release is the addition of a more flexible way of impl
existing system of DRWAV_MALLOC, DRWAV_REALLOC and DRWAV_FREE are still in place and will be used by default when no custom
allocation callbacks are specified.
To use the new system, you pass in a pointer to a drwav_allocation_callbacks object to drwav_open() and family, like this:
To use the new system, you pass in a pointer to a drwav_allocation_callbacks object to drwav_init() and family, like this:
void* my_malloc(size_t sz, void* pUserData)
{
@@ -1010,10 +1010,6 @@ void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks)
#define drwav_max(a, b) (((a) > (b)) ? (a) : (b))
#define drwav_clamp(x, lo, hi) (drwav_max((lo), drwav_min((hi), (x))))
#define drwav_assert DRWAV_ASSERT
#define drwav_copy_memory DRWAV_COPY_MEMORY
#define drwav_zero_memory DRWAV_ZERO_MEMORY
#define DRWAV_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */
/* CPU architecture. */
@@ -1706,8 +1702,8 @@ size_t drwav__on_read(drwav_read_proc onRead, void* pUserData, void* pBufferOut,
{
size_t bytesRead;
drwav_assert(onRead != NULL);
drwav_assert(pCursor != NULL);
DRWAV_ASSERT(onRead != NULL);
DRWAV_ASSERT(pCursor != NULL);
bytesRead = onRead(pUserData, pBufferOut, bytesToRead);
*pCursor += bytesRead;
@@ -1716,8 +1712,8 @@ size_t drwav__on_read(drwav_read_proc onRead, void* pUserData, void* pBufferOut,
drwav_bool32 drwav__on_seek(drwav_seek_proc onSeek, void* pUserData, int offset, drwav_seek_origin origin, drwav_uint64* pCursor)
{
drwav_assert(onSeek != NULL);
drwav_assert(pCursor != NULL);
DRWAV_ASSERT(onSeek != NULL);
DRWAV_ASSERT(pCursor != NULL);
if (!onSeek(pUserData, offset, origin)) {
return DRWAV_FALSE;
@@ -2580,8 +2576,8 @@ static size_t drwav__on_read_memory(void* pUserData, void* pBufferOut, size_t by
drwav* pWav = (drwav*)pUserData;
size_t bytesRemaining;
drwav_assert(pWav != NULL);
drwav_assert(pWav->memoryStream.dataSize >= pWav->memoryStream.currentReadPos);
DRWAV_ASSERT(pWav != NULL);
DRWAV_ASSERT(pWav->memoryStream.dataSize >= pWav->memoryStream.currentReadPos);
bytesRemaining = pWav->memoryStream.dataSize - pWav->memoryStream.currentReadPos;
if (bytesToRead > bytesRemaining) {
@@ -2599,7 +2595,7 @@ static size_t drwav__on_read_memory(void* pUserData, void* pBufferOut, size_t by
static drwav_bool32 drwav__on_seek_memory(void* pUserData, int offset, drwav_seek_origin origin)
{
drwav* pWav = (drwav*)pUserData;
drwav_assert(pWav != NULL);
DRWAV_ASSERT(pWav != NULL);
if (origin == drwav_seek_origin_current) {
if (offset > 0) {
@@ -2630,8 +2626,8 @@ static size_t drwav__on_write_memory(void* pUserData, const void* pDataIn, size_
drwav* pWav = (drwav*)pUserData;
size_t bytesRemaining;
drwav_assert(pWav != NULL);
drwav_assert(pWav->memoryStreamWrite.dataCapacity >= pWav->memoryStreamWrite.currentWritePos);
DRWAV_ASSERT(pWav != NULL);
DRWAV_ASSERT(pWav->memoryStreamWrite.dataCapacity >= pWav->memoryStreamWrite.currentWritePos);
bytesRemaining = pWav->memoryStreamWrite.dataCapacity - pWav->memoryStreamWrite.currentWritePos;
if (bytesRemaining < bytesToWrite) {
@@ -2668,7 +2664,7 @@ static size_t drwav__on_write_memory(void* pUserData, const void* pDataIn, size_
static drwav_bool32 drwav__on_seek_memory_write(void* pUserData, int offset, drwav_seek_origin origin)
{
drwav* pWav = (drwav*)pUserData;
drwav_assert(pWav != NULL);
DRWAV_ASSERT(pWav != NULL);
if (origin == drwav_seek_origin_current) {
if (offset > 0) {
@@ -2998,7 +2994,7 @@ drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64 targetFrameIndex)
drwav_uint64 offset;
totalSizeInBytes = pWav->totalPCMFrameCount * drwav_get_bytes_per_pcm_frame(pWav);
drwav_assert(totalSizeInBytes >= pWav->bytesRemaining);
DRWAV_ASSERT(totalSizeInBytes >= pWav->bytesRemaining);
currentBytePos = totalSizeInBytes - pWav->bytesRemaining;
targetBytePos = targetFrameIndex * drwav_get_bytes_per_pcm_frame(pWav);
@@ -3154,9 +3150,9 @@ drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwav_uint64 frames
{
drwav_uint64 totalFramesRead = 0;
drwav_assert(pWav != NULL);
drwav_assert(framesToRead > 0);
drwav_assert(pBufferOut != NULL);
DRWAV_ASSERT(pWav != NULL);
DRWAV_ASSERT(framesToRead > 0);
DRWAV_ASSERT(pBufferOut != NULL);
/* TODO: Lots of room for optimization here. */
@@ -3332,9 +3328,9 @@ drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_uint64 framesToRe
{
drwav_uint64 totalFramesRead = 0;
drwav_assert(pWav != NULL);
drwav_assert(framesToRead > 0);
drwav_assert(pBufferOut != NULL);
DRWAV_ASSERT(pWav != NULL);
DRWAV_ASSERT(framesToRead > 0);
DRWAV_ASSERT(pBufferOut != NULL);
/* TODO: Lots of room for optimization here. */
@@ -3553,7 +3549,7 @@ static void drwav__pcm_to_s16(drwav_int16* pOut, const unsigned char* pIn, size_
/* Anything more than 64 bits per sample is not supported. */
if (bytesPerSample > 8) {
drwav_zero_memory(pOut, totalSampleCount * sizeof(*pOut));
DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
return;
}
@@ -3584,7 +3580,7 @@ static void drwav__ieee_to_s16(drwav_int16* pOut, const unsigned char* pIn, size
return;
} else {
/* Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float. */
drwav_zero_memory(pOut, totalSampleCount * sizeof(*pOut));
DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
return;
}
}
@@ -3875,7 +3871,7 @@ static void drwav__pcm_to_f32(float* pOut, const unsigned char* pIn, size_t samp
/* Anything more than 64 bits per sample is not supported. */
if (bytesPerSample > 8) {
drwav_zero_memory(pOut, sampleCount * sizeof(*pOut));
DRWAV_ZERO_MEMORY(pOut, sampleCount * sizeof(*pOut));
return;
}
@@ -3909,7 +3905,7 @@ static void drwav__ieee_to_f32(float* pOut, const unsigned char* pIn, size_t sam
return;
} else {
/* Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float. */
drwav_zero_memory(pOut, sampleCount * sizeof(*pOut));
DRWAV_ZERO_MEMORY(pOut, sampleCount * sizeof(*pOut));
return;
}
}
@@ -4277,7 +4273,7 @@ static void drwav__pcm_to_s32(drwav_int32* pOut, const unsigned char* pIn, size_
/* Anything more than 64 bits per sample is not supported. */
if (bytesPerSample > 8) {
drwav_zero_memory(pOut, totalSampleCount * sizeof(*pOut));
DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
return;
}
@@ -4308,7 +4304,7 @@ static void drwav__ieee_to_s32(drwav_int32* pOut, const unsigned char* pIn, size
return;
} else {
/* Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float. */
drwav_zero_memory(pOut, totalSampleCount * sizeof(*pOut));
DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
return;
}
}
@@ -4644,7 +4640,7 @@ drwav_int16* drwav__read_pcm_frames_and_close_s16(drwav* pWav, unsigned int* cha
drwav_int16* pSampleData;
drwav_uint64 framesRead;
drwav_assert(pWav != NULL);
DRWAV_ASSERT(pWav != NULL);
sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int16);
if (sampleDataSize > DRWAV_SIZE_MAX) {
@@ -4686,7 +4682,7 @@ float* drwav__read_pcm_frames_and_close_f32(drwav* pWav, unsigned int* channels,
float* pSampleData;
drwav_uint64 framesRead;
drwav_assert(pWav != NULL);
DRWAV_ASSERT(pWav != NULL);
sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(float);
if (sampleDataSize > DRWAV_SIZE_MAX) {
@@ -4728,7 +4724,7 @@ drwav_int32* drwav__read_pcm_frames_and_close_s32(drwav* pWav, unsigned int* cha
drwav_int32* pSampleData;
drwav_uint64 framesRead;
drwav_assert(pWav != NULL);
DRWAV_ASSERT(pWav != NULL);
sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int32);
if (sampleDataSize > DRWAV_SIZE_MAX) {
@@ -5037,8 +5033,11 @@ void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks)
/*
REVISION HISTORY
================
v0.11.1 - 2019-10-07
- Internal code clean up.
v0.11.0 - 2019-10-06
- API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
- API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
- drwav_init()
- drwav_init_ex()
+1 -1
View File
@@ -34172,7 +34172,7 @@ ma_result ma_decoder_init_mp3__internal(const ma_decoder_config* pConfig, ma_dec
ma_zero_object(&mp3Config);
mp3Config.outputChannels = 2;
mp3Config.outputSampleRate = (pConfig->sampleRate != 0) ? pConfig->sampleRate : 44100;
if (!drmp3_init(pMP3, ma_decoder_internal_on_read__mp3, ma_decoder_internal_on_seek__mp3, pDecoder, &mp3Config)) {
if (!drmp3_init(pMP3, ma_decoder_internal_on_read__mp3, ma_decoder_internal_on_seek__mp3, pDecoder, &mp3Config, NULL)) {
ma_free(pMP3);
return MA_ERROR;
}