App-MHFS
view release on metacpan or search on metacpan
share/public_html/static/music_worklet_inprogress/decoder/deps/dr_libs/dr_flac.h view on Meta::CPAN
-------
Use pMetadata->type to determine which metadata block is being handled and how to read the data. This
will be set to one of the DRFLAC_METADATA_BLOCK_TYPE_* tokens.
*/
typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata);
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);
} drflac_allocation_callbacks;
/* Structure for internal use. Only used for decoders opened with drflac_open_memory. */
typedef struct
{
const drflac_uint8* data;
size_t dataSize;
size_t currentReadPos;
} drflac__memory_stream;
/* Structure for internal use. Used for bit streaming. */
typedef struct
{
/* The function to call when more data needs to be read. */
drflac_read_proc onRead;
/* The function to call when the current read position needs to be moved. */
drflac_seek_proc onSeek;
/* The user data to pass around to onRead and onSeek. */
void* pUserData;
/*
The number of unaligned bytes in the L2 cache. This will always be 0 until the end of the stream is hit. At the end of the
stream there will be a number of bytes that don't cleanly fit in an L1 cache line, so we use this variable to know whether
or not the bistreamer needs to run on a slower path to read those last bytes. This will never be more than sizeof(drflac_cache_t).
*/
size_t unalignedByteCount;
/* The content of the unaligned bytes. */
drflac_cache_t unalignedCache;
/* The index of the next valid cache line in the "L2" cache. */
drflac_uint32 nextL2Line;
/* The number of bits that have been consumed by the cache. This is used to determine how many valid bits are remaining. */
drflac_uint32 consumedBits;
/*
The cached data which was most recently read from the client. There are two levels of cache. Data flows as such:
Client -> L2 -> L1. The L2 -> L1 movement is aligned and runs on a fast path in just a few instructions.
*/
drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)];
drflac_cache_t cache;
/*
CRC-16. This is updated whenever bits are read from the bit stream. Manually set this to 0 to reset the CRC. For FLAC, this
is reset to 0 at the beginning of each frame.
*/
drflac_uint16 crc16;
drflac_cache_t crc16Cache; /* A cache for optimizing CRC calculations. This is filled when when the L1 cache is reloaded. */
drflac_uint32 crc16CacheIgnoredBytes; /* The number of bytes to ignore when updating the CRC-16 from the CRC-16 cache. */
} drflac_bs;
typedef struct
{
/* The type of the subframe: SUBFRAME_CONSTANT, SUBFRAME_VERBATIM, SUBFRAME_FIXED or SUBFRAME_LPC. */
drflac_uint8 subframeType;
/* The number of wasted bits per sample as specified by the sub-frame header. */
drflac_uint8 wastedBitsPerSample;
/* The order to use for the prediction stage for SUBFRAME_FIXED and SUBFRAME_LPC. */
drflac_uint8 lpcOrder;
/* A pointer to the buffer containing the decoded samples in the subframe. This pointer is an offset from drflac::pExtraData. */
drflac_int32* pSamplesS32;
} drflac_subframe;
typedef struct
{
/*
If the stream uses variable block sizes, this will be set to the index of the first PCM frame. If fixed block sizes are used, this will
always be set to 0. This is 64-bit because the decoded PCM frame number will be 36 bits.
*/
drflac_uint64 pcmFrameNumber;
/*
If the stream uses fixed block sizes, this will be set to the frame number. If variable block sizes are used, this will always be 0. This
is 32-bit because in fixed block sizes, the maximum frame number will be 31 bits.
*/
drflac_uint32 flacFrameNumber;
/* The sample rate of this frame. */
drflac_uint32 sampleRate;
/* The number of PCM frames in each sub-frame within this frame. */
drflac_uint16 blockSizeInPCMFrames;
/*
The channel assignment of this frame. This is not always set to the channel count. If interchannel decorrelation is being used this
will be set to DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE, DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE or DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE.
*/
drflac_uint8 channelAssignment;
/* The number of bits per sample within this frame. */
drflac_uint8 bitsPerSample;
/* The frame's CRC. */
drflac_uint8 crc8;
} drflac_frame_header;
typedef struct
{
/* The header. */
drflac_frame_header header;
share/public_html/static/music_worklet_inprogress/decoder/deps/dr_libs/dr_flac.h view on Meta::CPAN
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);
*pLastSuccessfulSeekOffset = pFlac->firstFLACFramePosInBytes;
for (;;) {
/* After rangeLo == rangeHi == targetByte fails, we need to break out. */
drflac_uint64 lastTargetByte = targetByte;
/* When seeking to a byte, failure probably means we've attempted to seek beyond the end of the stream. To counter this we just halve it each attempt. */
if (!drflac__seek_to_byte(&pFlac->bs, targetByte)) {
/* If we couldn't even seek to the first byte in the stream we have a problem. Just abandon the whole thing. */
if (targetByte == 0) {
drflac__seek_to_first_frame(pFlac); /* Try to recover. */
return DRFLAC_FALSE;
}
/* Halve the byte location and continue. */
targetByte = rangeLo + ((rangeHi - rangeLo)/2);
rangeHi = targetByte;
} else {
/* 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));
/*
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
CRC check and return bad data. We need to decode the entire frame to be more certain. Although this seems unlikely, this has happened to me in testing
so it needs to stay this way for now.
*/
#if 1
if (!drflac__read_and_decode_next_flac_frame(pFlac)) {
/* Halve the byte location and continue. */
targetByte = rangeLo + ((rangeHi - rangeLo)/2);
rangeHi = targetByte;
} else {
break;
}
#else
if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFLACFrame.header)) {
/* Halve the byte location and continue. */
targetByte = rangeLo + ((rangeHi - rangeLo)/2);
rangeHi = targetByte;
} else {
break;
}
#endif
}
/* We already tried this byte and there are no more to try, break out. */
if(targetByte == lastTargetByte) {
return DRFLAC_FALSE;
}
}
/* 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);
*pLastSuccessfulSeekOffset = targetByte;
return DRFLAC_TRUE;
}
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;
}
static drflac_bool32 drflac__seek_to_pcm_frame__binary_search_internal(drflac* pFlac, drflac_uint64 pcmFrameIndex, drflac_uint64 byteRangeLo, drflac_uint64 byteRangeHi)
{
/* This assumes pFlac->currentPCMFrame is sitting on byteRangeLo upon entry. */
drflac_uint64 targetByte;
drflac_uint64 pcmRangeLo = pFlac->totalPCMFrameCount;
drflac_uint64 pcmRangeHi = 0;
drflac_uint64 lastSuccessfulSeekOffset = (drflac_uint64)-1;
drflac_uint64 closestSeekOffsetBeforeTargetPCMFrame = byteRangeLo;
drflac_uint32 seekForwardThreshold = (pFlac->maxBlockSizeInPCMFrames != 0) ? pFlac->maxBlockSizeInPCMFrames*2 : 4096;
targetByte = byteRangeLo + (drflac_uint64)(((drflac_int64)((pcmFrameIndex - pFlac->currentPCMFrame) * pFlac->channels * pFlac->bitsPerSample)/8.0f) * DRFLAC_BINARY_SEARCH_APPROX_COMPRESSION_RATIO);
if (targetByte > byteRangeHi) {
targetByte = byteRangeHi;
}
for (;;) {
if (drflac__seek_to_approximate_flac_frame_to_byte(pFlac, targetByte, byteRangeLo, byteRangeHi, &lastSuccessfulSeekOffset)) {
/* We found a FLAC frame. We need to check if it contains the sample we're looking for. */
drflac_uint64 newPCMRangeLo;
drflac_uint64 newPCMRangeHi;
drflac__get_pcm_frame_range_of_current_flac_frame(pFlac, &newPCMRangeLo, &newPCMRangeHi);
/* If we selected the same frame, it means we should be pretty close. Just decode the rest. */
if (pcmRangeLo == newPCMRangeLo) {
if (!drflac__seek_to_approximate_flac_frame_to_byte(pFlac, closestSeekOffsetBeforeTargetPCMFrame, closestSeekOffsetBeforeTargetPCMFrame, byteRangeHi, &lastSuccessfulSeekOffset)) {
break; /* Failed to seek to closest frame. */
}
if (drflac__decode_flac_frame_and_seek_forward_by_pcm_frames(pFlac, pcmFrameIndex - pFlac->currentPCMFrame)) {
return DRFLAC_TRUE;
} else {
break; /* Failed to seek forward. */
}
}
( run in 0.565 second using v1.01-cache-2.11-cpan-39bf76dae61 )