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
offset (in)
The number of bytes to move, relative to the origin. Will never be negative.
origin (in)
The origin of the seek - the current position or the start of the stream.
Return Value
------------
Whether or not the seek was successful.
Remarks
-------
The offset will never be negative. Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which will be
either drflac_seek_origin_start or drflac_seek_origin_current.
When seeking to a PCM frame using drflac_seek_to_pcm_frame(), dr_flac may call this with an offset beyond the end of the FLAC stream. This needs to be detected
and handled by returning DRFLAC_FALSE.
*/
typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin);
/*
Callback for when a metadata block is read.
Parameters
----------
pUserData (in)
The user data that was passed to drflac_open() and family.
pMetadata (in)
A pointer to a structure containing the data of the metadata block.
Remarks
-------
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
share/public_html/static/music_worklet_inprogress/decoder/deps/dr_libs/dr_flac.h view on Meta::CPAN
coefficients128_0 = _mm_setzero_si128();
coefficients128_4 = _mm_setzero_si128();
coefficients128_8 = _mm_setzero_si128();
samples128_0 = _mm_setzero_si128();
samples128_4 = _mm_setzero_si128();
samples128_8 = _mm_setzero_si128();
/*
Pre-loading the coefficients and prior samples is annoying because we need to ensure we don't try reading more than
what's available in the input buffers. It would be convenient to use a fall-through switch to do this, but this results
in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
so I think there's opportunity for this to be simplified.
*/
#if 1
{
int runningOrder = order;
/* 0 - 3. */
if (runningOrder >= 4) {
coefficients128_0 = _mm_loadu_si128((const __m128i*)(coefficients + 0));
samples128_0 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 4));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_0 = _mm_set_epi32(0, coefficients[2], coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], pSamplesOut[-3], 0); break;
case 2: coefficients128_0 = _mm_set_epi32(0, 0, coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], 0, 0); break;
case 1: coefficients128_0 = _mm_set_epi32(0, 0, 0, coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], 0, 0, 0); break;
}
runningOrder = 0;
}
/* 4 - 7 */
if (runningOrder >= 4) {
coefficients128_4 = _mm_loadu_si128((const __m128i*)(coefficients + 4));
samples128_4 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 8));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_4 = _mm_set_epi32(0, coefficients[6], coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], pSamplesOut[-7], 0); break;
case 2: coefficients128_4 = _mm_set_epi32(0, 0, coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], 0, 0); break;
case 1: coefficients128_4 = _mm_set_epi32(0, 0, 0, coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], 0, 0, 0); break;
}
runningOrder = 0;
}
/* 8 - 11 */
if (runningOrder == 4) {
coefficients128_8 = _mm_loadu_si128((const __m128i*)(coefficients + 8));
samples128_8 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 12));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_8 = _mm_set_epi32(0, coefficients[10], coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], pSamplesOut[-11], 0); break;
case 2: coefficients128_8 = _mm_set_epi32(0, 0, coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], 0, 0); break;
case 1: coefficients128_8 = _mm_set_epi32(0, 0, 0, coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], 0, 0, 0); break;
}
runningOrder = 0;
}
/* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
coefficients128_0 = _mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(0, 1, 2, 3));
coefficients128_4 = _mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(0, 1, 2, 3));
coefficients128_8 = _mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(0, 1, 2, 3));
}
#else
/* This causes strict-aliasing warnings with GCC. */
switch (order)
{
case 12: ((drflac_int32*)&coefficients128_8)[0] = coefficients[11]; ((drflac_int32*)&samples128_8)[0] = pDecodedSamples[-12];
case 11: ((drflac_int32*)&coefficients128_8)[1] = coefficients[10]; ((drflac_int32*)&samples128_8)[1] = pDecodedSamples[-11];
case 10: ((drflac_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((drflac_int32*)&samples128_8)[2] = pDecodedSamples[-10];
case 9: ((drflac_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((drflac_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
case 8: ((drflac_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((drflac_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
case 7: ((drflac_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((drflac_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
case 6: ((drflac_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((drflac_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
case 5: ((drflac_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((drflac_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
case 4: ((drflac_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((drflac_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
case 3: ((drflac_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((drflac_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
case 2: ((drflac_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((drflac_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
case 1: ((drflac_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((drflac_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
}
#endif
/* For this version we are doing one sample at a time. */
while (pDecodedSamples < pDecodedSamplesEnd) {
__m128i prediction128;
__m128i zeroCountPart128;
__m128i riceParamPart128;
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
return DRFLAC_FALSE;
}
zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0);
riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0);
riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128);
riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam));
riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(drflac__mm_not_si128(_mm_and_si128(riceParamPart128, _mm_set1_epi32(0x01))), _mm_set1_epi32(0x01))); /* <-- SSE2 compatible */
/*riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_mullo_epi32(_mm_and_si128(riceParamPart128, _mm_set1_epi32(0x01)), _mm_set1_epi32(0xFFFFFFFF)));*/ /* <-- Only supported from SSE4.1 and is slower in my testing... ...
if (order <= 4) {
for (i = 0; i < 4; i += 1) {
prediction128 = _mm_mullo_epi32(coefficients128_0, samples128_0);
/* Horizontal add and shift. */
prediction128 = drflac__mm_hadd_epi32(prediction128);
prediction128 = _mm_srai_epi32(prediction128, shift);
prediction128 = _mm_add_epi32(riceParamPart128, prediction128);
samples128_0 = _mm_alignr_epi8(prediction128, samples128_0, 4);
riceParamPart128 = _mm_alignr_epi8(_mm_setzero_si128(), riceParamPart128, 4);
}
} else if (order <= 8) {
for (i = 0; i < 4; i += 1) {
prediction128 = _mm_mullo_epi32(coefficients128_4, samples128_4);
prediction128 = _mm_add_epi32(prediction128, _mm_mullo_epi32(coefficients128_0, samples128_0));
share/public_html/static/music_worklet_inprogress/decoder/deps/dr_libs/dr_flac.h view on Meta::CPAN
riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
riceParamMask128 = _mm_set1_epi32(riceParamMask);
prediction128 = _mm_setzero_si128();
/* Pre-load. */
coefficients128_0 = _mm_setzero_si128();
coefficients128_4 = _mm_setzero_si128();
coefficients128_8 = _mm_setzero_si128();
samples128_0 = _mm_setzero_si128();
samples128_4 = _mm_setzero_si128();
samples128_8 = _mm_setzero_si128();
#if 1
{
int runningOrder = order;
/* 0 - 3. */
if (runningOrder >= 4) {
coefficients128_0 = _mm_loadu_si128((const __m128i*)(coefficients + 0));
samples128_0 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 4));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_0 = _mm_set_epi32(0, coefficients[2], coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], pSamplesOut[-3], 0); break;
case 2: coefficients128_0 = _mm_set_epi32(0, 0, coefficients[1], coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], pSamplesOut[-2], 0, 0); break;
case 1: coefficients128_0 = _mm_set_epi32(0, 0, 0, coefficients[0]); samples128_0 = _mm_set_epi32(pSamplesOut[-1], 0, 0, 0); break;
}
runningOrder = 0;
}
/* 4 - 7 */
if (runningOrder >= 4) {
coefficients128_4 = _mm_loadu_si128((const __m128i*)(coefficients + 4));
samples128_4 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 8));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_4 = _mm_set_epi32(0, coefficients[6], coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], pSamplesOut[-7], 0); break;
case 2: coefficients128_4 = _mm_set_epi32(0, 0, coefficients[5], coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], pSamplesOut[-6], 0, 0); break;
case 1: coefficients128_4 = _mm_set_epi32(0, 0, 0, coefficients[4]); samples128_4 = _mm_set_epi32(pSamplesOut[-5], 0, 0, 0); break;
}
runningOrder = 0;
}
/* 8 - 11 */
if (runningOrder == 4) {
coefficients128_8 = _mm_loadu_si128((const __m128i*)(coefficients + 8));
samples128_8 = _mm_loadu_si128((const __m128i*)(pSamplesOut - 12));
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: coefficients128_8 = _mm_set_epi32(0, coefficients[10], coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], pSamplesOut[-11], 0); break;
case 2: coefficients128_8 = _mm_set_epi32(0, 0, coefficients[9], coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], pSamplesOut[-10], 0, 0); break;
case 1: coefficients128_8 = _mm_set_epi32(0, 0, 0, coefficients[8]); samples128_8 = _mm_set_epi32(pSamplesOut[-9], 0, 0, 0); break;
}
runningOrder = 0;
}
/* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
coefficients128_0 = _mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(0, 1, 2, 3));
coefficients128_4 = _mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(0, 1, 2, 3));
coefficients128_8 = _mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(0, 1, 2, 3));
}
#else
switch (order)
{
case 12: ((drflac_int32*)&coefficients128_8)[0] = coefficients[11]; ((drflac_int32*)&samples128_8)[0] = pDecodedSamples[-12];
case 11: ((drflac_int32*)&coefficients128_8)[1] = coefficients[10]; ((drflac_int32*)&samples128_8)[1] = pDecodedSamples[-11];
case 10: ((drflac_int32*)&coefficients128_8)[2] = coefficients[ 9]; ((drflac_int32*)&samples128_8)[2] = pDecodedSamples[-10];
case 9: ((drflac_int32*)&coefficients128_8)[3] = coefficients[ 8]; ((drflac_int32*)&samples128_8)[3] = pDecodedSamples[- 9];
case 8: ((drflac_int32*)&coefficients128_4)[0] = coefficients[ 7]; ((drflac_int32*)&samples128_4)[0] = pDecodedSamples[- 8];
case 7: ((drflac_int32*)&coefficients128_4)[1] = coefficients[ 6]; ((drflac_int32*)&samples128_4)[1] = pDecodedSamples[- 7];
case 6: ((drflac_int32*)&coefficients128_4)[2] = coefficients[ 5]; ((drflac_int32*)&samples128_4)[2] = pDecodedSamples[- 6];
case 5: ((drflac_int32*)&coefficients128_4)[3] = coefficients[ 4]; ((drflac_int32*)&samples128_4)[3] = pDecodedSamples[- 5];
case 4: ((drflac_int32*)&coefficients128_0)[0] = coefficients[ 3]; ((drflac_int32*)&samples128_0)[0] = pDecodedSamples[- 4];
case 3: ((drflac_int32*)&coefficients128_0)[1] = coefficients[ 2]; ((drflac_int32*)&samples128_0)[1] = pDecodedSamples[- 3];
case 2: ((drflac_int32*)&coefficients128_0)[2] = coefficients[ 1]; ((drflac_int32*)&samples128_0)[2] = pDecodedSamples[- 2];
case 1: ((drflac_int32*)&coefficients128_0)[3] = coefficients[ 0]; ((drflac_int32*)&samples128_0)[3] = pDecodedSamples[- 1];
}
#endif
/* For this version we are doing one sample at a time. */
while (pDecodedSamples < pDecodedSamplesEnd) {
__m128i zeroCountPart128;
__m128i riceParamPart128;
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) {
return DRFLAC_FALSE;
}
zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0);
riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0);
riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128);
riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam));
riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(drflac__mm_not_si128(_mm_and_si128(riceParamPart128, _mm_set1_epi32(1))), _mm_set1_epi32(1)));
for (i = 0; i < 4; i += 1) {
prediction128 = _mm_xor_si128(prediction128, prediction128); /* Reset to 0. */
switch (order)
{
case 12:
case 11: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_8, _MM_SHUFFLE(1, 1, 0, 0))));
case 10:
case 9: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_8, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_8, _MM_SHUFFLE(3, 3, 2, 2))));
case 8:
case 7: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_4, _MM_SHUFFLE(1, 1, 0, 0))));
case 6:
case 5: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_4, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_4, _MM_SHUFFLE(3, 3, 2, 2))));
case 4:
case 3: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(1, 1, 0, 0)), _mm_shuffle_epi32(samples128_0, _MM_SHUFFLE(1, 1, 0, 0))));
case 2:
case 1: prediction128 = _mm_add_epi64(prediction128, _mm_mul_epi32(_mm_shuffle_epi32(coefficients128_0, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_epi32(samples128_0, _MM_SHUFFLE(3, 3, 2, 2))));
}
share/public_html/static/music_worklet_inprogress/decoder/deps/dr_libs/dr_flac.h view on Meta::CPAN
what's available in the input buffers. It would be conenient to use a fall-through switch to do this, but this results
in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
so I think there's opportunity for this to be simplified.
*/
{
int runningOrder = order;
drflac_int32 tempC[4] = {0, 0, 0, 0};
drflac_int32 tempS[4] = {0, 0, 0, 0};
/* 0 - 3. */
if (runningOrder >= 4) {
coefficients128_0 = vld1q_s32(coefficients + 0);
samples128_0 = vld1q_s32(pSamplesOut - 4);
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: tempC[2] = coefficients[2]; tempS[1] = pSamplesOut[-3]; /* fallthrough */
case 2: tempC[1] = coefficients[1]; tempS[2] = pSamplesOut[-2]; /* fallthrough */
case 1: tempC[0] = coefficients[0]; tempS[3] = pSamplesOut[-1]; /* fallthrough */
}
coefficients128_0 = vld1q_s32(tempC);
samples128_0 = vld1q_s32(tempS);
runningOrder = 0;
}
/* 4 - 7 */
if (runningOrder >= 4) {
coefficients128_4 = vld1q_s32(coefficients + 4);
samples128_4 = vld1q_s32(pSamplesOut - 8);
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: tempC[2] = coefficients[6]; tempS[1] = pSamplesOut[-7]; /* fallthrough */
case 2: tempC[1] = coefficients[5]; tempS[2] = pSamplesOut[-6]; /* fallthrough */
case 1: tempC[0] = coefficients[4]; tempS[3] = pSamplesOut[-5]; /* fallthrough */
}
coefficients128_4 = vld1q_s32(tempC);
samples128_4 = vld1q_s32(tempS);
runningOrder = 0;
}
/* 8 - 11 */
if (runningOrder == 4) {
coefficients128_8 = vld1q_s32(coefficients + 8);
samples128_8 = vld1q_s32(pSamplesOut - 12);
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: tempC[2] = coefficients[10]; tempS[1] = pSamplesOut[-11]; /* fallthrough */
case 2: tempC[1] = coefficients[ 9]; tempS[2] = pSamplesOut[-10]; /* fallthrough */
case 1: tempC[0] = coefficients[ 8]; tempS[3] = pSamplesOut[- 9]; /* fallthrough */
}
coefficients128_8 = vld1q_s32(tempC);
samples128_8 = vld1q_s32(tempS);
runningOrder = 0;
}
/* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
coefficients128_0 = drflac__vrevq_s32(coefficients128_0);
coefficients128_4 = drflac__vrevq_s32(coefficients128_4);
coefficients128_8 = drflac__vrevq_s32(coefficients128_8);
}
/* For this version we are doing one sample at a time. */
while (pDecodedSamples < pDecodedSamplesEnd) {
int32x4_t prediction128;
int32x2_t prediction64;
uint32x4_t zeroCountPart128;
uint32x4_t riceParamPart128;
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
return DRFLAC_FALSE;
}
zeroCountPart128 = vld1q_u32(zeroCountParts);
riceParamPart128 = vld1q_u32(riceParamParts);
riceParamPart128 = vandq_u32(riceParamPart128, riceParamMask128);
riceParamPart128 = vorrq_u32(riceParamPart128, vshlq_u32(zeroCountPart128, riceParam128));
riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(drflac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
if (order <= 4) {
for (i = 0; i < 4; i += 1) {
prediction128 = vmulq_s32(coefficients128_0, samples128_0);
/* Horizontal add and shift. */
prediction64 = drflac__vhaddq_s32(prediction128);
prediction64 = vshl_s32(prediction64, shift64);
prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
}
} else if (order <= 8) {
for (i = 0; i < 4; i += 1) {
prediction128 = vmulq_s32(coefficients128_4, samples128_4);
prediction128 = vmlaq_s32(prediction128, coefficients128_0, samples128_0);
/* Horizontal add and shift. */
prediction64 = drflac__vhaddq_s32(prediction128);
prediction64 = vshl_s32(prediction64, shift64);
prediction64 = vadd_s32(prediction64, vget_low_s32(vreinterpretq_s32_u32(riceParamPart128)));
samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
samples128_0 = drflac__valignrq_s32_1(vcombine_s32(prediction64, vdup_n_s32(0)), samples128_0);
riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
}
} else {
for (i = 0; i < 4; i += 1) {
prediction128 = vmulq_s32(coefficients128_8, samples128_8);
prediction128 = vmlaq_s32(prediction128, coefficients128_4, samples128_4);
prediction128 = vmlaq_s32(prediction128, coefficients128_0, samples128_0);
/* Horizontal add and shift. */
prediction64 = drflac__vhaddq_s32(prediction128);
share/public_html/static/music_worklet_inprogress/decoder/deps/dr_libs/dr_flac.h view on Meta::CPAN
what's available in the input buffers. It would be convenient to use a fall-through switch to do this, but this results
in strict aliasing warnings with GCC. To work around this I'm just doing something hacky. This feels a bit convoluted
so I think there's opportunity for this to be simplified.
*/
{
int runningOrder = order;
drflac_int32 tempC[4] = {0, 0, 0, 0};
drflac_int32 tempS[4] = {0, 0, 0, 0};
/* 0 - 3. */
if (runningOrder >= 4) {
coefficients128_0 = vld1q_s32(coefficients + 0);
samples128_0 = vld1q_s32(pSamplesOut - 4);
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: tempC[2] = coefficients[2]; tempS[1] = pSamplesOut[-3]; /* fallthrough */
case 2: tempC[1] = coefficients[1]; tempS[2] = pSamplesOut[-2]; /* fallthrough */
case 1: tempC[0] = coefficients[0]; tempS[3] = pSamplesOut[-1]; /* fallthrough */
}
coefficients128_0 = vld1q_s32(tempC);
samples128_0 = vld1q_s32(tempS);
runningOrder = 0;
}
/* 4 - 7 */
if (runningOrder >= 4) {
coefficients128_4 = vld1q_s32(coefficients + 4);
samples128_4 = vld1q_s32(pSamplesOut - 8);
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: tempC[2] = coefficients[6]; tempS[1] = pSamplesOut[-7]; /* fallthrough */
case 2: tempC[1] = coefficients[5]; tempS[2] = pSamplesOut[-6]; /* fallthrough */
case 1: tempC[0] = coefficients[4]; tempS[3] = pSamplesOut[-5]; /* fallthrough */
}
coefficients128_4 = vld1q_s32(tempC);
samples128_4 = vld1q_s32(tempS);
runningOrder = 0;
}
/* 8 - 11 */
if (runningOrder == 4) {
coefficients128_8 = vld1q_s32(coefficients + 8);
samples128_8 = vld1q_s32(pSamplesOut - 12);
runningOrder -= 4;
} else {
switch (runningOrder) {
case 3: tempC[2] = coefficients[10]; tempS[1] = pSamplesOut[-11]; /* fallthrough */
case 2: tempC[1] = coefficients[ 9]; tempS[2] = pSamplesOut[-10]; /* fallthrough */
case 1: tempC[0] = coefficients[ 8]; tempS[3] = pSamplesOut[- 9]; /* fallthrough */
}
coefficients128_8 = vld1q_s32(tempC);
samples128_8 = vld1q_s32(tempS);
runningOrder = 0;
}
/* Coefficients need to be shuffled for our streaming algorithm below to work. Samples are already in the correct order from the loading routine above. */
coefficients128_0 = drflac__vrevq_s32(coefficients128_0);
coefficients128_4 = drflac__vrevq_s32(coefficients128_4);
coefficients128_8 = drflac__vrevq_s32(coefficients128_8);
}
/* For this version we are doing one sample at a time. */
while (pDecodedSamples < pDecodedSamplesEnd) {
int64x2_t prediction128;
uint32x4_t zeroCountPart128;
uint32x4_t riceParamPart128;
if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[0], &riceParamParts[0]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[1], &riceParamParts[1]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[2], &riceParamParts[2]) ||
!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts[3], &riceParamParts[3])) {
return DRFLAC_FALSE;
}
zeroCountPart128 = vld1q_u32(zeroCountParts);
riceParamPart128 = vld1q_u32(riceParamParts);
riceParamPart128 = vandq_u32(riceParamPart128, riceParamMask128);
riceParamPart128 = vorrq_u32(riceParamPart128, vshlq_u32(zeroCountPart128, riceParam128));
riceParamPart128 = veorq_u32(vshrq_n_u32(riceParamPart128, 1), vaddq_u32(drflac__vnotq_u32(vandq_u32(riceParamPart128, one128)), one128));
for (i = 0; i < 4; i += 1) {
int64x1_t prediction64;
prediction128 = veorq_s64(prediction128, prediction128); /* Reset to 0. */
switch (order)
{
case 12:
case 11: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_8), vget_low_s32(samples128_8)));
case 10:
case 9: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_8), vget_high_s32(samples128_8)));
case 8:
case 7: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_4), vget_low_s32(samples128_4)));
case 6:
case 5: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_4), vget_high_s32(samples128_4)));
case 4:
case 3: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_low_s32(coefficients128_0), vget_low_s32(samples128_0)));
case 2:
case 1: prediction128 = vaddq_s64(prediction128, vmull_s32(vget_high_s32(coefficients128_0), vget_high_s32(samples128_0)));
}
/* Horizontal add and shift. */
prediction64 = drflac__vhaddq_s64(prediction128);
prediction64 = vshl_s64(prediction64, shift64);
prediction64 = vadd_s64(prediction64, vdup_n_s64(vgetq_lane_u32(riceParamPart128, 0)));
/* Our value should be sitting in prediction64[0]. We need to combine this with our SSE samples. */
samples128_8 = drflac__valignrq_s32_1(samples128_4, samples128_8);
samples128_4 = drflac__valignrq_s32_1(samples128_0, samples128_4);
samples128_0 = drflac__valignrq_s32_1(vcombine_s32(vreinterpret_s32_s64(prediction64), vdup_n_s32(0)), samples128_0);
/* Slide our rice parameter down so that the value in position 0 contains the next one to process. */
riceParamPart128 = drflac__valignrq_u32_1(vdupq_n_u32(0), riceParamPart128);
}
/* We store samples in groups of 4. */
share/public_html/static/music_worklet_inprogress/decoder/deps/dr_libs/dr_flac.h view on Meta::CPAN
memoryStream.currentReadPos = 0;
pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, onMeta, drflac_container_unknown, &memoryStream, pUserData, pAllocationCallbacks);
if (pFlac == NULL) {
return NULL;
}
pFlac->memoryStream = memoryStream;
/* This is an awful hack... */
#ifndef DR_FLAC_NO_OGG
if (pFlac->container == drflac_container_ogg)
{
drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
oggbs->pUserData = &pFlac->memoryStream;
}
else
#endif
{
pFlac->bs.pUserData = &pFlac->memoryStream;
}
return pFlac;
}
DRFLAC_API drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
{
return drflac_open_with_metadata_private(onRead, onSeek, NULL, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
}
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
{
return drflac_open_with_metadata_private(onRead, onSeek, NULL, container, pUserData, pUserData, pAllocationCallbacks);
}
DRFLAC_API drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
{
return drflac_open_with_metadata_private(onRead, onSeek, onMeta, drflac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
}
DRFLAC_API drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
{
return drflac_open_with_metadata_private(onRead, onSeek, onMeta, container, pUserData, pUserData, pAllocationCallbacks);
}
DRFLAC_API void drflac_close(drflac* pFlac)
{
if (pFlac == NULL) {
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* pOutpu...
{
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* pOutputSa...
{
drflac_uint64 i;
drflac_uint64 frameCount4 = frameCount >> 2;
const drflac_uint32* pInputSamples0U32 = (const drflac_uint32*)pInputSamples0;
const drflac_uint32* pInputSamples1U32 = (const drflac_uint32*)pInputSamples1;
drflac_uint32 shift0 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[0].wastedBitsPerSample;
drflac_uint32 shift1 = unusedBitsPerSample + pFlac->currentFLACFrame.subframes[1].wastedBitsPerSample;
for (i = 0; i < frameCount4; ++i) {
drflac_uint32 left0 = pInputSamples0U32[i*4+0] << shift0;
drflac_uint32 left1 = pInputSamples0U32[i*4+1] << shift0;
drflac_uint32 left2 = pInputSamples0U32[i*4+2] << shift0;
drflac_uint32 left3 = pInputSamples0U32[i*4+3] << shift0;
drflac_uint32 side0 = pInputSamples1U32[i*4+0] << shift1;
drflac_uint32 side1 = pInputSamples1U32[i*4+1] << shift1;
drflac_uint32 side2 = pInputSamples1U32[i*4+2] << shift1;
drflac_uint32 side3 = pInputSamples1U32[i*4+3] << shift1;
drflac_uint32 right0 = left0 - side0;
drflac_uint32 right1 = left1 - side1;
drflac_uint32 right2 = left2 - side2;
drflac_uint32 right3 = left3 - side3;
pOutputSamples[i*8+0] = (drflac_int32)left0;
pOutputSamples[i*8+1] = (drflac_int32)right0;
pOutputSamples[i*8+2] = (drflac_int32)left1;
pOutputSamples[i*8+3] = (drflac_int32)right1;
pOutputSamples[i*8+4] = (drflac_int32)left2;
share/public_html/static/music_worklet_inprogress/decoder/deps/dr_libs/dr_flac.h view on Meta::CPAN
v0.9.4 - 2018-06-14
- Optimizations to seeking.
- Clean up.
v0.9.3 - 2018-05-22
- Bug fix.
v0.9.2 - 2018-05-12
- Fix a compilation error due to a missing break statement.
v0.9.1 - 2018-04-29
- Fix compilation error with Clang.
v0.9 - 2018-04-24
- Fix Clang build.
- Start using major.minor.revision versioning.
v0.8g - 2018-04-19
- Fix build on non-x86/x64 architectures.
v0.8f - 2018-02-02
- Stop pretending to support changing rate/channels mid stream.
v0.8e - 2018-02-01
- Fix a crash when the block size of a frame is larger than the maximum block size defined by the FLAC stream.
- Fix a crash the the Rice partition order is invalid.
v0.8d - 2017-09-22
- Add support for decoding streams with ID3 tags. ID3 tags are just skipped.
v0.8c - 2017-09-07
- Fix warning on non-x86/x64 architectures.
v0.8b - 2017-08-19
- Fix build on non-x86/x64 architectures.
v0.8a - 2017-08-13
- A small optimization for the Clang build.
v0.8 - 2017-08-12
- API CHANGE: Rename dr_* types to drflac_*.
- Optimizations. This brings dr_flac back to about the same class of efficiency as the reference implementation.
- Add support for custom implementations of malloc(), realloc(), etc.
- Add CRC checking to Ogg encapsulated streams.
- Fix VC++ 6 build. This is only for the C++ compiler. The C compiler is not currently supported.
- Bug fixes.
v0.7 - 2017-07-23
- Add support for opening a stream without a header block. To do this, use drflac_open_relaxed() / drflac_open_with_metadata_relaxed().
v0.6 - 2017-07-22
- Add support for recovering from invalid frames. With this change, dr_flac will simply skip over invalid frames as if they
never existed. Frames are checked against their sync code, the CRC-8 of the frame header and the CRC-16 of the whole frame.
v0.5 - 2017-07-16
- Fix typos.
- Change drflac_bool* types to unsigned.
- Add CRC checking. This makes dr_flac slower, but can be disabled with #define DR_FLAC_NO_CRC.
v0.4f - 2017-03-10
- Fix a couple of bugs with the bitstreaming code.
v0.4e - 2017-02-17
- Fix some warnings.
v0.4d - 2016-12-26
- Add support for 32-bit floating-point PCM decoding.
- Use drflac_int* and drflac_uint* sized types to improve compiler support.
- Minor improvements to documentation.
v0.4c - 2016-12-26
- Add support for signed 16-bit integer PCM decoding.
v0.4b - 2016-10-23
- A minor change to drflac_bool8 and drflac_bool32 types.
v0.4a - 2016-10-11
- Rename drBool32 to drflac_bool32 for styling consistency.
v0.4 - 2016-09-29
- API/ABI CHANGE: Use fixed size 32-bit booleans instead of the built-in bool type.
- API CHANGE: Rename drflac_open_and_decode*() to drflac_open_and_decode*_s32().
- API CHANGE: Swap the order of "channels" and "sampleRate" parameters in drflac_open_and_decode*(). Rationale for this is to
keep it consistent with drflac_audio.
v0.3f - 2016-09-21
- Fix a warning with GCC.
v0.3e - 2016-09-18
- Fixed a bug where GCC 4.3+ was not getting properly identified.
- Fixed a few typos.
- Changed date formats to ISO 8601 (YYYY-MM-DD).
v0.3d - 2016-06-11
- Minor clean up.
v0.3c - 2016-05-28
- Fixed compilation error.
v0.3b - 2016-05-16
- Fixed Linux/GCC build.
- Updated documentation.
v0.3a - 2016-05-15
- Minor fixes to documentation.
v0.3 - 2016-05-11
- Optimizations. Now at about parity with the reference implementation on 32-bit builds.
- Lots of clean up.
v0.2b - 2016-05-10
- Bug fixes.
v0.2a - 2016-05-10
- Made drflac_open_and_decode() more robust.
- Removed an unused debugging variable
v0.2 - 2016-05-09
- Added support for Ogg encapsulation.
- API CHANGE. Have the onSeek callback take a third argument which specifies whether or not the seek
should be relative to the start or the current position. Also changes the seeking rules such that