From acaf19d97e028fc499a316942bfa62c5934bc957 Mon Sep 17 00:00:00 2001 From: dimitri Date: Thu, 13 Dec 2018 10:21:09 -0800 Subject: [PATCH] implement basic mp3 decoding using public-domain minimp3 library --- examples/src/Main.cpp | 8 +- src/Mp3Decoder.cpp | 41 +- test_data/ad_hoc/acetylene.mp3 | Bin 0 -> 130402 bytes third_party/minimp3/LICENSE | 117 ++ third_party/minimp3/minimp3.h | 1807 ++++++++++++++++++++++++++++++ third_party/minimp3/minimp3_ex.h | 386 +++++++ 6 files changed, 2334 insertions(+), 25 deletions(-) create mode 100644 test_data/ad_hoc/acetylene.mp3 create mode 100644 third_party/minimp3/LICENSE create mode 100644 third_party/minimp3/minimp3.h create mode 100644 third_party/minimp3/minimp3_ex.h diff --git a/examples/src/Main.cpp b/examples/src/Main.cpp index 117f1a4..2dab2aa 100644 --- a/examples/src/Main.cpp +++ b/examples/src/Main.cpp @@ -90,8 +90,12 @@ int main(int argc, const char **argv) try //loader.Load(fileData.get(), "test_data/ad_hoc/44_16_mono.mpc"); // In-memory ogg - auto memory = ReadFile("test_data/ad_hoc/BlockWoosh_Stereo.ogg"); - loader.Load(fileData.get(), "ogg", memory.buffer); + //auto memory = ReadFile("test_data/ad_hoc/BlockWoosh_Stereo.ogg"); + //loader.Load(fileData.get(), "ogg", memory.buffer); + + // In-memory Mp3 + auto memory = ReadFile("test_data/ad_hoc/acetylene.mp3"); + loader.Load(fileData.get(), "mp3", memory.buffer); } /* diff --git a/src/Mp3Decoder.cpp b/src/Mp3Decoder.cpp index eca1294..f4609ab 100644 --- a/src/Mp3Decoder.cpp +++ b/src/Mp3Decoder.cpp @@ -32,9 +32,13 @@ using namespace nqr; #include "musepack/libmpcdec/decoder.h" #include "musepack/libmpcdec/internal.h" +#define MINIMP3_FLOAT_OUTPUT +#define MINIMP3_IMPLEMENTATION +#include "minimp3/minimp3.h" +#include "minimp3/minimp3_ex.h" + class Mp3Internal { - NO_MOVE(Mp3Internal); AudioData * d; @@ -42,29 +46,20 @@ public: Mp3Internal(AudioData * d, const std::vector & fileData) : d(d) { - /* - d->sampleRate = (int) streamInfo.sample_freq; - d->channelCount = streamInfo.channels; - d->sourceFormat = MakeFormatForBits(32, true, false); - d->lengthSeconds = (double) mpc_streaminfo_get_length(&streamInfo); - - auto totalSamples = size_t(mpc_streaminfo_get_length_samples(&streamInfo)); - d->samples.reserve(totalSamples * d->channelCount + (MPC_DECODER_BUFFER_LENGTH / sizeof(MPC_SAMPLE_FORMAT))); // demux writes in chunks - d->samples.resize(totalSamples * d->channelCount); - - if (!read_implementation()) - { - throw std::runtime_error("could not read any data"); - } - */ - } - - size_t read_implementation() - { - return 0; - } + mp3dec_t mp3d; + mp3dec_file_info_t info; + mp3dec_load_buf(&mp3d, (const uint8_t*) fileData.data(), fileData.size(), &info, 0, 0); - ~Mp3Internal() {} + d->sampleRate = info.hz; + d->channelCount = info.channels; + d->sourceFormat = MakeFormatForBits(32, true, false); + d->lengthSeconds = ((float) info.samples / (float)d->channelCount) / (float)d->sampleRate; + + if (info.samples == 0) throw std::runtime_error("mp3: could not read any data"); + + d->samples.resize(info.samples); + std::memcpy(d->samples.data(), info.buffer, sizeof(float) * info.samples); + } }; ////////////////////// diff --git a/test_data/ad_hoc/acetylene.mp3 b/test_data/ad_hoc/acetylene.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..fdeb454ebbf50b3ad4b1cae22eff2628ba5d20c0 GIT binary patch literal 130402 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 a_sq}}nE3BXJTvqJ**!D#1SbBw68{H8Jt46G literal 0 HcmV?d00001 diff --git a/third_party/minimp3/LICENSE b/third_party/minimp3/LICENSE new file mode 100644 index 0000000..2c4afab --- /dev/null +++ b/third_party/minimp3/LICENSE @@ -0,0 +1,117 @@ +CC0 1.0 Universal + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later +claims of infringement build upon, modify, incorporate in other works, reuse +and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may +contribute to the Commons to promote the ideal of a free culture and the +further production of creative, cultural and scientific works, or to gain +reputation or greater distribution for their Work in part through the use and +efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with a +Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not limited +to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + + ii. moral rights retained by the original author(s) and/or performer(s); + + iii. publicity and privacy rights pertaining to a person's image or likeness + depicted in a Work; + + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + + v. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + + vii. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer's Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer's heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer's express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, +non transferable, non sublicensable, non exclusive, irrevocable and +unconditional license to exercise Affirmer's Copyright and Related Rights in +the Work (i) in all territories worldwide, (ii) for the maximum duration +provided by applicable law or treaty (including future time extensions), (iii) +in any current or future medium and for any number of copies, and (iv) for any +purpose whatsoever, including without limitation commercial, advertising or +promotional purposes (the "License"). The License shall be deemed effective as +of the date CC0 was applied by Affirmer to the Work. Should any part of the +License for any reason be judged legally invalid or ineffective under +applicable law, such partial invalidity or ineffectiveness shall not +invalidate the remainder of the License, and in such case Affirmer hereby +affirms that he or she will not (i) exercise any of his or her remaining +Copyright and Related Rights in the Work or (ii) assert any associated claims +and causes of action with respect to the Work, in either case contrary to +Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + + b. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or otherwise, + including without limitation warranties of title, merchantability, fitness + for a particular purpose, non infringement, or the absence of latent or + other defects, accuracy, or the present or absence of errors, whether or not + discoverable, all to the greatest extent permissible under applicable law. + + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without limitation + any person's Copyright and Related Rights in the Work. Further, Affirmer + disclaims responsibility for obtaining any necessary consents, permissions + or other rights required for any use of the Work. + + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see + + diff --git a/third_party/minimp3/minimp3.h b/third_party/minimp3/minimp3.h new file mode 100644 index 0000000..a878b12 --- /dev/null +++ b/third_party/minimp3/minimp3.h @@ -0,0 +1,1807 @@ +#ifndef MINIMP3_H +#define MINIMP3_H +/* + https://github.com/lieff/minimp3 + To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. + This software is distributed without any warranty. + See . +*/ +#include + +#define MINIMP3_MAX_SAMPLES_PER_FRAME (1152*2) + +typedef struct +{ + int frame_bytes, channels, hz, layer, bitrate_kbps; +} mp3dec_frame_info_t; + +typedef struct +{ + float mdct_overlap[2][9*32], qmf_state[15*2*32]; + int reserv, free_format_bytes; + unsigned char header[4], reserv_buf[511]; +} mp3dec_t; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void mp3dec_init(mp3dec_t *dec); +#ifndef MINIMP3_FLOAT_OUTPUT +typedef int16_t mp3d_sample_t; +#else /* MINIMP3_FLOAT_OUTPUT */ +typedef float mp3d_sample_t; +void mp3dec_f32_to_s16(const float *in, int16_t *out, int num_samples); +#endif /* MINIMP3_FLOAT_OUTPUT */ +int mp3dec_decode_frame(mp3dec_t *dec, const uint8_t *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* MINIMP3_H */ +#if defined(MINIMP3_IMPLEMENTATION) && !defined(_MINIMP3_IMPLEMENTATION_GUARD) +#define _MINIMP3_IMPLEMENTATION_GUARD + +#include +#include + +#define MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */ +#ifndef MAX_FRAME_SYNC_MATCHES +#define MAX_FRAME_SYNC_MATCHES 10 +#endif /* MAX_FRAME_SYNC_MATCHES */ + +#define MAX_L3_FRAME_PAYLOAD_BYTES MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */ + +#define MAX_BITRESERVOIR_BYTES 511 +#define SHORT_BLOCK_TYPE 2 +#define STOP_BLOCK_TYPE 3 +#define MODE_MONO 3 +#define MODE_JOINT_STEREO 1 +#define HDR_SIZE 4 +#define HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0) +#define HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60) +#define HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0) +#define HDR_IS_CRC(h) (!((h[1]) & 1)) +#define HDR_TEST_PADDING(h) ((h[2]) & 0x2) +#define HDR_TEST_MPEG1(h) ((h[1]) & 0x8) +#define HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10) +#define HDR_TEST_I_STEREO(h) ((h[3]) & 0x10) +#define HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20) +#define HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3) +#define HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3) +#define HDR_GET_LAYER(h) (((h[1]) >> 1) & 3) +#define HDR_GET_BITRATE(h) ((h[2]) >> 4) +#define HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3) +#define HDR_GET_MY_SAMPLE_RATE(h) (HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3) +#define HDR_IS_FRAME_576(h) ((h[1] & 14) == 2) +#define HDR_IS_LAYER_1(h) ((h[1] & 6) == 6) + +#define BITS_DEQUANTIZER_OUT -1 +#define MAX_SCF (255 + BITS_DEQUANTIZER_OUT*4 - 210) +#define MAX_SCFI ((MAX_SCF + 3) & ~3) + +#define MINIMP3_MIN(a, b) ((a) > (b) ? (b) : (a)) +#define MINIMP3_MAX(a, b) ((a) < (b) ? (b) : (a)) + +#if !defined(MINIMP3_NO_SIMD) + +#if !defined(MINIMP3_ONLY_SIMD) && (defined(_M_X64) || defined(_M_ARM64) || defined(__x86_64__) || defined(__aarch64__)) +/* x64 always have SSE2, arm64 always have neon, no need for generic code */ +#define MINIMP3_ONLY_SIMD +#endif /* SIMD checks... */ + +#if (defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__)) +#if defined(_MSC_VER) +#include +#endif /* defined(_MSC_VER) */ +#include +#define HAVE_SSE 1 +#define HAVE_SIMD 1 +#define VSTORE _mm_storeu_ps +#define VLD _mm_loadu_ps +#define VSET _mm_set1_ps +#define VADD _mm_add_ps +#define VSUB _mm_sub_ps +#define VMUL _mm_mul_ps +#define VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y)) +#define VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y)) +#define VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s)) +#define VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3)) +typedef __m128 f4; +#if defined(_MSC_VER) || defined(MINIMP3_ONLY_SIMD) +#define minimp3_cpuid __cpuid +#else /* defined(_MSC_VER) || defined(MINIMP3_ONLY_SIMD) */ +static __inline__ __attribute__((always_inline)) void minimp3_cpuid(int CPUInfo[], const int InfoType) +{ +#if defined(__PIC__) + __asm__ __volatile__( +#if defined(__x86_64__) + "push %%rbx\n" + "cpuid\n" + "xchgl %%ebx, %1\n" + "pop %%rbx\n" +#else /* defined(__x86_64__) */ + "xchgl %%ebx, %1\n" + "cpuid\n" + "xchgl %%ebx, %1\n" +#endif /* defined(__x86_64__) */ + : "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) + : "a" (InfoType)); +#else /* defined(__PIC__) */ + __asm__ __volatile__( + "cpuid" + : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) + : "a" (InfoType)); +#endif /* defined(__PIC__)*/ +} +#endif /* defined(_MSC_VER) || defined(MINIMP3_ONLY_SIMD) */ +static int have_simd() +{ +#ifdef MINIMP3_ONLY_SIMD + return 1; +#else /* MINIMP3_ONLY_SIMD */ + static int g_have_simd; + int CPUInfo[4]; +#ifdef MINIMP3_TEST + static int g_counter; + if (g_counter++ > 100) + return 0; +#endif /* MINIMP3_TEST */ + if (g_have_simd) + goto end; + minimp3_cpuid(CPUInfo, 0); + g_have_simd = 1; + if (CPUInfo[0] > 0) + { + minimp3_cpuid(CPUInfo, 1); + g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */ + } +end: + return g_have_simd - 1; +#endif /* MINIMP3_ONLY_SIMD */ +} +#elif defined(__ARM_NEON) || defined(__aarch64__) +#include +#define HAVE_SIMD 1 +#define VSTORE vst1q_f32 +#define VLD vld1q_f32 +#define VSET vmovq_n_f32 +#define VADD vaddq_f32 +#define VSUB vsubq_f32 +#define VMUL vmulq_f32 +#define VMAC(a, x, y) vmlaq_f32(a, x, y) +#define VMSB(a, x, y) vmlsq_f32(a, x, y) +#define VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s)) +#define VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x))) +typedef float32x4_t f4; +static int have_simd() +{ /* TODO: detect neon for !MINIMP3_ONLY_SIMD */ + return 1; +} +#else /* SIMD checks... */ +#define HAVE_SIMD 0 +#ifdef MINIMP3_ONLY_SIMD +#error MINIMP3_ONLY_SIMD used, but SSE/NEON not enabled +#endif /* MINIMP3_ONLY_SIMD */ +#endif /* SIMD checks... */ +#else /* !defined(MINIMP3_NO_SIMD) */ +#define HAVE_SIMD 0 +#endif /* !defined(MINIMP3_NO_SIMD) */ + +typedef struct +{ + const uint8_t *buf; + int pos, limit; +} bs_t; + +typedef struct +{ + float scf[3*64]; + uint8_t total_bands, stereo_bands, bitalloc[64], scfcod[64]; +} L12_scale_info; + +typedef struct +{ + uint8_t tab_offset, code_tab_width, band_count; +} L12_subband_alloc_t; + +typedef struct +{ + const uint8_t *sfbtab; + uint16_t part_23_length, big_values, scalefac_compress; + uint8_t global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb; + uint8_t table_select[3], region_count[3], subblock_gain[3]; + uint8_t preflag, scalefac_scale, count1_table, scfsi; +} L3_gr_info_t; + +typedef struct +{ + bs_t bs; + uint8_t maindata[MAX_BITRESERVOIR_BYTES + MAX_L3_FRAME_PAYLOAD_BYTES]; + L3_gr_info_t gr_info[4]; + float grbuf[2][576], scf[40], syn[18 + 15][2*32]; + uint8_t ist_pos[2][39]; +} mp3dec_scratch_t; + +static void bs_init(bs_t *bs, const uint8_t *data, int bytes) +{ + bs->buf = data; + bs->pos = 0; + bs->limit = bytes*8; +} + +static uint32_t get_bits(bs_t *bs, int n) +{ + uint32_t next, cache = 0, s = bs->pos & 7; + int shl = n + s; + const uint8_t *p = bs->buf + (bs->pos >> 3); + if ((bs->pos += n) > bs->limit) + return 0; + next = *p++ & (255 >> s); + while ((shl -= 8) > 0) + { + cache |= next << shl; + next = *p++; + } + return cache | (next >> -shl); +} + +static int hdr_valid(const uint8_t *h) +{ + return h[0] == 0xff && + ((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) && + (HDR_GET_LAYER(h) != 0) && + (HDR_GET_BITRATE(h) != 15) && + (HDR_GET_SAMPLE_RATE(h) != 3); +} + +static int hdr_compare(const uint8_t *h1, const uint8_t *h2) +{ + return hdr_valid(h2) && + ((h1[1] ^ h2[1]) & 0xFE) == 0 && + ((h1[2] ^ h2[2]) & 0x0C) == 0 && + !(HDR_IS_FREE_FORMAT(h1) ^ HDR_IS_FREE_FORMAT(h2)); +} + +static unsigned hdr_bitrate_kbps(const uint8_t *h) +{ + static const uint8_t halfrate[2][3][15] = { + { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } }, + { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } }, + }; + return 2*halfrate[!!HDR_TEST_MPEG1(h)][HDR_GET_LAYER(h) - 1][HDR_GET_BITRATE(h)]; +} + +static unsigned hdr_sample_rate_hz(const uint8_t *h) +{ + static const unsigned g_hz[3] = { 44100, 48000, 32000 }; + return g_hz[HDR_GET_SAMPLE_RATE(h)] >> (int)!HDR_TEST_MPEG1(h) >> (int)!HDR_TEST_NOT_MPEG25(h); +} + +static unsigned hdr_frame_samples(const uint8_t *h) +{ + return HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)HDR_IS_FRAME_576(h)); +} + +static int hdr_frame_bytes(const uint8_t *h, int free_format_size) +{ + int frame_bytes = hdr_frame_samples(h)*hdr_bitrate_kbps(h)*125/hdr_sample_rate_hz(h); + if (HDR_IS_LAYER_1(h)) + { + frame_bytes &= ~3; /* slot align */ + } + return frame_bytes ? frame_bytes : free_format_size; +} + +static int hdr_padding(const uint8_t *h) +{ + return HDR_TEST_PADDING(h) ? (HDR_IS_LAYER_1(h) ? 4 : 1) : 0; +} + +#ifndef MINIMP3_ONLY_MP3 +static const L12_subband_alloc_t *L12_subband_alloc_table(const uint8_t *hdr, L12_scale_info *sci) +{ + const L12_subband_alloc_t *alloc; + int mode = HDR_GET_STEREO_MODE(hdr); + int nbands, stereo_bands = (mode == MODE_MONO) ? 0 : (mode == MODE_JOINT_STEREO) ? (HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32; + + if (HDR_IS_LAYER_1(hdr)) + { + static const L12_subband_alloc_t g_alloc_L1[] = { { 76, 4, 32 } }; + alloc = g_alloc_L1; + nbands = 32; + } else if (!HDR_TEST_MPEG1(hdr)) + { + static const L12_subband_alloc_t g_alloc_L2M2[] = { { 60, 4, 4 }, { 44, 3, 7 }, { 44, 2, 19 } }; + alloc = g_alloc_L2M2; + nbands = 30; + } else + { + static const L12_subband_alloc_t g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } }; + int sample_rate_idx = HDR_GET_SAMPLE_RATE(hdr); + unsigned kbps = hdr_bitrate_kbps(hdr) >> (int)(mode != MODE_MONO); + if (!kbps) /* free-format */ + { + kbps = 192; + } + + alloc = g_alloc_L2M1; + nbands = 27; + if (kbps < 56) + { + static const L12_subband_alloc_t g_alloc_L2M1_lowrate[] = { { 44, 4, 2 }, { 44, 3, 10 } }; + alloc = g_alloc_L2M1_lowrate; + nbands = sample_rate_idx == 2 ? 12 : 8; + } else if (kbps >= 96 && sample_rate_idx != 1) + { + nbands = 30; + } + } + + sci->total_bands = (uint8_t)nbands; + sci->stereo_bands = (uint8_t)MINIMP3_MIN(stereo_bands, nbands); + + return alloc; +} + +static void L12_read_scalefactors(bs_t *bs, uint8_t *pba, uint8_t *scfcod, int bands, float *scf) +{ + static const float g_deq_L12[18*3] = { +#define DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x + DQ(3),DQ(7),DQ(15),DQ(31),DQ(63),DQ(127),DQ(255),DQ(511),DQ(1023),DQ(2047),DQ(4095),DQ(8191),DQ(16383),DQ(32767),DQ(65535),DQ(3),DQ(5),DQ(9) + }; + int i, m; + for (i = 0; i < bands; i++) + { + float s = 0; + int ba = *pba++; + int mask = ba ? 4 + ((19 >> scfcod[i]) & 3) : 0; + for (m = 4; m; m >>= 1) + { + if (mask & m) + { + int b = get_bits(bs, 6); + s = g_deq_L12[ba*3 - 6 + b % 3]*(1 << 21 >> b/3); + } + *scf++ = s; + } + } +} + +static void L12_read_scale_info(const uint8_t *hdr, bs_t *bs, L12_scale_info *sci) +{ + static const uint8_t g_bitalloc_code_tab[] = { + 0,17, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16, + 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,16, + 0,17,18, 3,19,4,5,16, + 0,17,18,16, + 0,17,18,19, 4,5,6, 7,8, 9,10,11,12,13,14,15, + 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,14, + 0, 2, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16 + }; + const L12_subband_alloc_t *subband_alloc = L12_subband_alloc_table(hdr, sci); + + int i, k = 0, ba_bits = 0; + const uint8_t *ba_code_tab = g_bitalloc_code_tab; + + for (i = 0; i < sci->total_bands; i++) + { + uint8_t ba; + if (i == k) + { + k += subband_alloc->band_count; + ba_bits = subband_alloc->code_tab_width; + ba_code_tab = g_bitalloc_code_tab + subband_alloc->tab_offset; + subband_alloc++; + } + ba = ba_code_tab[get_bits(bs, ba_bits)]; + sci->bitalloc[2*i] = ba; + if (i < sci->stereo_bands) + { + ba = ba_code_tab[get_bits(bs, ba_bits)]; + } + sci->bitalloc[2*i + 1] = sci->stereo_bands ? ba : 0; + } + + for (i = 0; i < 2*sci->total_bands; i++) + { + sci->scfcod[i] = sci->bitalloc[i] ? HDR_IS_LAYER_1(hdr) ? 2 : get_bits(bs, 2) : 6; + } + + L12_read_scalefactors(bs, sci->bitalloc, sci->scfcod, sci->total_bands*2, sci->scf); + + for (i = sci->stereo_bands; i < sci->total_bands; i++) + { + sci->bitalloc[2*i + 1] = 0; + } +} + +static int L12_dequantize_granule(float *grbuf, bs_t *bs, L12_scale_info *sci, int group_size) +{ + int i, j, k, choff = 576; + for (j = 0; j < 4; j++) + { + float *dst = grbuf + group_size*j; + for (i = 0; i < 2*sci->total_bands; i++) + { + int ba = sci->bitalloc[i]; + if (ba != 0) + { + if (ba < 17) + { + int half = (1 << (ba - 1)) - 1; + for (k = 0; k < group_size; k++) + { + dst[k] = (float)((int)get_bits(bs, ba) - half); + } + } else + { + unsigned mod = (2 << (ba - 17)) + 1; /* 3, 5, 9 */ + unsigned code = get_bits(bs, mod + 2 - (mod >> 3)); /* 5, 7, 10 */ + for (k = 0; k < group_size; k++, code /= mod) + { + dst[k] = (float)((int)(code % mod - mod/2)); + } + } + } + dst += choff; + choff = 18 - choff; + } + } + return group_size*4; +} + +static void L12_apply_scf_384(L12_scale_info *sci, const float *scf, float *dst) +{ + int i, k; + memcpy(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float)); + for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6) + { + for (k = 0; k < 12; k++) + { + dst[k + 0] *= scf[0]; + dst[k + 576] *= scf[3]; + } + } +} +#endif /* MINIMP3_ONLY_MP3 */ + +static int L3_read_side_info(bs_t *bs, L3_gr_info_t *gr, const uint8_t *hdr) +{ + static const uint8_t g_scf_long[8][23] = { + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158,0 }, + { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 }, + { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 } + }; + static const uint8_t g_scf_short[8][40] = { + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 } + }; + static const uint8_t g_scf_mixed[8][40] = { + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 }, + { 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 }, + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 }, + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 } + }; + + unsigned tables, scfsi = 0; + int main_data_begin, part_23_sum = 0; + int sr_idx = HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0); + int gr_count = HDR_IS_MONO(hdr) ? 1 : 2; + + if (HDR_TEST_MPEG1(hdr)) + { + gr_count *= 2; + main_data_begin = get_bits(bs, 9); + scfsi = get_bits(bs, 7 + gr_count); + } else + { + main_data_begin = get_bits(bs, 8 + gr_count) >> gr_count; + } + + do + { + if (HDR_IS_MONO(hdr)) + { + scfsi <<= 4; + } + gr->part_23_length = (uint16_t)get_bits(bs, 12); + part_23_sum += gr->part_23_length; + gr->big_values = (uint16_t)get_bits(bs, 9); + if (gr->big_values > 288) + { + return -1; + } + gr->global_gain = (uint8_t)get_bits(bs, 8); + gr->scalefac_compress = (uint16_t)get_bits(bs, HDR_TEST_MPEG1(hdr) ? 4 : 9); + gr->sfbtab = g_scf_long[sr_idx]; + gr->n_long_sfb = 22; + gr->n_short_sfb = 0; + if (get_bits(bs, 1)) + { + gr->block_type = (uint8_t)get_bits(bs, 2); + if (!gr->block_type) + { + return -1; + } + gr->mixed_block_flag = (uint8_t)get_bits(bs, 1); + gr->region_count[0] = 7; + gr->region_count[1] = 255; + if (gr->block_type == SHORT_BLOCK_TYPE) + { + scfsi &= 0x0F0F; + if (!gr->mixed_block_flag) + { + gr->region_count[0] = 8; + gr->sfbtab = g_scf_short[sr_idx]; + gr->n_long_sfb = 0; + gr->n_short_sfb = 39; + } else + { + gr->sfbtab = g_scf_mixed[sr_idx]; + gr->n_long_sfb = HDR_TEST_MPEG1(hdr) ? 8 : 6; + gr->n_short_sfb = 30; + } + } + tables = get_bits(bs, 10); + tables <<= 5; + gr->subblock_gain[0] = (uint8_t)get_bits(bs, 3); + gr->subblock_gain[1] = (uint8_t)get_bits(bs, 3); + gr->subblock_gain[2] = (uint8_t)get_bits(bs, 3); + } else + { + gr->block_type = 0; + gr->mixed_block_flag = 0; + tables = get_bits(bs, 15); + gr->region_count[0] = (uint8_t)get_bits(bs, 4); + gr->region_count[1] = (uint8_t)get_bits(bs, 3); + gr->region_count[2] = 255; + } + gr->table_select[0] = (uint8_t)(tables >> 10); + gr->table_select[1] = (uint8_t)((tables >> 5) & 31); + gr->table_select[2] = (uint8_t)((tables) & 31); + gr->preflag = HDR_TEST_MPEG1(hdr) ? get_bits(bs, 1) : (gr->scalefac_compress >= 500); + gr->scalefac_scale = (uint8_t)get_bits(bs, 1); + gr->count1_table = (uint8_t)get_bits(bs, 1); + gr->scfsi = (uint8_t)((scfsi >> 12) & 15); + scfsi <<= 4; + gr++; + } while(--gr_count); + + if (part_23_sum + bs->pos > bs->limit + main_data_begin*8) + { + return -1; + } + + return main_data_begin; +} + +static void L3_read_scalefactors(uint8_t *scf, uint8_t *ist_pos, const uint8_t *scf_size, const uint8_t *scf_count, bs_t *bitbuf, int scfsi) +{ + int i, k; + for (i = 0; i < 4 && scf_count[i]; i++, scfsi *= 2) + { + int cnt = scf_count[i]; + if (scfsi & 8) + { + memcpy(scf, ist_pos, cnt); + } else + { + int bits = scf_size[i]; + if (!bits) + { + memset(scf, 0, cnt); + memset(ist_pos, 0, cnt); + } else + { + int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1; + for (k = 0; k < cnt; k++) + { + int s = get_bits(bitbuf, bits); + ist_pos[k] = (s == max_scf ? -1 : s); + scf[k] = s; + } + } + } + ist_pos += cnt; + scf += cnt; + } + scf[0] = scf[1] = scf[2] = 0; +} + +static float L3_ldexp_q2(float y, int exp_q2) +{ + static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f }; + int e; + do + { + e = MINIMP3_MIN(30*4, exp_q2); + y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2)); + } while ((exp_q2 -= e) > 0); + return y; +} + +static void L3_decode_scalefactors(const uint8_t *hdr, uint8_t *ist_pos, bs_t *bs, const L3_gr_info_t *gr, float *scf, int ch) +{ + static const uint8_t g_scf_partitions[3][28] = { + { 6,5,5, 5,6,5,5,5,6,5, 7,3,11,10,0,0, 7, 7, 7,0, 6, 6,6,3, 8, 8,5,0 }, + { 8,9,6,12,6,9,9,9,6,9,12,6,15,18,0,0, 6,15,12,0, 6,12,9,6, 6,18,9,0 }, + { 9,9,6,12,9,9,9,9,9,9,12,6,18,18,0,0,12,12,12,0,12, 9,9,6,15,12,9,0 } + }; + const uint8_t *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb]; + uint8_t scf_size[4], iscf[40]; + int i, scf_shift = gr->scalefac_scale + 1, gain_exp, scfsi = gr->scfsi; + float gain; + + if (HDR_TEST_MPEG1(hdr)) + { + static const uint8_t g_scfc_decode[16] = { 0,1,2,3, 12,5,6,7, 9,10,11,13, 14,15,18,19 }; + int part = g_scfc_decode[gr->scalefac_compress]; + scf_size[1] = scf_size[0] = (uint8_t)(part >> 2); + scf_size[3] = scf_size[2] = (uint8_t)(part & 3); + } else + { + static const uint8_t g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 }; + int k, modprod, sfc, ist = HDR_TEST_I_STEREO(hdr) && ch; + sfc = gr->scalefac_compress >> ist; + for (k = ist*3*4; sfc >= 0; sfc -= modprod, k += 4) + { + for (modprod = 1, i = 3; i >= 0; i--) + { + scf_size[i] = (uint8_t)(sfc / modprod % g_mod[k + i]); + modprod *= g_mod[k + i]; + } + } + scf_partition += k; + scfsi = -16; + } + L3_read_scalefactors(iscf, ist_pos, scf_size, scf_partition, bs, scfsi); + + if (gr->n_short_sfb) + { + int sh = 3 - scf_shift; + for (i = 0; i < gr->n_short_sfb; i += 3) + { + iscf[gr->n_long_sfb + i + 0] += gr->subblock_gain[0] << sh; + iscf[gr->n_long_sfb + i + 1] += gr->subblock_gain[1] << sh; + iscf[gr->n_long_sfb + i + 2] += gr->subblock_gain[2] << sh; + } + } else if (gr->preflag) + { + static const uint8_t g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 }; + for (i = 0; i < 10; i++) + { + iscf[11 + i] += g_preamp[i]; + } + } + + gain_exp = gr->global_gain + BITS_DEQUANTIZER_OUT*4 - 210 - (HDR_IS_MS_STEREO(hdr) ? 2 : 0); + gain = L3_ldexp_q2(1 << (MAX_SCFI/4), MAX_SCFI - gain_exp); + for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++) + { + scf[i] = L3_ldexp_q2(gain, iscf[i] << scf_shift); + } +} + +static const float g_pow43[129 + 16] = { + 0,-1,-2.519842f,-4.326749f,-6.349604f,-8.549880f,-10.902724f,-13.390518f,-16.000000f,-18.720754f,-21.544347f,-24.463781f,-27.473142f,-30.567351f,-33.741992f,-36.993181f, + 0,1,2.519842f,4.326749f,6.349604f,8.549880f,10.902724f,13.390518f,16.000000f,18.720754f,21.544347f,24.463781f,27.473142f,30.567351f,33.741992f,36.993181f,40.317474f,43.711787f,47.173345f,50.699631f,54.288352f,57.937408f,61.644865f,65.408941f,69.227979f,73.100443f,77.024898f,81.000000f,85.024491f,89.097188f,93.216975f,97.382800f,101.593667f,105.848633f,110.146801f,114.487321f,118.869381f,123.292209f,127.755065f,132.257246f,136.798076f,141.376907f,145.993119f,150.646117f,155.335327f,160.060199f,164.820202f,169.614826f,174.443577f,179.305980f,184.201575f,189.129918f,194.090580f,199.083145f,204.107210f,209.162385f,214.248292f,219.364564f,224.510845f,229.686789f,234.892058f,240.126328f,245.389280f,250.680604f,256.000000f,261.347174f,266.721841f,272.123723f,277.552547f,283.008049f,288.489971f,293.998060f,299.532071f,305.091761f,310.676898f,316.287249f,321.922592f,327.582707f,333.267377f,338.976394f,344.709550f,350.466646f,356.247482f,362.051866f,367.879608f,373.730522f,379.604427f,385.501143f,391.420496f,397.362314f,403.326427f,409.312672f,415.320884f,421.350905f,427.402579f,433.475750f,439.570269f,445.685987f,451.822757f,457.980436f,464.158883f,470.357960f,476.577530f,482.817459f,489.077615f,495.357868f,501.658090f,507.978156f,514.317941f,520.677324f,527.056184f,533.454404f,539.871867f,546.308458f,552.764065f,559.238575f,565.731879f,572.243870f,578.774440f,585.323483f,591.890898f,598.476581f,605.080431f,611.702349f,618.342238f,625.000000f,631.675540f,638.368763f,645.079578f +}; + +static float L3_pow_43(int x) +{ + float frac; + int sign, mult = 256; + + if (x < 129) + { + return g_pow43[16 + x]; + } + + if (x < 1024) + { + mult = 16; + x <<= 3; + } + + sign = 2*x & 64; + frac = (float)((x & 63) - sign) / ((x & ~63) + sign); + return g_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult; +} + +static void L3_huffman(float *dst, bs_t *bs, const L3_gr_info_t *gr_info, const float *scf, int layer3gr_limit) +{ + static const int16_t tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256, + -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288, + -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288, + -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258, + -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259, + -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258, + -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258, + -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259, + -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258, + -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290, + -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259, + -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258, + -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259, + -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258, + -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 }; + static const uint8_t tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205 }; + static const uint8_t tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 }; + static const int16_t tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 }; + static const uint8_t g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 }; + +#define PEEK_BITS(n) (bs_cache >> (32 - n)) +#define FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); } +#define CHECK_BITS while (bs_sh >= 0) { bs_cache |= (uint32_t)*bs_next_ptr++ << bs_sh; bs_sh -= 8; } +#define BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh) + + float one = 0.0f; + int ireg = 0, big_val_cnt = gr_info->big_values; + const uint8_t *sfb = gr_info->sfbtab; + const uint8_t *bs_next_ptr = bs->buf + bs->pos/8; + uint32_t bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7); + int pairs_to_decode, np, bs_sh = (bs->pos & 7) - 8; + bs_next_ptr += 4; + + while (big_val_cnt > 0) + { + int tab_num = gr_info->table_select[ireg]; + int sfb_cnt = gr_info->region_count[ireg++]; + const int16_t *codebook = tabs + tabindex[tab_num]; + int linbits = g_linbits[tab_num]; + do + { + np = *sfb++ / 2; + pairs_to_decode = MINIMP3_MIN(big_val_cnt, np); + one = *scf++; + do + { + int j, w = 5; + int leaf = codebook[PEEK_BITS(w)]; + while (leaf < 0) + { + FLUSH_BITS(w); + w = leaf & 7; + leaf = codebook[PEEK_BITS(w) - (leaf >> 3)]; + } + FLUSH_BITS(leaf >> 8); + + for (j = 0; j < 2; j++, dst++, leaf >>= 4) + { + int lsb = leaf & 0x0F; + if (lsb == 15 && linbits) + { + lsb += PEEK_BITS(linbits); + FLUSH_BITS(linbits); + CHECK_BITS; + *dst = one*L3_pow_43(lsb)*((int32_t)bs_cache < 0 ? -1: 1); + } else + { + *dst = g_pow43[16 + lsb - 16*(bs_cache >> 31)]*one; + } + FLUSH_BITS(lsb ? 1 : 0); + } + CHECK_BITS; + } while (--pairs_to_decode); + } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0); + } + + for (np = 1 - big_val_cnt;; dst += 4) + { + const uint8_t *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32; + int leaf = codebook_count1[PEEK_BITS(4)]; + if (!(leaf & 8)) + { + leaf = codebook_count1[(leaf >> 3) + (bs_cache << 4 >> (32 - (leaf & 3)))]; + } + FLUSH_BITS(leaf & 7); + if (BSPOS > layer3gr_limit) + { + break; + } +#define RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; } +#define DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((int32_t)bs_cache < 0) ? -one : one; FLUSH_BITS(1) } + RELOAD_SCALEFACTOR; + DEQ_COUNT1(0); + DEQ_COUNT1(1); + RELOAD_SCALEFACTOR; + DEQ_COUNT1(2); + DEQ_COUNT1(3); + CHECK_BITS; + } + + bs->pos = layer3gr_limit; +} + +static void L3_midside_stereo(float *left, int n) +{ + int i = 0; + float *right = left + 576; +#if HAVE_SIMD + if (have_simd()) for (; i < n - 3; i += 4) + { + f4 vl = VLD(left + i); + f4 vr = VLD(right + i); + VSTORE(left + i, VADD(vl, vr)); + VSTORE(right + i, VSUB(vl, vr)); + } +#endif /* HAVE_SIMD */ + for (; i < n; i++) + { + float a = left[i]; + float b = right[i]; + left[i] = a + b; + right[i] = a - b; + } +} + +static void L3_intensity_stereo_band(float *left, int n, float kl, float kr) +{ + int i; + for (i = 0; i < n; i++) + { + left[i + 576] = left[i]*kr; + left[i] = left[i]*kl; + } +} + +static void L3_stereo_top_band(const float *right, const uint8_t *sfb, int nbands, int max_band[3]) +{ + int i, k; + + max_band[0] = max_band[1] = max_band[2] = -1; + + for (i = 0; i < nbands; i++) + { + for (k = 0; k < sfb[i]; k += 2) + { + if (right[k] != 0 || right[k + 1] != 0) + { + max_band[i % 3] = i; + break; + } + } + right += sfb[i]; + } +} + +static void L3_stereo_process(float *left, const uint8_t *ist_pos, const uint8_t *sfb, const uint8_t *hdr, int max_band[3], int mpeg2_sh) +{ + static const float g_pan[7*2] = { 0,1,0.21132487f,0.78867513f,0.36602540f,0.63397460f,0.5f,0.5f,0.63397460f,0.36602540f,0.78867513f,0.21132487f,1,0 }; + unsigned i, max_pos = HDR_TEST_MPEG1(hdr) ? 7 : 64; + + for (i = 0; sfb[i]; i++) + { + unsigned ipos = ist_pos[i]; + if ((int)i > max_band[i % 3] && ipos < max_pos) + { + float kl, kr, s = HDR_TEST_MS_STEREO(hdr) ? 1.41421356f : 1; + if (HDR_TEST_MPEG1(hdr)) + { + kl = g_pan[2*ipos]; + kr = g_pan[2*ipos + 1]; + } else + { + kl = 1; + kr = L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh); + if (ipos & 1) + { + kl = kr; + kr = 1; + } + } + L3_intensity_stereo_band(left, sfb[i], kl*s, kr*s); + } else if (HDR_TEST_MS_STEREO(hdr)) + { + L3_midside_stereo(left, sfb[i]); + } + left += sfb[i]; + } +} + +static void L3_intensity_stereo(float *left, uint8_t *ist_pos, const L3_gr_info_t *gr, const uint8_t *hdr) +{ + int max_band[3], n_sfb = gr->n_long_sfb + gr->n_short_sfb; + int i, max_blocks = gr->n_short_sfb ? 3 : 1; + + L3_stereo_top_band(left + 576, gr->sfbtab, n_sfb, max_band); + if (gr->n_long_sfb) + { + max_band[0] = max_band[1] = max_band[2] = MINIMP3_MAX(MINIMP3_MAX(max_band[0], max_band[1]), max_band[2]); + } + for (i = 0; i < max_blocks; i++) + { + int default_pos = HDR_TEST_MPEG1(hdr) ? 3 : 0; + int itop = n_sfb - max_blocks + i; + int prev = itop - max_blocks; + ist_pos[itop] = max_band[i] >= prev ? default_pos : ist_pos[prev]; + } + L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress & 1); +} + +static void L3_reorder(float *grbuf, float *scratch, const uint8_t *sfb) +{ + int i, len; + float *src = grbuf, *dst = scratch; + + for (;0 != (len = *sfb); sfb += 3, src += 2*len) + { + for (i = 0; i < len; i++, src++) + { + *dst++ = src[0*len]; + *dst++ = src[1*len]; + *dst++ = src[2*len]; + } + } + memcpy(grbuf, scratch, (dst - scratch)*sizeof(float)); +} + +static void L3_antialias(float *grbuf, int nbands) +{ + static const float g_aa[2][8] = { + {0.85749293f,0.88174200f,0.94962865f,0.98331459f,0.99551782f,0.99916056f,0.99989920f,0.99999316f}, + {0.51449576f,0.47173197f,0.31337745f,0.18191320f,0.09457419f,0.04096558f,0.01419856f,0.00369997f} + }; + + for (; nbands > 0; nbands--, grbuf += 18) + { + int i = 0; +#if HAVE_SIMD + if (have_simd()) for (; i < 8; i += 4) + { + f4 vu = VLD(grbuf + 18 + i); + f4 vd = VLD(grbuf + 14 - i); + f4 vc0 = VLD(g_aa[0] + i); + f4 vc1 = VLD(g_aa[1] + i); + vd = VREV(vd); + VSTORE(grbuf + 18 + i, VSUB(VMUL(vu, vc0), VMUL(vd, vc1))); + vd = VADD(VMUL(vu, vc1), VMUL(vd, vc0)); + VSTORE(grbuf + 14 - i, VREV(vd)); + } +#endif /* HAVE_SIMD */ +#ifndef MINIMP3_ONLY_SIMD + for(; i < 8; i++) + { + float u = grbuf[18 + i]; + float d = grbuf[17 - i]; + grbuf[18 + i] = u*g_aa[0][i] - d*g_aa[1][i]; + grbuf[17 - i] = u*g_aa[1][i] + d*g_aa[0][i]; + } +#endif /* MINIMP3_ONLY_SIMD */ + } +} + +static void L3_dct3_9(float *y) +{ + float s0, s1, s2, s3, s4, s5, s6, s7, s8, t0, t2, t4; + + s0 = y[0]; s2 = y[2]; s4 = y[4]; s6 = y[6]; s8 = y[8]; + t0 = s0 + s6*0.5f; + s0 -= s6; + t4 = (s4 + s2)*0.93969262f; + t2 = (s8 + s2)*0.76604444f; + s6 = (s4 - s8)*0.17364818f; + s4 += s8 - s2; + + s2 = s0 - s4*0.5f; + y[4] = s4 + s0; + s8 = t0 - t2 + s6; + s0 = t0 - t4 + t2; + s4 = t0 + t4 - s6; + + s1 = y[1]; s3 = y[3]; s5 = y[5]; s7 = y[7]; + + s3 *= 0.86602540f; + t0 = (s5 + s1)*0.98480775f; + t4 = (s5 - s7)*0.34202014f; + t2 = (s1 + s7)*0.64278761f; + s1 = (s1 - s5 - s7)*0.86602540f; + + s5 = t0 - s3 - t2; + s7 = t4 - s3 - t0; + s3 = t4 + s3 - t2; + + y[0] = s4 - s7; + y[1] = s2 + s1; + y[2] = s0 - s3; + y[3] = s8 + s5; + y[5] = s8 - s5; + y[6] = s0 + s3; + y[7] = s2 - s1; + y[8] = s4 + s7; +} + +static void L3_imdct36(float *grbuf, float *overlap, const float *window, int nbands) +{ + int i, j; + static const float g_twid9[18] = { + 0.73727734f,0.79335334f,0.84339145f,0.88701083f,0.92387953f,0.95371695f,0.97629601f,0.99144486f,0.99904822f,0.67559021f,0.60876143f,0.53729961f,0.46174861f,0.38268343f,0.30070580f,0.21643961f,0.13052619f,0.04361938f + }; + + for (j = 0; j < nbands; j++, grbuf += 18, overlap += 9) + { + float co[9], si[9]; + co[0] = -grbuf[0]; + si[0] = grbuf[17]; + for (i = 0; i < 4; i++) + { + si[8 - 2*i] = grbuf[4*i + 1] - grbuf[4*i + 2]; + co[1 + 2*i] = grbuf[4*i + 1] + grbuf[4*i + 2]; + si[7 - 2*i] = grbuf[4*i + 4] - grbuf[4*i + 3]; + co[2 + 2*i] = -(grbuf[4*i + 3] + grbuf[4*i + 4]); + } + L3_dct3_9(co); + L3_dct3_9(si); + + si[1] = -si[1]; + si[3] = -si[3]; + si[5] = -si[5]; + si[7] = -si[7]; + + i = 0; + +#if HAVE_SIMD + if (have_simd()) for (; i < 8; i += 4) + { + f4 vovl = VLD(overlap + i); + f4 vc = VLD(co + i); + f4 vs = VLD(si + i); + f4 vr0 = VLD(g_twid9 + i); + f4 vr1 = VLD(g_twid9 + 9 + i); + f4 vw0 = VLD(window + i); + f4 vw1 = VLD(window + 9 + i); + f4 vsum = VADD(VMUL(vc, vr1), VMUL(vs, vr0)); + VSTORE(overlap + i, VSUB(VMUL(vc, vr0), VMUL(vs, vr1))); + VSTORE(grbuf + i, VSUB(VMUL(vovl, vw0), VMUL(vsum, vw1))); + vsum = VADD(VMUL(vovl, vw1), VMUL(vsum, vw0)); + VSTORE(grbuf + 14 - i, VREV(vsum)); + } +#endif /* HAVE_SIMD */ + for (; i < 9; i++) + { + float ovl = overlap[i]; + float sum = co[i]*g_twid9[9 + i] + si[i]*g_twid9[0 + i]; + overlap[i] = co[i]*g_twid9[0 + i] - si[i]*g_twid9[9 + i]; + grbuf[i] = ovl*window[0 + i] - sum*window[9 + i]; + grbuf[17 - i] = ovl*window[9 + i] + sum*window[0 + i]; + } + } +} + +static void L3_idct3(float x0, float x1, float x2, float *dst) +{ + float m1 = x1*0.86602540f; + float a1 = x0 - x2*0.5f; + dst[1] = x0 + x2; + dst[0] = a1 + m1; + dst[2] = a1 - m1; +} + +static void L3_imdct12(float *x, float *dst, float *overlap) +{ + static const float g_twid3[6] = { 0.79335334f,0.92387953f,0.99144486f, 0.60876143f,0.38268343f,0.13052619f }; + float co[3], si[3]; + int i; + + L3_idct3(-x[0], x[6] + x[3], x[12] + x[9], co); + L3_idct3(x[15], x[12] - x[9], x[6] - x[3], si); + si[1] = -si[1]; + + for (i = 0; i < 3; i++) + { + float ovl = overlap[i]; + float sum = co[i]*g_twid3[3 + i] + si[i]*g_twid3[0 + i]; + overlap[i] = co[i]*g_twid3[0 + i] - si[i]*g_twid3[3 + i]; + dst[i] = ovl*g_twid3[2 - i] - sum*g_twid3[5 - i]; + dst[5 - i] = ovl*g_twid3[5 - i] + sum*g_twid3[2 - i]; + } +} + +static void L3_imdct_short(float *grbuf, float *overlap, int nbands) +{ + for (;nbands > 0; nbands--, overlap += 9, grbuf += 18) + { + float tmp[18]; + memcpy(tmp, grbuf, sizeof(tmp)); + memcpy(grbuf, overlap, 6*sizeof(float)); + L3_imdct12(tmp, grbuf + 6, overlap + 6); + L3_imdct12(tmp + 1, grbuf + 12, overlap + 6); + L3_imdct12(tmp + 2, overlap, overlap + 6); + } +} + +static void L3_change_sign(float *grbuf) +{ + int b, i; + for (b = 0, grbuf += 18; b < 32; b += 2, grbuf += 36) + for (i = 1; i < 18; i += 2) + grbuf[i] = -grbuf[i]; +} + +static void L3_imdct_gr(float *grbuf, float *overlap, unsigned block_type, unsigned n_long_bands) +{ + static const float g_mdct_window[2][18] = { + { 0.99904822f,0.99144486f,0.97629601f,0.95371695f,0.92387953f,0.88701083f,0.84339145f,0.79335334f,0.73727734f,0.04361938f,0.13052619f,0.21643961f,0.30070580f,0.38268343f,0.46174861f,0.53729961f,0.60876143f,0.67559021f }, + { 1,1,1,1,1,1,0.99144486f,0.92387953f,0.79335334f,0,0,0,0,0,0,0.13052619f,0.38268343f,0.60876143f } + }; + if (n_long_bands) + { + L3_imdct36(grbuf, overlap, g_mdct_window[0], n_long_bands); + grbuf += 18*n_long_bands; + overlap += 9*n_long_bands; + } + if (block_type == SHORT_BLOCK_TYPE) + L3_imdct_short(grbuf, overlap, 32 - n_long_bands); + else + L3_imdct36(grbuf, overlap, g_mdct_window[block_type == STOP_BLOCK_TYPE], 32 - n_long_bands); +} + +static void L3_save_reservoir(mp3dec_t *h, mp3dec_scratch_t *s) +{ + int pos = (s->bs.pos + 7)/8u; + int remains = s->bs.limit/8u - pos; + if (remains > MAX_BITRESERVOIR_BYTES) + { + pos += remains - MAX_BITRESERVOIR_BYTES; + remains = MAX_BITRESERVOIR_BYTES; + } + if (remains > 0) + { + memmove(h->reserv_buf, s->maindata + pos, remains); + } + h->reserv = remains; +} + +static int L3_restore_reservoir(mp3dec_t *h, bs_t *bs, mp3dec_scratch_t *s, int main_data_begin) +{ + int frame_bytes = (bs->limit - bs->pos)/8; + int bytes_have = MINIMP3_MIN(h->reserv, main_data_begin); + memcpy(s->maindata, h->reserv_buf + MINIMP3_MAX(0, h->reserv - main_data_begin), MINIMP3_MIN(h->reserv, main_data_begin)); + memcpy(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes); + bs_init(&s->bs, s->maindata, bytes_have + frame_bytes); + return h->reserv >= main_data_begin; +} + +static void L3_decode(mp3dec_t *h, mp3dec_scratch_t *s, L3_gr_info_t *gr_info, int nch) +{ + int ch; + + for (ch = 0; ch < nch; ch++) + { + int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length; + L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch); + L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit); + } + + if (HDR_TEST_I_STEREO(h->header)) + { + L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header); + } else if (HDR_IS_MS_STEREO(h->header)) + { + L3_midside_stereo(s->grbuf[0], 576); + } + + for (ch = 0; ch < nch; ch++, gr_info++) + { + int aa_bands = 31; + int n_long_bands = (gr_info->mixed_block_flag ? 2 : 0) << (int)(HDR_GET_MY_SAMPLE_RATE(h->header) == 2); + + if (gr_info->n_short_sfb) + { + aa_bands = n_long_bands - 1; + L3_reorder(s->grbuf[ch] + n_long_bands*18, s->syn[0], gr_info->sfbtab + gr_info->n_long_sfb); + } + + L3_antialias(s->grbuf[ch], aa_bands); + L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands); + L3_change_sign(s->grbuf[ch]); + } +} + +static void mp3d_DCT_II(float *grbuf, int n) +{ + static const float g_sec[24] = { + 10.19000816f,0.50060302f,0.50241929f,3.40760851f,0.50547093f,0.52249861f,2.05778098f,0.51544732f,0.56694406f,1.48416460f,0.53104258f,0.64682180f,1.16943991f,0.55310392f,0.78815460f,0.97256821f,0.58293498f,1.06067765f,0.83934963f,0.62250412f,1.72244716f,0.74453628f,0.67480832f,5.10114861f + }; + int i, k = 0; +#if HAVE_SIMD + if (have_simd()) for (; k < n; k += 4) + { + f4 t[4][8], *x; + float *y = grbuf + k; + + for (x = t[0], i = 0; i < 8; i++, x++) + { + f4 x0 = VLD(&y[i*18]); + f4 x1 = VLD(&y[(15 - i)*18]); + f4 x2 = VLD(&y[(16 + i)*18]); + f4 x3 = VLD(&y[(31 - i)*18]); + f4 t0 = VADD(x0, x3); + f4 t1 = VADD(x1, x2); + f4 t2 = VMUL_S(VSUB(x1, x2), g_sec[3*i + 0]); + f4 t3 = VMUL_S(VSUB(x0, x3), g_sec[3*i + 1]); + x[0] = VADD(t0, t1); + x[8] = VMUL_S(VSUB(t0, t1), g_sec[3*i + 2]); + x[16] = VADD(t3, t2); + x[24] = VMUL_S(VSUB(t3, t2), g_sec[3*i + 2]); + } + for (x = t[0], i = 0; i < 4; i++, x += 8) + { + f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt; + xt = VSUB(x0, x7); x0 = VADD(x0, x7); + x7 = VSUB(x1, x6); x1 = VADD(x1, x6); + x6 = VSUB(x2, x5); x2 = VADD(x2, x5); + x5 = VSUB(x3, x4); x3 = VADD(x3, x4); + x4 = VSUB(x0, x3); x0 = VADD(x0, x3); + x3 = VSUB(x1, x2); x1 = VADD(x1, x2); + x[0] = VADD(x0, x1); + x[4] = VMUL_S(VSUB(x0, x1), 0.70710677f); + x5 = VADD(x5, x6); + x6 = VMUL_S(VADD(x6, x7), 0.70710677f); + x7 = VADD(x7, xt); + x3 = VMUL_S(VADD(x3, x4), 0.70710677f); + x5 = VSUB(x5, VMUL_S(x7, 0.198912367f)); /* rotate by PI/8 */ + x7 = VADD(x7, VMUL_S(x5, 0.382683432f)); + x5 = VSUB(x5, VMUL_S(x7, 0.198912367f)); + x0 = VSUB(xt, x6); xt = VADD(xt, x6); + x[1] = VMUL_S(VADD(xt, x7), 0.50979561f); + x[2] = VMUL_S(VADD(x4, x3), 0.54119611f); + x[3] = VMUL_S(VSUB(x0, x5), 0.60134488f); + x[5] = VMUL_S(VADD(x0, x5), 0.89997619f); + x[6] = VMUL_S(VSUB(x4, x3), 1.30656302f); + x[7] = VMUL_S(VSUB(xt, x7), 2.56291556f); + } + + if (k > n - 3) + { +#if HAVE_SSE +#define VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v) +#else /* HAVE_SSE */ +#define VSAVE2(i, v) vst1_f32((float32_t *)&y[i*18], vget_low_f32(v)) +#endif /* HAVE_SSE */ + for (i = 0; i < 7; i++, y += 4*18) + { + f4 s = VADD(t[3][i], t[3][i + 1]); + VSAVE2(0, t[0][i]); + VSAVE2(1, VADD(t[2][i], s)); + VSAVE2(2, VADD(t[1][i], t[1][i + 1])); + VSAVE2(3, VADD(t[2][1 + i], s)); + } + VSAVE2(0, t[0][7]); + VSAVE2(1, VADD(t[2][7], t[3][7])); + VSAVE2(2, t[1][7]); + VSAVE2(3, t[3][7]); + } else + { +#define VSAVE4(i, v) VSTORE(&y[i*18], v) + for (i = 0; i < 7; i++, y += 4*18) + { + f4 s = VADD(t[3][i], t[3][i + 1]); + VSAVE4(0, t[0][i]); + VSAVE4(1, VADD(t[2][i], s)); + VSAVE4(2, VADD(t[1][i], t[1][i + 1])); + VSAVE4(3, VADD(t[2][1 + i], s)); + } + VSAVE4(0, t[0][7]); + VSAVE4(1, VADD(t[2][7], t[3][7])); + VSAVE4(2, t[1][7]); + VSAVE4(3, t[3][7]); + } + } else +#endif /* HAVE_SIMD */ +#ifdef MINIMP3_ONLY_SIMD + {} +#else /* MINIMP3_ONLY_SIMD */ + for (; k < n; k++) + { + float t[4][8], *x, *y = grbuf + k; + + for (x = t[0], i = 0; i < 8; i++, x++) + { + float x0 = y[i*18]; + float x1 = y[(15 - i)*18]; + float x2 = y[(16 + i)*18]; + float x3 = y[(31 - i)*18]; + float t0 = x0 + x3; + float t1 = x1 + x2; + float t2 = (x1 - x2)*g_sec[3*i + 0]; + float t3 = (x0 - x3)*g_sec[3*i + 1]; + x[0] = t0 + t1; + x[8] = (t0 - t1)*g_sec[3*i + 2]; + x[16] = t3 + t2; + x[24] = (t3 - t2)*g_sec[3*i + 2]; + } + for (x = t[0], i = 0; i < 4; i++, x += 8) + { + float x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt; + xt = x0 - x7; x0 += x7; + x7 = x1 - x6; x1 += x6; + x6 = x2 - x5; x2 += x5; + x5 = x3 - x4; x3 += x4; + x4 = x0 - x3; x0 += x3; + x3 = x1 - x2; x1 += x2; + x[0] = x0 + x1; + x[4] = (x0 - x1)*0.70710677f; + x5 = x5 + x6; + x6 = (x6 + x7)*0.70710677f; + x7 = x7 + xt; + x3 = (x3 + x4)*0.70710677f; + x5 -= x7*0.198912367f; /* rotate by PI/8 */ + x7 += x5*0.382683432f; + x5 -= x7*0.198912367f; + x0 = xt - x6; xt += x6; + x[1] = (xt + x7)*0.50979561f; + x[2] = (x4 + x3)*0.54119611f; + x[3] = (x0 - x5)*0.60134488f; + x[5] = (x0 + x5)*0.89997619f; + x[6] = (x4 - x3)*1.30656302f; + x[7] = (xt - x7)*2.56291556f; + + } + for (i = 0; i < 7; i++, y += 4*18) + { + y[0*18] = t[0][i]; + y[1*18] = t[2][i] + t[3][i] + t[3][i + 1]; + y[2*18] = t[1][i] + t[1][i + 1]; + y[3*18] = t[2][i + 1] + t[3][i] + t[3][i + 1]; + } + y[0*18] = t[0][7]; + y[1*18] = t[2][7] + t[3][7]; + y[2*18] = t[1][7]; + y[3*18] = t[3][7]; + } +#endif /* MINIMP3_ONLY_SIMD */ +} + +#ifndef MINIMP3_FLOAT_OUTPUT +static int16_t mp3d_scale_pcm(float sample) +{ + if (sample >= 32766.5) return (int16_t) 32767; + if (sample <= -32767.5) return (int16_t)-32768; + int16_t s = (int16_t)(sample + .5f); + s -= (s < 0); /* away from zero, to be compliant */ + return s; +} +#else /* MINIMP3_FLOAT_OUTPUT */ +static float mp3d_scale_pcm(float sample) +{ + return sample*(1.f/32768.f); +} +#endif /* MINIMP3_FLOAT_OUTPUT */ + +static void mp3d_synth_pair(mp3d_sample_t *pcm, int nch, const float *z) +{ + float a; + a = (z[14*64] - z[ 0]) * 29; + a += (z[ 1*64] + z[13*64]) * 213; + a += (z[12*64] - z[ 2*64]) * 459; + a += (z[ 3*64] + z[11*64]) * 2037; + a += (z[10*64] - z[ 4*64]) * 5153; + a += (z[ 5*64] + z[ 9*64]) * 6574; + a += (z[ 8*64] - z[ 6*64]) * 37489; + a += z[ 7*64] * 75038; + pcm[0] = mp3d_scale_pcm(a); + + z += 2; + a = z[14*64] * 104; + a += z[12*64] * 1567; + a += z[10*64] * 9727; + a += z[ 8*64] * 64019; + a += z[ 6*64] * -9975; + a += z[ 4*64] * -45; + a += z[ 2*64] * 146; + a += z[ 0*64] * -5; + pcm[16*nch] = mp3d_scale_pcm(a); +} + +static void mp3d_synth(float *xl, mp3d_sample_t *dstl, int nch, float *lins) +{ + int i; + float *xr = xl + 576*(nch - 1); + mp3d_sample_t *dstr = dstl + (nch - 1); + + static const float g_win[] = { + -1,26,-31,208,218,401,-519,2063,2000,4788,-5517,7134,5959,35640,-39336,74992, + -1,24,-35,202,222,347,-581,2080,1952,4425,-5879,7640,5288,33791,-41176,74856, + -1,21,-38,196,225,294,-645,2087,1893,4063,-6237,8092,4561,31947,-43006,74630, + -1,19,-41,190,227,244,-711,2085,1822,3705,-6589,8492,3776,30112,-44821,74313, + -1,17,-45,183,228,197,-779,2075,1739,3351,-6935,8840,2935,28289,-46617,73908, + -1,16,-49,176,228,153,-848,2057,1644,3004,-7271,9139,2037,26482,-48390,73415, + -2,14,-53,169,227,111,-919,2032,1535,2663,-7597,9389,1082,24694,-50137,72835, + -2,13,-58,161,224,72,-991,2001,1414,2330,-7910,9592,70,22929,-51853,72169, + -2,11,-63,154,221,36,-1064,1962,1280,2006,-8209,9750,-998,21189,-53534,71420, + -2,10,-68,147,215,2,-1137,1919,1131,1692,-8491,9863,-2122,19478,-55178,70590, + -3,9,-73,139,208,-29,-1210,1870,970,1388,-8755,9935,-3300,17799,-56778,69679, + -3,8,-79,132,200,-57,-1283,1817,794,1095,-8998,9966,-4533,16155,-58333,68692, + -4,7,-85,125,189,-83,-1356,1759,605,814,-9219,9959,-5818,14548,-59838,67629, + -4,7,-91,117,177,-106,-1428,1698,402,545,-9416,9916,-7154,12980,-61289,66494, + -5,6,-97,111,163,-127,-1498,1634,185,288,-9585,9838,-8540,11455,-62684,65290 + }; + float *zlin = lins + 15*64; + const float *w = g_win; + + zlin[4*15] = xl[18*16]; + zlin[4*15 + 1] = xr[18*16]; + zlin[4*15 + 2] = xl[0]; + zlin[4*15 + 3] = xr[0]; + + zlin[4*31] = xl[1 + 18*16]; + zlin[4*31 + 1] = xr[1 + 18*16]; + zlin[4*31 + 2] = xl[1]; + zlin[4*31 + 3] = xr[1]; + + mp3d_synth_pair(dstr, nch, lins + 4*15 + 1); + mp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1); + mp3d_synth_pair(dstl, nch, lins + 4*15); + mp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64); + +#if HAVE_SIMD + if (have_simd()) for (i = 14; i >= 0; i--) + { +#define VLOAD(k) f4 w0 = VSET(*w++); f4 w1 = VSET(*w++); f4 vz = VLD(&zlin[4*i - 64*k]); f4 vy = VLD(&zlin[4*i - 64*(15 - k)]); +#define V0(k) { VLOAD(k) b = VADD(VMUL(vz, w1), VMUL(vy, w0)) ; a = VSUB(VMUL(vz, w0), VMUL(vy, w1)); } +#define V1(k) { VLOAD(k) b = VADD(b, VADD(VMUL(vz, w1), VMUL(vy, w0))); a = VADD(a, VSUB(VMUL(vz, w0), VMUL(vy, w1))); } +#define V2(k) { VLOAD(k) b = VADD(b, VADD(VMUL(vz, w1), VMUL(vy, w0))); a = VADD(a, VSUB(VMUL(vy, w1), VMUL(vz, w0))); } + f4 a, b; + zlin[4*i] = xl[18*(31 - i)]; + zlin[4*i + 1] = xr[18*(31 - i)]; + zlin[4*i + 2] = xl[1 + 18*(31 - i)]; + zlin[4*i + 3] = xr[1 + 18*(31 - i)]; + zlin[4*i + 64] = xl[1 + 18*(1 + i)]; + zlin[4*i + 64 + 1] = xr[1 + 18*(1 + i)]; + zlin[4*i - 64 + 2] = xl[18*(1 + i)]; + zlin[4*i - 64 + 3] = xr[18*(1 + i)]; + + V0(0) V2(1) V1(2) V2(3) V1(4) V2(5) V1(6) V2(7) + + { +#ifndef MINIMP3_FLOAT_OUTPUT +#if HAVE_SSE + static const f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f }; + static const f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f }; + __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)), + _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min))); + dstr[(15 - i)*nch] = _mm_extract_epi16(pcm8, 1); + dstr[(17 + i)*nch] = _mm_extract_epi16(pcm8, 5); + dstl[(15 - i)*nch] = _mm_extract_epi16(pcm8, 0); + dstl[(17 + i)*nch] = _mm_extract_epi16(pcm8, 4); + dstr[(47 - i)*nch] = _mm_extract_epi16(pcm8, 3); + dstr[(49 + i)*nch] = _mm_extract_epi16(pcm8, 7); + dstl[(47 - i)*nch] = _mm_extract_epi16(pcm8, 2); + dstl[(49 + i)*nch] = _mm_extract_epi16(pcm8, 6); +#else /* HAVE_SSE */ + int16x4_t pcma, pcmb; + a = VADD(a, VSET(0.5f)); + b = VADD(b, VSET(0.5f)); + pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, VSET(0))))); + pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, VSET(0))))); + vst1_lane_s16(dstr + (15 - i)*nch, pcma, 1); + vst1_lane_s16(dstr + (17 + i)*nch, pcmb, 1); + vst1_lane_s16(dstl + (15 - i)*nch, pcma, 0); + vst1_lane_s16(dstl + (17 + i)*nch, pcmb, 0); + vst1_lane_s16(dstr + (47 - i)*nch, pcma, 3); + vst1_lane_s16(dstr + (49 + i)*nch, pcmb, 3); + vst1_lane_s16(dstl + (47 - i)*nch, pcma, 2); + vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2); +#endif /* HAVE_SSE */ + +#else /* MINIMP3_FLOAT_OUTPUT */ + + static const f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f }; + a = VMUL(a, g_scale); + b = VMUL(b, g_scale); +#if HAVE_SSE + _mm_store_ss(dstr + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1))); + _mm_store_ss(dstr + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(1, 1, 1, 1))); + _mm_store_ss(dstl + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0))); + _mm_store_ss(dstl + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 0, 0, 0))); + _mm_store_ss(dstr + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3))); + _mm_store_ss(dstr + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 3, 3, 3))); + _mm_store_ss(dstl + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + _mm_store_ss(dstl + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 2, 2, 2))); +#else /* HAVE_SSE */ + vst1q_lane_f32(dstr + (15 - i)*nch, a, 1); + vst1q_lane_f32(dstr + (17 + i)*nch, b, 1); + vst1q_lane_f32(dstl + (15 - i)*nch, a, 0); + vst1q_lane_f32(dstl + (17 + i)*nch, b, 0); + vst1q_lane_f32(dstr + (47 - i)*nch, a, 3); + vst1q_lane_f32(dstr + (49 + i)*nch, b, 3); + vst1q_lane_f32(dstl + (47 - i)*nch, a, 2); + vst1q_lane_f32(dstl + (49 + i)*nch, b, 2); +#endif /* HAVE_SSE */ +#endif /* MINIMP3_FLOAT_OUTPUT */ + } + } else +#endif /* HAVE_SIMD */ +#ifdef MINIMP3_ONLY_SIMD + {} +#else /* MINIMP3_ONLY_SIMD */ + for (i = 14; i >= 0; i--) + { +#define LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64]; +#define S0(k) { int j; LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1; } +#define S1(k) { int j; LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; } +#define S2(k) { int j; LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; } + float a[4], b[4]; + + zlin[4*i] = xl[18*(31 - i)]; + zlin[4*i + 1] = xr[18*(31 - i)]; + zlin[4*i + 2] = xl[1 + 18*(31 - i)]; + zlin[4*i + 3] = xr[1 + 18*(31 - i)]; + zlin[4*(i + 16)] = xl[1 + 18*(1 + i)]; + zlin[4*(i + 16) + 1] = xr[1 + 18*(1 + i)]; + zlin[4*(i - 16) + 2] = xl[18*(1 + i)]; + zlin[4*(i - 16) + 3] = xr[18*(1 + i)]; + + S0(0) S2(1) S1(2) S2(3) S1(4) S2(5) S1(6) S2(7) + + dstr[(15 - i)*nch] = mp3d_scale_pcm(a[1]); + dstr[(17 + i)*nch] = mp3d_scale_pcm(b[1]); + dstl[(15 - i)*nch] = mp3d_scale_pcm(a[0]); + dstl[(17 + i)*nch] = mp3d_scale_pcm(b[0]); + dstr[(47 - i)*nch] = mp3d_scale_pcm(a[3]); + dstr[(49 + i)*nch] = mp3d_scale_pcm(b[3]); + dstl[(47 - i)*nch] = mp3d_scale_pcm(a[2]); + dstl[(49 + i)*nch] = mp3d_scale_pcm(b[2]); + } +#endif /* MINIMP3_ONLY_SIMD */ +} + +static void mp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, mp3d_sample_t *pcm, float *lins) +{ + int i; + for (i = 0; i < nch; i++) + { + mp3d_DCT_II(grbuf + 576*i, nbands); + } + + memcpy(lins, qmf_state, sizeof(float)*15*64); + + for (i = 0; i < nbands; i += 2) + { + mp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64); + } +#ifndef MINIMP3_NONSTANDARD_BUT_LOGICAL + if (nch == 1) + { + for (i = 0; i < 15*64; i += 2) + { + qmf_state[i] = lins[nbands*64 + i]; + } + } else +#endif /* MINIMP3_NONSTANDARD_BUT_LOGICAL */ + { + memcpy(qmf_state, lins + nbands*64, sizeof(float)*15*64); + } +} + +static int mp3d_match_frame(const uint8_t *hdr, int mp3_bytes, int frame_bytes) +{ + int i, nmatch; + for (i = 0, nmatch = 0; nmatch < MAX_FRAME_SYNC_MATCHES; nmatch++) + { + i += hdr_frame_bytes(hdr + i, frame_bytes) + hdr_padding(hdr + i); + if (i + HDR_SIZE > mp3_bytes) + return nmatch > 0; + if (!hdr_compare(hdr, hdr + i)) + return 0; + } + return 1; +} + +static int mp3d_find_frame(const uint8_t *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes) +{ + int i, k; + for (i = 0; i < mp3_bytes - HDR_SIZE; i++, mp3++) + { + if (hdr_valid(mp3)) + { + int frame_bytes = hdr_frame_bytes(mp3, *free_format_bytes); + int frame_and_padding = frame_bytes + hdr_padding(mp3); + + for (k = HDR_SIZE; !frame_bytes && k < MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - HDR_SIZE; k++) + { + if (hdr_compare(mp3, mp3 + k)) + { + int fb = k - hdr_padding(mp3); + int nextfb = fb + hdr_padding(mp3 + k); + if (i + k + nextfb + HDR_SIZE > mp3_bytes || !hdr_compare(mp3, mp3 + k + nextfb)) + continue; + frame_and_padding = k; + frame_bytes = fb; + *free_format_bytes = fb; + } + } + if ((frame_bytes && i + frame_and_padding <= mp3_bytes && + mp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) || + (!i && frame_and_padding == mp3_bytes)) + { + *ptr_frame_bytes = frame_and_padding; + return i; + } + *free_format_bytes = 0; + } + } + *ptr_frame_bytes = 0; + return i; +} + +void mp3dec_init(mp3dec_t *dec) +{ + dec->header[0] = 0; +} + +int mp3dec_decode_frame(mp3dec_t *dec, const uint8_t *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info) +{ + int i = 0, igr, frame_size = 0, success = 1; + const uint8_t *hdr; + bs_t bs_frame[1]; + mp3dec_scratch_t scratch; + + if (mp3_bytes > 4 && dec->header[0] == 0xff && hdr_compare(dec->header, mp3)) + { + frame_size = hdr_frame_bytes(mp3, dec->free_format_bytes) + hdr_padding(mp3); + if (frame_size != mp3_bytes && (frame_size + HDR_SIZE > mp3_bytes || !hdr_compare(mp3, mp3 + frame_size))) + { + frame_size = 0; + } + } + if (!frame_size) + { + memset(dec, 0, sizeof(mp3dec_t)); + i = mp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size); + if (!frame_size || i + frame_size > mp3_bytes) + { + info->frame_bytes = i; + return 0; + } + } + + hdr = mp3 + i; + memcpy(dec->header, hdr, HDR_SIZE); + info->frame_bytes = i + frame_size; + info->channels = HDR_IS_MONO(hdr) ? 1 : 2; + info->hz = hdr_sample_rate_hz(hdr); + info->layer = 4 - HDR_GET_LAYER(hdr); + info->bitrate_kbps = hdr_bitrate_kbps(hdr); + + if (!pcm) + { + return hdr_frame_samples(hdr); + } + + bs_init(bs_frame, hdr + HDR_SIZE, frame_size - HDR_SIZE); + if (HDR_IS_CRC(hdr)) + { + get_bits(bs_frame, 16); + } + + if (info->layer == 3) + { + int main_data_begin = L3_read_side_info(bs_frame, scratch.gr_info, hdr); + if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit) + { + mp3dec_init(dec); + return 0; + } + success = L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin); + if (success) + { + for (igr = 0; igr < (HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm += 576*info->channels) + { + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels); + mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, pcm, scratch.syn[0]); + } + } + L3_save_reservoir(dec, &scratch); + } else + { +#ifdef MINIMP3_ONLY_MP3 + return 0; +#else /* MINIMP3_ONLY_MP3 */ + L12_scale_info sci[1]; + L12_read_scale_info(hdr, bs_frame, sci); + + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + for (i = 0, igr = 0; igr < 3; igr++) + { + if (12 == (i += L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) + { + i = 0; + L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]); + mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, pcm, scratch.syn[0]); + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + pcm += 384*info->channels; + } + if (bs_frame->pos > bs_frame->limit) + { + mp3dec_init(dec); + return 0; + } + } +#endif /* MINIMP3_ONLY_MP3 */ + } + return success*hdr_frame_samples(dec->header); +} + +#ifdef MINIMP3_FLOAT_OUTPUT +void mp3dec_f32_to_s16(const float *in, int16_t *out, int num_samples) +{ + if(num_samples > 0) + { + int i = 0; +#if HAVE_SIMD + int aligned_count = num_samples & ~7; + + for(;i < aligned_count;i+=8) + { + static const f4 g_scale = { 32768.0f, 32768.0f, 32768.0f, 32768.0f }; + f4 a = VMUL(VLD(&in[i ]), g_scale); + f4 b = VMUL(VLD(&in[i+4]), g_scale); +#if HAVE_SSE + static const f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f }; + static const f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f }; + __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)), + _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min))); + out[i ] = _mm_extract_epi16(pcm8, 0); + out[i+1] = _mm_extract_epi16(pcm8, 1); + out[i+2] = _mm_extract_epi16(pcm8, 2); + out[i+3] = _mm_extract_epi16(pcm8, 3); + out[i+4] = _mm_extract_epi16(pcm8, 4); + out[i+5] = _mm_extract_epi16(pcm8, 5); + out[i+6] = _mm_extract_epi16(pcm8, 6); + out[i+7] = _mm_extract_epi16(pcm8, 7); +#else /* HAVE_SSE */ + int16x4_t pcma, pcmb; + a = VADD(a, VSET(0.5f)); + b = VADD(b, VSET(0.5f)); + pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, VSET(0))))); + pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, VSET(0))))); + vst1_lane_s16(out+i , pcma, 0); + vst1_lane_s16(out+i+1, pcma, 1); + vst1_lane_s16(out+i+2, pcma, 2); + vst1_lane_s16(out+i+3, pcma, 3); + vst1_lane_s16(out+i+4, pcmb, 0); + vst1_lane_s16(out+i+5, pcmb, 1); + vst1_lane_s16(out+i+6, pcmb, 2); + vst1_lane_s16(out+i+7, pcmb, 3); +#endif /* HAVE_SSE */ + } +#endif /* HAVE_SIMD */ + for(; i < num_samples; i++) + { + float sample = in[i] * 32768.0f; + if (sample >= 32766.5) + out[i] = (int16_t) 32767; + else if (sample <= -32767.5) + out[i] = (int16_t)-32768; + else + { + int16_t s = (int16_t)(sample + .5f); + s -= (s < 0); /* away from zero, to be compliant */ + out[i] = s; + } + } + } +} +#endif /* MINIMP3_FLOAT_OUTPUT */ +#endif /* MINIMP3_IMPLEMENTATION && !_MINIMP3_IMPLEMENTATION_GUARD */ diff --git a/third_party/minimp3/minimp3_ex.h b/third_party/minimp3/minimp3_ex.h new file mode 100644 index 0000000..773ee67 --- /dev/null +++ b/third_party/minimp3/minimp3_ex.h @@ -0,0 +1,386 @@ +#ifndef MINIMP3_EXT_H +#define MINIMP3_EXT_H +/* + https://github.com/lieff/minimp3 + To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. + This software is distributed without any warranty. + See . +*/ +#include "minimp3.h" + +#define MP3D_SEEK_TO_BYTE 0 +#define MP3D_SEEK_TO_SAMPLE 1 +#define MP3D_SEEK_TO_SAMPLE_INDEXED 2 + +typedef struct +{ + mp3d_sample_t *buffer; + size_t samples; /* channels included, byte size = samples*sizeof(int16_t) */ + int channels, hz, layer, avg_bitrate_kbps; +} mp3dec_file_info_t; + +typedef struct +{ + const uint8_t *buffer; + size_t size; +} mp3dec_map_info_t; + +typedef struct +{ + mp3dec_t mp3d; + mp3dec_map_info_t file; + int seek_method; +#ifndef MINIMP3_NO_STDIO + int is_file; +#endif +} mp3dec_ex_t; + +typedef int (*MP3D_ITERATE_CB)(void *user_data, const uint8_t *frame, int frame_size, size_t offset, mp3dec_frame_info_t *info); +typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, size_t offset, mp3dec_frame_info_t *info); + +#ifdef __cplusplus +extern "C" { +#endif + +/* decode whole buffer block */ +void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data); +/* iterate through frames with optional decoding */ +void mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data); +/* decoder with seeking capability */ +int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int seek_method); +void mp3dec_ex_close(mp3dec_ex_t *dec); +void mp3dec_ex_seek(mp3dec_ex_t *dec, size_t position); +int mp3dec_ex_read(mp3dec_ex_t *dec, int16_t *buf, int samples); +#ifndef MINIMP3_NO_STDIO +/* stdio versions with file pre-load */ +int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data); +int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data); +int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method); +#endif + +#ifdef __cplusplus +} +#endif +#endif /*MINIMP3_EXT_H*/ + +#ifdef MINIMP3_IMPLEMENTATION + +static size_t mp3dec_skip_id3v2(const uint8_t *buf, size_t buf_size) +{ + if (buf_size > 10 && !strncmp((char *)buf, "ID3", 3)) + { + return (((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | + ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f)) + 10; + } + return 0; +} + +void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data) +{ + size_t orig_buf_size = buf_size; + mp3d_sample_t pcm[MINIMP3_MAX_SAMPLES_PER_FRAME]; + mp3dec_frame_info_t frame_info; + memset(info, 0, sizeof(*info)); + memset(&frame_info, 0, sizeof(frame_info)); + /* skip id3v2 */ + size_t id3v2size = mp3dec_skip_id3v2(buf, buf_size); + if (id3v2size > buf_size) + return; + buf += id3v2size; + buf_size -= id3v2size; + /* try to make allocation size assumption by first frame */ + mp3dec_init(dec); + int samples; + do + { + samples = mp3dec_decode_frame(dec, buf, buf_size, pcm, &frame_info); + buf += frame_info.frame_bytes; + buf_size -= frame_info.frame_bytes; + if (samples) + break; + } while (frame_info.frame_bytes); + if (!samples) + return; + samples *= frame_info.channels; + size_t allocated = (buf_size/frame_info.frame_bytes)*samples*sizeof(mp3d_sample_t) + MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t); + info->buffer = (mp3d_sample_t*)malloc(allocated); + if (!info->buffer) + return; + info->samples = samples; + memcpy(info->buffer, pcm, info->samples*sizeof(mp3d_sample_t)); + /* save info */ + info->channels = frame_info.channels; + info->hz = frame_info.hz; + info->layer = frame_info.layer; + size_t avg_bitrate_kbps = frame_info.bitrate_kbps; + size_t frames = 1; + /* decode rest frames */ + int frame_bytes; + do + { + if ((allocated - info->samples*sizeof(mp3d_sample_t)) < MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t)) + { + allocated *= 2; + info->buffer = (mp3d_sample_t*)realloc(info->buffer, allocated); + } + samples = mp3dec_decode_frame(dec, buf, buf_size, info->buffer + info->samples, &frame_info); + frame_bytes = frame_info.frame_bytes; + buf += frame_bytes; + buf_size -= frame_bytes; + if (samples) + { + if (info->hz != frame_info.hz || info->layer != frame_info.layer) + break; + if (info->channels && info->channels != frame_info.channels) +#ifdef MINIMP3_ALLOW_MONO_STEREO_TRANSITION + info->channels = 0; /* mark file with mono-stereo transition */ +#else + break; +#endif + info->samples += samples*frame_info.channels; + avg_bitrate_kbps += frame_info.bitrate_kbps; + frames++; + if (progress_cb) + progress_cb(user_data, orig_buf_size, orig_buf_size - buf_size, &frame_info); + } + } while (frame_bytes); + /* reallocate to normal buffer size */ + if (allocated != info->samples*sizeof(mp3d_sample_t)) + info->buffer = (mp3d_sample_t*)realloc(info->buffer, info->samples*sizeof(mp3d_sample_t)); + info->avg_bitrate_kbps = avg_bitrate_kbps/frames; +} + +void mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data) +{ + if (!callback) + return; + mp3dec_frame_info_t frame_info; + memset(&frame_info, 0, sizeof(frame_info)); + /* skip id3v2 */ + size_t id3v2size = mp3dec_skip_id3v2(buf, buf_size); + if (id3v2size > buf_size) + return; + const uint8_t *orig_buf = buf; + buf += id3v2size; + buf_size -= id3v2size; + do + { + int free_format_bytes = 0, frame_size = 0; + int i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size); + buf += i; + buf_size -= i; + if (i && !frame_size) + continue; + if (!frame_size) + break; + const uint8_t *hdr = buf; + frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2; + frame_info.hz = hdr_sample_rate_hz(hdr); + frame_info.layer = 4 - HDR_GET_LAYER(hdr); + frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr); + frame_info.frame_bytes = frame_size; + + if (callback(user_data, hdr, frame_size, hdr - orig_buf, &frame_info)) + break; + buf += frame_size; + buf_size -= frame_size; + } while (1); +} + +int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int seek_method) +{ + memset(dec, 0, sizeof(*dec)); + dec->file.buffer = buf; + dec->file.size = buf_size; + dec->seek_method = seek_method; + mp3dec_init(&dec->mp3d); + return 0; +} + +/*void mp3dec_ex_seek(mp3dec_ex_t *dec, size_t position) +{ +} + +int mp3dec_ex_read(mp3dec_ex_t *dec, int16_t *buf, int samples) +{ + return 0; +}*/ + +#ifndef MINIMP3_NO_STDIO + +#if defined(__linux__) || defined(__FreeBSD__) +#include +#include +#include +#include +#include +#include +#if !defined(MAP_POPULATE) && defined(__linux__) +#define MAP_POPULATE 0x08000 +#elif !defined(MAP_POPULATE) +#define MAP_POPULATE 0 +#endif + +static void mp3dec_close_file(mp3dec_map_info_t *map_info) +{ + if (map_info->buffer && MAP_FAILED != map_info->buffer) + munmap((void *)map_info->buffer, map_info->size); + map_info->buffer = 0; + map_info->size = 0; +} + +static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info) +{ + int file; + struct stat st; + memset(map_info, 0, sizeof(*map_info)); +retry_open: + file = open(file_name, O_RDONLY); + if (file < 0 && (errno == EAGAIN || errno == EINTR)) + goto retry_open; + if (file < 0 || fstat(file, &st) < 0) + { + close(file); + return -1; + } + + map_info->size = st.st_size; +retry_mmap: + map_info->buffer = (const uint8_t *)mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, file, 0); + if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR)) + goto retry_mmap; + close(file); + if (MAP_FAILED == map_info->buffer) + return -1; + return 0; +} +#elif defined(_WIN32) +#include + +static void mp3dec_close_file(mp3dec_map_info_t *map_info) +{ + if (map_info->buffer) + UnmapViewOfFile(map_info->buffer); + map_info->buffer = 0; + map_info->size = 0; +} + +static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info) +{ + memset(map_info, 0, sizeof(*map_info)); + + HANDLE file = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if (INVALID_HANDLE_VALUE == file) + return -1; + LARGE_INTEGER s; + s.LowPart = GetFileSize(file, (DWORD*)&s.HighPart); + if (s.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) + goto error; + map_info->size = s.QuadPart; + + HANDLE mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL); + if (!mapping) + goto error; + map_info->buffer = (const uint8_t *) MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, s.QuadPart); + CloseHandle(mapping); + if (!map_info->buffer) + goto error; + + CloseHandle(file); + return 0; +error: + mp3dec_close_file(map_info); + CloseHandle(file); + return -1; +} +#else +#include + +static void mp3dec_close_file(mp3dec_map_info_t *map_info) +{ + if (map_info->buffer) + free((void *)map_info->buffer); + map_info->buffer = 0; + map_info->size = 0; +} + +static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info) +{ + memset(map_info, 0, sizeof(*map_info)); + FILE *file = fopen(file_name, "rb"); + if (!file) + return -1; + long size = -1; + if (fseek(file, 0, SEEK_END)) + goto error; + size = ftell(file); + if (size < 0) + goto error; + map_info->size = (size_t)size; + if (fseek(file, 0, SEEK_SET)) + goto error; + map_info->buffer = (uint8_t *)malloc(map_info->size); + if (!map_info->buffer) + goto error; + if (fread((void *)map_info->buffer, 1, map_info->size, file) != map_info->size) + goto error; + fclose(file); + return 0; +error: + mp3dec_close_file(map_info); + fclose(file); + return -1; +} +#endif + +int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data) +{ + int ret; + mp3dec_map_info_t map_info; + if ((ret = mp3dec_open_file(file_name, &map_info))) + return ret; + mp3dec_load_buf(dec, map_info.buffer, map_info.size, info, progress_cb, user_data); + mp3dec_close_file(&map_info); + return 0; +} + +int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data) +{ + int ret; + mp3dec_map_info_t map_info; + if ((ret = mp3dec_open_file(file_name, &map_info))) + return ret; + mp3dec_iterate_buf(map_info.buffer, map_info.size, callback, user_data); + mp3dec_close_file(&map_info); + return 0; +} + +void mp3dec_ex_close(mp3dec_ex_t *dec) +{ + if (dec->is_file) + mp3dec_close_file(&dec->file); + else + free((void *)dec->file.buffer); + memset(dec, 0, sizeof(*dec)); +} + +int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method) +{ + int ret; + memset(dec, 0, sizeof(*dec)); + if ((ret = mp3dec_open_file(file_name, &dec->file))) + return ret; + dec->seek_method = seek_method; + dec->is_file = 1; + mp3dec_init(&dec->mp3d); + return 0; +} +#else +void mp3dec_ex_close(mp3dec_ex_t *dec) +{ + free(dec->file.buffer); + memset(dec, 0, sizeof(*dec)); +} +#endif + +#endif /*MINIMP3_IMPLEMENTATION*/