*/
DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex);
-
-
-#ifndef DR_FLAC_NO_STDIO
-/*
-Opens a FLAC decoder from the file at the given path.
-
-
-Parameters
-----------
-pFileName (in)
- The path of the file to open, either absolute or relative to the current directory.
-
-pAllocationCallbacks (in, optional)
- A pointer to application defined callbacks for managing memory allocations.
-
-
-Return Value
-------------
-A pointer to an object representing the decoder.
-
-
-Remarks
--------
-Close the decoder with drflac_close().
-
-
-Remarks
--------
-This will hold a handle to the file until the decoder is closed with drflac_close(). Some platforms will restrict the number of files a process can have open
-at any given time, so keep this mind if you have many decoders open at the same time.
-
-
-See Also
---------
-drflac_open_file_with_metadata()
-drflac_open()
-drflac_close()
-*/
-DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
-DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
-
-/*
-Opens a FLAC decoder from the file at the given path and notifies the caller of the metadata chunks (album art, etc.)
-
-
-Parameters
-----------
-pFileName (in)
- The path of the file to open, either absolute or relative to the current directory.
-
-pAllocationCallbacks (in, optional)
- A pointer to application defined callbacks for managing memory allocations.
-
-onMeta (in)
- The callback to fire for each metadata block.
-
-pUserData (in)
- A pointer to the user data to pass to the metadata callback.
-
-pAllocationCallbacks (in)
- A pointer to application defined callbacks for managing memory allocations.
-
-
-Remarks
--------
-Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled.
-
-
-See Also
---------
-drflac_open_with_metadata()
-drflac_open()
-drflac_close()
-*/
-DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
-DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
-#endif
-
/*
Opens a FLAC decoder from a pre-allocated block of memory
/* Same as drflac_open_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
DRFLAC_API float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
-#ifndef DR_FLAC_NO_STDIO
-/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a file. */
-DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
-
-/* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */
-DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
-
-/* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */
-DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
-#endif
-
/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a block of memory. */
DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
(void)data;
(void)count;
return 0;
-#else
-#if 0
- /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc8(crc, 0, 8);") */
- drflac_uint8 p = 0x07;
- for (int i = count-1; i >= 0; --i) {
- drflac_uint8 bit = (data & (1 << i)) >> i;
- if (crc & 0x80) {
- crc = ((crc << 1) | bit) ^ p;
- } else {
- crc = ((crc << 1) | bit);
- }
- }
- return crc;
#else
drflac_uint32 wholeBytes;
drflac_uint32 leftoverBits;
}
return crc;
#endif
-#endif
}
static DRFLAC_INLINE drflac_uint16 drflac_crc16_byte(drflac_uint16 crc, drflac_uint8 data)
return crc;
}
-#if 0
-static DRFLAC_INLINE drflac_uint16 drflac_crc16__32bit(drflac_uint16 crc, drflac_uint32 data, drflac_uint32 count)
-{
-#ifdef DR_FLAC_NO_CRC
- (void)crc;
- (void)data;
- (void)count;
- return 0;
-#else
-#if 0
- /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc16(crc, 0, 16);") */
- drflac_uint16 p = 0x8005;
- for (int i = count-1; i >= 0; --i) {
- drflac_uint16 bit = (data & (1ULL << i)) >> i;
- if (r & 0x8000) {
- r = ((r << 1) | bit) ^ p;
- } else {
- r = ((r << 1) | bit);
- }
- }
-
- return crc;
-#else
- drflac_uint32 wholeBytes;
- drflac_uint32 leftoverBits;
- drflac_uint64 leftoverDataMask;
-
- static drflac_uint64 leftoverDataMaskTable[8] = {
- 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
- };
-
- DRFLAC_ASSERT(count <= 64);
-
- wholeBytes = count >> 3;
- leftoverBits = count & 7;
- leftoverDataMask = leftoverDataMaskTable[leftoverBits];
-
- switch (wholeBytes) {
- default:
- case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits)));
- case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits)));
- case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits)));
- case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits)));
- case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
- }
- return crc;
-#endif
-#endif
-}
-
-static DRFLAC_INLINE drflac_uint16 drflac_crc16__64bit(drflac_uint16 crc, drflac_uint64 data, drflac_uint32 count)
-{
-#ifdef DR_FLAC_NO_CRC
- (void)crc;
- (void)data;
- (void)count;
- return 0;
-#else
- drflac_uint32 wholeBytes;
- drflac_uint32 leftoverBits;
- drflac_uint64 leftoverDataMask;
-
- static drflac_uint64 leftoverDataMaskTable[8] = {
- 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F
- };
-
- DRFLAC_ASSERT(count <= 64);
-
- wholeBytes = count >> 3;
- leftoverBits = count & 7;
- leftoverDataMask = leftoverDataMaskTable[leftoverBits];
-
- switch (wholeBytes) {
- default:
- case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000 << 32) << leftoverBits)) >> (56 + leftoverBits))); /* Weird "<< 32" bitshift is required for C89 because it doesn't support 64-bit constants. Should be optimized out by a good compiler. */
- case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 << 32) << leftoverBits)) >> (48 + leftoverBits)));
- case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 << 32) << leftoverBits)) >> (40 + leftoverBits)));
- case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF << 32) << leftoverBits)) >> (32 + leftoverBits)));
- case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000 ) << leftoverBits)) >> (24 + leftoverBits)));
- case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 ) << leftoverBits)) >> (16 + leftoverBits)));
- case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 ) << leftoverBits)) >> ( 8 + leftoverBits)));
- case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF ) << leftoverBits)) >> ( 0 + leftoverBits)));
- case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)];
- }
- return crc;
-#endif
-}
-
-
-static DRFLAC_INLINE drflac_uint16 drflac_crc16(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 count)
-{
-#ifdef DRFLAC_64BIT
- return drflac_crc16__64bit(crc, data, count);
-#else
- return drflac_crc16__32bit(crc, data, count);
-#endif
-}
-#endif
-
-
#ifdef DRFLAC_64BIT
#define drflac__be2host__cache_line drflac__be2host_64
#else
}
#endif
-/* Function below is unused, but leaving it here in case I need to quickly add it again. */
-#if 0
-static drflac_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, drflac_int64* pResultOut)
-{
- drflac_uint64 result;
- drflac_uint64 signbit;
-
- DRFLAC_ASSERT(bitCount <= 64);
-
- if (!drflac__read_uint64(bs, bitCount, &result)) {
- return DRFLAC_FALSE;
- }
-
- signbit = ((result >> (bitCount-1)) & 0x01);
- result |= (~signbit + 1) << bitCount;
-
- *pResultOut = (drflac_int64)result;
- return DRFLAC_TRUE;
-}
-#endif
-
static drflac_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, drflac_uint16* pResult)
{
drflac_uint32 result;
return DRFLAC_TRUE;
}
-#if 0
-static drflac_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, drflac_int16* pResult)
-{
- drflac_int32 result;
-
- 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;
- }
-
- *pResult = (drflac_int16)result;
- return DRFLAC_TRUE;
-}
-#endif
-
static drflac_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, drflac_uint8* pResult)
{
drflac_uint32 result;
return (drflac_int32)(prediction >> shift);
}
-
-#if 0
-/*
-Reference implementation for reading and decoding samples with residual. This is intentionally left unoptimized for the
-sake of readability and should only be used as a reference.
-*/
-static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(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)
+static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x1(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
{
- drflac_uint32 i;
+ drflac_uint32 riceParamPlus1 = riceParam + 1;
+ /*drflac_cache_t riceParamPlus1Mask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParamPlus1);*/
+ drflac_uint32 riceParamPlus1Shift = DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPlus1);
+ drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
- DRFLAC_ASSERT(bs != NULL);
- DRFLAC_ASSERT(count > 0);
- DRFLAC_ASSERT(pSamplesOut != NULL);
+ /*
+ The idea here is to use local variables for the cache in an attempt to encourage the compiler to store them in registers. I have
+ no idea how this will work in practice...
+ */
+ drflac_cache_t bs_cache = bs->cache;
+ drflac_uint32 bs_consumedBits = bs->consumedBits;
- for (i = 0; i < count; ++i) {
- drflac_uint32 zeroCounter = 0;
- for (;;) {
- drflac_uint8 bit;
- if (!drflac__read_uint8(bs, 1, &bit)) {
- return DRFLAC_FALSE;
- }
+ /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */
+ drflac_uint32 lzcount = drflac__clz(bs_cache);
+ if (lzcount < sizeof(bs_cache)*8) {
+ pZeroCounterOut[0] = lzcount;
- if (bit == 0) {
- zeroCounter += 1;
- } else {
- break;
- }
- }
+ /*
+ It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting
+ this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled
+ outside of this function at a higher level.
+ */
+ extract_rice_param_part:
+ bs_cache <<= lzcount;
+ bs_consumedBits += lzcount;
- drflac_uint32 decodedRice;
- if (riceParam > 0) {
- if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
- return DRFLAC_FALSE;
- }
+ if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) {
+ /* Getting here means the rice parameter part is wholly contained within the current cache line. */
+ pRiceParamPartOut[0] = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
+ bs_cache <<= riceParamPlus1;
+ bs_consumedBits += riceParamPlus1;
} else {
- decodedRice = 0;
- }
+ drflac_uint32 riceParamPartHi;
+ drflac_uint32 riceParamPartLo;
+ drflac_uint32 riceParamPartLoBitCount;
- decodedRice |= (zeroCounter << riceParam);
- if ((decodedRice & 0x01)) {
- decodedRice = ~(decodedRice >> 1);
- } else {
- decodedRice = (decodedRice >> 1);
- }
+ /*
+ Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache
+ line, reload the cache, and then combine it with the head of the next cache line.
+ */
+ /* Grab the high part of the rice parameter part. */
+ riceParamPartHi = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
- if (bitsPerSample+shift >= 32) {
- pSamplesOut[i] = decodedRice + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i);
- } else {
- pSamplesOut[i] = decodedRice + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i);
- }
- }
+ /* 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);
- return DRFLAC_TRUE;
-}
-#endif
+ /* Now reload the cache. */
+ if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
+ #ifndef DR_FLAC_NO_CRC
+ drflac__update_crc16(bs);
+ #endif
+ bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
+ bs_consumedBits = riceParamPartLoBitCount;
+ #ifndef DR_FLAC_NO_CRC
+ bs->crc16Cache = bs_cache;
+ #endif
+ } else {
+ /* Slow path. We need to fetch more data from the client. */
+ if (!drflac__reload_cache(bs)) {
+ return DRFLAC_FALSE;
+ }
-#if 0
-static drflac_bool32 drflac__read_rice_parts__reference(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
-{
- drflac_uint32 zeroCounter = 0;
- drflac_uint32 decodedRice;
-
- for (;;) {
- drflac_uint8 bit;
- if (!drflac__read_uint8(bs, 1, &bit)) {
- return DRFLAC_FALSE;
- }
-
- if (bit == 0) {
- zeroCounter += 1;
- } else {
- break;
- }
- }
-
- if (riceParam > 0) {
- if (!drflac__read_uint32(bs, riceParam, &decodedRice)) {
- return DRFLAC_FALSE;
- }
- } else {
- decodedRice = 0;
- }
-
- *pZeroCounterOut = zeroCounter;
- *pRiceParamPartOut = decodedRice;
- return DRFLAC_TRUE;
-}
-#endif
-
-#if 0
-static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
-{
- drflac_cache_t riceParamMask;
- drflac_uint32 zeroCounter;
- drflac_uint32 setBitOffsetPlus1;
- 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. */
-
- riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam);
-
- zeroCounter = 0;
- while (bs->cache == 0) {
- zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
- if (!drflac__reload_cache(bs)) {
- return DRFLAC_FALSE;
- }
- }
-
- setBitOffsetPlus1 = drflac__clz(bs->cache);
- zeroCounter += setBitOffsetPlus1;
- setBitOffsetPlus1 += 1;
-
- riceLength = setBitOffsetPlus1 + riceParam;
- if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
- riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceLength));
-
- bs->consumedBits += riceLength;
- bs->cache <<= riceLength;
- } else {
- drflac_uint32 bitCountLo;
- drflac_cache_t resultHi;
-
- bs->consumedBits += riceLength;
- bs->cache <<= setBitOffsetPlus1 & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1); /* <-- Equivalent to "if (setBitOffsetPlus1 < DRFLAC_CACHE_L1_SIZE_BITS(bs)) { bs->cache <<= setBitOffsetPlus1; }" */
-
- /* It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them. */
- bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs);
- resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, riceParam); /* <-- Use DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE() if ever this function allows riceParam=0. */
-
- if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
-#ifndef DR_FLAC_NO_CRC
- drflac__update_crc16(bs);
-#endif
- bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
- bs->consumedBits = 0;
-#ifndef DR_FLAC_NO_CRC
- bs->crc16Cache = bs->cache;
-#endif
- } else {
- /* Slow path. We need to fetch more data from the client. */
- if (!drflac__reload_cache(bs)) {
- return DRFLAC_FALSE;
- }
- }
-
- riceParamPart = (drflac_uint32)(resultHi | DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, bitCountLo));
-
- bs->consumedBits += bitCountLo;
- bs->cache <<= bitCountLo;
- }
-
- pZeroCounterOut[0] = zeroCounter;
- pRiceParamPartOut[0] = riceParamPart;
-
- return DRFLAC_TRUE;
-}
-#endif
-
-static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x1(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
-{
- drflac_uint32 riceParamPlus1 = riceParam + 1;
- /*drflac_cache_t riceParamPlus1Mask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParamPlus1);*/
- drflac_uint32 riceParamPlus1Shift = DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPlus1);
- drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1;
-
- /*
- The idea here is to use local variables for the cache in an attempt to encourage the compiler to store them in registers. I have
- no idea how this will work in practice...
- */
- drflac_cache_t bs_cache = bs->cache;
- drflac_uint32 bs_consumedBits = bs->consumedBits;
-
- /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */
- drflac_uint32 lzcount = drflac__clz(bs_cache);
- if (lzcount < sizeof(bs_cache)*8) {
- pZeroCounterOut[0] = lzcount;
-
- /*
- It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting
- this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled
- outside of this function at a higher level.
- */
- extract_rice_param_part:
- bs_cache <<= lzcount;
- bs_consumedBits += lzcount;
-
- if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) {
- /* Getting here means the rice parameter part is wholly contained within the current cache line. */
- pRiceParamPartOut[0] = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
- bs_cache <<= riceParamPlus1;
- bs_consumedBits += riceParamPlus1;
- } else {
- drflac_uint32 riceParamPartHi;
- drflac_uint32 riceParamPartLo;
- drflac_uint32 riceParamPartLoBitCount;
-
- /*
- Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache
- line, reload the cache, and then combine it with the head of the next cache line.
- */
-
- /* Grab the high part of the rice parameter part. */
- riceParamPartHi = (drflac_uint32)(bs_cache >> riceParamPlus1Shift);
-
- /* 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);
-
- /* Now reload the cache. */
- if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
- #ifndef DR_FLAC_NO_CRC
- drflac__update_crc16(bs);
- #endif
- bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
- bs_consumedBits = riceParamPartLoBitCount;
- #ifndef DR_FLAC_NO_CRC
- bs->crc16Cache = bs_cache;
- #endif
- } else {
- /* Slow path. We need to fetch more data from the client. */
- if (!drflac__reload_cache(bs)) {
- return DRFLAC_FALSE;
- }
-
- bs_cache = bs->cache;
- bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount;
- }
+ bs_cache = bs->cache;
+ bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount;
+ }
/* We should now have enough information to construct the rice parameter part. */
riceParamPartLo = (drflac_uint32)(bs_cache >> (DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPartLoBitCount)));
#endif
{
/* Scalar fallback. */
- #if 0
- return drflac__decode_samples_with_residual__rice__reference(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
- #else
return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
- #endif
}
}
static drflac_bool32 drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 offset)
{
- /* This section of code would be used if we were only decoding the FLAC frame header when calling drflac__seek_to_approximate_flac_frame_to_byte(). */
-#if 0
- if (drflac__decode_flac_frame(pFlac) != DRFLAC_SUCCESS) {
- /* We failed to decode this frame which may be due to it being corrupt. We'll just use the next valid FLAC frame. */
- if (drflac__read_and_decode_next_flac_frame(pFlac) == DRFLAC_FALSE) {
- return DRFLAC_FALSE;
- }
- }
-#endif
-
return drflac__seek_forward_by_pcm_frames(pFlac, offset) == offset;
}
#endif
}
-#if 0
-static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint32(drflac_uint32 crc32, drflac_uint32 data)
-{
- crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 24) & 0xFF));
- crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 16) & 0xFF));
- crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 8) & 0xFF));
- crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 0) & 0xFF));
- return crc32;
-}
-
-static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint64(drflac_uint32 crc32, drflac_uint64 data)
-{
- crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 32) & 0xFFFFFFFF));
- crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 0) & 0xFFFFFFFF));
- return crc32;
-}
-#endif
-
static DRFLAC_INLINE drflac_uint32 drflac_crc32_buffer(drflac_uint32 crc32, drflac_uint8* pData, drflac_uint32 dataSize)
{
/* This can be optimized. */
}
}
-/* Function below is unused at the moment, but I might be re-adding it later. */
-#if 0
-static drflac_uint8 drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, drflac_uint8* pBytesRemainingInSeg)
-{
- drflac_uint32 bytesConsumedInPage = drflac_ogg__get_page_body_size(&oggbs->currentPageHeader) - oggbs->bytesRemainingInPage;
- drflac_uint8 iSeg = 0;
- drflac_uint32 iByte = 0;
- while (iByte < bytesConsumedInPage) {
- drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
- if (iByte + segmentSize > bytesConsumedInPage) {
- break;
- } else {
- iSeg += 1;
- iByte += segmentSize;
- }
- }
-
- *pBytesRemainingInSeg = oggbs->currentPageHeader.segmentTable[iSeg] - (drflac_uint8)(bytesConsumedInPage - iByte);
- return iSeg;
-}
-
-static drflac_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs)
-{
- /* The current packet ends when we get to the segment with a lacing value of < 255 which is not at the end of a page. */
- for (;;) {
- drflac_bool32 atEndOfPage = DRFLAC_FALSE;
-
- drflac_uint8 bytesRemainingInSeg;
- drflac_uint8 iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg);
-
- drflac_uint32 bytesToEndOfPacketOrPage = bytesRemainingInSeg;
- for (drflac_uint8 iSeg = iFirstSeg; iSeg < oggbs->currentPageHeader.segmentCount; ++iSeg) {
- drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg];
- if (segmentSize < 255) {
- if (iSeg == oggbs->currentPageHeader.segmentCount-1) {
- atEndOfPage = DRFLAC_TRUE;
- }
-
- break;
- }
-
- bytesToEndOfPacketOrPage += segmentSize;
- }
-
- /*
- At this point we will have found either the packet or the end of the page. If were at the end of the page we'll
- want to load the next page and keep searching for the end of the packet.
- */
- drflac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, drflac_seek_origin_current);
- oggbs->bytesRemainingInPage -= bytesToEndOfPacketOrPage;
-
- if (atEndOfPage) {
- /*
- We're potentially at the next packet, but we need to check the next page first to be sure because the packet may
- straddle pages.
- */
- if (!drflac_oggbs__goto_next_page(oggbs)) {
- return DRFLAC_FALSE;
- }
-
- /* If it's a fresh packet it most likely means we're at the next packet. */
- if ((oggbs->currentPageHeader.headerType & 0x01) == 0) {
- return DRFLAC_TRUE;
- }
- } else {
- /* We're at the next packet. */
- return DRFLAC_TRUE;
- }
- }
-}
-
-static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs)
-{
- /* The bitstream should be sitting on the first byte just after the header of the frame. */
-
- /* What we're actually doing here is seeking to the start of the next packet. */
- return drflac_oggbs__seek_to_next_packet(oggbs);
-}
-#endif
-
static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead)
{
drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
pFlac->pSeekpoints[iSeekpoint].pcmFrameCount = drflac__be2host_16(pFlac->pSeekpoints[iSeekpoint].pcmFrameCount);
}
} else {
- /* Failed to read the seektable. Pretend we don't have one. */
- pFlac->pSeekpoints = NULL;
- pFlac->seekpointCount = 0;
- }
-
- /* We need to seek back to where we were. If this fails it's a critical error. */
- if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, drflac_seek_origin_start)) {
- drflac__free_from_callbacks(pFlac, &allocationCallbacks);
- return NULL;
- }
- } else {
- /* Failed to seek to the seektable. Ominous sign, but for now we can just pretend we don't have one. */
- pFlac->pSeekpoints = NULL;
- pFlac->seekpointCount = 0;
- }
- }
- }
-
-
- /*
- If we get here, but don't have a STREAMINFO block, it means we've opened the stream in relaxed mode and need to decode
- the first frame.
- */
- if (!init.hasStreamInfoBlock) {
- pFlac->currentFLACFrame.header = init.firstFrameHeader;
- for (;;) {
- drflac_result result = drflac__decode_flac_frame(pFlac);
- if (result == DRFLAC_SUCCESS) {
- break;
- } else {
- if (result == DRFLAC_CRC_MISMATCH) {
- if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
- drflac__free_from_callbacks(pFlac, &allocationCallbacks);
- return NULL;
- }
- continue;
- } else {
- drflac__free_from_callbacks(pFlac, &allocationCallbacks);
- return NULL;
- }
- }
- }
- }
-
- return pFlac;
-}
-
-
-
-#ifndef DR_FLAC_NO_STDIO
-#include <stdio.h>
-#include <wchar.h> /* For wcslen(), wcsrtombs() */
-
-/* drflac_result_from_errno() is only used for fopen() and wfopen() so putting it inside DR_WAV_NO_STDIO for now. If something else needs this later we can move it out. */
-#include <errno.h>
-static drflac_result drflac_result_from_errno(int e)
-{
- switch (e)
- {
- case 0: return DRFLAC_SUCCESS;
- #ifdef EPERM
- case EPERM: return DRFLAC_INVALID_OPERATION;
- #endif
- #ifdef ENOENT
- case ENOENT: return DRFLAC_DOES_NOT_EXIST;
- #endif
- #ifdef ESRCH
- case ESRCH: return DRFLAC_DOES_NOT_EXIST;
- #endif
- #ifdef EINTR
- case EINTR: return DRFLAC_INTERRUPT;
- #endif
- #ifdef EIO
- case EIO: return DRFLAC_IO_ERROR;
- #endif
- #ifdef ENXIO
- case ENXIO: return DRFLAC_DOES_NOT_EXIST;
- #endif
- #ifdef E2BIG
- case E2BIG: return DRFLAC_INVALID_ARGS;
- #endif
- #ifdef ENOEXEC
- case ENOEXEC: return DRFLAC_INVALID_FILE;
- #endif
- #ifdef EBADF
- case EBADF: return DRFLAC_INVALID_FILE;
- #endif
- #ifdef ECHILD
- case ECHILD: return DRFLAC_ERROR;
- #endif
- #ifdef EAGAIN
- case EAGAIN: return DRFLAC_UNAVAILABLE;
- #endif
- #ifdef ENOMEM
- case ENOMEM: return DRFLAC_OUT_OF_MEMORY;
- #endif
- #ifdef EACCES
- case EACCES: return DRFLAC_ACCESS_DENIED;
- #endif
- #ifdef EFAULT
- case EFAULT: return DRFLAC_BAD_ADDRESS;
- #endif
- #ifdef ENOTBLK
- case ENOTBLK: return DRFLAC_ERROR;
- #endif
- #ifdef EBUSY
- case EBUSY: return DRFLAC_BUSY;
- #endif
- #ifdef EEXIST
- case EEXIST: return DRFLAC_ALREADY_EXISTS;
- #endif
- #ifdef EXDEV
- case EXDEV: return DRFLAC_ERROR;
- #endif
- #ifdef ENODEV
- case ENODEV: return DRFLAC_DOES_NOT_EXIST;
- #endif
- #ifdef ENOTDIR
- case ENOTDIR: return DRFLAC_NOT_DIRECTORY;
- #endif
- #ifdef EISDIR
- case EISDIR: return DRFLAC_IS_DIRECTORY;
- #endif
- #ifdef EINVAL
- case EINVAL: return DRFLAC_INVALID_ARGS;
- #endif
- #ifdef ENFILE
- case ENFILE: return DRFLAC_TOO_MANY_OPEN_FILES;
- #endif
- #ifdef EMFILE
- case EMFILE: return DRFLAC_TOO_MANY_OPEN_FILES;
- #endif
- #ifdef ENOTTY
- case ENOTTY: return DRFLAC_INVALID_OPERATION;
- #endif
- #ifdef ETXTBSY
- case ETXTBSY: return DRFLAC_BUSY;
- #endif
- #ifdef EFBIG
- case EFBIG: return DRFLAC_TOO_BIG;
- #endif
- #ifdef ENOSPC
- case ENOSPC: return DRFLAC_NO_SPACE;
- #endif
- #ifdef ESPIPE
- case ESPIPE: return DRFLAC_BAD_SEEK;
- #endif
- #ifdef EROFS
- case EROFS: return DRFLAC_ACCESS_DENIED;
- #endif
- #ifdef EMLINK
- case EMLINK: return DRFLAC_TOO_MANY_LINKS;
- #endif
- #ifdef EPIPE
- case EPIPE: return DRFLAC_BAD_PIPE;
- #endif
- #ifdef EDOM
- case EDOM: return DRFLAC_OUT_OF_RANGE;
- #endif
- #ifdef ERANGE
- case ERANGE: return DRFLAC_OUT_OF_RANGE;
- #endif
- #ifdef EDEADLK
- case EDEADLK: return DRFLAC_DEADLOCK;
- #endif
- #ifdef ENAMETOOLONG
- case ENAMETOOLONG: return DRFLAC_PATH_TOO_LONG;
- #endif
- #ifdef ENOLCK
- case ENOLCK: return DRFLAC_ERROR;
- #endif
- #ifdef ENOSYS
- case ENOSYS: return DRFLAC_NOT_IMPLEMENTED;
- #endif
- #ifdef ENOTEMPTY
- case ENOTEMPTY: return DRFLAC_DIRECTORY_NOT_EMPTY;
- #endif
- #ifdef ELOOP
- case ELOOP: return DRFLAC_TOO_MANY_LINKS;
- #endif
- #ifdef ENOMSG
- case ENOMSG: return DRFLAC_NO_MESSAGE;
- #endif
- #ifdef EIDRM
- case EIDRM: return DRFLAC_ERROR;
- #endif
- #ifdef ECHRNG
- case ECHRNG: return DRFLAC_ERROR;
- #endif
- #ifdef EL2NSYNC
- case EL2NSYNC: return DRFLAC_ERROR;
- #endif
- #ifdef EL3HLT
- case EL3HLT: return DRFLAC_ERROR;
- #endif
- #ifdef EL3RST
- case EL3RST: return DRFLAC_ERROR;
- #endif
- #ifdef ELNRNG
- case ELNRNG: return DRFLAC_OUT_OF_RANGE;
- #endif
- #ifdef EUNATCH
- case EUNATCH: return DRFLAC_ERROR;
- #endif
- #ifdef ENOCSI
- case ENOCSI: return DRFLAC_ERROR;
- #endif
- #ifdef EL2HLT
- case EL2HLT: return DRFLAC_ERROR;
- #endif
- #ifdef EBADE
- case EBADE: return DRFLAC_ERROR;
- #endif
- #ifdef EBADR
- case EBADR: return DRFLAC_ERROR;
- #endif
- #ifdef EXFULL
- case EXFULL: return DRFLAC_ERROR;
- #endif
- #ifdef ENOANO
- case ENOANO: return DRFLAC_ERROR;
- #endif
- #ifdef EBADRQC
- case EBADRQC: return DRFLAC_ERROR;
- #endif
- #ifdef EBADSLT
- case EBADSLT: return DRFLAC_ERROR;
- #endif
- #ifdef EBFONT
- case EBFONT: return DRFLAC_INVALID_FILE;
- #endif
- #ifdef ENOSTR
- case ENOSTR: return DRFLAC_ERROR;
- #endif
- #ifdef ENODATA
- case ENODATA: return DRFLAC_NO_DATA_AVAILABLE;
- #endif
- #ifdef ETIME
- case ETIME: return DRFLAC_TIMEOUT;
- #endif
- #ifdef ENOSR
- case ENOSR: return DRFLAC_NO_DATA_AVAILABLE;
- #endif
- #ifdef ENONET
- case ENONET: return DRFLAC_NO_NETWORK;
- #endif
- #ifdef ENOPKG
- case ENOPKG: return DRFLAC_ERROR;
- #endif
- #ifdef EREMOTE
- case EREMOTE: return DRFLAC_ERROR;
- #endif
- #ifdef ENOLINK
- case ENOLINK: return DRFLAC_ERROR;
- #endif
- #ifdef EADV
- case EADV: return DRFLAC_ERROR;
- #endif
- #ifdef ESRMNT
- case ESRMNT: return DRFLAC_ERROR;
- #endif
- #ifdef ECOMM
- case ECOMM: return DRFLAC_ERROR;
- #endif
- #ifdef EPROTO
- case EPROTO: return DRFLAC_ERROR;
- #endif
- #ifdef EMULTIHOP
- case EMULTIHOP: return DRFLAC_ERROR;
- #endif
- #ifdef EDOTDOT
- case EDOTDOT: return DRFLAC_ERROR;
- #endif
- #ifdef EBADMSG
- case EBADMSG: return DRFLAC_BAD_MESSAGE;
- #endif
- #ifdef EOVERFLOW
- case EOVERFLOW: return DRFLAC_TOO_BIG;
- #endif
- #ifdef ENOTUNIQ
- case ENOTUNIQ: return DRFLAC_NOT_UNIQUE;
- #endif
- #ifdef EBADFD
- case EBADFD: return DRFLAC_ERROR;
- #endif
- #ifdef EREMCHG
- case EREMCHG: return DRFLAC_ERROR;
- #endif
- #ifdef ELIBACC
- case ELIBACC: return DRFLAC_ACCESS_DENIED;
- #endif
- #ifdef ELIBBAD
- case ELIBBAD: return DRFLAC_INVALID_FILE;
- #endif
- #ifdef ELIBSCN
- case ELIBSCN: return DRFLAC_INVALID_FILE;
- #endif
- #ifdef ELIBMAX
- case ELIBMAX: return DRFLAC_ERROR;
- #endif
- #ifdef ELIBEXEC
- case ELIBEXEC: return DRFLAC_ERROR;
- #endif
- #ifdef EILSEQ
- case EILSEQ: return DRFLAC_INVALID_DATA;
- #endif
- #ifdef ERESTART
- case ERESTART: return DRFLAC_ERROR;
- #endif
- #ifdef ESTRPIPE
- case ESTRPIPE: return DRFLAC_ERROR;
- #endif
- #ifdef EUSERS
- case EUSERS: return DRFLAC_ERROR;
- #endif
- #ifdef ENOTSOCK
- case ENOTSOCK: return DRFLAC_NOT_SOCKET;
- #endif
- #ifdef EDESTADDRREQ
- case EDESTADDRREQ: return DRFLAC_NO_ADDRESS;
- #endif
- #ifdef EMSGSIZE
- case EMSGSIZE: return DRFLAC_TOO_BIG;
- #endif
- #ifdef EPROTOTYPE
- case EPROTOTYPE: return DRFLAC_BAD_PROTOCOL;
- #endif
- #ifdef ENOPROTOOPT
- case ENOPROTOOPT: return DRFLAC_PROTOCOL_UNAVAILABLE;
- #endif
- #ifdef EPROTONOSUPPORT
- case EPROTONOSUPPORT: return DRFLAC_PROTOCOL_NOT_SUPPORTED;
- #endif
- #ifdef ESOCKTNOSUPPORT
- case ESOCKTNOSUPPORT: return DRFLAC_SOCKET_NOT_SUPPORTED;
- #endif
- #ifdef EOPNOTSUPP
- case EOPNOTSUPP: return DRFLAC_INVALID_OPERATION;
- #endif
- #ifdef EPFNOSUPPORT
- case EPFNOSUPPORT: return DRFLAC_PROTOCOL_FAMILY_NOT_SUPPORTED;
- #endif
- #ifdef EAFNOSUPPORT
- case EAFNOSUPPORT: return DRFLAC_ADDRESS_FAMILY_NOT_SUPPORTED;
- #endif
- #ifdef EADDRINUSE
- case EADDRINUSE: return DRFLAC_ALREADY_IN_USE;
- #endif
- #ifdef EADDRNOTAVAIL
- case EADDRNOTAVAIL: return DRFLAC_ERROR;
- #endif
- #ifdef ENETDOWN
- case ENETDOWN: return DRFLAC_NO_NETWORK;
- #endif
- #ifdef ENETUNREACH
- case ENETUNREACH: return DRFLAC_NO_NETWORK;
- #endif
- #ifdef ENETRESET
- case ENETRESET: return DRFLAC_NO_NETWORK;
- #endif
- #ifdef ECONNABORTED
- case ECONNABORTED: return DRFLAC_NO_NETWORK;
- #endif
- #ifdef ECONNRESET
- case ECONNRESET: return DRFLAC_CONNECTION_RESET;
- #endif
- #ifdef ENOBUFS
- case ENOBUFS: return DRFLAC_NO_SPACE;
- #endif
- #ifdef EISCONN
- case EISCONN: return DRFLAC_ALREADY_CONNECTED;
- #endif
- #ifdef ENOTCONN
- case ENOTCONN: return DRFLAC_NOT_CONNECTED;
- #endif
- #ifdef ESHUTDOWN
- case ESHUTDOWN: return DRFLAC_ERROR;
- #endif
- #ifdef ETOOMANYREFS
- case ETOOMANYREFS: return DRFLAC_ERROR;
- #endif
- #ifdef ETIMEDOUT
- case ETIMEDOUT: return DRFLAC_TIMEOUT;
- #endif
- #ifdef ECONNREFUSED
- case ECONNREFUSED: return DRFLAC_CONNECTION_REFUSED;
- #endif
- #ifdef EHOSTDOWN
- case EHOSTDOWN: return DRFLAC_NO_HOST;
- #endif
- #ifdef EHOSTUNREACH
- case EHOSTUNREACH: return DRFLAC_NO_HOST;
- #endif
- #ifdef EALREADY
- case EALREADY: return DRFLAC_IN_PROGRESS;
- #endif
- #ifdef EINPROGRESS
- case EINPROGRESS: return DRFLAC_IN_PROGRESS;
- #endif
- #ifdef ESTALE
- case ESTALE: return DRFLAC_INVALID_FILE;
- #endif
- #ifdef EUCLEAN
- case EUCLEAN: return DRFLAC_ERROR;
- #endif
- #ifdef ENOTNAM
- case ENOTNAM: return DRFLAC_ERROR;
- #endif
- #ifdef ENAVAIL
- case ENAVAIL: return DRFLAC_ERROR;
- #endif
- #ifdef EISNAM
- case EISNAM: return DRFLAC_ERROR;
- #endif
- #ifdef EREMOTEIO
- case EREMOTEIO: return DRFLAC_IO_ERROR;
- #endif
- #ifdef EDQUOT
- case EDQUOT: return DRFLAC_NO_SPACE;
- #endif
- #ifdef ENOMEDIUM
- case ENOMEDIUM: return DRFLAC_DOES_NOT_EXIST;
- #endif
- #ifdef EMEDIUMTYPE
- case EMEDIUMTYPE: return DRFLAC_ERROR;
- #endif
- #ifdef ECANCELED
- case ECANCELED: return DRFLAC_CANCELLED;
- #endif
- #ifdef ENOKEY
- case ENOKEY: return DRFLAC_ERROR;
- #endif
- #ifdef EKEYEXPIRED
- case EKEYEXPIRED: return DRFLAC_ERROR;
- #endif
- #ifdef EKEYREVOKED
- case EKEYREVOKED: return DRFLAC_ERROR;
- #endif
- #ifdef EKEYREJECTED
- case EKEYREJECTED: return DRFLAC_ERROR;
- #endif
- #ifdef EOWNERDEAD
- case EOWNERDEAD: return DRFLAC_ERROR;
- #endif
- #ifdef ENOTRECOVERABLE
- case ENOTRECOVERABLE: return DRFLAC_ERROR;
- #endif
- #ifdef ERFKILL
- case ERFKILL: return DRFLAC_ERROR;
- #endif
- #ifdef EHWPOISON
- case EHWPOISON: return DRFLAC_ERROR;
- #endif
- default: return DRFLAC_ERROR;
- }
-}
-
-static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
-{
-#if defined(_MSC_VER) && _MSC_VER >= 1400
- errno_t err;
-#endif
-
- if (ppFile != NULL) {
- *ppFile = NULL; /* Safety. */
- }
-
- if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
- return DRFLAC_INVALID_ARGS;
- }
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
- err = fopen_s(ppFile, pFilePath, pOpenMode);
- if (err != 0) {
- return drflac_result_from_errno(err);
- }
-#else
-#if defined(_WIN32) || defined(__APPLE__)
- *ppFile = fopen(pFilePath, pOpenMode);
-#else
- #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
- *ppFile = fopen64(pFilePath, pOpenMode);
- #else
- *ppFile = fopen(pFilePath, pOpenMode);
- #endif
-#endif
- if (*ppFile == NULL) {
- drflac_result result = drflac_result_from_errno(errno);
- if (result == DRFLAC_SUCCESS) {
- result = DRFLAC_ERROR; /* Just a safety check to make sure we never ever return success when pFile == NULL. */
- }
-
- return result;
- }
-#endif
-
- return DRFLAC_SUCCESS;
-}
-
-/*
-_wfopen() isn't always available in all compilation environments.
-
- * Windows only.
- * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
- * MinGW-64 (both 32- and 64-bit) seems to support it.
- * MinGW wraps it in !defined(__STRICT_ANSI__).
- * OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
-
-This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
-fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
-*/
-#if defined(_WIN32)
- #if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
- #define DRFLAC_HAS_WFOPEN
- #endif
-#endif
-
-static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drflac_allocation_callbacks* pAllocationCallbacks)
-{
- if (ppFile != NULL) {
- *ppFile = NULL; /* Safety. */
- }
-
- if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
- return DRFLAC_INVALID_ARGS;
- }
-
-#if defined(DRFLAC_HAS_WFOPEN)
- {
- /* Use _wfopen() on Windows. */
- #if defined(_MSC_VER) && _MSC_VER >= 1400
- errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
- if (err != 0) {
- return drflac_result_from_errno(err);
- }
- #else
- *ppFile = _wfopen(pFilePath, pOpenMode);
- if (*ppFile == NULL) {
- return drflac_result_from_errno(errno);
- }
- #endif
- (void)pAllocationCallbacks;
- }
-#else
- /*
- Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
- think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
- maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility.
- */
- {
- mbstate_t mbs;
- size_t lenMB;
- const wchar_t* pFilePathTemp = pFilePath;
- char* pFilePathMB = NULL;
- char pOpenModeMB[32] = {0};
-
- /* Get the length first. */
- DRFLAC_ZERO_OBJECT(&mbs);
- lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
- if (lenMB == (size_t)-1) {
- return drflac_result_from_errno(errno);
- }
-
- pFilePathMB = (char*)drflac__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
- if (pFilePathMB == NULL) {
- return DRFLAC_OUT_OF_MEMORY;
- }
-
- pFilePathTemp = pFilePath;
- DRFLAC_ZERO_OBJECT(&mbs);
- wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
-
- /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */
- {
- size_t i = 0;
- for (;;) {
- if (pOpenMode[i] == 0) {
- pOpenModeMB[i] = '\0';
- break;
- }
-
- pOpenModeMB[i] = (char)pOpenMode[i];
- i += 1;
- }
- }
-
- *ppFile = fopen(pFilePathMB, pOpenModeMB);
-
- drflac__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
- }
-
- if (*ppFile == NULL) {
- return DRFLAC_ERROR;
- }
-#endif
-
- return DRFLAC_SUCCESS;
-}
-
-static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
-{
- return fread(bufferOut, 1, bytesToRead, (FILE*)pUserData);
-}
-
-static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
-{
- DRFLAC_ASSERT(offset >= 0); /* <-- Never seek backwards. */
-
- return fseek((FILE*)pUserData, offset, (origin == drflac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
-}
-
-
-DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks)
-{
- drflac* pFlac;
- FILE* pFile;
-
- if (drflac_fopen(&pFile, pFileName, "rb") != DRFLAC_SUCCESS) {
- return NULL;
- }
-
- pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
- if (pFlac == NULL) {
- fclose(pFile);
- return NULL;
- }
-
- return pFlac;
-}
-
-DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks)
-{
- drflac* pFlac;
- FILE* pFile;
-
- if (drflac_wfopen(&pFile, pFileName, L"rb", pAllocationCallbacks) != DRFLAC_SUCCESS) {
- return NULL;
- }
-
- pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
- if (pFlac == NULL) {
- fclose(pFile);
- return NULL;
- }
-
- return pFlac;
-}
-
-DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
-{
- drflac* pFlac;
- FILE* pFile;
-
- if (drflac_fopen(&pFile, pFileName, "rb") != DRFLAC_SUCCESS) {
- return NULL;
- }
+ /* Failed to read the seektable. Pretend we don't have one. */
+ pFlac->pSeekpoints = NULL;
+ pFlac->seekpointCount = 0;
+ }
- pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
- if (pFlac == NULL) {
- fclose(pFile);
- return pFlac;
+ /* We need to seek back to where we were. If this fails it's a critical error. */
+ if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, drflac_seek_origin_start)) {
+ drflac__free_from_callbacks(pFlac, &allocationCallbacks);
+ return NULL;
+ }
+ } else {
+ /* Failed to seek to the seektable. Ominous sign, but for now we can just pretend we don't have one. */
+ pFlac->pSeekpoints = NULL;
+ pFlac->seekpointCount = 0;
+ }
+ }
}
- return pFlac;
-}
-
-DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
-{
- drflac* pFlac;
- FILE* pFile;
-
- if (drflac_wfopen(&pFile, pFileName, L"rb", pAllocationCallbacks) != DRFLAC_SUCCESS) {
- return NULL;
- }
- pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
- if (pFlac == NULL) {
- fclose(pFile);
- return pFlac;
+ /*
+ If we get here, but don't have a STREAMINFO block, it means we've opened the stream in relaxed mode and need to decode
+ the first frame.
+ */
+ if (!init.hasStreamInfoBlock) {
+ pFlac->currentFLACFrame.header = init.firstFrameHeader;
+ for (;;) {
+ drflac_result result = drflac__decode_flac_frame(pFlac);
+ if (result == DRFLAC_SUCCESS) {
+ break;
+ } else {
+ if (result == DRFLAC_CRC_MISMATCH) {
+ if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
+ drflac__free_from_callbacks(pFlac, &allocationCallbacks);
+ return NULL;
+ }
+ continue;
+ } else {
+ drflac__free_from_callbacks(pFlac, &allocationCallbacks);
+ return NULL;
+ }
+ }
+ }
}
return pFlac;
}
-#endif /* DR_FLAC_NO_STDIO */
static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t bytesToRead)
{
return;
}
-#ifndef DR_FLAC_NO_STDIO
- /*
- If we opened the file with drflac_open_file() we will want to close the file handle. We can know whether or not drflac_open_file()
- was used by looking at the callbacks.
- */
- if (pFlac->bs.onRead == drflac__on_read_stdio) {
- fclose((FILE*)pFlac->bs.pUserData);
- }
-
-#ifndef DR_FLAC_NO_OGG
- /* 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);
-
- if (oggbs->onRead == drflac__on_read_stdio) {
- fclose((FILE*)oggbs->pUserData);
- }
- }
-#endif
-#endif
-
drflac__free_from_callbacks(pFlac, &pFlac->allocationCallbacks);
}
-
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
-{
- drflac_uint64 i;
- for (i = 0; i < frameCount; ++i) {
- drflac_uint32 left = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
- drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
- drflac_uint32 right = left - side;
-
- pOutputSamples[i*2+0] = (drflac_int32)left;
- pOutputSamples[i*2+1] = (drflac_int32)right;
- }
-}
-#endif
-
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
drflac_uint64 i;
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_s32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_s32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
}
}
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
-{
- drflac_uint64 i;
- for (i = 0; i < frameCount; ++i) {
- drflac_uint32 side = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
- drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
- drflac_uint32 left = right + side;
-
- pOutputSamples[i*2+0] = (drflac_int32)left;
- pOutputSamples[i*2+1] = (drflac_int32)right;
- }
-}
-#endif
-
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
drflac_uint64 i;
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_s32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_s32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
}
}
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
-{
- for (drflac_uint64 i = 0; i < frameCount; ++i) {
- drflac_uint32 mid = pInputSamples0U32[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
- drflac_uint32 side = pInputSamples1U32[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
-
- mid = (mid << 1) | (side & 0x01);
-
- pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample);
- pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample);
- }
-}
-#endif
-
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
drflac_uint64 i;
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_s32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_s32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
}
}
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
-{
- for (drflac_uint64 i = 0; i < frameCount; ++i) {
- pOutputSamples[i*2+0] = (drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample));
- pOutputSamples[i*2+1] = (drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample));
- }
-}
-#endif
-
static DRFLAC_INLINE void drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int32* pOutputSamples)
{
drflac_uint64 i;
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_s32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_s32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
}
}
return framesRead;
}
-
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
-{
- drflac_uint64 i;
- for (i = 0; i < frameCount; ++i) {
- drflac_uint32 left = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
- drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
- drflac_uint32 right = left - side;
-
- left >>= 16;
- right >>= 16;
-
- pOutputSamples[i*2+0] = (drflac_int16)left;
- pOutputSamples[i*2+1] = (drflac_int16)right;
- }
-}
-#endif
-
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
drflac_uint64 i;
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_s16__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_s16__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
}
}
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
-{
- drflac_uint64 i;
- for (i = 0; i < frameCount; ++i) {
- drflac_uint32 side = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
- drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
- drflac_uint32 left = right + side;
-
- left >>= 16;
- right >>= 16;
-
- pOutputSamples[i*2+0] = (drflac_int16)left;
- pOutputSamples[i*2+1] = (drflac_int16)right;
- }
-}
-#endif
-
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
drflac_uint64 i;
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_s16__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_s16__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
}
}
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
-{
- for (drflac_uint64 i = 0; i < frameCount; ++i) {
- drflac_uint32 mid = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
- drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
-
- mid = (mid << 1) | (side & 0x01);
-
- pOutputSamples[i*2+0] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid + side) >> 1) << unusedBitsPerSample) >> 16);
- pOutputSamples[i*2+1] = (drflac_int16)(((drflac_uint32)((drflac_int32)(mid - side) >> 1) << unusedBitsPerSample) >> 16);
- }
-}
-#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_s16__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_s16__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
- }
-}
-
-
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
-{
- for (drflac_uint64 i = 0; i < frameCount; ++i) {
- pOutputSamples[i*2+0] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) >> 16);
- pOutputSamples[i*2+1] = (drflac_int16)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) >> 16);
}
}
-#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, drflac_int16* pOutputSamples)
{
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_s16__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_s16__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
}
}
return framesRead;
}
-
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
-{
- drflac_uint64 i;
- for (i = 0; i < frameCount; ++i) {
- drflac_uint32 left = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
- drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
- drflac_uint32 right = left - side;
-
- pOutputSamples[i*2+0] = (float)((drflac_int32)left / 2147483648.0);
- pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
- }
-}
-#endif
-
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
drflac_uint64 i;
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
}
}
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
-{
- drflac_uint64 i;
- for (i = 0; i < frameCount; ++i) {
- drflac_uint32 side = (drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample);
- drflac_uint32 right = (drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample);
- drflac_uint32 left = right + side;
-
- pOutputSamples[i*2+0] = (float)((drflac_int32)left / 2147483648.0);
- pOutputSamples[i*2+1] = (float)((drflac_int32)right / 2147483648.0);
- }
-}
-#endif
-
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
drflac_uint64 i;
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
- }
-}
-
-
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
-{
- for (drflac_uint64 i = 0; i < frameCount; ++i) {
- drflac_uint32 mid = (drflac_uint32)pInputSamples0[i] << pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
- drflac_uint32 side = (drflac_uint32)pInputSamples1[i] << pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
-
- mid = (mid << 1) | (side & 0x01);
-
- pOutputSamples[i*2+0] = (float)((((drflac_int32)(mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
- pOutputSamples[i*2+1] = (float)((((drflac_int32)(mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0);
}
}
-#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
- }
-}
-
-#if 0
-static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
-{
- for (drflac_uint64 i = 0; i < frameCount; ++i) {
- pOutputSamples[i*2+0] = (float)((drflac_int32)((drflac_uint32)pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0);
- pOutputSamples[i*2+1] = (float)((drflac_int32)((drflac_uint32)pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0);
}
}
-#endif
static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_uint32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples)
{
#endif
{
/* Scalar fallback. */
-#if 0
- drflac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#else
drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples);
-#endif
}
}
return drflac__full_read_and_close_f32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}
-#ifndef DR_FLAC_NO_STDIO
-DRFLAC_API drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
-{
- drflac* pFlac;
-
- if (sampleRate) {
- *sampleRate = 0;
- }
- if (channels) {
- *channels = 0;
- }
- if (totalPCMFrameCount) {
- *totalPCMFrameCount = 0;
- }
-
- pFlac = drflac_open_file(filename, pAllocationCallbacks);
- if (pFlac == NULL) {
- return NULL;
- }
-
- return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount);
-}
-
-DRFLAC_API drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
-{
- drflac* pFlac;
-
- if (sampleRate) {
- *sampleRate = 0;
- }
- if (channels) {
- *channels = 0;
- }
- if (totalPCMFrameCount) {
- *totalPCMFrameCount = 0;
- }
-
- pFlac = drflac_open_file(filename, pAllocationCallbacks);
- if (pFlac == NULL) {
- return NULL;
- }
-
- return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount);
-}
-
-DRFLAC_API float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
-{
- drflac* pFlac;
-
- if (sampleRate) {
- *sampleRate = 0;
- }
- if (channels) {
- *channels = 0;
- }
- if (totalPCMFrameCount) {
- *totalPCMFrameCount = 0;
- }
-
- pFlac = drflac_open_file(filename, pAllocationCallbacks);
- if (pFlac == NULL) {
- return NULL;
- }
-
- return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount);
-}
-#endif
-
DRFLAC_API drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks)
{
drflac* pFlac;