acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

aac_decoder.cpp (452995B)

      1 /*
      2  * aac_decoder.cpp
      3  * libhelix_HAACDECODER
      4  *
      5  *  Created on: 26.10.2018
      6  *  Updated on: 27.05.2022
      7  ************************************************************************************/
      8 
      9 #include "aac_decoder.h"
     10 
     11 const uint32_t SQRTHALF             = 0x5a82799a;    /* sqrt(0.5), format = Q31 */
     12 const uint32_t Q28_2                = 0x20000000;    /* Q28: 2.0 */
     13 const uint32_t Q28_15               = 0x30000000;    /* Q28: 1.5 */
     14 const uint8_t  NUM_ITER_IRN         = 5;
     15 const uint8_t  NUM_TERMS_RPI        = 5;
     16 const uint32_t LOG2_EXP_INV         = 0x58b90bfc;    /* 1/log2(e), Q31 */
     17 const uint8_t  SF_OFFSET            = 100;
     18 const uint8_t  AAC_PROFILE_LC       = 1;
     19 const uint8_t  NUM_TIME_SLOTS       = 16;
     20 const uint8_t  SAMPLES_PER_SLOT     = 2;             /* RATE in spec */
     21 const uint8_t  SYNCWORDH            = 0xff;          /* 12-bit syncword */
     22 const uint8_t  SYNCWORDL            = 0xf0;
     23 const uint8_t  NUM_SAMPLE_RATES     = 12;
     24 const uint8_t  NUM_DEF_CHAN_MAPS    = 8;
     25 const uint32_t NSAMPS_LONG          = 1024;
     26 const uint8_t  NSAMPS_SHORT         = 128;
     27 const uint8_t  NUM_SYN_ID_BITS      = 3;
     28 const uint8_t  NUM_INST_TAG_BITS    = 4;
     29 const uint8_t  NWINDOWS_LONG        = 1;
     30 const uint8_t  NWINDOWS_SHORT       = 8;
     31 const uint8_t  AAC_MAX_NCHANS       = 2;             /* set to default max number of channels  */
     32 const uint16_t AAC_MAX_NSAMPS       = 1024;
     33 const uint8_t  MAX_NCHANS_ELEM      = 2;             /* max number of channels in any single bitstream element */
     34 const uint8_t  MAX_NUM_PCE_ADIF     = 16;
     35 const uint8_t  ADIF_COPYID_SIZE     = 9;
     36 const uint8_t  HUFFTAB_SPEC_OFFSET  = 1;
     37 const uint8_t  FBITS_OUT_DQ_OFF     = 20 - 15;       /* (FBITS_OUT_DQ - SF_DQ_OFFSET)  */
     38 const uint8_t  GBITS_IN_DCT4        = 4;             /* min guard bits in for DCT4 */
     39 const uint8_t  FBITS_LOST_DCT4      = 1;             /* number of fraction bits lost (>> out) in DCT-IV */
     40 const uint8_t  FBITS_OUT_IMDCT      = 3;
     41 const uint8_t  NUM_IMDCT_SIZES      = 2;
     42 const uint8_t  FBITS_LPC_COEFS      = 20;
     43 const uint8_t  NUM_ITER_INVSQRT     = 4;
     44 const uint32_t X0_COEF_2            = 0xc0000000;    /* Q29: -2.0 */
     45 const uint32_t X0_OFF_2             = 0x60000000;    /* Q29:  3.0 */
     46 const uint32_t Q26_3                = 0x0c000000;    /* Q26:  3.0 */
     47 const uint8_t  EXT_SBR_DATA         = 0x0d;
     48 const uint8_t  EXT_SBR_DATA_CRC     = 0x0e;
     49 const uint8_t  NUM_SAMPLE_RATES_SBR = 9;             /* downsampled (single-rate) mode unsupported */
     50 const uint8_t  MAX_NUM_PATCHES      = 5;
     51 const uint8_t  MAX_QMF_BANDS        = 48;            /* max QMF subbands covered by SBR (4.6.18.3.6) */
     52 const uint8_t  MAX_NUM_ENV          = 5;
     53 const uint8_t  NUM_QMF_DELAY_BUFS   = 10;
     54 const uint8_t  FBITS_IN_QMFA        = 14;
     55 const uint8_t  NOISE_FLOOR_OFFSET   = 6;
     56 const uint8_t  FBITS_OUT_DQ_NOISE   = 24;            /* range of Q_orig = [2^-24, 2^6] */
     57 const uint8_t  FBITS_LOST_QMFA      = (1 + 2 + 3 + 2 + 1);
     58 const uint8_t  FBITS_OUT_QMFA       = (FBITS_IN_QMFA - FBITS_LOST_QMFA);
     59 const uint8_t  FBITS_IN_QMFS        = FBITS_OUT_QMFA;
     60 const uint8_t  FBITS_LOST_DCT4_64   = (2 + 3 + 2);   /* 2 in premul, 3 in FFT, 2 in postmul */
     61 const uint8_t  FBITS_OUT_QMFS       = (FBITS_IN_QMFS - FBITS_LOST_DCT4_64 + 6 - 1);
     62 const uint8_t  RND_VAL              = (1 << (FBITS_OUT_QMFS-1));
     63 const uint8_t  HF_ADJ               = 2;
     64 const uint8_t  HF_GEN               = 8;
     65 const uint8_t  FBITS_LPCOEFS        = 29;            /* Q29 for range of (-4, 4) */
     66 const uint32_t MAG_16               = (16 * (1 << (32 - (2*(32-FBITS_LPCOEFS)))));     /* i.e. 16 in Q26 format */
     67 const uint32_t RELAX_COEF           = 0x7ffff79c;    /* 1.0 / (1.0 + 1e-6), Q31 */
     68 const uint8_t  MAX_NUM_SMOOTH_COEFS = 5;
     69 const uint8_t  FBITS_OUT_DQ_ENV     = 29;            /* dequantized env scalefactors are Q(29 - envDataDequantScale) */
     70 const uint8_t  FBITS_GLIM_BOOST     = 24;
     71 const uint8_t  FBITS_QLIM_BOOST     = 14;
     72 const uint8_t  MIN_GBITS_IN_QMFS    = 2;
     73 const uint16_t nmdctTab[2]          = {128, 1024};
     74 const uint8_t  postSkip[2]          = {15, 1};
     75 const uint16_t nfftTab[2]           = {64, 512};
     76 const uint8_t  nfftlog2Tab[2]       = {6, 9};
     77 const uint8_t  cos4sin4tabOffset[2] = {0, 128};
     78 
     79 PSInfoBase_t        *m_PSInfoBase;
     80 AACDecInfo_t        *m_AACDecInfo;
     81 AACFrameInfo_t       m_AACFrameInfo;
     82 ADTSHeader_t         m_fhADTS;
     83 ADIFHeader_t         m_fhADIF;
     84 ProgConfigElement_t *m_pce[16];
     85 PulseInfo_t          m_pulseInfo[2]; // [MAX_NCHANS_ELEM]
     86 aac_BitStreamInfo_t  m_aac_BitStreamInfo;
     87 PSInfoSBR_t         *m_PSInfoSBR;
     88 
     89 //----------------------------------------------------------------------------------------------------------------------
     90 inline int MULSHIFT32(int x, int y){
     91     int z; z = (int64_t)x * (int64_t)y >> 32;
     92     return z;
     93 }
     94 inline int CLZ(int x){
     95 #ifdef __XTENSA__
     96     return __builtin_clz(x);
     97 #else
     98     int numZeros;
     99     if(!x) return 32; /* count leading zeros with binary search (function should be 17 ARM instructions total) */
    100     numZeros = 1;
    101     if (!((unsigned int)x >> 16))    { numZeros += 16; x <<= 16; }
    102     if (!((unsigned int)x >> 24))    { numZeros +=  8; x <<=  8; }
    103     if (!((unsigned int)x >> 28))    { numZeros +=  4; x <<=  4; }
    104     if (!((unsigned int)x >> 30))    { numZeros +=  2; x <<=  2; }
    105     numZeros -= ((unsigned int)x >> 31);
    106     return numZeros;
    107 #endif
    108 }
    109 inline int FASTABS(int x){
    110 #ifdef __XTENSA__ //fb
    111     return __builtin_abs(x);
    112 #else
    113     int sign;
    114     sign = x >> (sizeof(int) * 8 - 1);
    115     x ^= sign; x -= sign; return x;
    116 #endif
    117 }
    118 inline int64_t MADD64(int64_t sum64, int x, int y){
    119     sum64 += (int64_t)x * (int64_t)y;
    120     return sum64;
    121 }
    122 inline short CLIPTOSHORT(int x){
    123 #ifdef __XTENSA__ //fb
    124     asm ("clamps %0, %1, 15" : "=a" (x) : "a" (x) : );
    125     return x;
    126 #else
    127     int sign; /* clip to [-32768, 32767] */
    128     sign = x >> 31;
    129     if (sign != (x >> 15)) x = sign ^ ((1 << 15) - 1);
    130     return (short)x;
    131 #endif
    132 }
    133 inline int CLIP_2N(int y, int n){
    134 #ifdef __XTENSA__ //fb
    135     int x = 1 << n; \
    136     if (y < -x) y = -x; \
    137     x--; \
    138     if (y > x) y = x; \
    139     return y;
    140 #else
    141     int sign = y >> 31;
    142     if(sign != (y >> n))
    143         y = sign ^ ((1 << n) - 1);
    144     return y;
    145 #endif
    146 }
    147 inline int CLIP_2N_SHIFT30(int y, int n){
    148     int sign = y >> 31;
    149     if(sign != (y >> (30 - n)))
    150             y = sign ^ (0x3fffffff);
    151     else
    152         y = (y << n);
    153     return y;
    154 }
    155 //----------------------------------------------------------------------------------------------------------------------
    156 
    157 const uint32_t cos4sin4tab[128 + 1024] PROGMEM = {
    158 /* 128 - format = Q30 * 2^-7 */
    159 0xbf9bc731, 0xff9b783c, 0xbed5332c, 0xc002c697, 0xbe112251, 0xfe096c8d, 0xbd4f9c30, 0xc00f1c4a,
    160 0xbc90a83f, 0xfc77ae5e, 0xbbd44dd9, 0xc0254e27, 0xbb1a9443, 0xfae67ba2, 0xba6382a6, 0xc04558c0,
    161 0xb9af200f, 0xf9561237, 0xb8fd7373, 0xc06f3726, 0xb84e83ac, 0xf7c6afdc, 0xb7a25779, 0xc0a2e2e3,
    162 0xb6f8f57c, 0xf6389228, 0xb652643e, 0xc0e05401, 0xb5aeaa2a, 0xf4abf67e, 0xb50dcd90, 0xc1278104,
    163 0xb46fd4a4, 0xf3211a07, 0xb3d4c57c, 0xc1785ef4, 0xb33ca614, 0xf19839a6, 0xb2a77c49, 0xc1d2e158,
    164 0xb2154dda, 0xf01191f3, 0xb186206b, 0xc236fa3b, 0xb0f9f981, 0xee8d5f29, 0xb070de82, 0xc2a49a2e,
    165 0xafead4b9, 0xed0bdd25, 0xaf67e14f, 0xc31bb049, 0xaee80952, 0xeb8d475b, 0xae6b51ae, 0xc39c2a2f,
    166 0xadf1bf34, 0xea11d8c8, 0xad7b5692, 0xc425f410, 0xad081c5a, 0xe899cbf1, 0xac9814fd, 0xc4b8f8ad,
    167 0xac2b44cc, 0xe7255ad1, 0xabc1aff9, 0xc555215a, 0xab5b5a96, 0xe5b4bed8, 0xaaf84896, 0xc5fa5603,
    168 0xaa987dca, 0xe44830dd, 0xaa3bfde3, 0xc6a87d2d, 0xa9e2cc73, 0xe2dfe917, 0xa98cece9, 0xc75f7bfe,
    169 0xa93a6296, 0xe17c1f15, 0xa8eb30a7, 0xc81f363d, 0xa89f5a2b, 0xe01d09b4, 0xa856e20e, 0xc8e78e5b,
    170 0xa811cb1b, 0xdec2df18, 0xa7d017fc, 0xc9b86572, 0xa791cb39, 0xdd6dd4a2, 0xa756e73a, 0xca919b4e,
    171 0xa71f6e43, 0xdc1e1ee9, 0xa6eb6279, 0xcb730e70, 0xa6bac5dc, 0xdad3f1b1, 0xa68d9a4c, 0xcc5c9c14,
    172 0xa663e188, 0xd98f7fe6, 0xa63d9d2b, 0xcd4e2037, 0xa61aceaf, 0xd850fb8e, 0xa5fb776b, 0xce47759a,
    173 0xa5df9894, 0xd71895c9, 0xa5c7333e, 0xcf4875ca, 0xa5b2485a, 0xd5e67ec1, 0xa5a0d8b5, 0xd050f926,
    174 0xa592e4fd, 0xd4bae5ab, 0xa5886dba, 0xd160d6e5, 0xa5817354, 0xd395f8ba, 0xa57df60f, 0xd277e518,
    175 /* 1024 - format = Q30 * 2^-10 */
    176 0xbff3703e, 0xfff36f02, 0xbfda5824, 0xc0000b1a, 0xbfc149ed, 0xffc12b16, 0xbfa845a0, 0xc0003c74,
    177 0xbf8f4b3e, 0xff8ee750, 0xbf765acc, 0xc0009547, 0xbf5d744e, 0xff5ca3d0, 0xbf4497c8, 0xc0011594,
    178 0xbf2bc53d, 0xff2a60b4, 0xbf12fcb2, 0xc001bd5c, 0xbefa3e2a, 0xfef81e1d, 0xbee189a8, 0xc0028c9c,
    179 0xbec8df32, 0xfec5dc28, 0xbeb03eca, 0xc0038356, 0xbe97a875, 0xfe939af5, 0xbe7f1c36, 0xc004a188,
    180 0xbe669a10, 0xfe615aa3, 0xbe4e2209, 0xc005e731, 0xbe35b423, 0xfe2f1b50, 0xbe1d5062, 0xc0075452,
    181 0xbe04f6cb, 0xfdfcdd1d, 0xbdeca760, 0xc008e8e8, 0xbdd46225, 0xfdcaa027, 0xbdbc2720, 0xc00aa4f3,
    182 0xbda3f652, 0xfd98648d, 0xbd8bcfbf, 0xc00c8872, 0xbd73b36d, 0xfd662a70, 0xbd5ba15d, 0xc00e9364,
    183 0xbd439995, 0xfd33f1ed, 0xbd2b9c17, 0xc010c5c7, 0xbd13a8e7, 0xfd01bb24, 0xbcfbc00a, 0xc0131f9b,
    184 0xbce3e182, 0xfccf8634, 0xbccc0d53, 0xc015a0dd, 0xbcb44382, 0xfc9d533b, 0xbc9c8411, 0xc018498c,
    185 0xbc84cf05, 0xfc6b2259, 0xbc6d2461, 0xc01b19a7, 0xbc558428, 0xfc38f3ac, 0xbc3dee5f, 0xc01e112b,
    186 0xbc266309, 0xfc06c754, 0xbc0ee22a, 0xc0213018, 0xbbf76bc4, 0xfbd49d70, 0xbbdfffdd, 0xc024766a,
    187 0xbbc89e77, 0xfba2761e, 0xbbb14796, 0xc027e421, 0xbb99fb3e, 0xfb70517d, 0xbb82b972, 0xc02b7939,
    188 0xbb6b8235, 0xfb3e2fac, 0xbb54558d, 0xc02f35b1, 0xbb3d337b, 0xfb0c10cb, 0xbb261c04, 0xc0331986,
    189 0xbb0f0f2b, 0xfad9f4f8, 0xbaf80cf4, 0xc03724b6, 0xbae11561, 0xfaa7dc52, 0xbaca2878, 0xc03b573f,
    190 0xbab3463b, 0xfa75c6f8, 0xba9c6eae, 0xc03fb11d, 0xba85a1d4, 0xfa43b508, 0xba6edfb1, 0xc044324f,
    191 0xba582849, 0xfa11a6a3, 0xba417b9e, 0xc048dad1, 0xba2ad9b5, 0xf9df9be6, 0xba144291, 0xc04daaa1,
    192 0xb9fdb635, 0xf9ad94f0, 0xb9e734a4, 0xc052a1bb, 0xb9d0bde4, 0xf97b91e1, 0xb9ba51f6, 0xc057c01d,
    193 0xb9a3f0de, 0xf94992d7, 0xb98d9aa0, 0xc05d05c3, 0xb9774f3f, 0xf91797f0, 0xb9610ebe, 0xc06272aa,
    194 0xb94ad922, 0xf8e5a14d, 0xb934ae6d, 0xc06806ce, 0xb91e8ea3, 0xf8b3af0c, 0xb90879c7, 0xc06dc22e,
    195 0xb8f26fdc, 0xf881c14b, 0xb8dc70e7, 0xc073a4c3, 0xb8c67cea, 0xf84fd829, 0xb8b093ea, 0xc079ae8c,
    196 0xb89ab5e8, 0xf81df3c5, 0xb884e2e9, 0xc07fdf85, 0xb86f1af0, 0xf7ec143e, 0xb8595e00, 0xc08637a9,
    197 0xb843ac1d, 0xf7ba39b3, 0xb82e0549, 0xc08cb6f5, 0xb818698a, 0xf7886442, 0xb802d8e0, 0xc0935d64,
    198 0xb7ed5351, 0xf756940a, 0xb7d7d8df, 0xc09a2af3, 0xb7c2698e, 0xf724c92a, 0xb7ad0561, 0xc0a11f9d,
    199 0xb797ac5b, 0xf6f303c0, 0xb7825e80, 0xc0a83b5e, 0xb76d1bd2, 0xf6c143ec, 0xb757e455, 0xc0af7e33,
    200 0xb742b80d, 0xf68f89cb, 0xb72d96fd, 0xc0b6e815, 0xb7188127, 0xf65dd57d, 0xb7037690, 0xc0be7901,
    201 0xb6ee773a, 0xf62c2721, 0xb6d98328, 0xc0c630f2, 0xb6c49a5e, 0xf5fa7ed4, 0xb6afbce0, 0xc0ce0fe3,
    202 0xb69aeab0, 0xf5c8dcb6, 0xb68623d1, 0xc0d615cf, 0xb6716847, 0xf59740e5, 0xb65cb815, 0xc0de42b2,
    203 0xb648133e, 0xf565ab80, 0xb63379c5, 0xc0e69686, 0xb61eebae, 0xf5341ca5, 0xb60a68fb, 0xc0ef1147,
    204 0xb5f5f1b1, 0xf5029473, 0xb5e185d1, 0xc0f7b2ee, 0xb5cd255f, 0xf4d11308, 0xb5b8d05f, 0xc1007b77,
    205 0xb5a486d2, 0xf49f9884, 0xb59048be, 0xc1096add, 0xb57c1624, 0xf46e2504, 0xb567ef08, 0xc1128119,
    206 0xb553d36c, 0xf43cb8a7, 0xb53fc355, 0xc11bbe26, 0xb52bbec4, 0xf40b538b, 0xb517c5be, 0xc12521ff,
    207 0xb503d845, 0xf3d9f5cf, 0xb4eff65c, 0xc12eac9d, 0xb4dc2007, 0xf3a89f92, 0xb4c85548, 0xc1385dfb,
    208 0xb4b49622, 0xf37750f2, 0xb4a0e299, 0xc1423613, 0xb48d3ab0, 0xf3460a0d, 0xb4799e69, 0xc14c34df,
    209 0xb4660dc8, 0xf314cb02, 0xb45288cf, 0xc1565a58, 0xb43f0f82, 0xf2e393ef, 0xb42ba1e4, 0xc160a678,
    210 0xb4183ff7, 0xf2b264f2, 0xb404e9bf, 0xc16b193a, 0xb3f19f3e, 0xf2813e2a, 0xb3de6078, 0xc175b296,
    211 0xb3cb2d70, 0xf2501fb5, 0xb3b80628, 0xc1807285, 0xb3a4eaa4, 0xf21f09b1, 0xb391dae6, 0xc18b5903,
    212 0xb37ed6f1, 0xf1edfc3d, 0xb36bdec9, 0xc1966606, 0xb358f26f, 0xf1bcf777, 0xb34611e8, 0xc1a1998a,
    213 0xb3333d36, 0xf18bfb7d, 0xb320745c, 0xc1acf386, 0xb30db75d, 0xf15b086d, 0xb2fb063b, 0xc1b873f5,
    214 0xb2e860fa, 0xf12a1e66, 0xb2d5c79d, 0xc1c41ace, 0xb2c33a26, 0xf0f93d86, 0xb2b0b898, 0xc1cfe80a,
    215 0xb29e42f6, 0xf0c865ea, 0xb28bd943, 0xc1dbdba3, 0xb2797b82, 0xf09797b2, 0xb26729b5, 0xc1e7f591,
    216 0xb254e3e0, 0xf066d2fa, 0xb242aa05, 0xc1f435cc, 0xb2307c27, 0xf03617e2, 0xb21e5a49, 0xc2009c4e,
    217 0xb20c446d, 0xf0056687, 0xb1fa3a97, 0xc20d290d, 0xb1e83cc9, 0xefd4bf08, 0xb1d64b06, 0xc219dc03,
    218 0xb1c46551, 0xefa42181, 0xb1b28bad, 0xc226b528, 0xb1a0be1b, 0xef738e12, 0xb18efca0, 0xc233b473,
    219 0xb17d473d, 0xef4304d8, 0xb16b9df6, 0xc240d9de, 0xb15a00cd, 0xef1285f2, 0xb1486fc5, 0xc24e255e,
    220 0xb136eae1, 0xeee2117c, 0xb1257223, 0xc25b96ee, 0xb114058e, 0xeeb1a796, 0xb102a524, 0xc2692e83,
    221 0xb0f150e9, 0xee81485c, 0xb0e008e0, 0xc276ec16, 0xb0cecd09, 0xee50f3ed, 0xb0bd9d6a, 0xc284cf9f,
    222 0xb0ac7a03, 0xee20aa67, 0xb09b62d8, 0xc292d914, 0xb08a57eb, 0xedf06be6, 0xb079593f, 0xc2a1086d,
    223 0xb06866d7, 0xedc0388a, 0xb05780b5, 0xc2af5da2, 0xb046a6db, 0xed901070, 0xb035d94e, 0xc2bdd8a9,
    224 0xb025180e, 0xed5ff3b5, 0xb014631e, 0xc2cc7979, 0xb003ba82, 0xed2fe277, 0xaff31e3b, 0xc2db400a,
    225 0xafe28e4d, 0xecffdcd4, 0xafd20ab9, 0xc2ea2c53, 0xafc19383, 0xeccfe2ea, 0xafb128ad, 0xc2f93e4a,
    226 0xafa0ca39, 0xec9ff4d6, 0xaf90782a, 0xc30875e5, 0xaf803283, 0xec7012b5, 0xaf6ff945, 0xc317d31c,
    227 0xaf5fcc74, 0xec403ca5, 0xaf4fac12, 0xc32755e5, 0xaf3f9822, 0xec1072c4, 0xaf2f90a5, 0xc336fe37,
    228 0xaf1f959f, 0xebe0b52f, 0xaf0fa712, 0xc346cc07, 0xaeffc500, 0xebb10404, 0xaeefef6c, 0xc356bf4d,
    229 0xaee02658, 0xeb815f60, 0xaed069c7, 0xc366d7fd, 0xaec0b9bb, 0xeb51c760, 0xaeb11636, 0xc377160f,
    230 0xaea17f3b, 0xeb223c22, 0xae91f4cd, 0xc3877978, 0xae8276ed, 0xeaf2bdc3, 0xae73059f, 0xc398022f,
    231 0xae63a0e3, 0xeac34c60, 0xae5448be, 0xc3a8b028, 0xae44fd31, 0xea93e817, 0xae35be3f, 0xc3b9835a,
    232 0xae268be9, 0xea649105, 0xae176633, 0xc3ca7bba, 0xae084d1f, 0xea354746, 0xadf940ae, 0xc3db993e,
    233 0xadea40e4, 0xea060af9, 0xaddb4dc2, 0xc3ecdbdc, 0xadcc674b, 0xe9d6dc3b, 0xadbd8d82, 0xc3fe4388,
    234 0xadaec067, 0xe9a7bb28, 0xad9fffff, 0xc40fd037, 0xad914c4b, 0xe978a7dd, 0xad82a54c, 0xc42181e0,
    235 0xad740b07, 0xe949a278, 0xad657d7c, 0xc4335877, 0xad56fcaf, 0xe91aab16, 0xad4888a0, 0xc44553f2,
    236 0xad3a2153, 0xe8ebc1d3, 0xad2bc6ca, 0xc4577444, 0xad1d7907, 0xe8bce6cd, 0xad0f380c, 0xc469b963,
    237 0xad0103db, 0xe88e1a20, 0xacf2dc77, 0xc47c2344, 0xace4c1e2, 0xe85f5be9, 0xacd6b41e, 0xc48eb1db,
    238 0xacc8b32c, 0xe830ac45, 0xacbabf10, 0xc4a1651c, 0xacacd7cb, 0xe8020b52, 0xac9efd60, 0xc4b43cfd,
    239 0xac912fd1, 0xe7d3792b, 0xac836f1f, 0xc4c73972, 0xac75bb4d, 0xe7a4f5ed, 0xac68145d, 0xc4da5a6f,
    240 0xac5a7a52, 0xe77681b6, 0xac4ced2c, 0xc4ed9fe7, 0xac3f6cef, 0xe7481ca1, 0xac31f99d, 0xc50109d0,
    241 0xac249336, 0xe719c6cb, 0xac1739bf, 0xc514981d, 0xac09ed38, 0xe6eb8052, 0xabfcada3, 0xc5284ac3,
    242 0xabef7b04, 0xe6bd4951, 0xabe2555b, 0xc53c21b4, 0xabd53caa, 0xe68f21e5, 0xabc830f5, 0xc5501ce5,
    243 0xabbb323c, 0xe6610a2a, 0xabae4082, 0xc5643c4a, 0xaba15bc9, 0xe633023e, 0xab948413, 0xc5787fd6,
    244 0xab87b962, 0xe6050a3b, 0xab7afbb7, 0xc58ce77c, 0xab6e4b15, 0xe5d72240, 0xab61a77d, 0xc5a17330,
    245 0xab5510f3, 0xe5a94a67, 0xab488776, 0xc5b622e6, 0xab3c0b0b, 0xe57b82cd, 0xab2f9bb1, 0xc5caf690,
    246 0xab23396c, 0xe54dcb8f, 0xab16e43d, 0xc5dfee22, 0xab0a9c27, 0xe52024c9, 0xaafe612a, 0xc5f5098f,
    247 0xaaf23349, 0xe4f28e96, 0xaae61286, 0xc60a48c9, 0xaad9fee3, 0xe4c50914, 0xaacdf861, 0xc61fabc4,
    248 0xaac1ff03, 0xe497945d, 0xaab612ca, 0xc6353273, 0xaaaa33b8, 0xe46a308f, 0xaa9e61cf, 0xc64adcc7,
    249 0xaa929d10, 0xe43cddc4, 0xaa86e57e, 0xc660aab5, 0xaa7b3b1b, 0xe40f9c1a, 0xaa6f9de7, 0xc6769c2e,
    250 0xaa640de6, 0xe3e26bac, 0xaa588b18, 0xc68cb124, 0xaa4d157f, 0xe3b54c95, 0xaa41ad1e, 0xc6a2e98b,
    251 0xaa3651f6, 0xe3883ef2, 0xaa2b0409, 0xc6b94554, 0xaa1fc358, 0xe35b42df, 0xaa148fe6, 0xc6cfc472,
    252 0xaa0969b3, 0xe32e5876, 0xa9fe50c2, 0xc6e666d7, 0xa9f34515, 0xe3017fd5, 0xa9e846ad, 0xc6fd2c75,
    253 0xa9dd558b, 0xe2d4b916, 0xa9d271b2, 0xc714153e, 0xa9c79b23, 0xe2a80456, 0xa9bcd1e0, 0xc72b2123,
    254 0xa9b215ea, 0xe27b61af, 0xa9a76744, 0xc7425016, 0xa99cc5ee, 0xe24ed13d, 0xa99231eb, 0xc759a20a,
    255 0xa987ab3c, 0xe222531c, 0xa97d31e3, 0xc77116f0, 0xa972c5e1, 0xe1f5e768, 0xa9686738, 0xc788aeb9,
    256 0xa95e15e9, 0xe1c98e3b, 0xa953d1f7, 0xc7a06957, 0xa9499b62, 0xe19d47b1, 0xa93f722c, 0xc7b846ba,
    257 0xa9355658, 0xe17113e5, 0xa92b47e5, 0xc7d046d6, 0xa92146d7, 0xe144f2f3, 0xa917532e, 0xc7e8699a,
    258 0xa90d6cec, 0xe118e4f6, 0xa9039413, 0xc800aef7, 0xa8f9c8a4, 0xe0ecea09, 0xa8f00aa0, 0xc81916df,
    259 0xa8e65a0a, 0xe0c10247, 0xa8dcb6e2, 0xc831a143, 0xa8d3212a, 0xe0952dcb, 0xa8c998e3, 0xc84a4e14,
    260 0xa8c01e10, 0xe0696cb0, 0xa8b6b0b1, 0xc8631d42, 0xa8ad50c8, 0xe03dbf11, 0xa8a3fe57, 0xc87c0ebd,
    261 0xa89ab95e, 0xe012250a, 0xa89181df, 0xc8952278, 0xa88857dc, 0xdfe69eb4, 0xa87f3b57, 0xc8ae5862,
    262 0xa8762c4f, 0xdfbb2c2c, 0xa86d2ac8, 0xc8c7b06b, 0xa86436c2, 0xdf8fcd8b, 0xa85b503e, 0xc8e12a84,
    263 0xa852773f, 0xdf6482ed, 0xa849abc4, 0xc8fac69e, 0xa840edd1, 0xdf394c6b, 0xa8383d66, 0xc91484a8,
    264 0xa82f9a84, 0xdf0e2a22, 0xa827052d, 0xc92e6492, 0xa81e7d62, 0xdee31c2b, 0xa8160324, 0xc948664d,
    265 0xa80d9675, 0xdeb822a1, 0xa8053756, 0xc96289c9, 0xa7fce5c9, 0xde8d3d9e, 0xa7f4a1ce, 0xc97ccef5,
    266 0xa7ec6b66, 0xde626d3e, 0xa7e44294, 0xc99735c2, 0xa7dc2759, 0xde37b199, 0xa7d419b4, 0xc9b1be1e,
    267 0xa7cc19a9, 0xde0d0acc, 0xa7c42738, 0xc9cc67fa, 0xa7bc4262, 0xdde278ef, 0xa7b46b29, 0xc9e73346,
    268 0xa7aca18e, 0xddb7fc1e, 0xa7a4e591, 0xca021fef, 0xa79d3735, 0xdd8d9472, 0xa795967a, 0xca1d2de7,
    269 0xa78e0361, 0xdd634206, 0xa7867dec, 0xca385d1d, 0xa77f061c, 0xdd3904f4, 0xa7779bf2, 0xca53ad7e,
    270 0xa7703f70, 0xdd0edd55, 0xa768f095, 0xca6f1efc, 0xa761af64, 0xdce4cb44, 0xa75a7bdd, 0xca8ab184,
    271 0xa7535602, 0xdcbacedb, 0xa74c3dd4, 0xcaa66506, 0xa7453353, 0xdc90e834, 0xa73e3681, 0xcac23971,
    272 0xa7374760, 0xdc671768, 0xa73065ef, 0xcade2eb3, 0xa7299231, 0xdc3d5c91, 0xa722cc25, 0xcafa44bc,
    273 0xa71c13ce, 0xdc13b7c9, 0xa715692c, 0xcb167b79, 0xa70ecc41, 0xdbea292b, 0xa7083d0d, 0xcb32d2da,
    274 0xa701bb91, 0xdbc0b0ce, 0xa6fb47ce, 0xcb4f4acd, 0xa6f4e1c6, 0xdb974ece, 0xa6ee8979, 0xcb6be341,
    275 0xa6e83ee8, 0xdb6e0342, 0xa6e20214, 0xcb889c23, 0xa6dbd2ff, 0xdb44ce46, 0xa6d5b1a9, 0xcba57563,
    276 0xa6cf9e13, 0xdb1baff2, 0xa6c9983e, 0xcbc26eee, 0xa6c3a02b, 0xdaf2a860, 0xa6bdb5da, 0xcbdf88b3,
    277 0xa6b7d94e, 0xdac9b7a9, 0xa6b20a86, 0xcbfcc29f, 0xa6ac4984, 0xdaa0dde7, 0xa6a69649, 0xcc1a1ca0,
    278 0xa6a0f0d5, 0xda781b31, 0xa69b5929, 0xcc3796a5, 0xa695cf46, 0xda4f6fa3, 0xa690532d, 0xcc55309b,
    279 0xa68ae4df, 0xda26db54, 0xa685845c, 0xcc72ea70, 0xa68031a6, 0xd9fe5e5e, 0xa67aecbd, 0xcc90c412,
    280 0xa675b5a3, 0xd9d5f8d9, 0xa6708c57, 0xccaebd6e, 0xa66b70db, 0xd9adaadf, 0xa6666330, 0xccccd671,
    281 0xa6616355, 0xd9857489, 0xa65c714d, 0xcceb0f0a, 0xa6578d18, 0xd95d55ef, 0xa652b6b6, 0xcd096725,
    282 0xa64dee28, 0xd9354f2a, 0xa6493370, 0xcd27deb0, 0xa644868d, 0xd90d6053, 0xa63fe781, 0xcd467599,
    283 0xa63b564c, 0xd8e58982, 0xa636d2ee, 0xcd652bcb, 0xa6325d6a, 0xd8bdcad0, 0xa62df5bf, 0xcd840134,
    284 0xa6299bed, 0xd8962456, 0xa6254ff7, 0xcda2f5c2, 0xa62111db, 0xd86e962b, 0xa61ce19c, 0xcdc20960,
    285 0xa618bf39, 0xd8472069, 0xa614aab3, 0xcde13bfd, 0xa610a40c, 0xd81fc328, 0xa60cab43, 0xce008d84,
    286 0xa608c058, 0xd7f87e7f, 0xa604e34e, 0xce1ffde2, 0xa6011424, 0xd7d15288, 0xa5fd52db, 0xce3f8d05,
    287 0xa5f99f73, 0xd7aa3f5a, 0xa5f5f9ed, 0xce5f3ad8, 0xa5f2624a, 0xd783450d, 0xa5eed88a, 0xce7f0748,
    288 0xa5eb5cae, 0xd75c63ba, 0xa5e7eeb6, 0xce9ef241, 0xa5e48ea3, 0xd7359b78, 0xa5e13c75, 0xcebefbb0,
    289 0xa5ddf82d, 0xd70eec60, 0xa5dac1cb, 0xcedf2380, 0xa5d79950, 0xd6e85689, 0xa5d47ebc, 0xceff699f,
    290 0xa5d17210, 0xd6c1da0b, 0xa5ce734d, 0xcf1fcdf8, 0xa5cb8272, 0xd69b76fe, 0xa5c89f80, 0xcf405077,
    291 0xa5c5ca77, 0xd6752d79, 0xa5c30359, 0xcf60f108, 0xa5c04a25, 0xd64efd94, 0xa5bd9edc, 0xcf81af97,
    292 0xa5bb017f, 0xd628e767, 0xa5b8720d, 0xcfa28c10, 0xa5b5f087, 0xd602eb0a, 0xa5b37cee, 0xcfc3865e,
    293 0xa5b11741, 0xd5dd0892, 0xa5aebf82, 0xcfe49e6d, 0xa5ac75b0, 0xd5b74019, 0xa5aa39cd, 0xd005d42a,
    294 0xa5a80bd7, 0xd59191b5, 0xa5a5ebd0, 0xd027277e, 0xa5a3d9b8, 0xd56bfd7d, 0xa5a1d590, 0xd0489856,
    295 0xa59fdf57, 0xd5468389, 0xa59df70e, 0xd06a269d, 0xa59c1cb5, 0xd52123f0, 0xa59a504c, 0xd08bd23f,
    296 0xa59891d4, 0xd4fbdec9, 0xa596e14e, 0xd0ad9b26, 0xa5953eb8, 0xd4d6b42b, 0xa593aa14, 0xd0cf813e,
    297 0xa5922362, 0xd4b1a42c, 0xa590aaa2, 0xd0f18472, 0xa58f3fd4, 0xd48caee4, 0xa58de2f8, 0xd113a4ad,
    298 0xa58c940f, 0xd467d469, 0xa58b5319, 0xd135e1d9, 0xa58a2016, 0xd44314d3, 0xa588fb06, 0xd1583be2,
    299 0xa587e3ea, 0xd41e7037, 0xa586dac1, 0xd17ab2b3, 0xa585df8c, 0xd3f9e6ad, 0xa584f24b, 0xd19d4636,
    300 0xa58412fe, 0xd3d5784a, 0xa58341a5, 0xd1bff656, 0xa5827e40, 0xd3b12526, 0xa581c8d0, 0xd1e2c2fd,
    301 0xa5812154, 0xd38ced57, 0xa58087cd, 0xd205ac17, 0xa57ffc3b, 0xd368d0f3, 0xa57f7e9d, 0xd228b18d,
    302 0xa57f0ef5, 0xd344d011, 0xa57ead41, 0xd24bd34a, 0xa57e5982, 0xd320eac6, 0xa57e13b8, 0xd26f1138,
    303 0xa57ddbe4, 0xd2fd2129, 0xa57db204, 0xd2926b41, 0xa57d961a, 0xd2d97350, 0xa57d8825, 0xd2b5e151,
    304 };
    305 
    306 const int cos1sin1tab[514] PROGMEM = {
    307 /* format = Q30 */
    308 0x40000000, 0x00000000, 0x40323034, 0x003243f1, 0x406438cf, 0x006487c4, 0x409619b2, 0x0096cb58,
    309 0x40c7d2bd, 0x00c90e90, 0x40f963d3, 0x00fb514b, 0x412accd4, 0x012d936c, 0x415c0da3, 0x015fd4d2,
    310 0x418d2621, 0x0192155f, 0x41be162f, 0x01c454f5, 0x41eeddaf, 0x01f69373, 0x421f7c84, 0x0228d0bb,
    311 0x424ff28f, 0x025b0caf, 0x42803fb2, 0x028d472e, 0x42b063d0, 0x02bf801a, 0x42e05ecb, 0x02f1b755,
    312 0x43103085, 0x0323ecbe, 0x433fd8e1, 0x03562038, 0x436f57c1, 0x038851a2, 0x439ead09, 0x03ba80df,
    313 0x43cdd89a, 0x03ecadcf, 0x43fcda59, 0x041ed854, 0x442bb227, 0x0451004d, 0x445a5fe8, 0x0483259d,
    314 0x4488e37f, 0x04b54825, 0x44b73ccf, 0x04e767c5, 0x44e56bbd, 0x0519845e, 0x4513702a, 0x054b9dd3,
    315 0x454149fc, 0x057db403, 0x456ef916, 0x05afc6d0, 0x459c7d5a, 0x05e1d61b, 0x45c9d6af, 0x0613e1c5,
    316 0x45f704f7, 0x0645e9af, 0x46240816, 0x0677edbb, 0x4650dff1, 0x06a9edc9, 0x467d8c6d, 0x06dbe9bb,
    317 0x46aa0d6d, 0x070de172, 0x46d662d6, 0x073fd4cf, 0x47028c8d, 0x0771c3b3, 0x472e8a76, 0x07a3adff,
    318 0x475a5c77, 0x07d59396, 0x47860275, 0x08077457, 0x47b17c54, 0x08395024, 0x47dcc9f9, 0x086b26de,
    319 0x4807eb4b, 0x089cf867, 0x4832e02d, 0x08cec4a0, 0x485da887, 0x09008b6a, 0x4888443d, 0x09324ca7,
    320 0x48b2b335, 0x09640837, 0x48dcf556, 0x0995bdfd, 0x49070a84, 0x09c76dd8, 0x4930f2a6, 0x09f917ac,
    321 0x495aada2, 0x0a2abb59, 0x49843b5f, 0x0a5c58c0, 0x49ad9bc2, 0x0a8defc3, 0x49d6ceb3, 0x0abf8043,
    322 0x49ffd417, 0x0af10a22, 0x4a28abd6, 0x0b228d42, 0x4a5155d6, 0x0b540982, 0x4a79d1ff, 0x0b857ec7,
    323 0x4aa22036, 0x0bb6ecef, 0x4aca4065, 0x0be853de, 0x4af23270, 0x0c19b374, 0x4b19f641, 0x0c4b0b94,
    324 0x4b418bbe, 0x0c7c5c1e, 0x4b68f2cf, 0x0cada4f5, 0x4b902b5c, 0x0cdee5f9, 0x4bb7354d, 0x0d101f0e,
    325 0x4bde1089, 0x0d415013, 0x4c04bcf8, 0x0d7278eb, 0x4c2b3a84, 0x0da39978, 0x4c518913, 0x0dd4b19a,
    326 0x4c77a88e, 0x0e05c135, 0x4c9d98de, 0x0e36c82a, 0x4cc359ec, 0x0e67c65a, 0x4ce8eb9f, 0x0e98bba7,
    327 0x4d0e4de2, 0x0ec9a7f3, 0x4d33809c, 0x0efa8b20, 0x4d5883b7, 0x0f2b650f, 0x4d7d571c, 0x0f5c35a3,
    328 0x4da1fab5, 0x0f8cfcbe, 0x4dc66e6a, 0x0fbdba40, 0x4deab226, 0x0fee6e0d, 0x4e0ec5d1, 0x101f1807,
    329 0x4e32a956, 0x104fb80e, 0x4e565c9f, 0x10804e06, 0x4e79df95, 0x10b0d9d0, 0x4e9d3222, 0x10e15b4e,
    330 0x4ec05432, 0x1111d263, 0x4ee345ad, 0x11423ef0, 0x4f06067f, 0x1172a0d7, 0x4f289692, 0x11a2f7fc,
    331 0x4f4af5d1, 0x11d3443f, 0x4f6d2427, 0x12038584, 0x4f8f217e, 0x1233bbac, 0x4fb0edc1, 0x1263e699,
    332 0x4fd288dc, 0x1294062f, 0x4ff3f2bb, 0x12c41a4f, 0x50152b47, 0x12f422db, 0x5036326e, 0x13241fb6,
    333 0x50570819, 0x135410c3, 0x5077ac37, 0x1383f5e3, 0x50981eb1, 0x13b3cefa, 0x50b85f74, 0x13e39be9,
    334 0x50d86e6d, 0x14135c94, 0x50f84b87, 0x144310dd, 0x5117f6ae, 0x1472b8a5, 0x51376fd0, 0x14a253d1,
    335 0x5156b6d9, 0x14d1e242, 0x5175cbb5, 0x150163dc, 0x5194ae52, 0x1530d881, 0x51b35e9b, 0x15604013,
    336 0x51d1dc80, 0x158f9a76, 0x51f027eb, 0x15bee78c, 0x520e40cc, 0x15ee2738, 0x522c270f, 0x161d595d,
    337 0x5249daa2, 0x164c7ddd, 0x52675b72, 0x167b949d, 0x5284a96e, 0x16aa9d7e, 0x52a1c482, 0x16d99864,
    338 0x52beac9f, 0x17088531, 0x52db61b0, 0x173763c9, 0x52f7e3a6, 0x1766340f, 0x5314326d, 0x1794f5e6,
    339 0x53304df6, 0x17c3a931, 0x534c362d, 0x17f24dd3, 0x5367eb03, 0x1820e3b0, 0x53836c66, 0x184f6aab,
    340 0x539eba45, 0x187de2a7, 0x53b9d48f, 0x18ac4b87, 0x53d4bb34, 0x18daa52f, 0x53ef6e23, 0x1908ef82,
    341 0x5409ed4b, 0x19372a64, 0x5424389d, 0x196555b8, 0x543e5007, 0x19937161, 0x5458337a, 0x19c17d44,
    342 0x5471e2e6, 0x19ef7944, 0x548b5e3b, 0x1a1d6544, 0x54a4a56a, 0x1a4b4128, 0x54bdb862, 0x1a790cd4,
    343 0x54d69714, 0x1aa6c82b, 0x54ef4171, 0x1ad47312, 0x5507b76a, 0x1b020d6c, 0x551ff8ef, 0x1b2f971e,
    344 0x553805f2, 0x1b5d100a, 0x554fde64, 0x1b8a7815, 0x55678236, 0x1bb7cf23, 0x557ef15a, 0x1be51518,
    345 0x55962bc0, 0x1c1249d8, 0x55ad315b, 0x1c3f6d47, 0x55c4021d, 0x1c6c7f4a, 0x55da9df7, 0x1c997fc4,
    346 0x55f104dc, 0x1cc66e99, 0x560736bd, 0x1cf34baf, 0x561d338d, 0x1d2016e9, 0x5632fb3f, 0x1d4cd02c,
    347 0x56488dc5, 0x1d79775c, 0x565deb11, 0x1da60c5d, 0x56731317, 0x1dd28f15, 0x568805c9, 0x1dfeff67,
    348 0x569cc31b, 0x1e2b5d38, 0x56b14b00, 0x1e57a86d, 0x56c59d6a, 0x1e83e0eb, 0x56d9ba4e, 0x1eb00696,
    349 0x56eda1a0, 0x1edc1953, 0x57015352, 0x1f081907, 0x5714cf59, 0x1f340596, 0x572815a8, 0x1f5fdee6,
    350 0x573b2635, 0x1f8ba4dc, 0x574e00f2, 0x1fb7575c, 0x5760a5d5, 0x1fe2f64c, 0x577314d2, 0x200e8190,
    351 0x57854ddd, 0x2039f90f, 0x579750ec, 0x20655cac, 0x57a91df2, 0x2090ac4d, 0x57bab4e6, 0x20bbe7d8,
    352 0x57cc15bc, 0x20e70f32, 0x57dd406a, 0x21122240, 0x57ee34e5, 0x213d20e8, 0x57fef323, 0x21680b0f,
    353 0x580f7b19, 0x2192e09b, 0x581fccbc, 0x21bda171, 0x582fe804, 0x21e84d76, 0x583fcce6, 0x2212e492,
    354 0x584f7b58, 0x223d66a8, 0x585ef351, 0x2267d3a0, 0x586e34c7, 0x22922b5e, 0x587d3fb0, 0x22bc6dca,
    355 0x588c1404, 0x22e69ac8, 0x589ab1b9, 0x2310b23e, 0x58a918c6, 0x233ab414, 0x58b74923, 0x2364a02e,
    356 0x58c542c5, 0x238e7673, 0x58d305a6, 0x23b836ca, 0x58e091bd, 0x23e1e117, 0x58ede700, 0x240b7543,
    357 0x58fb0568, 0x2434f332, 0x5907eced, 0x245e5acc, 0x59149d87, 0x2487abf7, 0x5921172e, 0x24b0e699,
    358 0x592d59da, 0x24da0a9a, 0x59396584, 0x250317df, 0x59453a24, 0x252c0e4f, 0x5950d7b3, 0x2554edd1,
    359 0x595c3e2a, 0x257db64c, 0x59676d82, 0x25a667a7, 0x597265b4, 0x25cf01c8, 0x597d26b8, 0x25f78497,
    360 0x5987b08a, 0x261feffa, 0x59920321, 0x264843d9, 0x599c1e78, 0x2670801a, 0x59a60288, 0x2698a4a6,
    361 0x59afaf4c, 0x26c0b162, 0x59b924bc, 0x26e8a637, 0x59c262d5, 0x2710830c, 0x59cb698f, 0x273847c8,
    362 0x59d438e5, 0x275ff452, 0x59dcd0d3, 0x27878893, 0x59e53151, 0x27af0472, 0x59ed5a5c, 0x27d667d5,
    363 0x59f54bee, 0x27fdb2a7, 0x59fd0603, 0x2824e4cc, 0x5a048895, 0x284bfe2f, 0x5a0bd3a1, 0x2872feb6,
    364 0x5a12e720, 0x2899e64a, 0x5a19c310, 0x28c0b4d2, 0x5a20676c, 0x28e76a37, 0x5a26d42f, 0x290e0661,
    365 0x5a2d0957, 0x29348937, 0x5a3306de, 0x295af2a3, 0x5a38ccc2, 0x2981428c, 0x5a3e5afe, 0x29a778db,
    366 0x5a43b190, 0x29cd9578, 0x5a48d074, 0x29f3984c, 0x5a4db7a6, 0x2a19813f, 0x5a526725, 0x2a3f503a,
    367 0x5a56deec, 0x2a650525, 0x5a5b1efa, 0x2a8a9fea, 0x5a5f274b, 0x2ab02071, 0x5a62f7dd, 0x2ad586a3,
    368 0x5a6690ae, 0x2afad269, 0x5a69f1bb, 0x2b2003ac, 0x5a6d1b03, 0x2b451a55, 0x5a700c84, 0x2b6a164d,
    369 0x5a72c63b, 0x2b8ef77d, 0x5a754827, 0x2bb3bdce, 0x5a779246, 0x2bd8692b, 0x5a79a498, 0x2bfcf97c,
    370 0x5a7b7f1a, 0x2c216eaa, 0x5a7d21cc, 0x2c45c8a0, 0x5a7e8cac, 0x2c6a0746, 0x5a7fbfbb, 0x2c8e2a87,
    371 0x5a80baf6, 0x2cb2324c, 0x5a817e5d, 0x2cd61e7f, 0x5a8209f1, 0x2cf9ef09, 0x5a825db0, 0x2d1da3d5,
    372 0x5a82799a, 0x2d413ccd,
    373 };
    374 
    375 const uint8_t sinWindowOffset[NUM_IMDCT_SIZES] PROGMEM = {0, 128};
    376 
    377 const int sinWindow[128 + 1024] PROGMEM = {
    378 /* 128 - format = Q31 * 2^0 */
    379 0x00c90f88, 0x7fff6216, 0x025b26d7, 0x7ffa72d1, 0x03ed26e6, 0x7ff09478, 0x057f0035, 0x7fe1c76b,
    380 0x0710a345, 0x7fce0c3e, 0x08a2009a, 0x7fb563b3, 0x0a3308bd, 0x7f97cebd, 0x0bc3ac35, 0x7f754e80,
    381 0x0d53db92, 0x7f4de451, 0x0ee38766, 0x7f2191b4, 0x1072a048, 0x7ef05860, 0x120116d5, 0x7eba3a39,
    382 0x138edbb1, 0x7e7f3957, 0x151bdf86, 0x7e3f57ff, 0x16a81305, 0x7dfa98a8, 0x183366e9, 0x7db0fdf8,
    383 0x19bdcbf3, 0x7d628ac6, 0x1b4732ef, 0x7d0f4218, 0x1ccf8cb3, 0x7cb72724, 0x1e56ca1e, 0x7c5a3d50,
    384 0x1fdcdc1b, 0x7bf88830, 0x2161b3a0, 0x7b920b89, 0x22e541af, 0x7b26cb4f, 0x24677758, 0x7ab6cba4,
    385 0x25e845b6, 0x7a4210d8, 0x27679df4, 0x79c89f6e, 0x28e5714b, 0x794a7c12, 0x2a61b101, 0x78c7aba2,
    386 0x2bdc4e6f, 0x78403329, 0x2d553afc, 0x77b417df, 0x2ecc681e, 0x77235f2d, 0x3041c761, 0x768e0ea6,
    387 0x31b54a5e, 0x75f42c0b, 0x3326e2c3, 0x7555bd4c, 0x34968250, 0x74b2c884, 0x36041ad9, 0x740b53fb,
    388 0x376f9e46, 0x735f6626, 0x38d8fe93, 0x72af05a7, 0x3a402dd2, 0x71fa3949, 0x3ba51e29, 0x71410805,
    389 0x3d07c1d6, 0x708378ff, 0x3e680b2c, 0x6fc19385, 0x3fc5ec98, 0x6efb5f12, 0x4121589b, 0x6e30e34a,
    390 0x427a41d0, 0x6d6227fa, 0x43d09aed, 0x6c8f351c, 0x452456bd, 0x6bb812d1, 0x46756828, 0x6adcc964,
    391 0x47c3c22f, 0x69fd614a, 0x490f57ee, 0x6919e320, 0x4a581c9e, 0x683257ab, 0x4b9e0390, 0x6746c7d8,
    392 0x4ce10034, 0x66573cbb, 0x4e210617, 0x6563bf92, 0x4f5e08e3, 0x646c59bf, 0x5097fc5e, 0x637114cc,
    393 0x51ced46e, 0x6271fa69, 0x53028518, 0x616f146c, 0x5433027d, 0x60686ccf, 0x556040e2, 0x5f5e0db3,
    394 0x568a34a9, 0x5e50015d, 0x57b0d256, 0x5d3e5237, 0x58d40e8c, 0x5c290acc, 0x59f3de12, 0x5b1035cf,
    395 /* 1024 - format = Q31 * 2^0 */
    396 0x001921fb, 0x7ffffd88, 0x004b65ee, 0x7fffe9cb, 0x007da9d4, 0x7fffc251, 0x00afeda8, 0x7fff8719,
    397 0x00e23160, 0x7fff3824, 0x011474f6, 0x7ffed572, 0x0146b860, 0x7ffe5f03, 0x0178fb99, 0x7ffdd4d7,
    398 0x01ab3e97, 0x7ffd36ee, 0x01dd8154, 0x7ffc8549, 0x020fc3c6, 0x7ffbbfe6, 0x024205e8, 0x7ffae6c7,
    399 0x027447b0, 0x7ff9f9ec, 0x02a68917, 0x7ff8f954, 0x02d8ca16, 0x7ff7e500, 0x030b0aa4, 0x7ff6bcf0,
    400 0x033d4abb, 0x7ff58125, 0x036f8a51, 0x7ff4319d, 0x03a1c960, 0x7ff2ce5b, 0x03d407df, 0x7ff1575d,
    401 0x040645c7, 0x7fefcca4, 0x04388310, 0x7fee2e30, 0x046abfb3, 0x7fec7c02, 0x049cfba7, 0x7feab61a,
    402 0x04cf36e5, 0x7fe8dc78, 0x05017165, 0x7fe6ef1c, 0x0533ab20, 0x7fe4ee06, 0x0565e40d, 0x7fe2d938,
    403 0x05981c26, 0x7fe0b0b1, 0x05ca5361, 0x7fde7471, 0x05fc89b8, 0x7fdc247a, 0x062ebf22, 0x7fd9c0ca,
    404 0x0660f398, 0x7fd74964, 0x06932713, 0x7fd4be46, 0x06c5598a, 0x7fd21f72, 0x06f78af6, 0x7fcf6ce8,
    405 0x0729bb4e, 0x7fcca6a7, 0x075bea8c, 0x7fc9ccb2, 0x078e18a7, 0x7fc6df08, 0x07c04598, 0x7fc3dda9,
    406 0x07f27157, 0x7fc0c896, 0x08249bdd, 0x7fbd9fd0, 0x0856c520, 0x7fba6357, 0x0888ed1b, 0x7fb7132b,
    407 0x08bb13c5, 0x7fb3af4e, 0x08ed3916, 0x7fb037bf, 0x091f5d06, 0x7facac7f, 0x09517f8f, 0x7fa90d8e,
    408 0x0983a0a7, 0x7fa55aee, 0x09b5c048, 0x7fa1949e, 0x09e7de6a, 0x7f9dbaa0, 0x0a19fb04, 0x7f99ccf4,
    409 0x0a4c1610, 0x7f95cb9a, 0x0a7e2f85, 0x7f91b694, 0x0ab0475c, 0x7f8d8de1, 0x0ae25d8d, 0x7f895182,
    410 0x0b147211, 0x7f850179, 0x0b4684df, 0x7f809dc5, 0x0b7895f0, 0x7f7c2668, 0x0baaa53b, 0x7f779b62,
    411 0x0bdcb2bb, 0x7f72fcb4, 0x0c0ebe66, 0x7f6e4a5e, 0x0c40c835, 0x7f698461, 0x0c72d020, 0x7f64aabf,
    412 0x0ca4d620, 0x7f5fbd77, 0x0cd6da2d, 0x7f5abc8a, 0x0d08dc3f, 0x7f55a7fa, 0x0d3adc4e, 0x7f507fc7,
    413 0x0d6cda53, 0x7f4b43f2, 0x0d9ed646, 0x7f45f47b, 0x0dd0d01f, 0x7f409164, 0x0e02c7d7, 0x7f3b1aad,
    414 0x0e34bd66, 0x7f359057, 0x0e66b0c3, 0x7f2ff263, 0x0e98a1e9, 0x7f2a40d2, 0x0eca90ce, 0x7f247ba5,
    415 0x0efc7d6b, 0x7f1ea2dc, 0x0f2e67b8, 0x7f18b679, 0x0f604faf, 0x7f12b67c, 0x0f923546, 0x7f0ca2e7,
    416 0x0fc41876, 0x7f067bba, 0x0ff5f938, 0x7f0040f6, 0x1027d784, 0x7ef9f29d, 0x1059b352, 0x7ef390ae,
    417 0x108b8c9b, 0x7eed1b2c, 0x10bd6356, 0x7ee69217, 0x10ef377d, 0x7edff570, 0x11210907, 0x7ed94538,
    418 0x1152d7ed, 0x7ed28171, 0x1184a427, 0x7ecbaa1a, 0x11b66dad, 0x7ec4bf36, 0x11e83478, 0x7ebdc0c6,
    419 0x1219f880, 0x7eb6aeca, 0x124bb9be, 0x7eaf8943, 0x127d7829, 0x7ea85033, 0x12af33ba, 0x7ea1039b,
    420 0x12e0ec6a, 0x7e99a37c, 0x1312a230, 0x7e922fd6, 0x13445505, 0x7e8aa8ac, 0x137604e2, 0x7e830dff,
    421 0x13a7b1bf, 0x7e7b5fce, 0x13d95b93, 0x7e739e1d, 0x140b0258, 0x7e6bc8eb, 0x143ca605, 0x7e63e03b,
    422 0x146e4694, 0x7e5be40c, 0x149fe3fc, 0x7e53d462, 0x14d17e36, 0x7e4bb13c, 0x1503153a, 0x7e437a9c,
    423 0x1534a901, 0x7e3b3083, 0x15663982, 0x7e32d2f4, 0x1597c6b7, 0x7e2a61ed, 0x15c95097, 0x7e21dd73,
    424 0x15fad71b, 0x7e194584, 0x162c5a3b, 0x7e109a24, 0x165dd9f0, 0x7e07db52, 0x168f5632, 0x7dff0911,
    425 0x16c0cef9, 0x7df62362, 0x16f2443e, 0x7ded2a47, 0x1723b5f9, 0x7de41dc0, 0x17552422, 0x7ddafdce,
    426 0x17868eb3, 0x7dd1ca75, 0x17b7f5a3, 0x7dc883b4, 0x17e958ea, 0x7dbf298d, 0x181ab881, 0x7db5bc02,
    427 0x184c1461, 0x7dac3b15, 0x187d6c82, 0x7da2a6c6, 0x18aec0db, 0x7d98ff17, 0x18e01167, 0x7d8f4409,
    428 0x19115e1c, 0x7d85759f, 0x1942a6f3, 0x7d7b93da, 0x1973ebe6, 0x7d719eba, 0x19a52ceb, 0x7d679642,
    429 0x19d669fc, 0x7d5d7a74, 0x1a07a311, 0x7d534b50, 0x1a38d823, 0x7d4908d9, 0x1a6a0929, 0x7d3eb30f,
    430 0x1a9b361d, 0x7d3449f5, 0x1acc5ef6, 0x7d29cd8c, 0x1afd83ad, 0x7d1f3dd6, 0x1b2ea43a, 0x7d149ad5,
    431 0x1b5fc097, 0x7d09e489, 0x1b90d8bb, 0x7cff1af5, 0x1bc1ec9e, 0x7cf43e1a, 0x1bf2fc3a, 0x7ce94dfb,
    432 0x1c240786, 0x7cde4a98, 0x1c550e7c, 0x7cd333f3, 0x1c861113, 0x7cc80a0f, 0x1cb70f43, 0x7cbcccec,
    433 0x1ce80906, 0x7cb17c8d, 0x1d18fe54, 0x7ca618f3, 0x1d49ef26, 0x7c9aa221, 0x1d7adb73, 0x7c8f1817,
    434 0x1dabc334, 0x7c837ad8, 0x1ddca662, 0x7c77ca65, 0x1e0d84f5, 0x7c6c06c0, 0x1e3e5ee5, 0x7c602fec,
    435 0x1e6f342c, 0x7c5445e9, 0x1ea004c1, 0x7c4848ba, 0x1ed0d09d, 0x7c3c3860, 0x1f0197b8, 0x7c3014de,
    436 0x1f325a0b, 0x7c23de35, 0x1f63178f, 0x7c179467, 0x1f93d03c, 0x7c0b3777, 0x1fc4840a, 0x7bfec765,
    437 0x1ff532f2, 0x7bf24434, 0x2025dcec, 0x7be5ade6, 0x205681f1, 0x7bd9047c, 0x208721f9, 0x7bcc47fa,
    438 0x20b7bcfe, 0x7bbf7860, 0x20e852f6, 0x7bb295b0, 0x2118e3dc, 0x7ba59fee, 0x21496fa7, 0x7b989719,
    439 0x2179f64f, 0x7b8b7b36, 0x21aa77cf, 0x7b7e4c45, 0x21daf41d, 0x7b710a49, 0x220b6b32, 0x7b63b543,
    440 0x223bdd08, 0x7b564d36, 0x226c4996, 0x7b48d225, 0x229cb0d5, 0x7b3b4410, 0x22cd12bd, 0x7b2da2fa,
    441 0x22fd6f48, 0x7b1feee5, 0x232dc66d, 0x7b1227d3, 0x235e1826, 0x7b044dc7, 0x238e646a, 0x7af660c2,
    442 0x23beab33, 0x7ae860c7, 0x23eeec78, 0x7ada4dd8, 0x241f2833, 0x7acc27f7, 0x244f5e5c, 0x7abdef25,
    443 0x247f8eec, 0x7aafa367, 0x24afb9da, 0x7aa144bc, 0x24dfdf20, 0x7a92d329, 0x250ffeb7, 0x7a844eae,
    444 0x25401896, 0x7a75b74f, 0x25702cb7, 0x7a670d0d, 0x25a03b11, 0x7a584feb, 0x25d0439f, 0x7a497feb,
    445 0x26004657, 0x7a3a9d0f, 0x26304333, 0x7a2ba75a, 0x26603a2c, 0x7a1c9ece, 0x26902b39, 0x7a0d836d,
    446 0x26c01655, 0x79fe5539, 0x26effb76, 0x79ef1436, 0x271fda96, 0x79dfc064, 0x274fb3ae, 0x79d059c8,
    447 0x277f86b5, 0x79c0e062, 0x27af53a6, 0x79b15435, 0x27df1a77, 0x79a1b545, 0x280edb23, 0x79920392,
    448 0x283e95a1, 0x79823f20, 0x286e49ea, 0x797267f2, 0x289df7f8, 0x79627e08, 0x28cd9fc1, 0x79528167,
    449 0x28fd4140, 0x79427210, 0x292cdc6d, 0x79325006, 0x295c7140, 0x79221b4b, 0x298bffb2, 0x7911d3e2,
    450 0x29bb87bc, 0x790179cd, 0x29eb0957, 0x78f10d0f, 0x2a1a847b, 0x78e08dab, 0x2a49f920, 0x78cffba3,
    451 0x2a796740, 0x78bf56f9, 0x2aa8ced3, 0x78ae9fb0, 0x2ad82fd2, 0x789dd5cb, 0x2b078a36, 0x788cf94c,
    452 0x2b36ddf7, 0x787c0a36, 0x2b662b0e, 0x786b088c, 0x2b957173, 0x7859f44f, 0x2bc4b120, 0x7848cd83,
    453 0x2bf3ea0d, 0x7837942b, 0x2c231c33, 0x78264849, 0x2c52478a, 0x7814e9df, 0x2c816c0c, 0x780378f1,
    454 0x2cb089b1, 0x77f1f581, 0x2cdfa071, 0x77e05f91, 0x2d0eb046, 0x77ceb725, 0x2d3db928, 0x77bcfc3f,
    455 0x2d6cbb10, 0x77ab2ee2, 0x2d9bb5f6, 0x77994f11, 0x2dcaa9d5, 0x77875cce, 0x2df996a3, 0x7775581d,
    456 0x2e287c5a, 0x776340ff, 0x2e575af3, 0x77511778, 0x2e863267, 0x773edb8b, 0x2eb502ae, 0x772c8d3a,
    457 0x2ee3cbc1, 0x771a2c88, 0x2f128d99, 0x7707b979, 0x2f41482e, 0x76f5340e, 0x2f6ffb7a, 0x76e29c4b,
    458 0x2f9ea775, 0x76cff232, 0x2fcd4c19, 0x76bd35c7, 0x2ffbe95d, 0x76aa670d, 0x302a7f3a, 0x76978605,
    459 0x30590dab, 0x768492b4, 0x308794a6, 0x76718d1c, 0x30b61426, 0x765e7540, 0x30e48c22, 0x764b4b23,
    460 0x3112fc95, 0x76380ec8, 0x31416576, 0x7624c031, 0x316fc6be, 0x76115f63, 0x319e2067, 0x75fdec60,
    461 0x31cc7269, 0x75ea672a, 0x31fabcbd, 0x75d6cfc5, 0x3228ff5c, 0x75c32634, 0x32573a3f, 0x75af6a7b,
    462 0x32856d5e, 0x759b9c9b, 0x32b398b3, 0x7587bc98, 0x32e1bc36, 0x7573ca75, 0x330fd7e1, 0x755fc635,
    463 0x333debab, 0x754bafdc, 0x336bf78f, 0x7537876c, 0x3399fb85, 0x75234ce8, 0x33c7f785, 0x750f0054,
    464 0x33f5eb89, 0x74faa1b3, 0x3423d78a, 0x74e63108, 0x3451bb81, 0x74d1ae55, 0x347f9766, 0x74bd199f,
    465 0x34ad6b32, 0x74a872e8, 0x34db36df, 0x7493ba34, 0x3508fa66, 0x747eef85, 0x3536b5be, 0x746a12df,
    466 0x356468e2, 0x74552446, 0x359213c9, 0x744023bc, 0x35bfb66e, 0x742b1144, 0x35ed50c9, 0x7415ece2,
    467 0x361ae2d3, 0x7400b69a, 0x36486c86, 0x73eb6e6e, 0x3675edd9, 0x73d61461, 0x36a366c6, 0x73c0a878,
    468 0x36d0d746, 0x73ab2ab4, 0x36fe3f52, 0x73959b1b, 0x372b9ee3, 0x737ff9ae, 0x3758f5f2, 0x736a4671,
    469 0x37864477, 0x73548168, 0x37b38a6d, 0x733eaa96, 0x37e0c7cc, 0x7328c1ff, 0x380dfc8d, 0x7312c7a5,
    470 0x383b28a9, 0x72fcbb8c, 0x38684c19, 0x72e69db7, 0x389566d6, 0x72d06e2b, 0x38c278d9, 0x72ba2cea,
    471 0x38ef821c, 0x72a3d9f7, 0x391c8297, 0x728d7557, 0x39497a43, 0x7276ff0d, 0x39766919, 0x7260771b,
    472 0x39a34f13, 0x7249dd86, 0x39d02c2a, 0x72333251, 0x39fd0056, 0x721c7580, 0x3a29cb91, 0x7205a716,
    473 0x3a568dd4, 0x71eec716, 0x3a834717, 0x71d7d585, 0x3aaff755, 0x71c0d265, 0x3adc9e86, 0x71a9bdba,
    474 0x3b093ca3, 0x71929789, 0x3b35d1a5, 0x717b5fd3, 0x3b625d86, 0x7164169d, 0x3b8ee03e, 0x714cbbeb,
    475 0x3bbb59c7, 0x71354fc0, 0x3be7ca1a, 0x711dd220, 0x3c143130, 0x7106430e, 0x3c408f03, 0x70eea28e,
    476 0x3c6ce38a, 0x70d6f0a4, 0x3c992ec0, 0x70bf2d53, 0x3cc5709e, 0x70a7589f, 0x3cf1a91c, 0x708f728b,
    477 0x3d1dd835, 0x70777b1c, 0x3d49fde1, 0x705f7255, 0x3d761a19, 0x70475839, 0x3da22cd7, 0x702f2ccd,
    478 0x3dce3614, 0x7016f014, 0x3dfa35c8, 0x6ffea212, 0x3e262bee, 0x6fe642ca, 0x3e52187f, 0x6fcdd241,
    479 0x3e7dfb73, 0x6fb5507a, 0x3ea9d4c3, 0x6f9cbd79, 0x3ed5a46b, 0x6f841942, 0x3f016a61, 0x6f6b63d8,
    480 0x3f2d26a0, 0x6f529d40, 0x3f58d921, 0x6f39c57d, 0x3f8481dd, 0x6f20dc92, 0x3fb020ce, 0x6f07e285,
    481 0x3fdbb5ec, 0x6eeed758, 0x40074132, 0x6ed5bb10, 0x4032c297, 0x6ebc8db0, 0x405e3a16, 0x6ea34f3d,
    482 0x4089a7a8, 0x6e89ffb9, 0x40b50b46, 0x6e709f2a, 0x40e064ea, 0x6e572d93, 0x410bb48c, 0x6e3daaf8,
    483 0x4136fa27, 0x6e24175c, 0x416235b2, 0x6e0a72c5, 0x418d6729, 0x6df0bd35, 0x41b88e84, 0x6dd6f6b1,
    484 0x41e3abbc, 0x6dbd1f3c, 0x420ebecb, 0x6da336dc, 0x4239c7aa, 0x6d893d93, 0x4264c653, 0x6d6f3365,
    485 0x428fbabe, 0x6d551858, 0x42baa4e6, 0x6d3aec6e, 0x42e584c3, 0x6d20afac, 0x43105a50, 0x6d066215,
    486 0x433b2585, 0x6cec03af, 0x4365e65b, 0x6cd1947c, 0x43909ccd, 0x6cb71482, 0x43bb48d4, 0x6c9c83c3,
    487 0x43e5ea68, 0x6c81e245, 0x44108184, 0x6c67300b, 0x443b0e21, 0x6c4c6d1a, 0x44659039, 0x6c319975,
    488 0x449007c4, 0x6c16b521, 0x44ba74bd, 0x6bfbc021, 0x44e4d71c, 0x6be0ba7b, 0x450f2edb, 0x6bc5a431,
    489 0x45397bf4, 0x6baa7d49, 0x4563be60, 0x6b8f45c7, 0x458df619, 0x6b73fdae, 0x45b82318, 0x6b58a503,
    490 0x45e24556, 0x6b3d3bcb, 0x460c5cce, 0x6b21c208, 0x46366978, 0x6b0637c1, 0x46606b4e, 0x6aea9cf8,
    491 0x468a624a, 0x6acef1b2, 0x46b44e65, 0x6ab335f4, 0x46de2f99, 0x6a9769c1, 0x470805df, 0x6a7b8d1e,
    492 0x4731d131, 0x6a5fa010, 0x475b9188, 0x6a43a29a, 0x478546de, 0x6a2794c1, 0x47aef12c, 0x6a0b7689,
    493 0x47d8906d, 0x69ef47f6, 0x48022499, 0x69d3090e, 0x482badab, 0x69b6b9d3, 0x48552b9b, 0x699a5a4c,
    494 0x487e9e64, 0x697dea7b, 0x48a805ff, 0x69616a65, 0x48d16265, 0x6944da10, 0x48fab391, 0x6928397e,
    495 0x4923f97b, 0x690b88b5, 0x494d341e, 0x68eec7b9, 0x49766373, 0x68d1f68f, 0x499f8774, 0x68b5153a,
    496 0x49c8a01b, 0x689823bf, 0x49f1ad61, 0x687b2224, 0x4a1aaf3f, 0x685e106c, 0x4a43a5b0, 0x6840ee9b,
    497 0x4a6c90ad, 0x6823bcb7, 0x4a957030, 0x68067ac3, 0x4abe4433, 0x67e928c5, 0x4ae70caf, 0x67cbc6c0,
    498 0x4b0fc99d, 0x67ae54ba, 0x4b387af9, 0x6790d2b6, 0x4b6120bb, 0x677340ba, 0x4b89badd, 0x67559eca,
    499 0x4bb24958, 0x6737ecea, 0x4bdacc28, 0x671a2b20, 0x4c034345, 0x66fc596f, 0x4c2baea9, 0x66de77dc,
    500 0x4c540e4e, 0x66c0866d, 0x4c7c622d, 0x66a28524, 0x4ca4aa41, 0x66847408, 0x4ccce684, 0x6666531d,
    501 0x4cf516ee, 0x66482267, 0x4d1d3b7a, 0x6629e1ec, 0x4d455422, 0x660b91af, 0x4d6d60df, 0x65ed31b5,
    502 0x4d9561ac, 0x65cec204, 0x4dbd5682, 0x65b0429f, 0x4de53f5a, 0x6591b38c, 0x4e0d1c30, 0x657314cf,
    503 0x4e34ecfc, 0x6554666d, 0x4e5cb1b9, 0x6535a86b, 0x4e846a60, 0x6516dacd, 0x4eac16eb, 0x64f7fd98,
    504 0x4ed3b755, 0x64d910d1, 0x4efb4b96, 0x64ba147d, 0x4f22d3aa, 0x649b08a0, 0x4f4a4f89, 0x647bed3f,
    505 0x4f71bf2e, 0x645cc260, 0x4f992293, 0x643d8806, 0x4fc079b1, 0x641e3e38, 0x4fe7c483, 0x63fee4f8,
    506 0x500f0302, 0x63df7c4d, 0x50363529, 0x63c0043b, 0x505d5af1, 0x63a07cc7, 0x50847454, 0x6380e5f6,
    507 0x50ab814d, 0x63613fcd, 0x50d281d5, 0x63418a50, 0x50f975e6, 0x6321c585, 0x51205d7b, 0x6301f171,
    508 0x5147388c, 0x62e20e17, 0x516e0715, 0x62c21b7e, 0x5194c910, 0x62a219aa, 0x51bb7e75, 0x628208a1,
    509 0x51e22740, 0x6261e866, 0x5208c36a, 0x6241b8ff, 0x522f52ee, 0x62217a72, 0x5255d5c5, 0x62012cc2,
    510 0x527c4bea, 0x61e0cff5, 0x52a2b556, 0x61c06410, 0x52c91204, 0x619fe918, 0x52ef61ee, 0x617f5f12,
    511 0x5315a50e, 0x615ec603, 0x533bdb5d, 0x613e1df0, 0x536204d7, 0x611d66de, 0x53882175, 0x60fca0d2,
    512 0x53ae3131, 0x60dbcbd1, 0x53d43406, 0x60bae7e1, 0x53fa29ed, 0x6099f505, 0x542012e1, 0x6078f344,
    513 0x5445eedb, 0x6057e2a2, 0x546bbdd7, 0x6036c325, 0x54917fce, 0x601594d1, 0x54b734ba, 0x5ff457ad,
    514 0x54dcdc96, 0x5fd30bbc, 0x5502775c, 0x5fb1b104, 0x55280505, 0x5f90478a, 0x554d858d, 0x5f6ecf53,
    515 0x5572f8ed, 0x5f4d4865, 0x55985f20, 0x5f2bb2c5, 0x55bdb81f, 0x5f0a0e77, 0x55e303e6, 0x5ee85b82,
    516 0x5608426e, 0x5ec699e9, 0x562d73b2, 0x5ea4c9b3, 0x565297ab, 0x5e82eae5, 0x5677ae54, 0x5e60fd84,
    517 0x569cb7a8, 0x5e3f0194, 0x56c1b3a1, 0x5e1cf71c, 0x56e6a239, 0x5dfade20, 0x570b8369, 0x5dd8b6a7,
    518 0x5730572e, 0x5db680b4, 0x57551d80, 0x5d943c4e, 0x5779d65b, 0x5d71e979, 0x579e81b8, 0x5d4f883b,
    519 0x57c31f92, 0x5d2d189a, 0x57e7afe4, 0x5d0a9a9a, 0x580c32a7, 0x5ce80e41, 0x5830a7d6, 0x5cc57394,
    520 0x58550f6c, 0x5ca2ca99, 0x58796962, 0x5c801354, 0x589db5b3, 0x5c5d4dcc, 0x58c1f45b, 0x5c3a7a05,
    521 0x58e62552, 0x5c179806, 0x590a4893, 0x5bf4a7d2, 0x592e5e19, 0x5bd1a971, 0x595265df, 0x5bae9ce7,
    522 0x59765fde, 0x5b8b8239, 0x599a4c12, 0x5b68596d, 0x59be2a74, 0x5b452288, 0x59e1faff, 0x5b21dd90,
    523 0x5a05bdae, 0x5afe8a8b, 0x5a29727b, 0x5adb297d, 0x5a4d1960, 0x5ab7ba6c, 0x5a70b258, 0x5a943d5e,
    524 };
    525 
    526 const int kbdWindowOffset[NUM_IMDCT_SIZES] PROGMEM = {0, 128};
    527 
    528 const int kbdWindow[128 + 1024] PROGMEM = {
    529 /* 128 - format = Q31 * 2^0 */
    530 0x00016f63, 0x7ffffffe, 0x0003e382, 0x7ffffff1, 0x00078f64, 0x7fffffc7, 0x000cc323, 0x7fffff5d,
    531 0x0013d9ed, 0x7ffffe76, 0x001d3a9d, 0x7ffffcaa, 0x0029581f, 0x7ffff953, 0x0038b1bd, 0x7ffff372,
    532 0x004bd34d, 0x7fffe98b, 0x00635538, 0x7fffd975, 0x007fdc64, 0x7fffc024, 0x00a219f1, 0x7fff995b,
    533 0x00cacad0, 0x7fff5f5b, 0x00fab72d, 0x7fff0a75, 0x0132b1af, 0x7ffe9091, 0x01739689, 0x7ffde49e,
    534 0x01be4a63, 0x7ffcf5ef, 0x0213b910, 0x7ffbaf84, 0x0274d41e, 0x7ff9f73a, 0x02e2913a, 0x7ff7acf1,
    535 0x035de86c, 0x7ff4a99a, 0x03e7d233, 0x7ff0be3d, 0x0481457c, 0x7febb2f1, 0x052b357c, 0x7fe545d4,
    536 0x05e68f77, 0x7fdd2a02, 0x06b4386f, 0x7fd30695, 0x07950acb, 0x7fc675b4, 0x0889d3ef, 0x7fb703be,
    537 0x099351e0, 0x7fa42e89, 0x0ab230e0, 0x7f8d64d8, 0x0be70923, 0x7f7205f8, 0x0d325c93, 0x7f516195,
    538 0x0e9494ae, 0x7f2ab7d0, 0x100e0085, 0x7efd3997, 0x119ed2ef, 0x7ec8094a, 0x134720d8, 0x7e8a3ba7,
    539 0x1506dfdc, 0x7e42d906, 0x16dde50b, 0x7df0dee4, 0x18cbe3f7, 0x7d9341b4, 0x1ad06e07, 0x7d28ef02,
    540 0x1ceaf215, 0x7cb0cfcc, 0x1f1abc4f, 0x7c29cb20, 0x215ef677, 0x7b92c8eb, 0x23b6a867, 0x7aeab4ec,
    541 0x2620b8ec, 0x7a3081d0, 0x289beef5, 0x79632c5a, 0x2b26f30b, 0x7881be95, 0x2dc0511f, 0x778b5304,
    542 0x30667aa2, 0x767f17c0, 0x3317c8dd, 0x755c5178, 0x35d27f98, 0x74225e50, 0x3894cff3, 0x72d0b887,
    543 0x3b5cdb7b, 0x7166f8e7, 0x3e28b770, 0x6fe4d8e8, 0x40f6702a, 0x6e4a3491, 0x43c40caa, 0x6c970bfc,
    544 0x468f9231, 0x6acb8483, 0x495707f5, 0x68e7e994, 0x4c187ac7, 0x66ecad1c, 0x4ed200c5, 0x64da6797,
    545 0x5181bcea, 0x62b1d7b7, 0x5425e28e, 0x6073e1ae, 0x56bcb8c2, 0x5e218e16, 0x59449d76, 0x5bbc0875,
    546 /* 1024 - format = Q31 * 2^0 */
    547 0x0009962f, 0x7fffffa4, 0x000e16fb, 0x7fffff39, 0x0011ea65, 0x7ffffebf, 0x0015750e, 0x7ffffe34,
    548 0x0018dc74, 0x7ffffd96, 0x001c332e, 0x7ffffce5, 0x001f83f5, 0x7ffffc1f, 0x0022d59a, 0x7ffffb43,
    549 0x00262cc2, 0x7ffffa4f, 0x00298cc4, 0x7ffff942, 0x002cf81f, 0x7ffff81a, 0x003070c4, 0x7ffff6d6,
    550 0x0033f840, 0x7ffff573, 0x00378fd9, 0x7ffff3f1, 0x003b38a1, 0x7ffff24d, 0x003ef381, 0x7ffff085,
    551 0x0042c147, 0x7fffee98, 0x0046a2a8, 0x7fffec83, 0x004a9847, 0x7fffea44, 0x004ea2b7, 0x7fffe7d8,
    552 0x0052c283, 0x7fffe53f, 0x0056f829, 0x7fffe274, 0x005b4422, 0x7fffdf76, 0x005fa6dd, 0x7fffdc43,
    553 0x006420c8, 0x7fffd8d6, 0x0068b249, 0x7fffd52f, 0x006d5bc4, 0x7fffd149, 0x00721d9a, 0x7fffcd22,
    554 0x0076f828, 0x7fffc8b6, 0x007bebca, 0x7fffc404, 0x0080f8d9, 0x7fffbf06, 0x00861fae, 0x7fffb9bb,
    555 0x008b609e, 0x7fffb41e, 0x0090bbff, 0x7fffae2c, 0x00963224, 0x7fffa7e1, 0x009bc362, 0x7fffa13a,
    556 0x00a17009, 0x7fff9a32, 0x00a7386c, 0x7fff92c5, 0x00ad1cdc, 0x7fff8af0, 0x00b31da8, 0x7fff82ad,
    557 0x00b93b21, 0x7fff79f9, 0x00bf7596, 0x7fff70cf, 0x00c5cd57, 0x7fff672a, 0x00cc42b1, 0x7fff5d05,
    558 0x00d2d5f3, 0x7fff525c, 0x00d9876c, 0x7fff4729, 0x00e05769, 0x7fff3b66, 0x00e74638, 0x7fff2f10,
    559 0x00ee5426, 0x7fff221f, 0x00f58182, 0x7fff148e, 0x00fcce97, 0x7fff0658, 0x01043bb3, 0x7ffef776,
    560 0x010bc923, 0x7ffee7e2, 0x01137733, 0x7ffed795, 0x011b4631, 0x7ffec68a, 0x01233669, 0x7ffeb4ba,
    561 0x012b4827, 0x7ffea21d, 0x01337bb8, 0x7ffe8eac, 0x013bd167, 0x7ffe7a61, 0x01444982, 0x7ffe6533,
    562 0x014ce454, 0x7ffe4f1c, 0x0155a229, 0x7ffe3813, 0x015e834d, 0x7ffe2011, 0x0167880c, 0x7ffe070d,
    563 0x0170b0b2, 0x7ffdecff, 0x0179fd8b, 0x7ffdd1df, 0x01836ee1, 0x7ffdb5a2, 0x018d0500, 0x7ffd9842,
    564 0x0196c035, 0x7ffd79b3, 0x01a0a0ca, 0x7ffd59ee, 0x01aaa70a, 0x7ffd38e8, 0x01b4d341, 0x7ffd1697,
    565 0x01bf25b9, 0x7ffcf2f2, 0x01c99ebd, 0x7ffccdee, 0x01d43e99, 0x7ffca780, 0x01df0597, 0x7ffc7f9e,
    566 0x01e9f401, 0x7ffc563d, 0x01f50a22, 0x7ffc2b51, 0x02004844, 0x7ffbfecf, 0x020baeb1, 0x7ffbd0ab,
    567 0x02173db4, 0x7ffba0da, 0x0222f596, 0x7ffb6f4f, 0x022ed6a1, 0x7ffb3bfd, 0x023ae11f, 0x7ffb06d8,
    568 0x02471558, 0x7ffacfd3, 0x02537397, 0x7ffa96e0, 0x025ffc25, 0x7ffa5bf2, 0x026caf4a, 0x7ffa1efc,
    569 0x02798d4f, 0x7ff9dfee, 0x0286967c, 0x7ff99ebb, 0x0293cb1b, 0x7ff95b55, 0x02a12b72, 0x7ff915ab,
    570 0x02aeb7cb, 0x7ff8cdaf, 0x02bc706d, 0x7ff88351, 0x02ca559f, 0x7ff83682, 0x02d867a9, 0x7ff7e731,
    571 0x02e6a6d2, 0x7ff7954e, 0x02f51361, 0x7ff740c8, 0x0303ad9c, 0x7ff6e98e, 0x031275ca, 0x7ff68f8f,
    572 0x03216c30, 0x7ff632ba, 0x03309116, 0x7ff5d2fb, 0x033fe4bf, 0x7ff57042, 0x034f6773, 0x7ff50a7a,
    573 0x035f1975, 0x7ff4a192, 0x036efb0a, 0x7ff43576, 0x037f0c78, 0x7ff3c612, 0x038f4e02, 0x7ff35353,
    574 0x039fbfeb, 0x7ff2dd24, 0x03b06279, 0x7ff26370, 0x03c135ed, 0x7ff1e623, 0x03d23a8b, 0x7ff16527,
    575 0x03e37095, 0x7ff0e067, 0x03f4d84e, 0x7ff057cc, 0x040671f7, 0x7fefcb40, 0x04183dd3, 0x7fef3aad,
    576 0x042a3c22, 0x7feea5fa, 0x043c6d25, 0x7fee0d11, 0x044ed11d, 0x7fed6fda, 0x04616849, 0x7fecce3d,
    577 0x047432eb, 0x7fec2821, 0x04873140, 0x7feb7d6c, 0x049a6388, 0x7feace07, 0x04adca01, 0x7fea19d6,
    578 0x04c164ea, 0x7fe960c0, 0x04d53481, 0x7fe8a2aa, 0x04e93902, 0x7fe7df79, 0x04fd72aa, 0x7fe71712,
    579 0x0511e1b6, 0x7fe6495a, 0x05268663, 0x7fe57634, 0x053b60eb, 0x7fe49d83, 0x05507189, 0x7fe3bf2b,
    580 0x0565b879, 0x7fe2db0f, 0x057b35f4, 0x7fe1f110, 0x0590ea35, 0x7fe10111, 0x05a6d574, 0x7fe00af3,
    581 0x05bcf7ea, 0x7fdf0e97, 0x05d351cf, 0x7fde0bdd, 0x05e9e35c, 0x7fdd02a6, 0x0600acc8, 0x7fdbf2d2,
    582 0x0617ae48, 0x7fdadc40, 0x062ee814, 0x7fd9becf, 0x06465a62, 0x7fd89a5e, 0x065e0565, 0x7fd76eca,
    583 0x0675e954, 0x7fd63bf1, 0x068e0662, 0x7fd501b0, 0x06a65cc3, 0x7fd3bfe4, 0x06beecaa, 0x7fd2766a,
    584 0x06d7b648, 0x7fd1251e, 0x06f0b9d1, 0x7fcfcbda, 0x0709f775, 0x7fce6a7a, 0x07236f65, 0x7fcd00d8,
    585 0x073d21d2, 0x7fcb8ecf, 0x07570eea, 0x7fca1439, 0x077136dd, 0x7fc890ed, 0x078b99da, 0x7fc704c7,
    586 0x07a6380d, 0x7fc56f9d, 0x07c111a4, 0x7fc3d147, 0x07dc26cc, 0x7fc2299e, 0x07f777b1, 0x7fc07878,
    587 0x0813047d, 0x7fbebdac, 0x082ecd5b, 0x7fbcf90f, 0x084ad276, 0x7fbb2a78, 0x086713f7, 0x7fb951bc,
    588 0x08839206, 0x7fb76eaf, 0x08a04ccb, 0x7fb58126, 0x08bd446e, 0x7fb388f4, 0x08da7915, 0x7fb185ee,
    589 0x08f7eae7, 0x7faf77e5, 0x09159a09, 0x7fad5ead, 0x0933869f, 0x7fab3a17, 0x0951b0cd, 0x7fa909f6,
    590 0x097018b7, 0x7fa6ce1a, 0x098ebe7f, 0x7fa48653, 0x09ada248, 0x7fa23273, 0x09ccc431, 0x7f9fd249,
    591 0x09ec245b, 0x7f9d65a4, 0x0a0bc2e7, 0x7f9aec53, 0x0a2b9ff3, 0x7f986625, 0x0a4bbb9e, 0x7f95d2e7,
    592 0x0a6c1604, 0x7f933267, 0x0a8caf43, 0x7f908472, 0x0aad8776, 0x7f8dc8d5, 0x0ace9eb9, 0x7f8aff5c,
    593 0x0aeff526, 0x7f8827d3, 0x0b118ad8, 0x7f854204, 0x0b335fe6, 0x7f824dbb, 0x0b557469, 0x7f7f4ac3,
    594 0x0b77c879, 0x7f7c38e4, 0x0b9a5c2b, 0x7f7917e9, 0x0bbd2f97, 0x7f75e79b, 0x0be042d0, 0x7f72a7c3,
    595 0x0c0395ec, 0x7f6f5828, 0x0c2728fd, 0x7f6bf892, 0x0c4afc16, 0x7f6888c9, 0x0c6f0f4a, 0x7f650894,
    596 0x0c9362a8, 0x7f6177b9, 0x0cb7f642, 0x7f5dd5ff, 0x0cdcca26, 0x7f5a232a, 0x0d01de63, 0x7f565f00,
    597 0x0d273307, 0x7f528947, 0x0d4cc81f, 0x7f4ea1c2, 0x0d729db7, 0x7f4aa835, 0x0d98b3da, 0x7f469c65,
    598 0x0dbf0a92, 0x7f427e13, 0x0de5a1e9, 0x7f3e4d04, 0x0e0c79e7, 0x7f3a08f9, 0x0e339295, 0x7f35b1b4,
    599 0x0e5aebfa, 0x7f3146f8, 0x0e82861a, 0x7f2cc884, 0x0eaa60fd, 0x7f28361b, 0x0ed27ca5, 0x7f238f7c,
    600 0x0efad917, 0x7f1ed467, 0x0f237656, 0x7f1a049d, 0x0f4c5462, 0x7f151fdc, 0x0f75733d, 0x7f1025e3,
    601 0x0f9ed2e6, 0x7f0b1672, 0x0fc8735e, 0x7f05f146, 0x0ff254a1, 0x7f00b61d, 0x101c76ae, 0x7efb64b4,
    602 0x1046d981, 0x7ef5fcca, 0x10717d15, 0x7ef07e19, 0x109c6165, 0x7eeae860, 0x10c7866a, 0x7ee53b5b,
    603 0x10f2ec1e, 0x7edf76c4, 0x111e9279, 0x7ed99a58, 0x114a7971, 0x7ed3a5d1, 0x1176a0fc, 0x7ecd98eb,
    604 0x11a30910, 0x7ec77360, 0x11cfb1a1, 0x7ec134eb, 0x11fc9aa2, 0x7ebadd44, 0x1229c406, 0x7eb46c27,
    605 0x12572dbf, 0x7eade14c, 0x1284d7bc, 0x7ea73c6c, 0x12b2c1ed, 0x7ea07d41, 0x12e0ec42, 0x7e99a382,
    606 0x130f56a8, 0x7e92aee7, 0x133e010b, 0x7e8b9f2a, 0x136ceb59, 0x7e847402, 0x139c157b, 0x7e7d2d25,
    607 0x13cb7f5d, 0x7e75ca4c, 0x13fb28e6, 0x7e6e4b2d, 0x142b1200, 0x7e66af7f, 0x145b3a92, 0x7e5ef6f8,
    608 0x148ba281, 0x7e572150, 0x14bc49b4, 0x7e4f2e3b, 0x14ed300f, 0x7e471d70, 0x151e5575, 0x7e3eeea5,
    609 0x154fb9c9, 0x7e36a18e, 0x15815ced, 0x7e2e35e2, 0x15b33ec1, 0x7e25ab56, 0x15e55f25, 0x7e1d019e,
    610 0x1617bdf9, 0x7e14386e, 0x164a5b19, 0x7e0b4f7d, 0x167d3662, 0x7e02467e, 0x16b04fb2, 0x7df91d25,
    611 0x16e3a6e2, 0x7defd327, 0x17173bce, 0x7de66837, 0x174b0e4d, 0x7ddcdc0a, 0x177f1e39, 0x7dd32e53,
    612 0x17b36b69, 0x7dc95ec6, 0x17e7f5b3, 0x7dbf6d17, 0x181cbcec, 0x7db558f9, 0x1851c0e9, 0x7dab221f,
    613 0x1887017d, 0x7da0c83c, 0x18bc7e7c, 0x7d964b05, 0x18f237b6, 0x7d8baa2b, 0x19282cfd, 0x7d80e563,
    614 0x195e5e20, 0x7d75fc5e, 0x1994caee, 0x7d6aeed0, 0x19cb7335, 0x7d5fbc6d, 0x1a0256c2, 0x7d5464e6,
    615 0x1a397561, 0x7d48e7ef, 0x1a70cede, 0x7d3d453b, 0x1aa86301, 0x7d317c7c, 0x1ae03195, 0x7d258d65,
    616 0x1b183a63, 0x7d1977aa, 0x1b507d30, 0x7d0d3afc, 0x1b88f9c5, 0x7d00d710, 0x1bc1afe6, 0x7cf44b97,
    617 0x1bfa9f58, 0x7ce79846, 0x1c33c7e0, 0x7cdabcce, 0x1c6d293f, 0x7ccdb8e4, 0x1ca6c337, 0x7cc08c39,
    618 0x1ce0958a, 0x7cb33682, 0x1d1a9ff8, 0x7ca5b772, 0x1d54e240, 0x7c980ebd, 0x1d8f5c21, 0x7c8a3c14,
    619 0x1dca0d56, 0x7c7c3f2e, 0x1e04f59f, 0x7c6e17bc, 0x1e4014b4, 0x7c5fc573, 0x1e7b6a53, 0x7c514807,
    620 0x1eb6f633, 0x7c429f2c, 0x1ef2b80f, 0x7c33ca96, 0x1f2eaf9e, 0x7c24c9fa, 0x1f6adc98, 0x7c159d0d,
    621 0x1fa73eb2, 0x7c064383, 0x1fe3d5a3, 0x7bf6bd11, 0x2020a11e, 0x7be7096c, 0x205da0d8, 0x7bd7284a,
    622 0x209ad483, 0x7bc71960, 0x20d83bd1, 0x7bb6dc65, 0x2115d674, 0x7ba6710d, 0x2153a41b, 0x7b95d710,
    623 0x2191a476, 0x7b850e24, 0x21cfd734, 0x7b7415ff, 0x220e3c02, 0x7b62ee59, 0x224cd28d, 0x7b5196e9,
    624 0x228b9a82, 0x7b400f67, 0x22ca938a, 0x7b2e578a, 0x2309bd52, 0x7b1c6f0b, 0x23491783, 0x7b0a55a1,
    625 0x2388a1c4, 0x7af80b07, 0x23c85bbf, 0x7ae58ef5, 0x2408451a, 0x7ad2e124, 0x24485d7c, 0x7ac0014e,
    626 0x2488a48a, 0x7aacef2e, 0x24c919e9, 0x7a99aa7e, 0x2509bd3d, 0x7a8632f8, 0x254a8e29, 0x7a728858,
    627 0x258b8c50, 0x7a5eaa5a, 0x25ccb753, 0x7a4a98b9, 0x260e0ed3, 0x7a365333, 0x264f9271, 0x7a21d983,
    628 0x269141cb, 0x7a0d2b68, 0x26d31c80, 0x79f8489e, 0x2715222f, 0x79e330e4, 0x27575273, 0x79cde3f8,
    629 0x2799acea, 0x79b8619a, 0x27dc3130, 0x79a2a989, 0x281ededf, 0x798cbb85, 0x2861b591, 0x7976974e,
    630 0x28a4b4e0, 0x79603ca5, 0x28e7dc65, 0x7949ab4c, 0x292b2bb8, 0x7932e304, 0x296ea270, 0x791be390,
    631 0x29b24024, 0x7904acb3, 0x29f6046b, 0x78ed3e30, 0x2a39eed8, 0x78d597cc, 0x2a7dff02, 0x78bdb94a,
    632 0x2ac2347c, 0x78a5a270, 0x2b068eda, 0x788d5304, 0x2b4b0dae, 0x7874cacb, 0x2b8fb08a, 0x785c098d,
    633 0x2bd47700, 0x78430f11, 0x2c1960a1, 0x7829db1f, 0x2c5e6cfd, 0x78106d7f, 0x2ca39ba3, 0x77f6c5fb,
    634 0x2ce8ec23, 0x77dce45c, 0x2d2e5e0b, 0x77c2c86e, 0x2d73f0e8, 0x77a871fa, 0x2db9a449, 0x778de0cd,
    635 0x2dff77b8, 0x777314b2, 0x2e456ac4, 0x77580d78, 0x2e8b7cf6, 0x773ccaeb, 0x2ed1addb, 0x77214cdb,
    636 0x2f17fcfb, 0x77059315, 0x2f5e69e2, 0x76e99d69, 0x2fa4f419, 0x76cd6ba9, 0x2feb9b27, 0x76b0fda4,
    637 0x30325e96, 0x7694532e, 0x30793dee, 0x76776c17, 0x30c038b5, 0x765a4834, 0x31074e72, 0x763ce759,
    638 0x314e7eab, 0x761f4959, 0x3195c8e6, 0x76016e0b, 0x31dd2ca9, 0x75e35545, 0x3224a979, 0x75c4fedc,
    639 0x326c3ed8, 0x75a66aab, 0x32b3ec4d, 0x75879887, 0x32fbb159, 0x7568884b, 0x33438d81, 0x754939d1,
    640 0x338b8045, 0x7529acf4, 0x33d3892a, 0x7509e18e, 0x341ba7b1, 0x74e9d77d, 0x3463db5a, 0x74c98e9e,
    641 0x34ac23a7, 0x74a906cd, 0x34f48019, 0x74883fec, 0x353cf02f, 0x746739d8, 0x3585736a, 0x7445f472,
    642 0x35ce0949, 0x74246f9c, 0x3616b14c, 0x7402ab37, 0x365f6af0, 0x73e0a727, 0x36a835b5, 0x73be6350,
    643 0x36f11118, 0x739bdf95, 0x3739fc98, 0x73791bdd, 0x3782f7b2, 0x7356180e, 0x37cc01e3, 0x7332d410,
    644 0x38151aa8, 0x730f4fc9, 0x385e417e, 0x72eb8b24, 0x38a775e1, 0x72c7860a, 0x38f0b74d, 0x72a34066,
    645 0x393a053e, 0x727eba24, 0x39835f30, 0x7259f331, 0x39ccc49e, 0x7234eb79, 0x3a163503, 0x720fa2eb,
    646 0x3a5fafda, 0x71ea1977, 0x3aa9349e, 0x71c44f0c, 0x3af2c2ca, 0x719e439d, 0x3b3c59d7, 0x7177f71a,
    647 0x3b85f940, 0x71516978, 0x3bcfa07e, 0x712a9aaa, 0x3c194f0d, 0x71038aa4, 0x3c630464, 0x70dc395e,
    648 0x3cacbfff, 0x70b4a6cd, 0x3cf68155, 0x708cd2e9, 0x3d4047e1, 0x7064bdab, 0x3d8a131c, 0x703c670d,
    649 0x3dd3e27e, 0x7013cf0a, 0x3e1db580, 0x6feaf59c, 0x3e678b9b, 0x6fc1dac1, 0x3eb16449, 0x6f987e76,
    650 0x3efb3f01, 0x6f6ee0b9, 0x3f451b3d, 0x6f45018b, 0x3f8ef874, 0x6f1ae0eb, 0x3fd8d620, 0x6ef07edb,
    651 0x4022b3b9, 0x6ec5db5d, 0x406c90b7, 0x6e9af675, 0x40b66c93, 0x6e6fd027, 0x410046c5, 0x6e446879,
    652 0x414a1ec6, 0x6e18bf71, 0x4193f40d, 0x6decd517, 0x41ddc615, 0x6dc0a972, 0x42279455, 0x6d943c8d,
    653 0x42715e45, 0x6d678e71, 0x42bb235f, 0x6d3a9f2a, 0x4304e31a, 0x6d0d6ec5, 0x434e9cf1, 0x6cdffd4f,
    654 0x4398505b, 0x6cb24ad6, 0x43e1fcd1, 0x6c84576b, 0x442ba1cd, 0x6c56231c, 0x44753ec7, 0x6c27adfd,
    655 0x44bed33a, 0x6bf8f81e, 0x45085e9d, 0x6bca0195, 0x4551e06b, 0x6b9aca75, 0x459b581e, 0x6b6b52d5,
    656 0x45e4c52f, 0x6b3b9ac9, 0x462e2717, 0x6b0ba26b, 0x46777d52, 0x6adb69d3, 0x46c0c75a, 0x6aaaf11b,
    657 0x470a04a9, 0x6a7a385c, 0x475334b9, 0x6a493fb3, 0x479c5707, 0x6a18073d, 0x47e56b0c, 0x69e68f17,
    658 0x482e7045, 0x69b4d761, 0x4877662c, 0x6982e039, 0x48c04c3f, 0x6950a9c0, 0x490921f8, 0x691e341a,
    659 0x4951e6d5, 0x68eb7f67, 0x499a9a51, 0x68b88bcd, 0x49e33beb, 0x68855970, 0x4a2bcb1f, 0x6851e875,
    660 0x4a74476b, 0x681e3905, 0x4abcb04c, 0x67ea4b47, 0x4b050541, 0x67b61f63, 0x4b4d45c9, 0x6781b585,
    661 0x4b957162, 0x674d0dd6, 0x4bdd878c, 0x67182883, 0x4c2587c6, 0x66e305b8, 0x4c6d7190, 0x66ada5a5,
    662 0x4cb5446a, 0x66780878, 0x4cfcffd5, 0x66422e60, 0x4d44a353, 0x660c1790, 0x4d8c2e64, 0x65d5c439,
    663 0x4dd3a08c, 0x659f348e, 0x4e1af94b, 0x656868c3, 0x4e623825, 0x6531610d, 0x4ea95c9d, 0x64fa1da3,
    664 0x4ef06637, 0x64c29ebb, 0x4f375477, 0x648ae48d, 0x4f7e26e1, 0x6452ef53, 0x4fc4dcfb, 0x641abf46,
    665 0x500b7649, 0x63e254a2, 0x5051f253, 0x63a9afa2, 0x5098509f, 0x6370d083, 0x50de90b3, 0x6337b784,
    666 0x5124b218, 0x62fe64e3, 0x516ab455, 0x62c4d8e0, 0x51b096f3, 0x628b13bc, 0x51f6597b, 0x625115b8,
    667 0x523bfb78, 0x6216df18, 0x52817c72, 0x61dc701f, 0x52c6dbf5, 0x61a1c912, 0x530c198d, 0x6166ea36,
    668 0x535134c5, 0x612bd3d2, 0x53962d2a, 0x60f0862d, 0x53db024a, 0x60b50190, 0x541fb3b1, 0x60794644,
    669 0x546440ef, 0x603d5494, 0x54a8a992, 0x60012cca, 0x54eced2b, 0x5fc4cf33, 0x55310b48, 0x5f883c1c,
    670 0x5575037c, 0x5f4b73d2, 0x55b8d558, 0x5f0e76a5, 0x55fc806f, 0x5ed144e5, 0x56400452, 0x5e93dee1,
    671 0x56836096, 0x5e5644ec, 0x56c694cf, 0x5e187757, 0x5709a092, 0x5dda7677, 0x574c8374, 0x5d9c429f,
    672 0x578f3d0d, 0x5d5ddc24, 0x57d1ccf2, 0x5d1f435d, 0x581432bd, 0x5ce078a0, 0x58566e04, 0x5ca17c45,
    673 0x58987e63, 0x5c624ea4, 0x58da6372, 0x5c22f016, 0x591c1ccc, 0x5be360f6, 0x595daa0d, 0x5ba3a19f,
    674 0x599f0ad1, 0x5b63b26c, 0x59e03eb6, 0x5b2393ba, 0x5a214558, 0x5ae345e7, 0x5a621e56, 0x5aa2c951,
    675 };
    676 /* bit reverse tables for FFT */
    677 const uint8_t bitrevtabOffset[NUM_IMDCT_SIZES] PROGMEM = {0, 17};
    678 const uint8_t bitrevtab[17 + 129] PROGMEM = {
    679 /* nfft = 64 */
    680 0x01, 0x08, 0x02, 0x04, 0x03, 0x0c, 0x05, 0x0a, 0x07, 0x0e, 0x0b, 0x0d, 0x00, 0x06, 0x09, 0x0f,
    681 0x00,
    682 /* nfft = 512 */
    683 0x01, 0x40, 0x02, 0x20, 0x03, 0x60, 0x04, 0x10, 0x05, 0x50, 0x06, 0x30, 0x07, 0x70, 0x09, 0x48,
    684 0x0a, 0x28, 0x0b, 0x68, 0x0c, 0x18, 0x0d, 0x58, 0x0e, 0x38, 0x0f, 0x78, 0x11, 0x44, 0x12, 0x24,
    685 0x13, 0x64, 0x15, 0x54, 0x16, 0x34, 0x17, 0x74, 0x19, 0x4c, 0x1a, 0x2c, 0x1b, 0x6c, 0x1d, 0x5c,
    686 0x1e, 0x3c, 0x1f, 0x7c, 0x21, 0x42, 0x23, 0x62, 0x25, 0x52, 0x26, 0x32, 0x27, 0x72, 0x29, 0x4a,
    687 0x2b, 0x6a, 0x2d, 0x5a, 0x2e, 0x3a, 0x2f, 0x7a, 0x31, 0x46, 0x33, 0x66, 0x35, 0x56, 0x37, 0x76,
    688 0x39, 0x4e, 0x3b, 0x6e, 0x3d, 0x5e, 0x3f, 0x7e, 0x43, 0x61, 0x45, 0x51, 0x47, 0x71, 0x4b, 0x69,
    689 0x4d, 0x59, 0x4f, 0x79, 0x53, 0x65, 0x57, 0x75, 0x5b, 0x6d, 0x5f, 0x7d, 0x67, 0x73, 0x6f, 0x7b,
    690 0x00, 0x08, 0x14, 0x1c, 0x22, 0x2a, 0x36, 0x3e, 0x41, 0x49, 0x55, 0x5d, 0x63, 0x6b, 0x77, 0x7f,
    691 0x00,
    692 };
    693 
    694 const uint8_t uniqueIDTab[8] = {0x5f, 0x4b, 0x43, 0x5f, 0x5f, 0x4a, 0x52, 0x5f};
    695 
    696 const uint32_t twidTabOdd[8*6 + 32*6 + 128*6] PROGMEM = {
    697     0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x539eba45, 0xe7821d59,
    698     0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59,
    699     0x539eba45, 0xc4df2862, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060,
    700     0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x22a2f4f8, 0xc4df2862,
    701     0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862,
    702     0xac6145bb, 0x187de2a7, 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52,
    703     0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x45f704f7, 0xf9ba1651,
    704     0x43103085, 0xfcdc1342, 0x48b2b335, 0xf69bf7c9, 0x4b418bbe, 0xf383a3e2, 0x45f704f7, 0xf9ba1651,
    705     0x4fd288dc, 0xed6bf9d1, 0x4fd288dc, 0xed6bf9d1, 0x48b2b335, 0xf69bf7c9, 0x553805f2, 0xe4a2eff6,
    706     0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x569cc31b, 0xe1d4a2c8,
    707     0x4da1fab5, 0xf0730342, 0x5a6690ae, 0xd5052d97, 0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1,
    708     0x5a12e720, 0xce86ff2a, 0x5a12e720, 0xd76619b6, 0x51d1dc80, 0xea70658a, 0x57cc15bc, 0xc91af976,
    709     0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x5a12e720, 0xce86ff2a,
    710     0x553805f2, 0xe4a2eff6, 0x4da1fab5, 0xc1eb0209, 0x58c542c5, 0xcac933ae, 0x569cc31b, 0xe1d4a2c8,
    711     0x45f704f7, 0xc04ee4b8, 0x569cc31b, 0xc78e9a1d, 0x57cc15bc, 0xdf18f0ce, 0x3cc85709, 0xc013bc39,
    712     0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, 0x4fd288dc, 0xc2c17d52,
    713     0x5987b08a, 0xd9e01006, 0x26b2a794, 0xc3bdbdf6, 0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6,
    714     0x1a4608ab, 0xc78e9a1d, 0x45f704f7, 0xc04ee4b8, 0x5a6690ae, 0xd5052d97, 0x0d47d096, 0xcc983f70,
    715     0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x396b3199, 0xc04ee4b8,
    716     0x5a6690ae, 0xd09441bb, 0xf2b82f6a, 0xd9e01006, 0x3248d382, 0xc13ad060, 0x5a12e720, 0xce86ff2a,
    717     0xe5b9f755, 0xe1d4a2c8, 0x2aaa7c7f, 0xc2c17d52, 0x5987b08a, 0xcc983f70, 0xd94d586c, 0xea70658a,
    718     0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x1a4608ab, 0xc78e9a1d,
    719     0x57cc15bc, 0xc91af976, 0xc337a8f7, 0xfcdc1342, 0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d,
    720     0xba08fb09, 0x0645e9af, 0x08df1a8c, 0xce86ff2a, 0x553805f2, 0xc6250a18, 0xb25e054b, 0x0f8cfcbe,
    721     0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xf720e574, 0xd76619b6,
    722     0x51d1dc80, 0xc3bdbdf6, 0xa833ea44, 0x20e70f32, 0xee57aa21, 0xdc71898d, 0x4fd288dc, 0xc2c17d52,
    723     0xa5ed18e0, 0x2899e64a, 0xe5b9f755, 0xe1d4a2c8, 0x4da1fab5, 0xc1eb0209, 0xa5996f52, 0x2f6bbe45,
    724     0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, 0xd5558381, 0xed6bf9d1,
    725     0x48b2b335, 0xc0b15502, 0xaac7fa0e, 0x39daf5e8, 0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8,
    726     0xb02d7724, 0x3d3e82ae, 0xc694ce67, 0xf9ba1651, 0x43103085, 0xc013bc39, 0xb74d4ccb, 0x3f4eaafe,
    727     0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x418d2621, 0xfe6deaa1,
    728     0x40c7d2bd, 0xff36f170, 0x424ff28f, 0xfda4f351, 0x43103085, 0xfcdc1342, 0x418d2621, 0xfe6deaa1,
    729     0x4488e37f, 0xfb4ab7db, 0x4488e37f, 0xfb4ab7db, 0x424ff28f, 0xfda4f351, 0x46aa0d6d, 0xf8f21e8e,
    730     0x45f704f7, 0xf9ba1651, 0x43103085, 0xfcdc1342, 0x48b2b335, 0xf69bf7c9, 0x475a5c77, 0xf82a6c6a,
    731     0x43cdd89a, 0xfc135231, 0x4aa22036, 0xf4491311, 0x48b2b335, 0xf69bf7c9, 0x4488e37f, 0xfb4ab7db,
    732     0x4c77a88e, 0xf1fa3ecb, 0x49ffd417, 0xf50ef5de, 0x454149fc, 0xfa824bfd, 0x4e32a956, 0xefb047f2,
    733     0x4b418bbe, 0xf383a3e2, 0x45f704f7, 0xf9ba1651, 0x4fd288dc, 0xed6bf9d1, 0x4c77a88e, 0xf1fa3ecb,
    734     0x46aa0d6d, 0xf8f21e8e, 0x5156b6d9, 0xeb2e1dbe, 0x4da1fab5, 0xf0730342, 0x475a5c77, 0xf82a6c6a,
    735     0x52beac9f, 0xe8f77acf, 0x4ec05432, 0xeeee2d9d, 0x4807eb4b, 0xf7630799, 0x5409ed4b, 0xe6c8d59c,
    736     0x4fd288dc, 0xed6bf9d1, 0x48b2b335, 0xf69bf7c9, 0x553805f2, 0xe4a2eff6, 0x50d86e6d, 0xebeca36c,
    737     0x495aada2, 0xf5d544a7, 0x56488dc5, 0xe28688a4, 0x51d1dc80, 0xea70658a, 0x49ffd417, 0xf50ef5de,
    738     0x573b2635, 0xe0745b24, 0x52beac9f, 0xe8f77acf, 0x4aa22036, 0xf4491311, 0x580f7b19, 0xde6d1f65,
    739     0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x5471e2e6, 0xe61086bc,
    740     0x4bde1089, 0xf2beafed, 0x595c3e2a, 0xda8249b4, 0x553805f2, 0xe4a2eff6, 0x4c77a88e, 0xf1fa3ecb,
    741     0x59d438e5, 0xd8a00bae, 0x55f104dc, 0xe3399167, 0x4d0e4de2, 0xf136580d, 0x5a2d0957, 0xd6cb76c9,
    742     0x569cc31b, 0xe1d4a2c8, 0x4da1fab5, 0xf0730342, 0x5a6690ae, 0xd5052d97, 0x573b2635, 0xe0745b24,
    743     0x4e32a956, 0xefb047f2, 0x5a80baf6, 0xd34dcdb4, 0x57cc15bc, 0xdf18f0ce, 0x4ec05432, 0xeeee2d9d,
    744     0x5a7b7f1a, 0xd1a5ef90, 0x584f7b58, 0xddc29958, 0x4f4af5d1, 0xee2cbbc1, 0x5a56deec, 0xd00e2639,
    745     0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, 0x5a12e720, 0xce86ff2a, 0x592d59da, 0xdb25f566,
    746     0x50570819, 0xecabef3d, 0x59afaf4c, 0xcd110216, 0x5987b08a, 0xd9e01006, 0x50d86e6d, 0xebeca36c,
    747     0x592d59da, 0xcbacb0bf, 0x59d438e5, 0xd8a00bae, 0x5156b6d9, 0xeb2e1dbe, 0x588c1404, 0xca5a86c4,
    748     0x5a12e720, 0xd76619b6, 0x51d1dc80, 0xea70658a, 0x57cc15bc, 0xc91af976, 0x5a43b190, 0xd6326a88,
    749     0x5249daa2, 0xe9b38223, 0x56eda1a0, 0xc7ee77b3, 0x5a6690ae, 0xd5052d97, 0x52beac9f, 0xe8f77acf,
    750     0x55f104dc, 0xc6d569be, 0x5a7b7f1a, 0xd3de9156, 0x53304df6, 0xe83c56cf, 0x54d69714, 0xc5d03118,
    751     0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x5a7b7f1a, 0xd1a5ef90,
    752     0x5409ed4b, 0xe6c8d59c, 0x5249daa2, 0xc402a33c, 0x5a6690ae, 0xd09441bb, 0x5471e2e6, 0xe61086bc,
    753     0x50d86e6d, 0xc33aee27, 0x5a43b190, 0xcf89e3e8, 0x54d69714, 0xe55937d5, 0x4f4af5d1, 0xc2884e6e,
    754     0x5a12e720, 0xce86ff2a, 0x553805f2, 0xe4a2eff6, 0x4da1fab5, 0xc1eb0209, 0x59d438e5, 0xcd8bbb6d,
    755     0x55962bc0, 0xe3edb628, 0x4bde1089, 0xc1633f8a, 0x5987b08a, 0xcc983f70, 0x55f104dc, 0xe3399167,
    756     0x49ffd417, 0xc0f1360b, 0x592d59da, 0xcbacb0bf, 0x56488dc5, 0xe28688a4, 0x4807eb4b, 0xc0950d1d,
    757     0x58c542c5, 0xcac933ae, 0x569cc31b, 0xe1d4a2c8, 0x45f704f7, 0xc04ee4b8, 0x584f7b58, 0xc9edeb50,
    758     0x56eda1a0, 0xe123e6ad, 0x43cdd89a, 0xc01ed535, 0x57cc15bc, 0xc91af976, 0x573b2635, 0xe0745b24,
    759     0x418d2621, 0xc004ef3f, 0x573b2635, 0xc8507ea7, 0x57854ddd, 0xdfc606f1, 0x3f35b59d, 0xc0013bd3,
    760     0x569cc31b, 0xc78e9a1d, 0x57cc15bc, 0xdf18f0ce, 0x3cc85709, 0xc013bc39, 0x55f104dc, 0xc6d569be,
    761     0x580f7b19, 0xde6d1f65, 0x3a45e1f7, 0xc03c6a07, 0x553805f2, 0xc6250a18, 0x584f7b58, 0xddc29958,
    762     0x37af354c, 0xc07b371e, 0x5471e2e6, 0xc57d965d, 0x588c1404, 0xdd196538, 0x350536f1, 0xc0d00db6,
    763     0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, 0x52beac9f, 0xc449d892,
    764     0x58fb0568, 0xdbcb0cce, 0x2f7afdfc, 0xc1bb5a11, 0x51d1dc80, 0xc3bdbdf6, 0x592d59da, 0xdb25f566,
    765     0x2c9caf6c, 0xc2517e31, 0x50d86e6d, 0xc33aee27, 0x595c3e2a, 0xda8249b4, 0x29aee694, 0xc2fd08a9,
    766     0x4fd288dc, 0xc2c17d52, 0x5987b08a, 0xd9e01006, 0x26b2a794, 0xc3bdbdf6, 0x4ec05432, 0xc2517e31,
    767     0x59afaf4c, 0xd93f4e9e, 0x23a8fb93, 0xc4935b3c, 0x4da1fab5, 0xc1eb0209, 0x59d438e5, 0xd8a00bae,
    768     0x2092f05f, 0xc57d965d, 0x4c77a88e, 0xc18e18a7, 0x59f54bee, 0xd8024d59, 0x1d719810, 0xc67c1e18,
    769     0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, 0x1a4608ab, 0xc78e9a1d, 0x49ffd417, 0xc0f1360b,
    770     0x5a2d0957, 0xd6cb76c9, 0x17115bc0, 0xc8b4ab32, 0x48b2b335, 0xc0b15502, 0x5a43b190, 0xd6326a88,
    771     0x13d4ae08, 0xc9edeb50, 0x475a5c77, 0xc07b371e, 0x5a56deec, 0xd59afadb, 0x10911f04, 0xcb39edca,
    772     0x45f704f7, 0xc04ee4b8, 0x5a6690ae, 0xd5052d97, 0x0d47d096, 0xcc983f70, 0x4488e37f, 0xc02c64a6,
    773     0x5a72c63b, 0xd4710883, 0x09f9e6a1, 0xce0866b8, 0x43103085, 0xc013bc39, 0x5a7b7f1a, 0xd3de9156,
    774     0x06a886a0, 0xcf89e3e8, 0x418d2621, 0xc004ef3f, 0x5a80baf6, 0xd34dcdb4, 0x0354d741, 0xd11c3142,
    775     0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x3e68fb62, 0xc004ef3f,
    776     0x5a80baf6, 0xd2317756, 0xfcab28bf, 0xd4710883, 0x3cc85709, 0xc013bc39, 0x5a7b7f1a, 0xd1a5ef90,
    777     0xf9577960, 0xd6326a88, 0x3b1e5335, 0xc02c64a6, 0x5a72c63b, 0xd11c3142, 0xf606195f, 0xd8024d59,
    778     0x396b3199, 0xc04ee4b8, 0x5a6690ae, 0xd09441bb, 0xf2b82f6a, 0xd9e01006, 0x37af354c, 0xc07b371e,
    779     0x5a56deec, 0xd00e2639, 0xef6ee0fc, 0xdbcb0cce, 0x35eaa2c7, 0xc0b15502, 0x5a43b190, 0xcf89e3e8,
    780     0xec2b51f8, 0xddc29958, 0x341dbfd3, 0xc0f1360b, 0x5a2d0957, 0xcf077fe1, 0xe8eea440, 0xdfc606f1,
    781     0x3248d382, 0xc13ad060, 0x5a12e720, 0xce86ff2a, 0xe5b9f755, 0xe1d4a2c8, 0x306c2624, 0xc18e18a7,
    782     0x59f54bee, 0xce0866b8, 0xe28e67f0, 0xe3edb628, 0x2e88013a, 0xc1eb0209, 0x59d438e5, 0xcd8bbb6d,
    783     0xdf6d0fa1, 0xe61086bc, 0x2c9caf6c, 0xc2517e31, 0x59afaf4c, 0xcd110216, 0xdc57046d, 0xe83c56cf,
    784     0x2aaa7c7f, 0xc2c17d52, 0x5987b08a, 0xcc983f70, 0xd94d586c, 0xea70658a, 0x28b1b544, 0xc33aee27,
    785     0x595c3e2a, 0xcc217822, 0xd651196c, 0xecabef3d, 0x26b2a794, 0xc3bdbdf6, 0x592d59da, 0xcbacb0bf,
    786     0xd3635094, 0xeeee2d9d, 0x24ada23d, 0xc449d892, 0x58fb0568, 0xcb39edca, 0xd0850204, 0xf136580d,
    787     0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x2092f05f, 0xc57d965d,
    788     0x588c1404, 0xca5a86c4, 0xcafac90f, 0xf5d544a7, 0x1e7de5df, 0xc6250a18, 0x584f7b58, 0xc9edeb50,
    789     0xc850cab4, 0xf82a6c6a, 0x1c6427a9, 0xc6d569be, 0x580f7b19, 0xc9836582, 0xc5ba1e09, 0xfa824bfd,
    790     0x1a4608ab, 0xc78e9a1d, 0x57cc15bc, 0xc91af976, 0xc337a8f7, 0xfcdc1342, 0x1823dc7d, 0xc8507ea7,
    791     0x57854ddd, 0xc8b4ab32, 0xc0ca4a63, 0xff36f170, 0x15fdf758, 0xc91af976, 0x573b2635, 0xc8507ea7,
    792     0xbe72d9df, 0x0192155f, 0x13d4ae08, 0xc9edeb50, 0x56eda1a0, 0xc7ee77b3, 0xbc322766, 0x03ecadcf,
    793     0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, 0xba08fb09, 0x0645e9af, 0x0f7944a7, 0xcbacb0bf,
    794     0x56488dc5, 0xc730e997, 0xb7f814b5, 0x089cf867, 0x0d47d096, 0xcc983f70, 0x55f104dc, 0xc6d569be,
    795     0xb6002be9, 0x0af10a22, 0x0b145041, 0xcd8bbb6d, 0x55962bc0, 0xc67c1e18, 0xb421ef77, 0x0d415013,
    796     0x08df1a8c, 0xce86ff2a, 0x553805f2, 0xc6250a18, 0xb25e054b, 0x0f8cfcbe, 0x06a886a0, 0xcf89e3e8,
    797     0x54d69714, 0xc5d03118, 0xb0b50a2f, 0x11d3443f, 0x0470ebdc, 0xd09441bb, 0x5471e2e6, 0xc57d965d,
    798     0xaf279193, 0x14135c94, 0x0238a1c6, 0xd1a5ef90, 0x5409ed4b, 0xc52d3d18, 0xadb6255e, 0x164c7ddd,
    799     0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xfdc75e3a, 0xd3de9156,
    800     0x53304df6, 0xc4935b3c, 0xab2968ec, 0x1aa6c82b, 0xfb8f1424, 0xd5052d97, 0x52beac9f, 0xc449d892,
    801     0xaa0efb24, 0x1cc66e99, 0xf9577960, 0xd6326a88, 0x5249daa2, 0xc402a33c, 0xa9125e60, 0x1edc1953,
    802     0xf720e574, 0xd76619b6, 0x51d1dc80, 0xc3bdbdf6, 0xa833ea44, 0x20e70f32, 0xf4ebafbf, 0xd8a00bae,
    803     0x5156b6d9, 0xc37b2b6a, 0xa773ebfc, 0x22e69ac8, 0xf2b82f6a, 0xd9e01006, 0x50d86e6d, 0xc33aee27,
    804     0xa6d2a626, 0x24da0a9a, 0xf086bb59, 0xdb25f566, 0x50570819, 0xc2fd08a9, 0xa65050b4, 0x26c0b162,
    805     0xee57aa21, 0xdc71898d, 0x4fd288dc, 0xc2c17d52, 0xa5ed18e0, 0x2899e64a, 0xec2b51f8, 0xddc29958,
    806     0x4f4af5d1, 0xc2884e6e, 0xa5a92114, 0x2a650525, 0xea0208a8, 0xdf18f0ce, 0x4ec05432, 0xc2517e31,
    807     0xa58480e6, 0x2c216eaa, 0xe7dc2383, 0xe0745b24, 0x4e32a956, 0xc21d0eb8, 0xa57f450a, 0x2dce88aa,
    808     0xe5b9f755, 0xe1d4a2c8, 0x4da1fab5, 0xc1eb0209, 0xa5996f52, 0x2f6bbe45, 0xe39bd857, 0xe3399167,
    809     0x4d0e4de2, 0xc1bb5a11, 0xa5d2f6a9, 0x30f8801f, 0xe1821a21, 0xe4a2eff6, 0x4c77a88e, 0xc18e18a7,
    810     0xa62bc71b, 0x32744493, 0xdf6d0fa1, 0xe61086bc, 0x4bde1089, 0xc1633f8a, 0xa6a3c1d6, 0x33de87de,
    811     0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, 0xdb525dc3, 0xe8f77acf,
    812     0x4aa22036, 0xc114ccb9, 0xa7f084e7, 0x367c9a7e, 0xd94d586c, 0xea70658a, 0x49ffd417, 0xc0f1360b,
    813     0xa8c4d9cb, 0x37af8159, 0xd74e4abc, 0xebeca36c, 0x495aada2, 0xc0d00db6, 0xa9b7723b, 0x38cf1669,
    814     0xd5558381, 0xed6bf9d1, 0x48b2b335, 0xc0b15502, 0xaac7fa0e, 0x39daf5e8, 0xd3635094, 0xeeee2d9d,
    815     0x4807eb4b, 0xc0950d1d, 0xabf612b5, 0x3ad2c2e8, 0xd177fec6, 0xf0730342, 0x475a5c77, 0xc07b371e,
    816     0xad415361, 0x3bb6276e, 0xcf93d9dc, 0xf1fa3ecb, 0x46aa0d6d, 0xc063d405, 0xaea94927, 0x3c84d496,
    817     0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, 0xb02d7724, 0x3d3e82ae, 0xcbe2402d, 0xf50ef5de,
    818     0x454149fc, 0xc03c6a07, 0xb1cd56aa, 0x3de2f148, 0xca155d39, 0xf69bf7c9, 0x4488e37f, 0xc02c64a6,
    819     0xb3885772, 0x3e71e759, 0xc850cab4, 0xf82a6c6a, 0x43cdd89a, 0xc01ed535, 0xb55ddfca, 0x3eeb3347,
    820     0xc694ce67, 0xf9ba1651, 0x43103085, 0xc013bc39, 0xb74d4ccb, 0x3f4eaafe, 0xc4e1accb, 0xfb4ab7db,
    821     0x424ff28f, 0xc00b1a20, 0xb955f293, 0x3f9c2bfb, 0xc337a8f7, 0xfcdc1342, 0x418d2621, 0xc004ef3f,
    822     0xbb771c81, 0x3fd39b5a, 0xc197049e, 0xfe6deaa1, 0x40c7d2bd, 0xc0013bd3, 0xbdb00d71, 0x3ff4e5e0,
    823 };
    824 
    825 const uint32_t twidTabEven[4*6 + 16*6 + 64*6] PROGMEM = {
    826     0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x5a82799a, 0xd2bec333,
    827     0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333,
    828     0x00000000, 0xd2bec333, 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7,
    829     0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x4b418bbe, 0xf383a3e2,
    830     0x45f704f7, 0xf9ba1651, 0x4fd288dc, 0xed6bf9d1, 0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2,
    831     0x58c542c5, 0xdc71898d, 0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, 0x5a12e720, 0xce86ff2a,
    832     0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xcac933ae,
    833     0x569cc31b, 0xe1d4a2c8, 0x45f704f7, 0xc04ee4b8, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d,
    834     0x3248d382, 0xc13ad060, 0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, 0x1a4608ab, 0xc78e9a1d,
    835     0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x3248d382, 0xc13ad060,
    836     0x5a12e720, 0xce86ff2a, 0xe5b9f755, 0xe1d4a2c8, 0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae,
    837     0xcdb72c7e, 0xf383a3e2, 0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, 0xba08fb09, 0x0645e9af,
    838     0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xee57aa21, 0xdc71898d,
    839     0x4fd288dc, 0xc2c17d52, 0xa5ed18e0, 0x2899e64a, 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060,
    840     0xa73abd3b, 0x3536cc52, 0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, 0xb02d7724, 0x3d3e82ae,
    841     0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x43103085, 0xfcdc1342,
    842     0x418d2621, 0xfe6deaa1, 0x4488e37f, 0xfb4ab7db, 0x45f704f7, 0xf9ba1651, 0x43103085, 0xfcdc1342,
    843     0x48b2b335, 0xf69bf7c9, 0x48b2b335, 0xf69bf7c9, 0x4488e37f, 0xfb4ab7db, 0x4c77a88e, 0xf1fa3ecb,
    844     0x4b418bbe, 0xf383a3e2, 0x45f704f7, 0xf9ba1651, 0x4fd288dc, 0xed6bf9d1, 0x4da1fab5, 0xf0730342,
    845     0x475a5c77, 0xf82a6c6a, 0x52beac9f, 0xe8f77acf, 0x4fd288dc, 0xed6bf9d1, 0x48b2b335, 0xf69bf7c9,
    846     0x553805f2, 0xe4a2eff6, 0x51d1dc80, 0xea70658a, 0x49ffd417, 0xf50ef5de, 0x573b2635, 0xe0745b24,
    847     0x539eba45, 0xe7821d59, 0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x553805f2, 0xe4a2eff6,
    848     0x4c77a88e, 0xf1fa3ecb, 0x59d438e5, 0xd8a00bae, 0x569cc31b, 0xe1d4a2c8, 0x4da1fab5, 0xf0730342,
    849     0x5a6690ae, 0xd5052d97, 0x57cc15bc, 0xdf18f0ce, 0x4ec05432, 0xeeee2d9d, 0x5a7b7f1a, 0xd1a5ef90,
    850     0x58c542c5, 0xdc71898d, 0x4fd288dc, 0xed6bf9d1, 0x5a12e720, 0xce86ff2a, 0x5987b08a, 0xd9e01006,
    851     0x50d86e6d, 0xebeca36c, 0x592d59da, 0xcbacb0bf, 0x5a12e720, 0xd76619b6, 0x51d1dc80, 0xea70658a,
    852     0x57cc15bc, 0xc91af976, 0x5a6690ae, 0xd5052d97, 0x52beac9f, 0xe8f77acf, 0x55f104dc, 0xc6d569be,
    853     0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59, 0x539eba45, 0xc4df2862, 0x5a6690ae, 0xd09441bb,
    854     0x5471e2e6, 0xe61086bc, 0x50d86e6d, 0xc33aee27, 0x5a12e720, 0xce86ff2a, 0x553805f2, 0xe4a2eff6,
    855     0x4da1fab5, 0xc1eb0209, 0x5987b08a, 0xcc983f70, 0x55f104dc, 0xe3399167, 0x49ffd417, 0xc0f1360b,
    856     0x58c542c5, 0xcac933ae, 0x569cc31b, 0xe1d4a2c8, 0x45f704f7, 0xc04ee4b8, 0x57cc15bc, 0xc91af976,
    857     0x573b2635, 0xe0745b24, 0x418d2621, 0xc004ef3f, 0x569cc31b, 0xc78e9a1d, 0x57cc15bc, 0xdf18f0ce,
    858     0x3cc85709, 0xc013bc39, 0x553805f2, 0xc6250a18, 0x584f7b58, 0xddc29958, 0x37af354c, 0xc07b371e,
    859     0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060, 0x51d1dc80, 0xc3bdbdf6,
    860     0x592d59da, 0xdb25f566, 0x2c9caf6c, 0xc2517e31, 0x4fd288dc, 0xc2c17d52, 0x5987b08a, 0xd9e01006,
    861     0x26b2a794, 0xc3bdbdf6, 0x4da1fab5, 0xc1eb0209, 0x59d438e5, 0xd8a00bae, 0x2092f05f, 0xc57d965d,
    862     0x4b418bbe, 0xc13ad060, 0x5a12e720, 0xd76619b6, 0x1a4608ab, 0xc78e9a1d, 0x48b2b335, 0xc0b15502,
    863     0x5a43b190, 0xd6326a88, 0x13d4ae08, 0xc9edeb50, 0x45f704f7, 0xc04ee4b8, 0x5a6690ae, 0xd5052d97,
    864     0x0d47d096, 0xcc983f70, 0x43103085, 0xc013bc39, 0x5a7b7f1a, 0xd3de9156, 0x06a886a0, 0xcf89e3e8,
    865     0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x3cc85709, 0xc013bc39,
    866     0x5a7b7f1a, 0xd1a5ef90, 0xf9577960, 0xd6326a88, 0x396b3199, 0xc04ee4b8, 0x5a6690ae, 0xd09441bb,
    867     0xf2b82f6a, 0xd9e01006, 0x35eaa2c7, 0xc0b15502, 0x5a43b190, 0xcf89e3e8, 0xec2b51f8, 0xddc29958,
    868     0x3248d382, 0xc13ad060, 0x5a12e720, 0xce86ff2a, 0xe5b9f755, 0xe1d4a2c8, 0x2e88013a, 0xc1eb0209,
    869     0x59d438e5, 0xcd8bbb6d, 0xdf6d0fa1, 0xe61086bc, 0x2aaa7c7f, 0xc2c17d52, 0x5987b08a, 0xcc983f70,
    870     0xd94d586c, 0xea70658a, 0x26b2a794, 0xc3bdbdf6, 0x592d59da, 0xcbacb0bf, 0xd3635094, 0xeeee2d9d,
    871     0x22a2f4f8, 0xc4df2862, 0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x1e7de5df, 0xc6250a18,
    872     0x584f7b58, 0xc9edeb50, 0xc850cab4, 0xf82a6c6a, 0x1a4608ab, 0xc78e9a1d, 0x57cc15bc, 0xc91af976,
    873     0xc337a8f7, 0xfcdc1342, 0x15fdf758, 0xc91af976, 0x573b2635, 0xc8507ea7, 0xbe72d9df, 0x0192155f,
    874     0x11a855df, 0xcac933ae, 0x569cc31b, 0xc78e9a1d, 0xba08fb09, 0x0645e9af, 0x0d47d096, 0xcc983f70,
    875     0x55f104dc, 0xc6d569be, 0xb6002be9, 0x0af10a22, 0x08df1a8c, 0xce86ff2a, 0x553805f2, 0xc6250a18,
    876     0xb25e054b, 0x0f8cfcbe, 0x0470ebdc, 0xd09441bb, 0x5471e2e6, 0xc57d965d, 0xaf279193, 0x14135c94,
    877     0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862, 0xac6145bb, 0x187de2a7, 0xfb8f1424, 0xd5052d97,
    878     0x52beac9f, 0xc449d892, 0xaa0efb24, 0x1cc66e99, 0xf720e574, 0xd76619b6, 0x51d1dc80, 0xc3bdbdf6,
    879     0xa833ea44, 0x20e70f32, 0xf2b82f6a, 0xd9e01006, 0x50d86e6d, 0xc33aee27, 0xa6d2a626, 0x24da0a9a,
    880     0xee57aa21, 0xdc71898d, 0x4fd288dc, 0xc2c17d52, 0xa5ed18e0, 0x2899e64a, 0xea0208a8, 0xdf18f0ce,
    881     0x4ec05432, 0xc2517e31, 0xa58480e6, 0x2c216eaa, 0xe5b9f755, 0xe1d4a2c8, 0x4da1fab5, 0xc1eb0209,
    882     0xa5996f52, 0x2f6bbe45, 0xe1821a21, 0xe4a2eff6, 0x4c77a88e, 0xc18e18a7, 0xa62bc71b, 0x32744493,
    883     0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52, 0xd94d586c, 0xea70658a,
    884     0x49ffd417, 0xc0f1360b, 0xa8c4d9cb, 0x37af8159, 0xd5558381, 0xed6bf9d1, 0x48b2b335, 0xc0b15502,
    885     0xaac7fa0e, 0x39daf5e8, 0xd177fec6, 0xf0730342, 0x475a5c77, 0xc07b371e, 0xad415361, 0x3bb6276e,
    886     0xcdb72c7e, 0xf383a3e2, 0x45f704f7, 0xc04ee4b8, 0xb02d7724, 0x3d3e82ae, 0xca155d39, 0xf69bf7c9,
    887     0x4488e37f, 0xc02c64a6, 0xb3885772, 0x3e71e759, 0xc694ce67, 0xf9ba1651, 0x43103085, 0xc013bc39,
    888     0xb74d4ccb, 0x3f4eaafe, 0xc337a8f7, 0xfcdc1342, 0x418d2621, 0xc004ef3f, 0xbb771c81, 0x3fd39b5a,
    889 };
    890 
    891 /* log2Tab[x] = floor(log2(x)), format = Q28 */
    892 const int log2Tab[65] PROGMEM = {
    893     0x00000000, 0x00000000, 0x10000000, 0x195c01a3, 0x20000000, 0x25269e12, 0x295c01a3, 0x2ceaecfe,
    894     0x30000000, 0x32b80347, 0x35269e12, 0x3759d4f8, 0x395c01a3, 0x3b350047, 0x3ceaecfe, 0x3e829fb6,
    895     0x40000000, 0x41663f6f, 0x42b80347, 0x43f782d7, 0x45269e12, 0x4646eea2, 0x4759d4f8, 0x48608280,
    896     0x495c01a3, 0x4a4d3c25, 0x4b350047, 0x4c1404ea, 0x4ceaecfe, 0x4dba4a47, 0x4e829fb6, 0x4f446359,
    897     0x50000000, 0x50b5d69b, 0x51663f6f, 0x52118b11, 0x52b80347, 0x5359ebc5, 0x53f782d7, 0x549101ea,
    898     0x55269e12, 0x55b88873, 0x5646eea2, 0x56d1fafd, 0x5759d4f8, 0x57dea15a, 0x58608280, 0x58df988f,
    899     0x595c01a3, 0x59d5d9fd, 0x5a4d3c25, 0x5ac24113, 0x5b350047, 0x5ba58feb, 0x5c1404ea, 0x5c80730b,
    900     0x5ceaecfe, 0x5d53847a, 0x5dba4a47, 0x5e1f4e51, 0x5e829fb6, 0x5ee44cd5, 0x5f446359, 0x5fa2f045,
    901     0x60000000
    902 };
    903 
    904 const HuffInfo_t huffTabSpecInfo[11] PROGMEM = {
    905     /* table 0 not used */
    906     {11, {  1,  0,  0,  0,  8,  0, 24,  0, 24,  8, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0},   0},
    907     { 9, {  0,  0,  1,  1,  7, 24, 15, 19, 14,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},  81},
    908     {16, {  1,  0,  0,  4,  2,  6,  3,  5, 15, 15,  8,  9,  3,  3,  5,  2,  0,  0,  0,  0}, 162},
    909     {12, {  0,  0,  0, 10,  6,  0,  9, 21,  8, 14, 11,  2,  0,  0,  0,  0,  0,  0,  0,  0}, 243},
    910     {13, {  1,  0,  0,  4,  4,  0,  4, 12, 12, 12, 18, 10,  4,  0,  0,  0,  0,  0,  0,  0}, 324},
    911     {11, {  0,  0,  0,  9,  0, 16, 13,  8, 23,  8,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0}, 405},
    912     {12, {  1,  0,  2,  1,  0,  4,  5, 10, 14, 15,  8,  4,  0,  0,  0,  0,  0,  0,  0,  0}, 486},
    913     {10, {  0,  0,  1,  5,  7, 10, 14, 15,  8,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}, 550},
    914     {15, {  1,  0,  2,  1,  0,  4,  3,  8, 11, 20, 31, 38, 32, 14,  4,  0,  0,  0,  0,  0}, 614},
    915     {12, {  0,  0,  0,  3,  8, 14, 17, 25, 31, 41, 22,  8,  0,  0,  0,  0,  0,  0,  0,  0}, 783},
    916     {12, {  0,  0,  0,  2,  6,  7, 16, 59, 55, 95, 43,  6,  0,  0,  0,  0,  0,  0,  0,  0}, 952},
    917 };
    918 
    919 const short huffTabSpec[1241] PROGMEM = {
    920     /* spectrum table 1 [81] (signed) */
    921     0x0000, 0x0200, 0x0e00, 0x0007, 0x0040, 0x0001, 0x0038, 0x0008, 0x01c0, 0x03c0, 0x0e40, 0x0039, 0x0078, 0x01c8, 0x000f, 0x0240,
    922     0x003f, 0x0fc0, 0x01f8, 0x0238, 0x0047, 0x0e08, 0x0009, 0x0208, 0x01c1, 0x0048, 0x0041, 0x0e38, 0x0201, 0x0e07, 0x0207, 0x0e01,
    923     0x01c7, 0x0278, 0x0e78, 0x03c8, 0x004f, 0x0079, 0x01c9, 0x01cf, 0x03f8, 0x0239, 0x007f, 0x0e48, 0x0e0f, 0x0fc8, 0x01f9, 0x03c1,
    924     0x03c7, 0x0e47, 0x0ff8, 0x01ff, 0x0049, 0x020f, 0x0241, 0x0e41, 0x0248, 0x0fc1, 0x0e3f, 0x0247, 0x023f, 0x0e39, 0x0fc7, 0x0e09,
    925     0x0209, 0x03cf, 0x0e79, 0x0e4f, 0x03f9, 0x0249, 0x0fc9, 0x027f, 0x0fcf, 0x0fff, 0x0279, 0x03c9, 0x0e49, 0x0e7f, 0x0ff9, 0x03ff,
    926     0x024f,
    927     /* spectrum table 2 [81] (signed) */
    928     0x0000, 0x0200, 0x0e00, 0x0001, 0x0038, 0x0007, 0x01c0, 0x0008, 0x0040, 0x01c8, 0x0e40, 0x0078, 0x000f, 0x0047, 0x0039, 0x0e07,
    929     0x03c0, 0x0238, 0x0fc0, 0x003f, 0x0208, 0x0201, 0x01c1, 0x0e08, 0x0041, 0x01f8, 0x0e01, 0x01c7, 0x0e38, 0x0240, 0x0048, 0x0009,
    930     0x0207, 0x0079, 0x0239, 0x0e78, 0x01cf, 0x03c8, 0x0247, 0x0209, 0x0e48, 0x01f9, 0x0248, 0x0e0f, 0x0ff8, 0x0e39, 0x03f8, 0x0278,
    931     0x03c1, 0x0e47, 0x0fc8, 0x0e09, 0x0fc1, 0x0fc7, 0x01ff, 0x020f, 0x023f, 0x007f, 0x0049, 0x0e41, 0x0e3f, 0x004f, 0x03c7, 0x01c9,
    932     0x0241, 0x03cf, 0x0e79, 0x03f9, 0x0fff, 0x0e4f, 0x0e49, 0x0249, 0x0fcf, 0x03c9, 0x0e7f, 0x0fc9, 0x027f, 0x03ff, 0x0ff9, 0x0279,
    933     0x024f,
    934     /* spectrum table 3 [81] (unsigned) */
    935     0x0000, 0x1200, 0x1001, 0x1040, 0x1008, 0x2240, 0x2009, 0x2048, 0x2041, 0x2208, 0x3049, 0x2201, 0x3248, 0x4249, 0x3209, 0x3241,
    936     0x1400, 0x1002, 0x200a, 0x2440, 0x3288, 0x2011, 0x3051, 0x2280, 0x304a, 0x3448, 0x1010, 0x2088, 0x2050, 0x1080, 0x2042, 0x2408,
    937     0x4289, 0x3089, 0x3250, 0x4251, 0x3281, 0x2210, 0x3211, 0x2081, 0x4449, 0x424a, 0x3441, 0x320a, 0x2012, 0x3052, 0x3488, 0x3290,
    938     0x2202, 0x2401, 0x3091, 0x2480, 0x4291, 0x3242, 0x3409, 0x4252, 0x4489, 0x2090, 0x308a, 0x3212, 0x3481, 0x3450, 0x3490, 0x3092,
    939     0x4491, 0x4451, 0x428a, 0x4292, 0x2082, 0x2410, 0x3282, 0x3411, 0x444a, 0x3442, 0x4492, 0x448a, 0x4452, 0x340a, 0x2402, 0x3482,
    940     0x3412,
    941     /* spectrum table 4 [81] (unsigned) */
    942     0x4249, 0x3049, 0x3241, 0x3248, 0x3209, 0x1200, 0x2240, 0x0000, 0x2009, 0x2208, 0x2201, 0x2048, 0x1001, 0x2041, 0x1008, 0x1040,
    943     0x4449, 0x4251, 0x4289, 0x424a, 0x3448, 0x3441, 0x3288, 0x3409, 0x3051, 0x304a, 0x3250, 0x3089, 0x320a, 0x3281, 0x3242, 0x3211,
    944     0x2440, 0x2408, 0x2280, 0x2401, 0x2042, 0x2088, 0x200a, 0x2050, 0x2081, 0x2202, 0x2011, 0x2210, 0x1400, 0x1002, 0x1080, 0x1010,
    945     0x4291, 0x4489, 0x4451, 0x4252, 0x428a, 0x444a, 0x3290, 0x3488, 0x3450, 0x3091, 0x3052, 0x3481, 0x308a, 0x3411, 0x3212, 0x4491,
    946     0x3282, 0x340a, 0x3442, 0x4292, 0x4452, 0x448a, 0x2090, 0x2480, 0x2012, 0x2410, 0x2082, 0x2402, 0x4492, 0x3092, 0x3490, 0x3482,
    947     0x3412,
    948     /* spectrum table 5 [81] (signed) */
    949     0x0000, 0x03e0, 0x0020, 0x0001, 0x001f, 0x003f, 0x03e1, 0x03ff, 0x0021, 0x03c0, 0x0002, 0x0040, 0x001e, 0x03df, 0x0041, 0x03fe,
    950     0x0022, 0x03c1, 0x005f, 0x03e2, 0x003e, 0x03a0, 0x0060, 0x001d, 0x0003, 0x03bf, 0x0023, 0x0061, 0x03fd, 0x03a1, 0x007f, 0x003d,
    951     0x03e3, 0x03c2, 0x0042, 0x03de, 0x005e, 0x03be, 0x007e, 0x03c3, 0x005d, 0x0062, 0x0043, 0x03a2, 0x03dd, 0x001c, 0x0380, 0x0081,
    952     0x0080, 0x039f, 0x0004, 0x009f, 0x03fc, 0x0024, 0x03e4, 0x0381, 0x003c, 0x007d, 0x03bd, 0x03a3, 0x03c4, 0x039e, 0x0082, 0x005c,
    953     0x0044, 0x0063, 0x0382, 0x03dc, 0x009e, 0x007c, 0x039d, 0x0383, 0x0064, 0x03a4, 0x0083, 0x009d, 0x03bc, 0x009c, 0x0384, 0x0084,
    954     0x039c,
    955     /* spectrum table 6 [81] (signed) */
    956     0x0000, 0x0020, 0x001f, 0x0001, 0x03e0, 0x0021, 0x03e1, 0x003f, 0x03ff, 0x005f, 0x0041, 0x03c1, 0x03df, 0x03c0, 0x03e2, 0x0040,
    957     0x003e, 0x0022, 0x001e, 0x03fe, 0x0002, 0x005e, 0x03c2, 0x03de, 0x0042, 0x03a1, 0x0061, 0x007f, 0x03e3, 0x03bf, 0x0023, 0x003d,
    958     0x03fd, 0x0060, 0x03a0, 0x001d, 0x0003, 0x0062, 0x03be, 0x03c3, 0x0043, 0x007e, 0x005d, 0x03dd, 0x03a2, 0x0063, 0x007d, 0x03bd,
    959     0x03a3, 0x003c, 0x03fc, 0x0081, 0x0381, 0x039f, 0x0024, 0x009f, 0x03e4, 0x001c, 0x0382, 0x039e, 0x0044, 0x03dc, 0x0380, 0x0082,
    960     0x009e, 0x03c4, 0x0080, 0x005c, 0x0004, 0x03bc, 0x03a4, 0x007c, 0x009d, 0x0064, 0x0083, 0x0383, 0x039d, 0x0084, 0x0384, 0x039c,
    961     0x009c,
    962     /* spectrum table 7 [64] (unsigned) */
    963     0x0000, 0x0420, 0x0401, 0x0821, 0x0841, 0x0822, 0x0440, 0x0402, 0x0861, 0x0823, 0x0842, 0x0460, 0x0403, 0x0843, 0x0862, 0x0824,
    964     0x0881, 0x0825, 0x08a1, 0x0863, 0x0844, 0x0404, 0x0480, 0x0882, 0x0845, 0x08a2, 0x0405, 0x08c1, 0x04a0, 0x0826, 0x0883, 0x0865,
    965     0x0864, 0x08a3, 0x0846, 0x08c2, 0x0827, 0x0866, 0x0406, 0x04c0, 0x0884, 0x08e1, 0x0885, 0x08e2, 0x08a4, 0x08c3, 0x0847, 0x08e3,
    966     0x08c4, 0x08a5, 0x0886, 0x0867, 0x04e0, 0x0407, 0x08c5, 0x08a6, 0x08e4, 0x0887, 0x08a7, 0x08e5, 0x08e6, 0x08c6, 0x08c7, 0x08e7,
    967     /* spectrum table 8 [64] (unsigned) */
    968     0x0821, 0x0841, 0x0420, 0x0822, 0x0401, 0x0842, 0x0000, 0x0440, 0x0402, 0x0861, 0x0823, 0x0862, 0x0843, 0x0863, 0x0881, 0x0824,
    969     0x0882, 0x0844, 0x0460, 0x0403, 0x0883, 0x0864, 0x08a2, 0x08a1, 0x0845, 0x0825, 0x08a3, 0x0865, 0x0884, 0x08a4, 0x0404, 0x0885,
    970     0x0480, 0x0846, 0x08c2, 0x08c1, 0x0826, 0x0866, 0x08c3, 0x08a5, 0x04a0, 0x08c4, 0x0405, 0x0886, 0x08e1, 0x08e2, 0x0847, 0x08c5,
    971     0x08e3, 0x0827, 0x08a6, 0x0867, 0x08c6, 0x08e4, 0x04c0, 0x0887, 0x0406, 0x08e5, 0x08e6, 0x08c7, 0x08a7, 0x04e0, 0x0407, 0x08e7,
    972     /* spectrum table 9 [169] (unsigned) */
    973     0x0000, 0x0420, 0x0401, 0x0821, 0x0841, 0x0822, 0x0440, 0x0402, 0x0861, 0x0842, 0x0823, 0x0460, 0x0403, 0x0843, 0x0862, 0x0824,
    974     0x0881, 0x0844, 0x0825, 0x0882, 0x0863, 0x0404, 0x0480, 0x08a1, 0x0845, 0x0826, 0x0864, 0x08a2, 0x08c1, 0x0883, 0x0405, 0x0846,
    975     0x04a0, 0x0827, 0x0865, 0x0828, 0x0901, 0x0884, 0x08a3, 0x08c2, 0x08e1, 0x0406, 0x0902, 0x0848, 0x0866, 0x0847, 0x0885, 0x0921,
    976     0x0829, 0x08e2, 0x04c0, 0x08a4, 0x08c3, 0x0903, 0x0407, 0x0922, 0x0868, 0x0886, 0x0867, 0x0408, 0x0941, 0x08c4, 0x0849, 0x08a5,
    977     0x0500, 0x04e0, 0x08e3, 0x0942, 0x0923, 0x0904, 0x082a, 0x08e4, 0x08c5, 0x08a6, 0x0888, 0x0887, 0x0869, 0x0961, 0x08a8, 0x0520,
    978     0x0905, 0x0943, 0x084a, 0x0409, 0x0962, 0x0924, 0x08c6, 0x0981, 0x0889, 0x0906, 0x082b, 0x0925, 0x0944, 0x08a7, 0x08e5, 0x084b,
    979     0x082c, 0x0982, 0x0963, 0x086a, 0x08a9, 0x08c7, 0x0907, 0x0964, 0x040a, 0x08e6, 0x0983, 0x0540, 0x0945, 0x088a, 0x08c8, 0x084c,
    980     0x0926, 0x0927, 0x088b, 0x0560, 0x08c9, 0x086b, 0x08aa, 0x0908, 0x08e8, 0x0985, 0x086c, 0x0965, 0x08e7, 0x0984, 0x0966, 0x0946,
    981     0x088c, 0x08e9, 0x08ab, 0x040b, 0x0986, 0x08ca, 0x0580, 0x0947, 0x08ac, 0x08ea, 0x0928, 0x040c, 0x0967, 0x0909, 0x0929, 0x0948,
    982     0x08eb, 0x0987, 0x08cb, 0x090b, 0x0968, 0x08ec, 0x08cc, 0x090a, 0x0949, 0x090c, 0x092a, 0x092b, 0x092c, 0x094b, 0x0989, 0x094a,
    983     0x0969, 0x0988, 0x096a, 0x098a, 0x098b, 0x094c, 0x096b, 0x096c, 0x098c,
    984     /* spectrum table 10 [169] (unsigned) */
    985     0x0821, 0x0822, 0x0841, 0x0842, 0x0420, 0x0401, 0x0823, 0x0862, 0x0861, 0x0843, 0x0863, 0x0440, 0x0402, 0x0844, 0x0882, 0x0824,
    986     0x0881, 0x0000, 0x0883, 0x0864, 0x0460, 0x0403, 0x0884, 0x0845, 0x08a2, 0x0825, 0x08a1, 0x08a3, 0x0865, 0x08a4, 0x0885, 0x08c2,
    987     0x0846, 0x08c3, 0x0480, 0x08c1, 0x0404, 0x0826, 0x0866, 0x08a5, 0x08c4, 0x0886, 0x08c5, 0x08e2, 0x0867, 0x0847, 0x08a6, 0x0902,
    988     0x08e3, 0x04a0, 0x08e1, 0x0405, 0x0901, 0x0827, 0x0903, 0x08e4, 0x0887, 0x0848, 0x08c6, 0x08e5, 0x0828, 0x0868, 0x0904, 0x0888,
    989     0x08a7, 0x0905, 0x08a8, 0x08e6, 0x08c7, 0x0922, 0x04c0, 0x08c8, 0x0923, 0x0869, 0x0921, 0x0849, 0x0406, 0x0906, 0x0924, 0x0889,
    990     0x0942, 0x0829, 0x08e7, 0x0907, 0x0925, 0x08e8, 0x0943, 0x08a9, 0x0944, 0x084a, 0x0941, 0x086a, 0x0926, 0x08c9, 0x0500, 0x088a,
    991     0x04e0, 0x0962, 0x08e9, 0x0963, 0x0946, 0x082a, 0x0961, 0x0927, 0x0407, 0x0908, 0x0945, 0x086b, 0x08aa, 0x0909, 0x0965, 0x0408,
    992     0x0964, 0x084b, 0x08ea, 0x08ca, 0x0947, 0x088b, 0x082b, 0x0982, 0x0928, 0x0983, 0x0966, 0x08ab, 0x0984, 0x0967, 0x0985, 0x086c,
    993     0x08cb, 0x0520, 0x0948, 0x0540, 0x0981, 0x0409, 0x088c, 0x0929, 0x0986, 0x084c, 0x090a, 0x092a, 0x082c, 0x0968, 0x0987, 0x08eb,
    994     0x08ac, 0x08cc, 0x0949, 0x090b, 0x0988, 0x040a, 0x08ec, 0x0560, 0x094a, 0x0969, 0x096a, 0x040b, 0x096b, 0x092b, 0x094b, 0x0580,
    995     0x090c, 0x0989, 0x094c, 0x092c, 0x096c, 0x098b, 0x040c, 0x098a, 0x098c,
    996     /* spectrum table 11 [289] (unsigned) */
    997     0x0000, 0x2041, 0x2410, 0x1040, 0x1001, 0x2081, 0x2042, 0x2082, 0x2043, 0x20c1, 0x20c2, 0x1080, 0x2083, 0x1002, 0x20c3, 0x2101,
    998     0x2044, 0x2102, 0x2084, 0x2103, 0x20c4, 0x10c0, 0x1003, 0x2141, 0x2142, 0x2085, 0x2104, 0x2045, 0x2143, 0x20c5, 0x2144, 0x2105,
    999     0x2182, 0x2086, 0x2181, 0x2183, 0x20c6, 0x2046, 0x2110, 0x20d0, 0x2405, 0x2403, 0x2404, 0x2184, 0x2406, 0x1100, 0x2106, 0x1004,
   1000     0x2090, 0x2145, 0x2150, 0x2407, 0x2402, 0x2408, 0x2087, 0x21c2, 0x20c7, 0x2185, 0x2146, 0x2190, 0x240a, 0x21c3, 0x21c1, 0x2409,
   1001     0x21d0, 0x2050, 0x2047, 0x2107, 0x240b, 0x21c4, 0x240c, 0x2210, 0x2401, 0x2186, 0x2250, 0x2088, 0x2147, 0x2290, 0x240d, 0x2203,
   1002     0x2202, 0x20c8, 0x1140, 0x240e, 0x22d0, 0x21c5, 0x2108, 0x2187, 0x21c6, 0x1005, 0x2204, 0x240f, 0x2310, 0x2048, 0x2201, 0x2390,
   1003     0x2148, 0x2350, 0x20c9, 0x2205, 0x21c7, 0x2089, 0x2206, 0x2242, 0x2243, 0x23d0, 0x2109, 0x2188, 0x1180, 0x2244, 0x2149, 0x2207,
   1004     0x21c8, 0x2049, 0x2283, 0x1006, 0x2282, 0x2241, 0x2245, 0x210a, 0x208a, 0x2246, 0x20ca, 0x2189, 0x2284, 0x2208, 0x2285, 0x2247,
   1005     0x22c3, 0x204a, 0x11c0, 0x2286, 0x21c9, 0x20cb, 0x214a, 0x2281, 0x210b, 0x22c2, 0x2342, 0x218a, 0x2343, 0x208b, 0x1400, 0x214b,
   1006     0x22c5, 0x22c4, 0x2248, 0x21ca, 0x2209, 0x1010, 0x210d, 0x1007, 0x20cd, 0x22c6, 0x2341, 0x2344, 0x2303, 0x208d, 0x2345, 0x220a,
   1007     0x218b, 0x2288, 0x2287, 0x2382, 0x2304, 0x204b, 0x210c, 0x22c1, 0x20cc, 0x204d, 0x2302, 0x21cb, 0x20ce, 0x214c, 0x214d, 0x2384,
   1008     0x210e, 0x22c7, 0x2383, 0x2305, 0x2346, 0x2306, 0x1200, 0x22c8, 0x208c, 0x2249, 0x2385, 0x218d, 0x228a, 0x23c2, 0x220b, 0x224a,
   1009     0x2386, 0x2289, 0x214e, 0x22c9, 0x2381, 0x208e, 0x218c, 0x204c, 0x2348, 0x1008, 0x2347, 0x21cc, 0x2307, 0x21cd, 0x23c3, 0x2301,
   1010     0x218e, 0x208f, 0x23c5, 0x23c4, 0x204e, 0x224b, 0x210f, 0x2387, 0x220d, 0x2349, 0x220c, 0x214f, 0x20cf, 0x228b, 0x22ca, 0x2308,
   1011     0x23c6, 0x23c7, 0x220e, 0x23c1, 0x21ce, 0x1240, 0x1009, 0x224d, 0x224c, 0x2309, 0x2388, 0x228d, 0x2389, 0x230a, 0x218f, 0x21cf,
   1012     0x224e, 0x23c8, 0x22cb, 0x22ce, 0x204f, 0x228c, 0x228e, 0x234b, 0x234a, 0x22cd, 0x22cc, 0x220f, 0x238b, 0x234c, 0x230d, 0x23c9,
   1013     0x238a, 0x1280, 0x230b, 0x224f, 0x100a, 0x230c, 0x12c0, 0x230e, 0x228f, 0x234d, 0x100d, 0x238c, 0x23ca, 0x23cb, 0x22cf, 0x238d,
   1014     0x1340, 0x100b, 0x234e, 0x23cc, 0x23cd, 0x230f, 0x1380, 0x238e, 0x234f, 0x1300, 0x238f, 0x100e, 0x100c, 0x23ce, 0x13c0, 0x100f,
   1015     0x23cf,
   1016 };
   1017 
   1018 /* coefficient table 4.A.87, format = Q31
   1019  * reordered as cTab[0], cTab[64], cTab[128], ... cTab[576], cTab[1], cTab[65], cTab[129], ... cTab[639]
   1020  * keeping full table (not using symmetry) to allow sequential access in synth filter inner loop
   1021  * format = Q31
   1022  */
   1023 const uint32_t cTabS[640] PROGMEM = {
   1024     0x00000000, 0x0055dba1, 0x01b2e41d, 0x09015651, 0x2e3a7532, 0x6d474e1d, 0xd1c58ace, 0x09015651, 0xfe4d1be3, 0x0055dba1,
   1025     0xffede50e, 0x005b5371, 0x01d78bfc, 0x08d3e41b, 0x2faa221c, 0x6d41d963, 0xd3337b3d, 0x09299ead, 0xfe70b8d1, 0x0050b177,
   1026     0xffed978a, 0x006090c4, 0x01fd3ba0, 0x08a24899, 0x311af3a4, 0x6d32730f, 0xd49fd55f, 0x094d7ec2, 0xfe933dc0, 0x004b6c46,
   1027     0xffefc9b9, 0x0065fde5, 0x02244a24, 0x086b1eeb, 0x328cc6f0, 0x6d18520e, 0xd60a46e5, 0x096d0e21, 0xfeb48d0d, 0x00465348,
   1028     0xfff0065d, 0x006b47fa, 0x024bf7a1, 0x082f552e, 0x33ff670e, 0x6cf4073e, 0xd7722f04, 0x09881dc5, 0xfed4bec3, 0x004103f4,
   1029     0xffeff6ca, 0x0070c8a5, 0x0274ba43, 0x07ee507c, 0x3572ec70, 0x6cc59bab, 0xd8d7f21f, 0x099ec3dc, 0xfef3f6ab, 0x003c1fa4,
   1030     0xffef7b8b, 0x0075fded, 0x029e35b4, 0x07a8127d, 0x36e69691, 0x6c8c4c7a, 0xda3b176a, 0x09b18a1d, 0xff120d70, 0x003745f9,
   1031     0xffeedfa4, 0x007b3875, 0x02c89901, 0x075ca90c, 0x385a49c4, 0x6c492217, 0xdb9b5b12, 0x09c018ce, 0xff2ef725, 0x00329ab6,
   1032     0xffee1650, 0x00807994, 0x02f3e48d, 0x070bbf58, 0x39ce0477, 0x6bfbdd98, 0xdcf898fb, 0x09caeb0f, 0xff4aabc8, 0x002d8e42,
   1033     0xffed651d, 0x0085c217, 0x03201116, 0x06b559c3, 0x3b415115, 0x6ba4629f, 0xde529086, 0x09d1fa23, 0xff6542d1, 0x00293718,
   1034     0xffecc31b, 0x008a7dd7, 0x034d01f0, 0x06593912, 0x3cb41219, 0x6b42a864, 0xdfa93ab5, 0x09d5560b, 0xff7ee3f1, 0x0024dd50,
   1035     0xffebe77b, 0x008f4bfc, 0x037ad438, 0x05f7fb90, 0x3e25b17e, 0x6ad73e8d, 0xe0fc421e, 0x09d52709, 0xff975c01, 0x002064f8,
   1036     0xffeb50b2, 0x009424c6, 0x03a966bb, 0x0590a67d, 0x3f962fb8, 0x6a619c5e, 0xe24b8f66, 0x09d19ca9, 0xffaea5d6, 0x001c3549,
   1037     0xffea9192, 0x0098b855, 0x03d8afe6, 0x05237f9d, 0x41058bc6, 0x69e29784, 0xe396a45d, 0x09cab9f2, 0xffc4e365, 0x0018703f,
   1038     0xffe9ca76, 0x009d10bf, 0x04083fec, 0x04b0adcb, 0x4272a385, 0x6959709d, 0xe4de0cb0, 0x09c0e59f, 0xffda17f2, 0x001471f8,
   1039     0xffe940f4, 0x00a1039c, 0x043889c6, 0x0437fb0a, 0x43de620a, 0x68c7269b, 0xe620c476, 0x09b3d77f, 0xffee183b, 0x0010bc63,
   1040     0xffe88ba8, 0x00a520bb, 0x04694101, 0x03b8f8dc, 0x4547daea, 0x682b39a4, 0xe75f8bb8, 0x09a3e163, 0x0000e790, 0x000d31b5,
   1041     0xffe83a07, 0x00a8739d, 0x049aa82f, 0x03343533, 0x46aea856, 0x6785c24d, 0xe89971b7, 0x099140a7, 0x00131c75, 0x0009aa3f,
   1042     0xffe79e16, 0x00abe79e, 0x04cc2fcf, 0x02a99097, 0x4812f848, 0x66d76725, 0xe9cea84a, 0x097c1ee8, 0x0023b989, 0x0006b1cf,
   1043     0xffe7746e, 0x00af374c, 0x04fe20be, 0x02186a91, 0x4973fef1, 0x661fd6b8, 0xeafee7f1, 0x0963ed46, 0x0033b927, 0x00039609,
   1044     0xffe6d466, 0x00b1978d, 0x05303f87, 0x01816e06, 0x4ad237a2, 0x655f63f2, 0xec2a3f5f, 0x0949eaac, 0x00426f36, 0x00007134,
   1045     0xffe6afee, 0x00b3d15c, 0x05626209, 0x00e42fa2, 0x4c2ca3df, 0x64964063, 0xed50a31d, 0x092d7970, 0x00504f41, 0xfffdfa25,
   1046     0xffe65416, 0x00b5c867, 0x05950122, 0x0040c496, 0x4d83976c, 0x63c45243, 0xee71b2fe, 0x090ec1fc, 0x005d36df, 0xfffb42b0,
   1047     0xffe681c6, 0x00b74c37, 0x05c76fed, 0xff96db90, 0x4ed62be3, 0x62ea6474, 0xef8d4d7b, 0x08edfeaa, 0x006928a0, 0xfff91fca,
   1048     0xffe66dd0, 0x00b8394b, 0x05f9c051, 0xfee723c6, 0x5024d70e, 0x6207f220, 0xf0a3959f, 0x08cb4e23, 0x007400b8, 0xfff681d6,
   1049     0xffe66fac, 0x00b8fe0d, 0x062bf5ec, 0xfe310657, 0x516eefb9, 0x611d58a3, 0xf1b461ab, 0x08a75da4, 0x007e0393, 0xfff48700,
   1050     0xffe69423, 0x00b8c6b0, 0x065dd56a, 0xfd7475d8, 0x52b449de, 0x602b0c7f, 0xf2bf6ea4, 0x0880ffdd, 0x00872c63, 0xfff294c3,
   1051     0xffe6fed4, 0x00b85f70, 0x068f8b44, 0xfcb1d740, 0x53f495aa, 0x5f30ff5f, 0xf3c4e887, 0x08594887, 0x008f87aa, 0xfff0e7ef,
   1052     0xffe75361, 0x00b73ab0, 0x06c0f0c0, 0xfbe8f5bd, 0x552f8ff7, 0x5e2f6367, 0xf4c473c6, 0x08303897, 0x0096dcc2, 0xffef2395,
   1053     0xffe80414, 0x00b58c8c, 0x06f1825d, 0xfb19b7bd, 0x56654bdd, 0x5d26be9b, 0xf5be0fa9, 0x08061671, 0x009da526, 0xffedc418,
   1054     0xffe85b4b, 0x00b36acd, 0x0721bf22, 0xfa44a069, 0x579505f5, 0x5c16d0ae, 0xf6b1f3c3, 0x07da2b7f, 0x00a3508f, 0xffec8409,
   1055     0xffe954d0, 0x00b06b68, 0x075112a2, 0xf96916f5, 0x58befacd, 0x5b001db8, 0xf79fa13a, 0x07ad8c26, 0x00a85e94, 0xffeb3849,
   1056     0xffea353a, 0x00acbd2f, 0x077fedb3, 0xf887507c, 0x59e2f69e, 0x59e2f69e, 0xf887507c, 0x077fedb3, 0x00acbd2f, 0xffea353a,
   1057     0xffeb3849, 0x00a85e94, 0x07ad8c26, 0xf79fa13a, 0x5b001db8, 0x58befacd, 0xf96916f5, 0x075112a2, 0x00b06b68, 0xffe954d0,
   1058     0xffec8409, 0x00a3508f, 0x07da2b7f, 0xf6b1f3c3, 0x5c16d0ae, 0x579505f5, 0xfa44a069, 0x0721bf22, 0x00b36acd, 0xffe85b4b,
   1059     0xffedc418, 0x009da526, 0x08061671, 0xf5be0fa9, 0x5d26be9b, 0x56654bdd, 0xfb19b7bd, 0x06f1825d, 0x00b58c8c, 0xffe80414,
   1060     0xffef2395, 0x0096dcc2, 0x08303897, 0xf4c473c6, 0x5e2f6367, 0x552f8ff7, 0xfbe8f5bd, 0x06c0f0c0, 0x00b73ab0, 0xffe75361,
   1061     0xfff0e7ef, 0x008f87aa, 0x08594887, 0xf3c4e887, 0x5f30ff5f, 0x53f495aa, 0xfcb1d740, 0x068f8b44, 0x00b85f70, 0xffe6fed4,
   1062     0xfff294c3, 0x00872c63, 0x0880ffdd, 0xf2bf6ea4, 0x602b0c7f, 0x52b449de, 0xfd7475d8, 0x065dd56a, 0x00b8c6b0, 0xffe69423,
   1063     0xfff48700, 0x007e0393, 0x08a75da4, 0xf1b461ab, 0x611d58a3, 0x516eefb9, 0xfe310657, 0x062bf5ec, 0x00b8fe0d, 0xffe66fac,
   1064     0xfff681d6, 0x007400b8, 0x08cb4e23, 0xf0a3959f, 0x6207f220, 0x5024d70e, 0xfee723c6, 0x05f9c051, 0x00b8394b, 0xffe66dd0,
   1065     0xfff91fca, 0x006928a0, 0x08edfeaa, 0xef8d4d7b, 0x62ea6474, 0x4ed62be3, 0xff96db90, 0x05c76fed, 0x00b74c37, 0xffe681c6,
   1066     0xfffb42b0, 0x005d36df, 0x090ec1fc, 0xee71b2fe, 0x63c45243, 0x4d83976c, 0x0040c496, 0x05950122, 0x00b5c867, 0xffe65416,
   1067     0xfffdfa25, 0x00504f41, 0x092d7970, 0xed50a31d, 0x64964063, 0x4c2ca3df, 0x00e42fa2, 0x05626209, 0x00b3d15c, 0xffe6afee,
   1068     0x00007134, 0x00426f36, 0x0949eaac, 0xec2a3f5f, 0x655f63f2, 0x4ad237a2, 0x01816e06, 0x05303f87, 0x00b1978d, 0xffe6d466,
   1069     0x00039609, 0x0033b927, 0x0963ed46, 0xeafee7f1, 0x661fd6b8, 0x4973fef1, 0x02186a91, 0x04fe20be, 0x00af374c, 0xffe7746e,
   1070     0x0006b1cf, 0x0023b989, 0x097c1ee8, 0xe9cea84a, 0x66d76725, 0x4812f848, 0x02a99097, 0x04cc2fcf, 0x00abe79e, 0xffe79e16,
   1071     0x0009aa3f, 0x00131c75, 0x099140a7, 0xe89971b7, 0x6785c24d, 0x46aea856, 0x03343533, 0x049aa82f, 0x00a8739d, 0xffe83a07,
   1072     0x000d31b5, 0x0000e790, 0x09a3e163, 0xe75f8bb8, 0x682b39a4, 0x4547daea, 0x03b8f8dc, 0x04694101, 0x00a520bb, 0xffe88ba8,
   1073     0x0010bc63, 0xffee183b, 0x09b3d77f, 0xe620c476, 0x68c7269b, 0x43de620a, 0x0437fb0a, 0x043889c6, 0x00a1039c, 0xffe940f4,
   1074     0x001471f8, 0xffda17f2, 0x09c0e59f, 0xe4de0cb0, 0x6959709d, 0x4272a385, 0x04b0adcb, 0x04083fec, 0x009d10bf, 0xffe9ca76,
   1075     0x0018703f, 0xffc4e365, 0x09cab9f2, 0xe396a45d, 0x69e29784, 0x41058bc6, 0x05237f9d, 0x03d8afe6, 0x0098b855, 0xffea9192,
   1076     0x001c3549, 0xffaea5d6, 0x09d19ca9, 0xe24b8f66, 0x6a619c5e, 0x3f962fb8, 0x0590a67d, 0x03a966bb, 0x009424c6, 0xffeb50b2,
   1077     0x002064f8, 0xff975c01, 0x09d52709, 0xe0fc421e, 0x6ad73e8d, 0x3e25b17e, 0x05f7fb90, 0x037ad438, 0x008f4bfc, 0xffebe77b,
   1078     0x0024dd50, 0xff7ee3f1, 0x09d5560b, 0xdfa93ab5, 0x6b42a864, 0x3cb41219, 0x06593912, 0x034d01f0, 0x008a7dd7, 0xffecc31b,
   1079     0x00293718, 0xff6542d1, 0x09d1fa23, 0xde529086, 0x6ba4629f, 0x3b415115, 0x06b559c3, 0x03201116, 0x0085c217, 0xffed651d,
   1080     0x002d8e42, 0xff4aabc8, 0x09caeb0f, 0xdcf898fb, 0x6bfbdd98, 0x39ce0477, 0x070bbf58, 0x02f3e48d, 0x00807994, 0xffee1650,
   1081     0x00329ab6, 0xff2ef725, 0x09c018ce, 0xdb9b5b12, 0x6c492217, 0x385a49c4, 0x075ca90c, 0x02c89901, 0x007b3875, 0xffeedfa4,
   1082     0x003745f9, 0xff120d70, 0x09b18a1d, 0xda3b176a, 0x6c8c4c7a, 0x36e69691, 0x07a8127d, 0x029e35b4, 0x0075fded, 0xffef7b8b,
   1083     0x003c1fa4, 0xfef3f6ab, 0x099ec3dc, 0xd8d7f21f, 0x6cc59bab, 0x3572ec70, 0x07ee507c, 0x0274ba43, 0x0070c8a5, 0xffeff6ca,
   1084     0x004103f4, 0xfed4bec3, 0x09881dc5, 0xd7722f04, 0x6cf4073e, 0x33ff670e, 0x082f552e, 0x024bf7a1, 0x006b47fa, 0xfff0065d,
   1085     0x00465348, 0xfeb48d0d, 0x096d0e21, 0xd60a46e5, 0x6d18520e, 0x328cc6f0, 0x086b1eeb, 0x02244a24, 0x0065fde5, 0xffefc9b9,
   1086     0x004b6c46, 0xfe933dc0, 0x094d7ec2, 0xd49fd55f, 0x6d32730f, 0x311af3a4, 0x08a24899, 0x01fd3ba0, 0x006090c4, 0xffed978a,
   1087     0x0050b177, 0xfe70b8d1, 0x09299ead, 0xd3337b3d, 0x6d41d963, 0x2faa221c, 0x08d3e41b, 0x01d78bfc, 0x005b5371, 0xffede50f,
   1088 };
   1089 
   1090 const HuffInfo_t huffTabScaleFactInfo PROGMEM =
   1091     {19, { 1,  0,  1,  3,  2,  4,  3,  5,  4,  6,  6,  6,  5,  8,  4,  7,  3,  7, 46,  0},   0};
   1092 
   1093 /* note - includes offset of -60 (4.6.2.3 in spec) */
   1094 const short huffTabScaleFact[121] PROGMEM = { /* scale factor table [121] */
   1095        0,   -1,    1,   -2,    2,   -3,    3,   -4,    4,   -5,    5,    6,   -6,    7,   -7,    8,
   1096       -8,    9,   -9,   10,  -10,  -11,   11,   12,  -12,   13,  -13,   14,  -14,   16,   15,   17,
   1097       18,  -15,  -17,  -16,   19,  -18,  -19,   20,  -20,   21,  -21,   22,  -22,   23,  -23,  -25,
   1098       25,  -27,  -24,  -26,   24,  -28,   27,   29,  -30,  -29,   26,  -31,  -34,  -33,  -32,  -36,
   1099       28,  -35,  -38,  -37,   30,  -39,  -41,  -57,  -59,  -58,  -60,   38,   39,   40,   41,   42,
   1100       57,   37,   31,   32,   33,   34,   35,   36,   44,   51,   52,   53,   54,   55,   56,   50,
   1101       45,   46,   47,   48,   49,   58,  -54,  -52,  -51,  -50,  -55,   43,   60,   59,  -56,  -53,
   1102      -45,  -44,  -42,  -40,  -43,  -49,  -48,  -46,  -47,
   1103 };
   1104 
   1105 /* noise table 4.A.88, format = Q31 */
   1106 const uint32_t noiseTab[512*2] PROGMEM = {
   1107     0x8010fd38, 0xb3dc7948, 0x7c4e2301, 0xa9904192, 0x121622a7, 0x86489625, 0xc3d53d25, 0xd0343fa9,
   1108     0x674d6f70, 0x25f4e9fd, 0xce1a8c8b, 0x72a726c5, 0xfea6efc6, 0xaa4adb1a, 0x8b2dd628, 0xf14029e4,
   1109     0x46321c1a, 0x604889a0, 0x33363b63, 0x815ed069, 0x802b4315, 0x8f2bf7f3, 0x85b86073, 0x745cfb46,
   1110     0xc57886b3, 0xb76731f0, 0xa2a66772, 0x828ca631, 0x60cc145e, 0x1ad1010f, 0x090c83d4, 0x9bd7ba87,
   1111     0x5f5aeea2, 0x8b4dbd99, 0x848e7b1e, 0x86bb9fa2, 0x26f18ae5, 0xc0b81194, 0x553407bf, 0x52c17953,
   1112     0x755f468d, 0x166b04f8, 0xa5687981, 0x4343248b, 0xa6558d5e, 0xc5f6fab7, 0x80a4fb8c, 0x8cb53cb7,
   1113     0x7da68a54, 0x9cd8df8a, 0xba05376c, 0xfcb58ee2, 0xfdd657a4, 0x005e35ca, 0x91c75c55, 0x367651e6,
   1114     0x816abf85, 0x8f831c4f, 0x423f9c9c, 0x55aa919e, 0x80779834, 0xb59f4244, 0x800a095c, 0x7de9e0cc,
   1115     0x46bda5cb, 0x4c184464, 0x2c438f71, 0x797216b5, 0x5035cee6, 0xa0c3a26e, 0x9d3f95fa, 0xd4a100c0,
   1116     0x8ac30dac, 0x04b87397, 0x9e5ac516, 0x8b0b442e, 0x66210ad6, 0x88ba7598, 0x45b9bd33, 0xf0be5087,
   1117     0x9261b85e, 0x364f6a31, 0x891c4b50, 0x23ad08ce, 0xf10366a6, 0x80414276, 0x1b562e06, 0x8be21591,
   1118     0x9e798195, 0x7fb4045c, 0x7d9506cf, 0x854e691f, 0x9207f092, 0x7a94c9d5, 0x88911536, 0x3f45cc61,
   1119     0x27059279, 0xa5b57109, 0x6d2bb67b, 0x3bdc5379, 0x74e662d8, 0x80348f8c, 0xf875e638, 0x5a8caea1,
   1120     0x2459ae75, 0x2c54b939, 0x79ee3203, 0xb9bc8683, 0x9b6f630c, 0x9f45b351, 0x8563b2b9, 0xe5dbba41,
   1121     0x697c7d0d, 0x7bb7c90e, 0xac900866, 0x8e6b5177, 0x8822dd37, 0x7fd5a91e, 0x7506da05, 0x82302aca,
   1122     0xa5e4be04, 0x4b4288eb, 0x00b8bc9f, 0x4f1033e4, 0x7200d612, 0x43900c8c, 0xa815b900, 0x676ed1d4,
   1123     0x5c5f23b2, 0xa758ee11, 0xaf73abfa, 0x11714ec0, 0x265239e0, 0xc50de679, 0x8a84e341, 0xa1438354,
   1124     0x7f1a341f, 0x343ec96b, 0x696e71b0, 0xa13bde39, 0x81e75094, 0x80091111, 0x853a73bf, 0x80f9c1ee,
   1125     0xe4980086, 0x886a8e28, 0xa7e89426, 0xdd93edd7, 0x7592100d, 0x0bfa8123, 0x850a26d4, 0x2e34f395,
   1126     0x421b6c00, 0xa4a462e4, 0x4e3f5090, 0x3c189f4c, 0x3c971a56, 0xdd0376d2, 0x747a5367, 0x7bcbc9d7,
   1127     0x3966be6a, 0x7efda616, 0x55445e15, 0x7ba2ab3f, 0x5fe684f2, 0x8cf42af9, 0x808c61c3, 0x4390c27b,
   1128     0x7cac62ff, 0xea6cab22, 0x5d0902ad, 0xc27b7208, 0x7a27389d, 0x5820a357, 0xa29bbe59, 0x9df0f1fd,
   1129     0x92bd67e5, 0x7195b587, 0x97cac65b, 0x8339807e, 0x8f72d832, 0x5fad8685, 0xa462d9d3, 0x81d46214,
   1130     0x6ae93e1d, 0x6b23a5b9, 0xc2732874, 0x81795268, 0x7c568cb6, 0x668513ea, 0x428d024e, 0x66b78b3a,
   1131     0xfee9ef03, 0x9ddcbb82, 0xa605f07e, 0x46dc55e0, 0x85415054, 0xc89ec271, 0x7c42edfb, 0x0befe59b,
   1132     0x89b8f607, 0x6d732a1a, 0xa7081ebd, 0x7e403258, 0x21feeb7b, 0x5dd7a1e7, 0x23e3a31a, 0x129bc896,
   1133     0xa11a6b54, 0x7f1e031c, 0xfdc1a4d1, 0x96402e53, 0xb9700f1a, 0x8168ecd6, 0x7d63d3cc, 0x87a70d65,
   1134     0x81075a7a, 0x55c8caa7, 0xa95d00b5, 0x102b1652, 0x0bb30215, 0xe5b63237, 0xa446ca44, 0x82d4c333,
   1135     0x67b2e094, 0x44c3d661, 0x33fd6036, 0xde1ea2a1, 0xa95e8e47, 0x78f66eb9, 0x6f2aef1e, 0xe8887247,
   1136     0x80a3b70e, 0xfca0d9d3, 0x6bf0fd20, 0x0d5226de, 0xf4341c87, 0x5902df05, 0x7ff1a38d, 0xf02e5a5b,
   1137     0x99f129af, 0x8ac63d01, 0x7b53f599, 0x7bb32532, 0x99ac59b0, 0x5255a80f, 0xf1320a41, 0x2497aa5c,
   1138     0xcce60bd8, 0x787c634b, 0x7ed58c5b, 0x8a28eb3a, 0x24a5e647, 0x8b79a2c1, 0x955f5ce5, 0xa9d12bc4,
   1139     0x7a1e20c6, 0x3eeda7ac, 0xf7be823a, 0x042924ce, 0x808b3f03, 0x364248da, 0xac2895e5, 0x69a8b5fa,
   1140     0x97fe8b63, 0xbdeac9aa, 0x8073e0ad, 0x6c25dba7, 0x005e51d2, 0x52e74389, 0x59d3988c, 0xe5d1f39c,
   1141     0x7b57dc91, 0x341adbe7, 0xa7d42b8d, 0x74e9f335, 0xd35bf7d8, 0x5b7c0a4b, 0x75bc0874, 0x552129bf,
   1142     0x8144b70d, 0x6de93bbb, 0x5825f14b, 0x473ec5ca, 0x80a8f37c, 0xe6552d69, 0x7898360b, 0x806379b0,
   1143     0xa9b59339, 0x3f6bf60c, 0xc367d731, 0x920ade99, 0x125592f7, 0x877e5ed1, 0xda895d95, 0x075f2ece,
   1144     0x380e5f5e, 0x9b006b62, 0xd17a6dd2, 0x530a0e13, 0xf4cc9a14, 0x7d0a0ed4, 0x847c6e3f, 0xbaee4975,
   1145     0x47131163, 0x64fb2cac, 0x5e2100a6, 0x7b756a42, 0xd87609f4, 0x98bfe48c, 0x0493745e, 0x836c5784,
   1146     0x7e5ccb40, 0x3df6b476, 0x97700d28, 0x8bbd93fd, 0x56de9cdb, 0x680b4e65, 0xebc3d90e, 0x6d286793,
   1147     0x6753712e, 0xe05c98a7, 0x3d2b6b85, 0xc4b18ddb, 0x7b59b869, 0x31435688, 0x811888e9, 0xe011ee7a,
   1148     0x6a5844f9, 0x86ae35ea, 0xb4cbc10b, 0x01a6f5d6, 0x7a49ed64, 0x927caa49, 0x847ddaed, 0xae0d9bb6,
   1149     0x836bdb04, 0x0fd810a6, 0x74fe126b, 0x4a346b5f, 0x80184d36, 0x5afd153c, 0x90cc8102, 0xe606d0e6,
   1150     0xde69aa58, 0xa89f1222, 0xe06df715, 0x8fd16144, 0x0317c3e8, 0x22ce92fc, 0x690c3eca, 0x93166f02,
   1151     0x71573414, 0x8d43cffb, 0xe8bd0bb6, 0xde86770f, 0x0bf99a41, 0x4633a661, 0xba064108, 0x7adafae3,
   1152     0x2f6cde5d, 0xb350a52c, 0xa5ebfb0b, 0x74c57b46, 0xd3b603b5, 0x80b70892, 0xa7f7fa53, 0xd94b566c,
   1153     0xdda3fd86, 0x6a635793, 0x3ed005ca, 0xc5f087d8, 0x31e3a746, 0x7a4278f9, 0x82def1f9, 0x06caa2b2,
   1154     0xe9d2c349, 0x8940e7f7, 0x7feef8dd, 0x4a9b01f0, 0xacde69f8, 0x57ddc280, 0xf09e4ba4, 0xb6d9f729,
   1155     0xb48c18f2, 0xd3654aa9, 0xca7a03c8, 0x14d57545, 0x7fda87a5, 0x0e411366, 0xb77d0df0, 0x8c2aa467,
   1156     0x787f2590, 0x2d292db1, 0x9f12682c, 0x44ac364d, 0x1a4b31a6, 0x871f7ded, 0x7ff99167, 0x6630a1d5,
   1157     0x25385eb9, 0x2d4dd549, 0xaf8a7004, 0x319ebe0f, 0x379ab730, 0x81dc56a4, 0x822d8523, 0x1ae8554c,
   1158     0x18fa0786, 0x875f7de4, 0x85ca350f, 0x7de818dc, 0x7786a38f, 0xa5456355, 0x92e60f88, 0xf5526122,
   1159     0x916039bc, 0xc561e2de, 0x31c42042, 0x7c82e290, 0x75d158b2, 0xb015bda1, 0x7220c750, 0x46565441,
   1160     0xd0da1fdd, 0x7b777481, 0x782e73c6, 0x8cd72b7b, 0x7f1006aa, 0xfb30e51e, 0x87994818, 0x34e7c7db,
   1161     0x7faae06b, 0xea74fbc0, 0xd20c7af4, 0xc44f396b, 0x06b4234e, 0xdf2e2a93, 0x2efb07c8, 0xce861911,
   1162     0x7550ea05, 0xd8d90bbb, 0x58522eec, 0x746b3520, 0xce844ce9, 0x7f5cacc3, 0xda8f17e0, 0x2fedf9cb,
   1163     0xb2f77ec4, 0x6f13f4c0, 0x834de085, 0x7b7ace4b, 0x713b16ac, 0x499c5ab0, 0x06a7961d, 0x1b39a48a,
   1164     0xbb853e6e, 0x7c781cc1, 0xc0baebf5, 0x7dace394, 0x815ceebc, 0xcc7b27d4, 0x8274b181, 0xa2be40a2,
   1165     0xdd01d5dc, 0x7fefeb14, 0x0813ec78, 0xba3077cc, 0xe5cf1e1c, 0xedcfacae, 0x54c43a9b, 0x5cd62a42,
   1166     0x93806b55, 0x03095c5b, 0x8e076ae3, 0x71bfcd2a, 0x7ac1989b, 0x623bc71a, 0x5e15d4d2, 0xfb341dd1,
   1167     0xd75dfbca, 0xd0da32be, 0xd4569063, 0x337869da, 0x3d30606a, 0xcd89cca2, 0x7dd2ae36, 0x028c03cd,
   1168     0xd85e052c, 0xe8dc9ec5, 0x7ffd9241, 0xde5bf4c6, 0x88c4b235, 0x8228be2e, 0x7fe6ec64, 0x996abe6a,
   1169     0xdeb0666d, 0x9eb86611, 0xd249b922, 0x18b3e26b, 0x80211168, 0x5f8bb99c, 0x6ecb0dd2, 0x4728ff8d,
   1170     0x2ac325b8, 0x6e5169d2, 0x7ebbd68d, 0x05e41d17, 0xaaa19f28, 0x8ab238a6, 0x51f105be, 0x140809cc,
   1171     0x7f7345d9, 0x3aae5a9d, 0xaecec6e4, 0x1afb3473, 0xf6229ed1, 0x8d55f467, 0x7e32003a, 0x70f30c14,
   1172     0x6686f33f, 0xd0d45ed8, 0x644fab57, 0x3a3fbbd3, 0x0b255fc4, 0x679a1701, 0x90e17b6e, 0x325d537b,
   1173     0xcd7b9b87, 0xaa7be2a2, 0x7d47c966, 0xa33dbce5, 0x8659c3bb, 0x72a41367, 0x15c446e0, 0x45fe8b0a,
   1174     0x9d8ddf26, 0x84d47643, 0x7fabe0da, 0x36a70122, 0x7a28ebfe, 0x7c29b8b8, 0x7f760406, 0xbabe4672,
   1175     0x23ea216e, 0x92bcc50a, 0x6d20dba2, 0xad5a7c7e, 0xbf3897f5, 0xabb793e1, 0x8391fc7e, 0xe270291c,
   1176     0x7a248d58, 0x80f8fd15, 0x83ef19f3, 0x5e6ece7d, 0x278430c1, 0x35239f4d, 0xe09c073b, 0x50e78cb5,
   1177     0xd4b811bd, 0xce834ee0, 0xf88aaa34, 0xf71da5a9, 0xe2b0a1d5, 0x7c3aef31, 0xe84eabca, 0x3ce25964,
   1178     0xf29336d3, 0x8fa78b2c, 0xa3fc3415, 0x63e1313d, 0x7fbc74e0, 0x7340bc93, 0x49ae583b, 0x8b79de4b,
   1179     0x25011ce9, 0x7b462279, 0x36007db0, 0x3da1599c, 0x77780772, 0xc845c9bb, 0x83ba68be, 0x6ee507d1,
   1180     0x2f0159b8, 0x5392c4ed, 0x98336ff6, 0x0b3c7f11, 0xde697aac, 0x893fc8d0, 0x6b83f8f3, 0x47799a0d,
   1181     0x801d9dfc, 0x8516a83e, 0x5f8d22ec, 0x0f8ba384, 0xa049dc4b, 0xdd920b05, 0x7a99bc9f, 0x9ad19344,
   1182     0x7a345dba, 0xf501a13f, 0x3e58bf19, 0x7fffaf9a, 0x3b4e1511, 0x0e08b991, 0x9e157620, 0x7230a326,
   1183     0x4977f9ff, 0x2d2bbae1, 0x607aa7fc, 0x7bc85d5f, 0xb441bbbe, 0x8d8fa5f2, 0x601cce26, 0xda1884f2,
   1184     0x81c82d64, 0x200b709c, 0xcbd36abe, 0x8cbdddd3, 0x55ab61d3, 0x7e3ee993, 0x833f18aa, 0xffc1aaea,
   1185     0x7362e16a, 0x7fb85db2, 0x904ee04c, 0x7f04dca6, 0x8ad7a046, 0xebe7d8f7, 0xfbc4c687, 0xd0609458,
   1186     0x093ed977, 0x8e546085, 0x7f5b8236, 0x7c47e118, 0xa01f2641, 0x7ffb3e48, 0x05de7cda, 0x7fc281b9,
   1187     0x8e0278fc, 0xd74e6d07, 0x94c24450, 0x7cf9e641, 0x2ad27871, 0x919fa815, 0x805fd205, 0x7758397f,
   1188     0xe2c7e02c, 0x1828e194, 0x5613d6fe, 0xfb55359f, 0xf9699516, 0x8978ee26, 0x7feebad9, 0x77d71d82,
   1189     0x55b28b60, 0x7e997600, 0x80821a6b, 0xc6d78af1, 0x691822ab, 0x7f6982a0, 0x7ef56f99, 0x5c307f40,
   1190     0xac6f8b76, 0x42cc8ba4, 0x782c61d9, 0xa0224dd0, 0x7bd234d1, 0x74576e3b, 0xe38cfe9a, 0x491e66ef,
   1191     0xc78291c5, 0x895bb87f, 0x924f7889, 0x71b89394, 0x757b779d, 0xc4a9c604, 0x5cdf7829, 0x8020e9df,
   1192     0x805e8245, 0x4a82c398, 0x6360bd62, 0x78bb60fc, 0x09e0d014, 0x4b0ea180, 0xb841978b, 0x69a0e864,
   1193     0x7df35977, 0x3284b0dd, 0x3cdc2efd, 0x57d31f5e, 0x541069cc, 0x1776e92e, 0x04309ea3, 0xa015eb2d,
   1194     0xce7bfabc, 0x41b638f8, 0x8365932e, 0x846ab44c, 0xbbcc80cb, 0x8afa6cac, 0x7fc422ea, 0x4e403fc0,
   1195     0xbfac9aee, 0x8e4c6709, 0x028e01fb, 0x6d160a9b, 0x7fe93004, 0x790f9cdc, 0x6a1f37a0, 0xf7e7ef30,
   1196     0xb4ea0f04, 0x7bf4c8e6, 0xe981701f, 0xc258a9d3, 0x6acbbfba, 0xef5479c7, 0x079c8bd8, 0x1a410f56,
   1197     0x6853b799, 0x86cd4f01, 0xc66e23b6, 0x34585565, 0x8d1fe00d, 0x7fcdba1a, 0x32c9717b, 0xa02f9f48,
   1198     0xf64940db, 0x5ed7d8f1, 0x61b823b2, 0x356f8918, 0xa0a7151e, 0x793fc969, 0x530beaeb, 0x34e93270,
   1199     0x4fc4ddb5, 0x88d58b6c, 0x36094774, 0xf620ac80, 0x03763a72, 0xf910c9a6, 0x6666fb2d, 0x752c8be8,
   1200     0x9a6dfdd8, 0xd1a7117d, 0x51c1b1d4, 0x0a67773d, 0x43b32a79, 0x4cdcd085, 0x5f067d30, 0x05bfe92a,
   1201     0x7ed7d203, 0xe71a3c85, 0x99127ce2, 0x8eb3cac4, 0xad4bbcea, 0x5c6a0fd0, 0x0eec04af, 0x94e95cd4,
   1202     0x8654f921, 0x83eabb5d, 0xb058d7ca, 0x69f12d3c, 0x03d881b2, 0x80558ef7, 0x82938cb3, 0x2ec0e1d6,
   1203     0x80044422, 0xd1e47051, 0x720fc6ff, 0x82b20316, 0x0d527b02, 0x63049a15, 0x7ad5b9ad, 0xd2a4641d,
   1204     0x41144f86, 0x7b04917a, 0x15c4a2c0, 0x9da07916, 0x211df54a, 0x7fdd09af, 0xfe924f3f, 0x7e132cfe,
   1205     0x9a1d18d6, 0x7c56508b, 0x80f0f0af, 0x8095ced6, 0x8037d0d7, 0x026719d1, 0xa55fec43, 0x2b1c7cb7,
   1206     0xa5cd5ac1, 0x77639fad, 0x7fcd8b62, 0x81a18c27, 0xaee4912e, 0xeae9eebe, 0xeb3081de, 0x8532aada,
   1207     0xc822362e, 0x86a649a9, 0x8031a71d, 0x7b319dc6, 0xea8022e6, 0x814bc5a9, 0x8f62f7a1, 0xa430ea17,
   1208     0x388deafb, 0x883b5185, 0x776fe13c, 0x801c683f, 0x87c11b98, 0xb7cbc644, 0x8e9ad3e8, 0x3cf5a10c,
   1209     0x7ff6a634, 0x949ef096, 0x9f84aa7c, 0x010af13f, 0x782d1de8, 0xf18e492a, 0x6cf63b01, 0x4301cd81,
   1210     0x32d15c9e, 0x68ad8cef, 0xd09bd2d6, 0x908c5c15, 0xd1e36260, 0x2c5bfdd0, 0x88765a99, 0x93deba1e,
   1211     0xac6ae342, 0xe865b84c, 0x0f4f2847, 0x7fdf0499, 0x78b1c9b3, 0x6a73261e, 0x601a96f6, 0xd2847933,
   1212     0x489aa888, 0xe12e8093, 0x3bfa5a5f, 0xd96ba5f7, 0x7c8f4c8d, 0x80940c6f, 0xcef9dd1a, 0x7e1a055f,
   1213     0x3483558b, 0x02b59cc4, 0x0c56333e, 0x05a5b813, 0x92d66287, 0x7516b679, 0x71bfe03f, 0x8056bf68,
   1214     0xc24d0724, 0x8416bcf3, 0x234afbdb, 0x4b0d6f9c, 0xaba97333, 0x4b4f42b6, 0x7e8343ab, 0x7ffe2603,
   1215     0xe590f73c, 0x45e10c76, 0xb07a6a78, 0xb35609d3, 0x1a027dfd, 0x90cb6e20, 0x82d3fe38, 0x7b409257,
   1216     0x0e395afa, 0x1b802093, 0xcb0c6c59, 0x241e17e7, 0x1ee3ea0a, 0x41a82302, 0xab04350a, 0xf570beb7,
   1217     0xbb444b9b, 0x83021459, 0x838d65dc, 0x1c439c84, 0x6fdcc454, 0xef9ef325, 0x18626c1c, 0x020d251f,
   1218     0xc4aae786, 0x8614cb48, 0xf6f53ca6, 0x8710dbab, 0x89abec0d, 0xf29d41c1, 0x94b50336, 0xfdd49178,
   1219     0x604658d1, 0x800e85be, 0xca1bb079, 0x7fa48eeb, 0xa3b7fafe, 0xd330436b, 0x64eb604c, 0x43a658ae,
   1220     0x7caa1337, 0xddd445e6, 0x7efbf955, 0xb706ec71, 0x624a6b53, 0x9e0e231f, 0x97097248, 0xa1e1a17a,
   1221     0x68dd2e44, 0x7f9d2e14, 0xddcc7074, 0x58324197, 0xc88fc426, 0x6d3640ae, 0x7ef83600, 0x759a0270,
   1222     0x98b6d854, 0xd63c9b84, 0x372474a2, 0xe3f18cfd, 0x56ab0bdb, 0x85c9be7e, 0x47dfcfeb, 0xa5830d41,
   1223     0x0ddd6283, 0xf4f480ad, 0x74c60e38, 0xab8943c3, 0xc1508fe7, 0x480cdc39, 0x8e097362, 0xa44793be,
   1224     0x538b7e18, 0x545f5b41, 0x56529175, 0x9771a97e, 0xc2da7421, 0xea8265f2, 0x805d1163, 0x883c5d28,
   1225     0x8ba94c48, 0x4f676e65, 0xf78735b3, 0xe1853671, 0x7f454f53, 0x18147f85, 0x7d09e15d, 0xdb4f3494,
   1226     0x795c8973, 0x83310632, 0x85d8061c, 0x9a1a0ebf, 0xc125583c, 0x2a1b1a95, 0x7fd9103f, 0x71e98c72,
   1227     0x40932ed7, 0x91ed227a, 0x3c5e560e, 0xe816dee9, 0xb0891b80, 0x600038ba, 0xc7d9a80d, 0x7fff5e09,
   1228     0x7e3f4351, 0xbb6b4424, 0xb14448d4, 0x8d6bb7e1, 0xfb153626, 0xa68ad537, 0xd9782006, 0xf62f6991,
   1229     0x359ba8c1, 0x02ccff0b, 0x91bf2256, 0x7ea71c4d, 0x560ce5df, 0xeeba289b, 0xa574c4e7, 0x9e04f6ee,
   1230     0x7860a5ec, 0x0b8db4a2, 0x968ba3d7, 0x0b6c77df, 0xd6f3157d, 0x402eff1a, 0x49b820b3, 0x8152aebb,
   1231     0xd180b0b6, 0x098604d4, 0x7ff92224, 0xede9c996, 0x89c58061, 0x829624c4, 0xc6e71ea7, 0xba94d915,
   1232     0x389c3cf6, 0x5b4c5a06, 0x04b335e6, 0x516a8aab, 0x42c8d7d9, 0x92b12af6, 0x86c8549f, 0xfda98acf,
   1233     0x819673b6, 0x69545dac, 0x6feaa230, 0x726e6d3f, 0x886ebdfe, 0x34f5730a, 0x7af63ba2, 0x77307bbf,
   1234     0x7cd80630, 0x6e45efe0, 0x7f8ad7eb, 0x59d7df99, 0x86c70946, 0xda233629, 0x753f6cbf, 0x825eeb40,
   1235 };
   1236 
   1237 /* sample rates (table 4.5.1) */
   1238 const int sampRateTab[12] PROGMEM = {
   1239     96000, 88200, 64000, 48000, 44100, 32000,
   1240     24000, 22050, 16000, 12000, 11025,  8000
   1241 };
   1242 
   1243 /* max scalefactor band for prediction (main profile only) */
   1244 const uint8_t predSFBMax[12] PROGMEM = {
   1245     33, 33, 38, 40, 40, 40, 41, 41, 37, 37, 37, 34
   1246 };
   1247 
   1248 /* channel mapping (table 1.6.3.4) (-1 = unknown, so need to determine mapping based on rules in 8.5.1) */
   1249 const int8_t channelMapTab[8] PROGMEM = {
   1250     -1, 1, 2, 3, 4, 5, 6, 8
   1251 };
   1252 
   1253 /* number of channels in each element (SCE, CPE, etc.)
   1254  * see AACElementID in aaccommon.h
   1255  */
   1256 const uint8_t elementNumChans[8] PROGMEM = {
   1257     1, 2, 0, 1, 0, 0, 0, 0
   1258 };
   1259 
   1260 /* total number of scale factor bands in one window */
   1261 const uint8_t /*char*/ sfBandTotalShort[12] PROGMEM = {
   1262     12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15
   1263 };
   1264 
   1265 const uint8_t /*char*/ sfBandTotalLong[12] PROGMEM = {
   1266     41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40
   1267 };
   1268 
   1269 /* scale factor band tables */
   1270 const uint8_t sfBandTabShortOffset[12] PROGMEM = {0, 0, 0, 13, 13, 13, 28, 28, 44, 44, 44, 60};
   1271 
   1272 const uint16_t sfBandTabShort[76] PROGMEM = {
   1273     /* short block 64, 88, 96 kHz [13] (tables 4.5.24, 4.5.26) */
   1274     0,   4,   8,  12,  16,  20,  24,  32,  40,  48,  64,  92, 128,
   1275 
   1276     /* short block 32, 44, 48 kHz [15] (table 4.5.15) */
   1277     0,   4,   8,  12,  16,  20,  28,  36,  44,  56,  68,  80,  96, 112, 128,
   1278 
   1279     /* short block 22, 24 kHz [16] (table 4.5.22) */
   1280     0,   4,   8,  12,  16,  20,  24,  28,  36,  44,  52,  64,  76,  92, 108, 128,
   1281 
   1282     /* short block 11, 12, 16 kHz [16] (table 4.5.20) */
   1283     0,   4,   8,  12,  16,  20,  24,  28,  32,  40,  48,  60,  72,  88, 108, 128,
   1284 
   1285     /* short block 8 kHz [16] (table 4.5.18) */
   1286     0,   4,   8,  12,  16,  20,  24,  28,  36,  44,  52,  60,  72,  88, 108, 128
   1287 };
   1288 
   1289 const uint16_t sfBandTabLongOffset[12] PROGMEM = {0, 0, 42, 90, 90, 140, 192, 192, 240, 240, 240, 284};
   1290 
   1291 const uint16_t sfBandTabLong[325] PROGMEM = {
   1292     /* long block 88, 96 kHz [42] (table 4.5.25) */
   1293       0,   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  44,  48,   52,
   1294      56,  64,  72,  80,  88,  96, 108, 120, 132, 144, 156, 172, 188,  212,
   1295     240, 276, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024,
   1296 
   1297     /* long block 64 kHz [48] (table 4.5.13) */
   1298       0,   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  44,  48,  52,  56,   64,
   1299      72,  80,  88, 100, 112, 124, 140, 156, 172, 192, 216, 240, 268, 304, 344,  384,
   1300     424, 464, 504, 544, 584, 624, 664, 704, 744, 784, 824, 864, 904, 944, 984, 1024,
   1301 
   1302     /* long block 44, 48 kHz [50] (table 4.5.14) */
   1303       0,   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  48,  56,  64,  72,   80,  88,
   1304      96, 108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, 352, 384,  416, 448,
   1305     480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 1024,
   1306 
   1307     /* long block 32 kHz [52] (table 4.5.16) */
   1308       0,   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  48,  56,  64,  72,   80,  88,  96,
   1309     108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, 352, 384, 416,  448, 480, 512,
   1310     544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960, 992, 1024,
   1311 
   1312     /* long block 22, 24 kHz [48] (table 4.5.21) */
   1313       0,   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  44,  52,  60,  68,   76,
   1314      84,  92, 100, 108, 116, 124, 136, 148, 160, 172, 188, 204, 220, 240, 260,  284,
   1315     308, 336, 364, 396, 432, 468, 508, 552, 600, 652, 704, 768, 832, 896, 960, 1024,
   1316 
   1317     /* long block 11, 12, 16 kHz [44] (table 4.5.19) */
   1318       0,   8,  16,  24,  32,  40,  48,  56,  64,  72,  80,  88, 100,  112, 124,
   1319     136, 148, 160, 172, 184, 196, 212, 228, 244, 260, 280, 300, 320,  344, 368,
   1320     396, 424, 456, 492, 532, 572, 616, 664, 716, 772, 832, 896, 960, 1024,
   1321 
   1322     /* long block 8 kHz [41] (table 4.5.17) */
   1323       0,  12,  24,  36,  48,  60,  72,  84,  96, 108, 120, 132,  144, 156,
   1324     172, 188, 204, 220, 236, 252, 268, 288, 308, 328, 348, 372,  396, 420,
   1325     448, 476, 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, 1024
   1326 };
   1327 
   1328 /* TNS max bands (table 4.139) and max order (table 4.138) */
   1329 const uint8_t tnsMaxBandsShortOffset[3] PROGMEM = {0, 0, 12};
   1330 
   1331 const uint16_t tnsMaxBandsShort[2*12] PROGMEM = {
   1332      9,  9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14,        /* short block, Main/LC */
   1333      7,  7,  7,  6,  6,  6,  7,  7,  8,  8,  8,  7        /* short block, SSR */
   1334 };
   1335 
   1336 const uint8_t tnsMaxOrderShort[3] PROGMEM = {7, 7, 7};
   1337 
   1338 const uint8_t tnsMaxBandsLongOffset[3] PROGMEM = {0, 0, 12};
   1339 
   1340 const uint16_t tnsMaxBandsLong[2*12] PROGMEM = {
   1341     31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39,        /* long block, Main/LC */
   1342     28, 28, 27, 26, 26, 26, 29, 29, 23, 23, 23, 19,        /* long block, SSR */
   1343 };
   1344 
   1345 const uint8_t tnsMaxOrderLong[3] PROGMEM = {20, 12, 12};
   1346 
   1347 
   1348 /* k0Tab[sampRateIdx][k] = k0 = startMin + offset(bs_start_freq) for given sample rate (4.6.18.3.2.1)
   1349  * downsampled (single-rate) SBR not currently supported
   1350  */
   1351 const uint8_t k0Tab[NUM_SAMPLE_RATES_SBR][16] = {
   1352     {  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 16, 18, 20, 23, 27, 31 }, /* 96 kHz */
   1353     {  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 16, 18, 20, 23, 27, 31 }, /* 88 kHz */
   1354     {  6,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 23, 26, 30 }, /* 64 kHz */
   1355     {  7,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 27, 31 }, /* 48 kHz */
   1356     {  8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 25, 28, 32 }, /* 44 kHz */
   1357     { 10, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 27, 29, 32 }, /* 32 kHz */
   1358     { 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 27, 29, 32 }, /* 24 kHz */
   1359     { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 28, 30 }, /* 22 kHz */
   1360     { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }, /* 16 kHz */
   1361 };
   1362 
   1363 
   1364 /* k2Tab[sampRateIdx][k] = stopVector(bs_stop_freq) for given sample rate, bs_stop_freq = [0, 13] (4.6.18.3.2.1)
   1365  * generated with Matlab script calc_stopvec.m
   1366  * downsampled (single-rate) SBR not currently supported
   1367  */
   1368 const uint8_t k2Tab[NUM_SAMPLE_RATES_SBR][14] = {
   1369     { 13, 15, 17, 19, 21, 24, 27, 31, 35, 39, 44, 50, 57, 64 }, /* 96 kHz */
   1370     { 15, 17, 19, 21, 23, 26, 29, 33, 37, 41, 46, 51, 57, 64 }, /* 88 kHz */
   1371     { 20, 22, 24, 26, 28, 31, 34, 37, 41, 45, 49, 54, 59, 64 }, /* 64 kHz */
   1372     { 21, 23, 25, 27, 29, 32, 35, 38, 41, 45, 49, 54, 59, 64 }, /* 48 kHz */
   1373     { 23, 25, 27, 29, 31, 34, 37, 40, 43, 47, 51, 55, 59, 64 }, /* 44 kHz */
   1374     { 32, 34, 36, 38, 40, 42, 44, 46, 49, 52, 55, 58, 61, 64 }, /* 32 kHz */
   1375     { 32, 34, 36, 38, 40, 42, 44, 46, 49, 52, 55, 58, 61, 64 }, /* 24 kHz */
   1376     { 35, 36, 38, 40, 42, 44, 46, 48, 50, 52, 55, 58, 61, 64 }, /* 22 kHz */
   1377     { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64 }, /* 16 kHz */
   1378 };
   1379 
   1380 const HuffInfo_t huffTabSBRInfo[10] PROGMEM = {
   1381     {19, { 0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  1,  2,  3,  4,  2,  7,  4,  8, 72,  0},   0},
   1382     {20, { 0,  2,  2,  2,  2,  2,  1,  3,  3,  2,  4,  4,  4,  3,  2,  5,  6, 13, 15, 46}, 121},
   1383     {17, { 1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  2,  2,  0,  0,  1, 25, 10,  0,  0,  0}, 242},
   1384     {19, { 1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  3,  1,  0,  1,  1,  2,  1, 29,  2,  0}, 291},
   1385     {19, { 1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  2,  1,  2,  5,  1,  4,  2,  3, 34,  0}, 340},
   1386     {20, { 1,  1,  1,  1,  1,  1,  0,  2,  2,  2,  2,  2,  1,  2,  3,  4,  4,  7, 10, 16}, 403},
   1387     {14, { 1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  1, 13,  2,  0,  0,  0,  0,  0,  0}, 466},
   1388     {14, { 1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  6,  8,  0,  0,  0,  0,  0,  0}, 491},
   1389     {14, { 1,  1,  1,  1,  1,  1,  0,  2,  0,  1,  1,  0, 51,  2,  0,  0,  0,  0,  0,  0}, 516},
   1390     { 8, { 1,  1,  1,  0,  1,  1,  0, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}, 579},
   1391 };
   1392 
   1393 /* Huffman tables from appendix 4.A.6.1, includes offset of -LAV[i] for table i */
   1394 const short huffTabSBR[604] PROGMEM = {
   1395         /* SBR table sbr_tenv15 [121] (signed) */
   1396        0,   -1,    1,   -2,    2,   -3,    3,   -4,    4,   -5,    5,   -6,    6,   -7,    7,   -8,
   1397       -9,    8,  -10,    9,  -11,   10,  -12,  -13,   11,  -14,   12,  -15,  -16,   13,  -19,  -18,
   1398      -17,   14,  -24,  -20,   16,  -26,  -21,   15,  -23,  -25,  -22,  -60,  -59,  -58,  -57,  -56,
   1399      -55,  -54,  -53,  -52,  -51,  -50,  -49,  -48,  -47,  -46,  -45,  -44,  -43,  -42,  -41,  -40,
   1400      -39,  -38,  -37,  -36,  -35,  -34,  -33,  -32,  -31,  -30,  -29,  -28,  -27,   17,   18,   19,
   1401       20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,
   1402       36,   37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,
   1403       52,   53,   54,   55,   56,   57,   58,   59,   60,
   1404         /* SBR table sbr_fenv15 [121] (signed) */
   1405        0,   -1,    1,   -2,   -3,    2,   -4,    3,   -5,    4,   -6,    5,   -7,    6,   -8,    7,
   1406       -9,    8,  -10,    9,  -11,   10,   11,  -12,   12,  -13,   13,   14,  -14,  -15,   15,   16,
   1407       17,  -16,  -17,  -18,  -19,   18,   19,  -20,  -21,   20,   21,  -24,  -23,  -22,  -26,  -28,
   1408       22,   23,   25,  -41,  -25,   26,   27,  -30,  -27,   24,   28,   44,  -51,  -46,  -44,  -43,
   1409      -37,  -33,  -31,  -29,   30,   37,   42,   47,   48,  -60,  -59,  -58,  -57,  -56,  -55,  -54,
   1410      -53,  -52,  -50,  -49,  -48,  -47,  -45,  -42,  -40,  -39,  -38,  -36,  -35,  -34,  -32,   29,
   1411       31,   32,   33,   34,   35,   36,   38,   39,   40,   41,   43,   45,   46,   49,   50,   51,
   1412       52,   53,   54,   55,   56,   57,   58,   59,   60,
   1413         /* SBR table sbr_tenv15b [49] (signed) */
   1414        0,    1,   -1,    2,   -2,    3,   -3,    4,   -4,   -5,    5,   -6,    6,    7,   -7,    8,
   1415      -24,  -23,  -22,  -21,  -20,  -19,  -18,  -17,  -16,  -15,  -14,  -13,  -12,  -11,  -10,   -9,
   1416       -8,    9,   10,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,   22,   23,
   1417       24,
   1418         /* SBR table sbr_fenv15b [49] (signed) */
   1419        0,   -1,    1,   -2,    2,    3,   -3,   -4,    4,   -5,    5,   -6,    6,   -7,    7,    8,
   1420       -9,   -8,  -24,  -23,  -22,  -21,  -20,  -19,  -18,  -17,  -16,  -15,  -14,  -13,  -12,  -11,
   1421      -10,    9,   10,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,   22,   23,
   1422       24,
   1423         /* SBR table sbr_tenv30 [63] (signed) */
   1424        0,   -1,    1,   -2,    2,   -3,    3,   -4,    4,   -5,    5,   -6,   -7,    6,   -8,    7,
   1425       -9,  -10,    8,    9,   10,  -13,  -11,  -12,  -14,   11,   12,  -31,  -30,  -29,  -28,  -27,
   1426      -26,  -25,  -24,  -23,  -22,  -21,  -20,  -19,  -18,  -17,  -16,  -15,   13,   14,   15,   16,
   1427       17,   18,   19,   20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,   31,
   1428         /* SBR table sbr_fenv30 [63] (signed) */
   1429        0,   -1,    1,   -2,    2,   -3,    3,   -4,    4,   -5,    5,   -6,    6,   -7,    7,   -8,
   1430        8,    9,   -9,  -10,   10,   11,  -11,  -12,   12,   13,  -13,  -15,   14,   15,  -14,   18,
   1431      -18,  -24,  -19,   16,   17,  -22,  -21,  -16,   20,   21,   22,   25,  -23,  -20,   24,  -31,
   1432      -30,  -29,  -28,  -27,  -26,  -25,  -17,   19,   23,   26,   27,   28,   29,   30,   31,
   1433         /* SBR table sbr_tenv30b [25] (signed) */
   1434        0,    1,   -1,   -2,    2,    3,   -3,   -4,    4,   -5,  -12,  -11,  -10,   -9,   -8,   -7,
   1435       -6,    5,    6,    7,    8,    9,   10,   11,   12,
   1436         /* SBR table sbr_fenv30b [25] (signed) */
   1437        0,   -1,    1,   -2,    2,    3,   -3,   -4,    4,   -5,    5,    6,  -12,  -11,  -10,   -9,
   1438       -8,   -7,   -6,    7,    8,    9,   10,   11,   12,
   1439         /* SBR table sbr_tnoise30 [63] (signed) */
   1440        0,    1,   -1,   -2,    2,   -3,    3,   -4,    4,   -5,    5,   11,  -31,  -30,  -29,  -28,
   1441      -27,  -26,  -25,  -24,  -23,  -22,  -21,  -20,  -19,  -18,  -17,  -16,  -15,  -14,  -13,  -12,
   1442      -11,  -10,   -9,   -8,   -7,   -6,    6,    7,    8,    9,   10,   12,   13,   14,   15,   16,
   1443       17,   18,   19,   20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,   31,
   1444         /* SBR table sbr_tnoise30b [25] (signed) */
   1445        0,   -1,    1,   -2,    2,  -12,  -11,  -10,   -9,   -8,   -7,   -6,   -5,   -4,   -3,    3,
   1446        4,    5,    6,    7,    8,    9,   10,   11,   12,
   1447 };
   1448 
   1449 /* newBWTab[prev invfMode][curr invfMode], format = Q31 (table 4.158)
   1450  * sample file which uses all of these: al_sbr_sr_64_2_fsaac32.aac
   1451  */
   1452 static const int newBWTab[4][4] PROGMEM = {
   1453     {0x00000000, 0x4ccccccd, 0x73333333, 0x7d70a3d7},
   1454     {0x4ccccccd, 0x60000000, 0x73333333, 0x7d70a3d7},
   1455     {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7},
   1456     {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7},
   1457 };
   1458 
   1459 /* NINT(2.048E6 / Fs) (figure 4.47)
   1460  * downsampled (single-rate) SBR not currently supported
   1461  */
   1462 const uint8_t goalSBTab[NUM_SAMPLE_RATES_SBR] = {
   1463     21, 23, 32, 43, 46, 64, 85, 93, 128
   1464 };
   1465 
   1466 /* twiddle table for radix 4 pass, format = Q31 */
   1467 static const uint32_t twidTabOdd32[8*6] = {
   1468     0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x539eba45, 0xe7821d59,
   1469     0x4b418bbe, 0xf383a3e2, 0x58c542c5, 0xdc71898d, 0x5a82799a, 0xd2bec333, 0x539eba45, 0xe7821d59,
   1470     0x539eba45, 0xc4df2862, 0x539eba45, 0xc4df2862, 0x58c542c5, 0xdc71898d, 0x3248d382, 0xc13ad060,
   1471     0x40000000, 0xc0000000, 0x5a82799a, 0xd2bec333, 0x00000000, 0xd2bec333, 0x22a2f4f8, 0xc4df2862,
   1472     0x58c542c5, 0xcac933ae, 0xcdb72c7e, 0xf383a3e2, 0x00000000, 0xd2bec333, 0x539eba45, 0xc4df2862,
   1473     0xac6145bb, 0x187de2a7, 0xdd5d0b08, 0xe7821d59, 0x4b418bbe, 0xc13ad060, 0xa73abd3b, 0x3536cc52,
   1474 };
   1475 
   1476 /* PostMultiply64() table
   1477  * format = Q30
   1478  * reordered for sequential access
   1479  *
   1480  * for (i = 0; i <= (32/2); i++) {
   1481  *   angle = i * M_PI / 64;
   1482  *   x = (cos(angle) + sin(angle));
   1483  *   x = sin(angle);
   1484  * }
   1485  */
   1486 static const int cos1sin1tab64[34] PROGMEM = {
   1487     0x40000000, 0x00000000, 0x43103085, 0x0323ecbe, 0x45f704f7, 0x0645e9af, 0x48b2b335, 0x09640837,
   1488     0x4b418bbe, 0x0c7c5c1e, 0x4da1fab5, 0x0f8cfcbe, 0x4fd288dc, 0x1294062f, 0x51d1dc80, 0x158f9a76,
   1489     0x539eba45, 0x187de2a7, 0x553805f2, 0x1b5d100a, 0x569cc31b, 0x1e2b5d38, 0x57cc15bc, 0x20e70f32,
   1490     0x58c542c5, 0x238e7673, 0x5987b08a, 0x261feffa, 0x5a12e720, 0x2899e64a, 0x5a6690ae, 0x2afad269,
   1491     0x5a82799a, 0x2d413ccd,
   1492 };
   1493 
   1494 /* coefficient table 4.A.87, format = Q31
   1495  * reordered as:
   1496  *   cTab[0],  cTab[64],  cTab[128], cTab[192], cTab[256],
   1497  *   cTab[2],  cTab[66],  cTab[130], cTab[194], cTab[258],
   1498  *   ...
   1499  *   cTab[64], cTab[128], cTab[192], cTab[256], cTab[320]
   1500  *
   1501  * NOTE: cTab[1, 2, ... , 318, 319] = cTab[639, 638, ... 322, 321]
   1502  *   except cTab[384] = -cTab[256], cTab[512] = -cTab[128]
   1503  */
   1504 const uint32_t cTabA[165] PROGMEM = {
   1505     0x00000000, 0x0055dba1, 0x01b2e41d, 0x09015651, 0x2e3a7532, 0xffed978a, 0x006090c4, 0x01fd3ba0, 0x08a24899, 0x311af3a4,
   1506     0xfff0065d, 0x006b47fa, 0x024bf7a1, 0x082f552e, 0x33ff670e, 0xffef7b8b, 0x0075fded, 0x029e35b4, 0x07a8127d, 0x36e69691,
   1507     0xffee1650, 0x00807994, 0x02f3e48d, 0x070bbf58, 0x39ce0477, 0xffecc31b, 0x008a7dd7, 0x034d01f0, 0x06593912, 0x3cb41219,
   1508     0xffeb50b2, 0x009424c6, 0x03a966bb, 0x0590a67d, 0x3f962fb8, 0xffe9ca76, 0x009d10bf, 0x04083fec, 0x04b0adcb, 0x4272a385,
   1509     0xffe88ba8, 0x00a520bb, 0x04694101, 0x03b8f8dc, 0x4547daea, 0xffe79e16, 0x00abe79e, 0x04cc2fcf, 0x02a99097, 0x4812f848,
   1510     0xffe6d466, 0x00b1978d, 0x05303f87, 0x01816e06, 0x4ad237a2, 0xffe65416, 0x00b5c867, 0x05950122, 0x0040c496, 0x4d83976c,
   1511     0xffe66dd0, 0x00b8394b, 0x05f9c051, 0xfee723c6, 0x5024d70e, 0xffe69423, 0x00b8c6b0, 0x065dd56a, 0xfd7475d8, 0x52b449de,
   1512     0xffe75361, 0x00b73ab0, 0x06c0f0c0, 0xfbe8f5bd, 0x552f8ff7, 0xffe85b4b, 0x00b36acd, 0x0721bf22, 0xfa44a069, 0x579505f5,
   1513     0xffea353a, 0x00acbd2f, 0x077fedb3, 0xf887507c, 0x59e2f69e, 0xffec8409, 0x00a3508f, 0x07da2b7f, 0xf6b1f3c3, 0x5c16d0ae,
   1514     0xffef2395, 0x0096dcc2, 0x08303897, 0xf4c473c6, 0x5e2f6367, 0xfff294c3, 0x00872c63, 0x0880ffdd, 0xf2bf6ea4, 0x602b0c7f,
   1515     0xfff681d6, 0x007400b8, 0x08cb4e23, 0xf0a3959f, 0x6207f220, 0xfffb42b0, 0x005d36df, 0x090ec1fc, 0xee71b2fe, 0x63c45243,
   1516     0x00007134, 0x00426f36, 0x0949eaac, 0xec2a3f5f, 0x655f63f2, 0x0006b1cf, 0x0023b989, 0x097c1ee8, 0xe9cea84a, 0x66d76725,
   1517     0x000d31b5, 0x0000e790, 0x09a3e163, 0xe75f8bb8, 0x682b39a4, 0x001471f8, 0xffda17f2, 0x09c0e59f, 0xe4de0cb0, 0x6959709d,
   1518     0x001c3549, 0xffaea5d6, 0x09d19ca9, 0xe24b8f66, 0x6a619c5e, 0x0024dd50, 0xff7ee3f1, 0x09d5560b, 0xdfa93ab5, 0x6b42a864,
   1519     0x002d8e42, 0xff4aabc8, 0x09caeb0f, 0xdcf898fb, 0x6bfbdd98, 0x003745f9, 0xff120d70, 0x09b18a1d, 0xda3b176a, 0x6c8c4c7a,
   1520     0x004103f4, 0xfed4bec3, 0x09881dc5, 0xd7722f04, 0x6cf4073e, 0x004b6c46, 0xfe933dc0, 0x094d7ec2, 0xd49fd55f, 0x6d32730f,
   1521     0x0055dba1, 0x01b2e41d, 0x09015651, 0x2e3a7532, 0x6d474e1d,
   1522 };
   1523 
   1524 /* PreMultiply64() table
   1525  * format = Q30
   1526  * reordered for sequential access
   1527  *
   1528  * for (i = 0; i < 64/4; i++) {
   1529  *   angle = (i + 0.25) * M_PI / nmdct;
   1530  *   x = (cos(angle) + sin(angle));
   1531  *   x =  sin(angle);
   1532  *
   1533  *   angle = (nmdct/2 - 1 - i + 0.25) * M_PI / nmdct;
   1534  *   x = (cos(angle) + sin(angle));
   1535  *   x =  sin(angle);
   1536  * }
   1537  */
   1538 static const int cos4sin4tab64[64] PROGMEM = {
   1539     0x40c7d2bd, 0x00c90e90, 0x424ff28f, 0x3ff4e5e0, 0x43cdd89a, 0x03ecadcf, 0x454149fc, 0x3fc395f9,
   1540     0x46aa0d6d, 0x070de172, 0x4807eb4b, 0x3f6af2e3, 0x495aada2, 0x0a2abb59, 0x4aa22036, 0x3eeb3347,
   1541     0x4bde1089, 0x0d415013, 0x4d0e4de2, 0x3e44a5ef, 0x4e32a956, 0x104fb80e, 0x4f4af5d1, 0x3d77b192,
   1542     0x50570819, 0x135410c3, 0x5156b6d9, 0x3c84d496, 0x5249daa2, 0x164c7ddd, 0x53304df6, 0x3b6ca4c4,
   1543     0x5409ed4b, 0x19372a64, 0x54d69714, 0x3a2fcee8, 0x55962bc0, 0x1c1249d8, 0x56488dc5, 0x38cf1669,
   1544     0x56eda1a0, 0x1edc1953, 0x57854ddd, 0x374b54ce, 0x580f7b19, 0x2192e09b, 0x588c1404, 0x35a5793c,
   1545     0x58fb0568, 0x2434f332, 0x595c3e2a, 0x33de87de, 0x59afaf4c, 0x26c0b162, 0x59f54bee, 0x31f79948,
   1546     0x5a2d0957, 0x29348937, 0x5a56deec, 0x2ff1d9c7, 0x5a72c63b, 0x2b8ef77d, 0x5a80baf6, 0x2dce88aa,
   1547 };
   1548 
   1549 /* invBandTab[i] = 1.0 / (i + 1), Q31 */
   1550 static const int invBandTab[64] PROGMEM = {
   1551     0x7fffffff, 0x40000000, 0x2aaaaaab, 0x20000000, 0x1999999a, 0x15555555, 0x12492492, 0x10000000,
   1552     0x0e38e38e, 0x0ccccccd, 0x0ba2e8ba, 0x0aaaaaab, 0x09d89d8a, 0x09249249, 0x08888889, 0x08000000,
   1553     0x07878788, 0x071c71c7, 0x06bca1af, 0x06666666, 0x06186186, 0x05d1745d, 0x0590b216, 0x05555555,
   1554     0x051eb852, 0x04ec4ec5, 0x04bda12f, 0x04924925, 0x0469ee58, 0x04444444, 0x04210842, 0x04000000,
   1555     0x03e0f83e, 0x03c3c3c4, 0x03a83a84, 0x038e38e4, 0x03759f23, 0x035e50d8, 0x03483483, 0x03333333,
   1556     0x031f3832, 0x030c30c3, 0x02fa0be8, 0x02e8ba2f, 0x02d82d83, 0x02c8590b, 0x02b93105, 0x02aaaaab,
   1557     0x029cbc15, 0x028f5c29, 0x02828283, 0x02762762, 0x026a439f, 0x025ed098, 0x0253c825, 0x02492492,
   1558     0x023ee090, 0x0234f72c, 0x022b63cc, 0x02222222, 0x02192e2a, 0x02108421, 0x02082082, 0x02000000,
   1559 };
   1560 
   1561 static const uint32_t poly43lo[5] PROGMEM = { 0x29a0bda9, 0xb02e4828, 0x5957aa1b, 0x236c498d, 0xff581859 };
   1562 static const uint32_t poly43hi[5] PROGMEM = { 0x10852163, 0xd333f6a4, 0x46e9408b, 0x27c2cef0, 0xfef577b4 };
   1563 
   1564 /* pow2exp[i] = pow(2, i*4/3) exponent */
   1565 static const uint16_t pow2exp[8] PROGMEM = { 14, 13, 11, 10, 9, 7, 6, 5 };
   1566 
   1567 /* pow2exp[i] = pow(2, i*4/3) fraction */
   1568 static const int pow2frac[8] PROGMEM = {
   1569     0x6597fa94, 0x50a28be6, 0x7fffffff, 0x6597fa94,
   1570     0x50a28be6, 0x7fffffff, 0x6597fa94, 0x50a28be6
   1571 };
   1572 
   1573 /* pow(2, i/4.0) for i = [0,1,2,3], format = Q30 */
   1574 static const int pow14[4] PROGMEM = {
   1575     0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65
   1576 };
   1577 
   1578 /* pow(2, i/4.0) * pow(j, 4.0/3.0) for i = [0,1,2,3],  j = [0,1,2,...,15]
   1579  * format = Q28 for j = [0-3], Q25 for j = [4-15]
   1580  */
   1581 static const uint32_t pow43_14[4][16] PROGMEM = {
   1582     {
   1583     0x00000000, 0x10000000, 0x285145f3, 0x453a5cdb, /* Q28 */
   1584     0x0cb2ff53, 0x111989d6, 0x15ce31c8, 0x1ac7f203, /* Q25 */
   1585     0x20000000, 0x257106b9, 0x2b16b4a3, 0x30ed74b4, /* Q25 */
   1586     0x36f23fa5, 0x3d227bd3, 0x437be656, 0x49fc823c, /* Q25 */
   1587     },
   1588     {
   1589     0x00000000, 0x1306fe0a, 0x2ff221af, 0x52538f52,
   1590     0x0f1a1bf4, 0x1455ccc2, 0x19ee62a8, 0x1fd92396,
   1591     0x260dfc14, 0x2c8694d8, 0x333dcb29, 0x3a2f5c7a,
   1592     0x4157aed5, 0x48b3aaa3, 0x50409f76, 0x57fc3010,
   1593     },
   1594     {
   1595     0x00000000, 0x16a09e66, 0x39047c0f, 0x61e734aa,
   1596     0x11f59ac4, 0x182ec633, 0x1ed66a45, 0x25dfc55a,
   1597     0x2d413ccd, 0x34f3462d, 0x3cefc603, 0x4531ab69,
   1598     0x4db4adf8, 0x56752054, 0x5f6fcfcd, 0x68a1eca1,
   1599     },
   1600     {
   1601     0x00000000, 0x1ae89f99, 0x43ce3e4b, 0x746d57b2,
   1602     0x155b8109, 0x1cc21cdc, 0x24ac1839, 0x2d0a479e,
   1603     0x35d13f33, 0x3ef80748, 0x48775c93, 0x524938cd,
   1604     0x5c68841d, 0x66d0df0a, 0x717e7bfe, 0x7c6e0305,
   1605     },
   1606 };
   1607 
   1608 /* pow(j, 4.0 / 3.0) for j = [16,17,18,...,63], format = Q23 */
   1609 static const int pow43[48] PROGMEM = {
   1610     0x1428a2fa, 0x15db1bd6, 0x1796302c, 0x19598d85,
   1611     0x1b24e8bb, 0x1cf7fcfa, 0x1ed28af2, 0x20b4582a,
   1612     0x229d2e6e, 0x248cdb55, 0x26832fda, 0x28800000,
   1613     0x2a832287, 0x2c8c70a8, 0x2e9bc5d8, 0x30b0ff99,
   1614     0x32cbfd4a, 0x34eca001, 0x3712ca62, 0x393e6088,
   1615     0x3b6f47e0, 0x3da56717, 0x3fe0a5fc, 0x4220ed72,
   1616     0x44662758, 0x46b03e7c, 0x48ff1e87, 0x4b52b3f3,
   1617     0x4daaebfd, 0x5007b497, 0x5268fc62, 0x54ceb29c,
   1618     0x5738c721, 0x59a72a59, 0x5c19cd35, 0x5e90a129,
   1619     0x610b9821, 0x638aa47f, 0x660db90f, 0x6894c90b,
   1620     0x6b1fc80c, 0x6daeaa0d, 0x70416360, 0x72d7e8b0,
   1621     0x75722ef9, 0x78102b85, 0x7ab1d3ec, 0x7d571e09,
   1622 };
   1623 
   1624 /* invTab[x] = 1/(x+1), format = Q30 */
   1625 static const int invTab[5] PROGMEM = {0x40000000, 0x20000000, 0x15555555, 0x10000000, 0x0ccccccd};
   1626 
   1627 /* inverse quantization tables for TNS filter coefficients, format = Q31
   1628  * see bottom of file for table generation
   1629  * negative (vs. spec) since we use MADD for filter kernel
   1630  */
   1631 static const uint32_t invQuant3[16] PROGMEM = {
   1632     0x00000000, 0xc8767f65, 0x9becf22c, 0x83358feb, 0x83358feb, 0x9becf22c, 0xc8767f65, 0x00000000,
   1633     0x2bc750e9, 0x5246dd49, 0x6ed9eba1, 0x7e0e2e32, 0x7e0e2e32, 0x6ed9eba1, 0x5246dd49, 0x2bc750e9,
   1634 };
   1635 
   1636 static const uint32_t invQuant4[16] PROGMEM = {
   1637     0x00000000, 0xe5632654, 0xcbf00dbe, 0xb4c373ee, 0xa0e0a15f, 0x9126145f, 0x8643c7b3, 0x80b381ac,
   1638     0x7f7437ad, 0x7b1d1a49, 0x7294b5f2, 0x66256db2, 0x563ba8aa, 0x4362210e, 0x2e3d2abb, 0x17851aad,
   1639 };
   1640 
   1641 static const int8_t sgnMask[3] = {0x02,  0x04,  0x08};
   1642 static const int8_t negMask[3] = {~0x03, ~0x07, ~0x0f};
   1643 
   1644 /***********************************************************************************************************************
   1645  * Function:    AACDecoder_AllocateBuffers
   1646  *
   1647  * Description: allocate all the memory needed for the AAC decoder
   1648  *              try heap first, because it's faster
   1649  *
   1650  * Inputs:      none
   1651  *
   1652  * Outputs:     none
   1653  *
   1654  * Return:      false if not enough memory, otherwise true
   1655  *
   1656  **********************************************************************************************************************/
   1657 
   1658 #ifdef CONFIG_IDF_TARGET_ESP32S3
   1659     // ESP32-S3: If there is PSRAM, prefer it
   1660     #define __malloc_heap_psram(size) \
   1661         heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
   1662 #else
   1663     // ESP32, PSRAM is too slow, prefer SRAM
   1664     #define __malloc_heap_psram(size) \
   1665         heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM)
   1666 #endif
   1667 
   1668 bool AACDecoder_AllocateBuffers(void){
   1669 
   1670     /* here, sizes are: AACDecInfo_t:96 PSInfoBase_t:27364 ProgConfigElement_t*16:1312 PSInfoSBR_t:50788 */
   1671 #ifdef AAC_ENABLE_SBR
   1672     if(!m_PSInfoSBR) {m_PSInfoSBR   = (PSInfoSBR_t*)__malloc_heap_psram(sizeof(PSInfoSBR_t));}
   1673 
   1674     if(!m_PSInfoSBR) {
   1675         log_e("OOM in SBR, can't allocate %d bytes\n", sizeof(PSInfoSBR_t));
   1676         return false; // ERR_AAC_SBR_INIT;
   1677     }
   1678     else {
   1679         log_d("AAC Spectral Band Replication enabled, %d additional bytes allocated", sizeof(PSInfoSBR_t));
   1680     }
   1681 #endif
   1682 
   1683     /* these could fall back to PSRAM if not enough heap available */
   1684     if(!m_AACDecInfo) {m_AACDecInfo = (AACDecInfo_t*)        __malloc_heap_psram(sizeof(AACDecInfo_t));}
   1685     if(!m_PSInfoBase) {m_PSInfoBase = (PSInfoBase_t*)        __malloc_heap_psram(sizeof(PSInfoBase_t));}
   1686     if(!m_pce[0])     {m_pce[0]     = (ProgConfigElement_t*) __malloc_heap_psram(sizeof(ProgConfigElement_t)*16);}
   1687 
   1688     if(!m_AACDecInfo || !m_PSInfoBase || !m_pce[0]) {
   1689             log_e("not enough memory to allocate aacdecoder buffers");
   1690             AACDecoder_FreeBuffers();
   1691             return false;
   1692     }
   1693 
   1694     // Clear Buffer
   1695     memset( m_AACDecInfo,        0, sizeof(AACDecInfo_t));              //Clear AACDecInfo
   1696     memset( m_PSInfoBase,        0, sizeof(PSInfoBase_t));              //Clear PSInfoBase
   1697     memset(&m_AACFrameInfo,      0, sizeof(AACFrameInfo_t));            //Clear AACFrameInfo
   1698     memset(&m_fhADTS,            0, sizeof(ADTSHeader_t));              //Clear fhADTS
   1699     memset(&m_fhADIF,            0, sizeof(ADIFHeader_t));              //Clear fhADIS
   1700     memset( m_pce[0],            0, sizeof(ProgConfigElement_t) * 16);  //Clear ProgConfigElement
   1701     memset(&m_pulseInfo[0],      0, sizeof(PulseInfo_t) *2);            //Clear PulseInfo
   1702     memset(&m_aac_BitStreamInfo, 0, sizeof(aac_BitStreamInfo_t));       //Clear aac_BitStreamInfo
   1703 #ifdef AAC_ENABLE_SBR
   1704     memset( m_PSInfoSBR,         0, sizeof(PSInfoSBR_t));               //Clear PSInfoSBR
   1705     InitSBRState();
   1706 #endif
   1707 
   1708     m_AACDecInfo->prevBlockID = AAC_ID_INVALID;
   1709     m_AACDecInfo->currBlockID = AAC_ID_INVALID;
   1710     m_AACDecInfo->currInstTag = -1;
   1711     for(int ch = 0; ch < MAX_NCHANS_ELEM; ch++)
   1712         m_AACDecInfo->sbDeinterleaveReqd[ch] = 0;
   1713     m_AACDecInfo->adtsBlocksLeft = 0;
   1714     m_AACDecInfo->tnsUsed = 0;
   1715     m_AACDecInfo->pnsUsed = 0;
   1716 
   1717     return true;
   1718 }
   1719 
   1720 /**************************************************************************************
   1721  * Function:    AACFlushCodec
   1722  *
   1723  * Description: flush internal codec state (after seeking, for example)
   1724  *
   1725  * Inputs:      valid AAC decoder instance pointer (HAACDecoder)
   1726  *
   1727  * Outputs:     updated state variables in aacDecInfo
   1728  *
   1729  * Return:      0 if successful, error code (< 0) if error
   1730  **************************************************************************************/
   1731 int AACFlushCodec()
   1732 {
   1733     int ch;
   1734 
   1735     if (!m_AACDecInfo)
   1736         return ERR_AAC_NULL_POINTER;
   1737 
   1738     /* reset common state variables which change per-frame
   1739      * don't touch state variables which are (usually) constant for entire clip
   1740      *   (nChans, sampRate, profile, format, sbrEnabled)
   1741      */
   1742     m_AACDecInfo->prevBlockID = AAC_ID_INVALID;
   1743     m_AACDecInfo->currBlockID = AAC_ID_INVALID;
   1744     m_AACDecInfo->currInstTag = -1;
   1745     for (ch = 0; ch < MAX_NCHANS_ELEM; ch++)
   1746         m_AACDecInfo->sbDeinterleaveReqd[ch] = 0;
   1747     m_AACDecInfo->adtsBlocksLeft = 0;
   1748     m_AACDecInfo->tnsUsed = 0;
   1749     m_AACDecInfo->pnsUsed = 0;
   1750 
   1751     /* reset internal codec state (flush overlap buffers, etc.) */
   1752     memset(m_PSInfoBase->overlap, 0,  AAC_MAX_NCHANS * AAC_MAX_NSAMPS * sizeof(int));
   1753     memset(m_PSInfoBase->prevWinShape, 0, AAC_MAX_NCHANS * sizeof(int));
   1754 
   1755     return ERR_AAC_NONE;
   1756 }
   1757 /***********************************************************************************************************************
   1758  * Function:    AACDecoder_FreeBuffers
   1759  *
   1760  * Description: allocate all the memory needed for the AAC decoder
   1761  *
   1762  * Inputs:      none
   1763  *
   1764  * Outputs:     none
   1765  *
   1766  * Return:      none
   1767 
   1768  **********************************************************************************************************************/
   1769 void AACDecoder_FreeBuffers(void) {
   1770 
   1771 //    uint32_t i = ESP.getFreeHeap();
   1772 
   1773     if(m_AACDecInfo)                         {free(m_AACDecInfo);    m_AACDecInfo=NULL;}
   1774     if(m_PSInfoBase)                         {free(m_PSInfoBase);    m_PSInfoBase=NULL;}
   1775     if(m_pce[0])                             {free(m_pce[0]);        m_pce[0]=NULL;}
   1776 
   1777 #ifdef AAC_ENABLE_SBR
   1778     if(m_PSInfoSBR)                           {free(m_PSInfoSBR);    m_PSInfoSBR=NULL;}               //Clear AACDecInfo
   1779 #endif
   1780 
   1781 //    log_i("AACDecoder: %lu bytes memory was freed", ESP.getFreeHeap() - i);
   1782 }
   1783 
   1784 /***********************************************************************************************************************
   1785  * Function:    AACDecoder_IsInit
   1786  *
   1787  * Description: returns AAC decoder initialization status
   1788  *
   1789  * Inputs:      none
   1790  *
   1791  * Outputs:     none
   1792  *
   1793  * Return:      true if buffers allocated, otherwise false
   1794 
   1795  **********************************************************************************************************************/
   1796 bool AACDecoder_IsInit(void) {
   1797     if(m_AACDecInfo && m_PSInfoBase && m_pce[0]){
   1798         return true;
   1799     }
   1800     return false;
   1801 }
   1802 
   1803 /***********************************************************************************************************************
   1804  * Function:    AACDecoder_FreeBuffers
   1805  *
   1806  * Description: allocate all the memory needed for the AAC decoder
   1807  *
   1808  * Inputs:      none
   1809  *
   1810  * Outputs:     none
   1811  *
   1812  * Return:      none
   1813 
   1814  **********************************************************************************************************************/
   1815 
   1816 /***********************************************************************************************************************
   1817  * Function:    AACFindSyncWord
   1818  *
   1819  * Description: locate the next byte-alinged sync word in the raw AAC stream
   1820  *
   1821  * Inputs:      buffer to search for sync word
   1822  *              max number of bytes to search in buffer
   1823  *
   1824  * Outputs:     none
   1825  *
   1826  * Return:      offset to first sync word (bytes from start of buf)
   1827  *              -1 if sync not found after searching nBytes
   1828  **********************************************************************************************************************/
   1829 int AACFindSyncWord(uint8_t *buf, int nBytes)
   1830 {
   1831     int i;
   1832 
   1833     /* find byte-aligned syncword (12 bits = 0xFFF) */
   1834     for (i = 0; i < nBytes - 1; i++) {
   1835         if ( (buf[i+0] & SYNCWORDH) == SYNCWORDH && (buf[i+1] & SYNCWORDL) == SYNCWORDL )
   1836             return i;
   1837     }
   1838 
   1839     return -1;
   1840 }
   1841 //**************************************************************************************
   1842 int AACGetSampRate(){return m_AACDecInfo->sampRate * (m_AACDecInfo->sbrEnabled ? 2 : 1);}
   1843 int AACGetChannels(){return m_AACDecInfo->nChans;}
   1844 int AACGetBitsPerSample(){return 16;}
   1845 int AACGetID() {return m_AACDecInfo->id;} // 0-MPEG4, 1-MPEG2
   1846 uint8_t AACGetProfile() {return (uint8_t)m_AACDecInfo->profile;} // 0-Main, 1-LC, 2-SSR, 3-reserved
   1847 uint8_t AACGetFormat() {return (uint8_t)m_AACDecInfo->format;}   // 0-unknown 1-ADTS 2-ADIF, 3-RAW
   1848 int AACGetOutputSamps(){return m_AACDecInfo->nChans * AAC_MAX_NSAMPS  * (m_AACDecInfo->sbrEnabled ? 2 : 1);}
   1849 int AACGetBitrate() {
   1850     uint32_t br = AACGetBitsPerSample() * AACGetChannels() *  AACGetSampRate();
   1851     return (br / m_AACDecInfo->compressionRatio);
   1852 }
   1853 /**************************************************************************************
   1854  * Function:    AACSetRawBlockParams
   1855  *
   1856  * Description: set internal state variables for decoding a stream of raw data blocks
   1857  *
   1858  * Inputs:      flag indicating source of parameters
   1859  *              nChans, sampRate,
   1860  *              and profile  0 = main, 1 = LC, 2 = SSR, 3 = reserved
   1861  *                optionally filled-in
   1862  *
   1863  * Outputs:     updated codec state
   1864  *
   1865  * Return:      0 if successful, error code (< 0) if error
   1866  *
   1867  * Notes:       if copyLast == 1, then the codec sets up its internal state (for
   1868  *                decoding raw blocks) based on previously-decoded ADTS header info
   1869  *              if copyLast == 0, then the codec uses the values passed in
   1870  *                aacFrameInfo to configure its internal state (useful when the
   1871  *                source is MP4 format, for example)
   1872  **************************************************************************************/
   1873 int AACSetRawBlockParams(int copyLast, int nChans, int sampRateCore, int profile)
   1874 {
   1875     if (!m_AACDecInfo)
   1876         return ERR_AAC_NULL_POINTER;
   1877 
   1878     m_AACDecInfo->format = AAC_FF_RAW;
   1879     if (copyLast)
   1880         return SetRawBlockParams(1, 0, 0, 0);
   1881     else
   1882         return SetRawBlockParams(0, nChans, sampRateCore, profile);
   1883 }
   1884 
   1885 /***********************************************************************************************************************
   1886  * Function:    AACDecode
   1887  *
   1888  * Description: decode AAC frame
   1889  *
   1890  * Inputs:      double pointer to buffer of AAC data
   1891  *              pointer to number of valid bytes remaining in inbuf
   1892  *              pointer to outbuf, big enough to hold one frame of decoded PCM samples
   1893  *
   1894  * Outputs:     PCM data in outbuf, interleaved LRLRLR... if stereo
   1895  *                number of output samples = 1024 per channel
   1896  *              updated inbuf pointer
   1897  *              updated bytesLeft
   1898  *
   1899  * Return:      0 if successful, error code (< 0) if error
   1900  *
   1901  * Notes:       inbuf pointer and bytesLeft are not updated until whole frame is
   1902  *                successfully decoded, so if ERR_AAC_INDATA_UNDERFLOW is returned
   1903  *                just call AACDecode again with more data in inbuf
   1904  **********************************************************************************************************************/
   1905 int AACDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf)
   1906 {
   1907     int err, offset, bitOffset, bitsAvail;
   1908     int ch, baseChan, elementChans;
   1909     uint8_t *inptr;
   1910 
   1911 #ifdef AAC_ENABLE_SBR
   1912     int baseChanSBR, elementChansSBR;
   1913 #endif
   1914 
   1915     /* make local copies (see "Notes" above) */
   1916     inptr = inbuf;
   1917     bitOffset = 0;
   1918     bitsAvail = (*bytesLeft) << 3;
   1919 
   1920     /* first time through figure out what the file format is */
   1921     if (m_AACDecInfo->format == AAC_FF_Unknown) {
   1922         if (bitsAvail < 32)
   1923             return ERR_AAC_INDATA_UNDERFLOW;
   1924 
   1925         if ((inptr)[0] == 'A' && (inptr)[1] == 'D' && (inptr)[2] == 'I' && (inptr)[3] == 'F') {
   1926             /* unpack ADIF header */
   1927             m_AACDecInfo->format = AAC_FF_ADIF;
   1928             err = UnpackADIFHeader(&inptr, &bitOffset, &bitsAvail);
   1929             if (err)
   1930                 return err;
   1931         } else {
   1932             /* assume ADTS by default */
   1933             m_AACDecInfo->format = AAC_FF_ADTS;
   1934         }
   1935     }
   1936     /* if ADTS, search for start of next frame */
   1937     if (m_AACDecInfo->format == AAC_FF_ADTS) {
   1938         /* can have 1-4 raw data blocks per ADTS frame (header only present for first one) */
   1939         if (m_AACDecInfo->adtsBlocksLeft == 0) {
   1940             offset = AACFindSyncWord(inptr, bitsAvail >> 3);
   1941             if (offset < 0)
   1942                 return ERR_AAC_INDATA_UNDERFLOW;
   1943             inptr += offset;
   1944             bitsAvail -= (offset << 3);
   1945 
   1946             err = UnpackADTSHeader(&inptr, &bitOffset, &bitsAvail);
   1947             if (err)
   1948                 return err;
   1949 
   1950             if (m_AACDecInfo->nChans == -1) {
   1951                 /* figure out implicit channel mapping if necessary */
   1952                 err = GetADTSChannelMapping(inptr, bitOffset, bitsAvail);
   1953                 if (err)
   1954                     return err;
   1955             }
   1956         }
   1957         m_AACDecInfo->adtsBlocksLeft--;
   1958     } else if (m_AACDecInfo->format == AAC_FF_RAW) {
   1959         err = PrepareRawBlock();
   1960         if (err)
   1961             return err;
   1962     }
   1963 
   1964     /* check for valid number of channels */
   1965     if (m_AACDecInfo->nChans > AAC_MAX_NCHANS || m_AACDecInfo->nChans <= 0)
   1966         return ERR_AAC_NCHANS_TOO_HIGH;
   1967 
   1968     /* will be set later if active in this frame */
   1969     m_AACDecInfo->tnsUsed = 0;
   1970     m_AACDecInfo->pnsUsed = 0;
   1971 
   1972     bitOffset = 0;
   1973     baseChan = 0;
   1974 
   1975 #ifdef AAC_ENABLE_SBR
   1976     baseChanSBR = 0;
   1977 #endif
   1978 
   1979     do {
   1980         /* parse next syntactic element */
   1981         err = DecodeNextElement(&inptr, &bitOffset, &bitsAvail);
   1982         if (err)
   1983             return err;
   1984 
   1985         elementChans = elementNumChans[m_AACDecInfo->currBlockID];
   1986         if (baseChan + elementChans > AAC_MAX_NCHANS)
   1987             return ERR_AAC_NCHANS_TOO_HIGH;
   1988 
   1989         /* noiseless decoder and dequantizer */
   1990         for (ch = 0; ch < elementChans; ch++) {
   1991             err = DecodeNoiselessData(&inptr, &bitOffset, &bitsAvail, ch);
   1992 
   1993             if (err)
   1994                 return err;
   1995 
   1996             if (AACDequantize(ch))
   1997                 return ERR_AAC_DEQUANT;
   1998         }
   1999 
   2000         /* mid-side and intensity stereo */
   2001         if (m_AACDecInfo->currBlockID == AAC_ID_CPE) {
   2002             if (StereoProcess())
   2003                 return ERR_AAC_STEREO_PROCESS;
   2004         }
   2005 
   2006         /* PNS, TNS, inverse transform */
   2007         for (ch = 0; ch < elementChans; ch++) {
   2008 
   2009             if (PNS(ch))
   2010                 return ERR_AAC_PNS;
   2011 
   2012             if (m_AACDecInfo->sbDeinterleaveReqd[ch]) {
   2013                 /* deinterleave short blocks, if required */
   2014                 if (DeinterleaveShortBlocks(ch))
   2015                     return ERR_AAC_SHORT_BLOCK_DEINT;
   2016                 m_AACDecInfo->sbDeinterleaveReqd[ch] = 0;
   2017             }
   2018 
   2019             if (TNSFilter(ch))
   2020                 return ERR_AAC_TNS;
   2021 
   2022             if (IMDCT(ch, baseChan + ch, outbuf))
   2023                 return ERR_AAC_IMDCT;
   2024         }
   2025 
   2026 #ifdef AAC_ENABLE_SBR
   2027         if (m_AACDecInfo->sbrEnabled && (m_AACDecInfo->currBlockID == AAC_ID_FIL ||
   2028                                          m_AACDecInfo->currBlockID == AAC_ID_LFE)) {
   2029             if (m_AACDecInfo->currBlockID == AAC_ID_LFE)
   2030                 elementChansSBR = elementNumChans[AAC_ID_LFE];
   2031             else if (m_AACDecInfo->currBlockID == AAC_ID_FIL && (m_AACDecInfo->prevBlockID == AAC_ID_SCE ||
   2032                                                                  m_AACDecInfo->prevBlockID == AAC_ID_CPE))
   2033                 elementChansSBR = elementNumChans[m_AACDecInfo->prevBlockID];
   2034             else
   2035                 elementChansSBR = 0;
   2036 
   2037             if (baseChanSBR + elementChansSBR > AAC_MAX_NCHANS)
   2038                 return ERR_AAC_SBR_NCHANS_TOO_HIGH;
   2039 
   2040             /* parse SBR extension data if present (contained in a fill element) */
   2041             if (DecodeSBRBitstream(baseChanSBR))
   2042                 return ERR_AAC_SBR_BITSTREAM;
   2043 
   2044             /* apply SBR */
   2045             if (DecodeSBRData(baseChanSBR, outbuf))
   2046                 return ERR_AAC_SBR_DATA;
   2047 
   2048             baseChanSBR += elementChansSBR;
   2049         }
   2050 #endif
   2051 
   2052     baseChan += elementChans;
   2053     } while (m_AACDecInfo->currBlockID != AAC_ID_END);
   2054 
   2055     /* byte align after each raw_data_block */
   2056     if (bitOffset) {
   2057         inptr++;
   2058         bitsAvail -= (8-bitOffset);
   2059         bitOffset = 0;
   2060         if (bitsAvail < 0)
   2061             return ERR_AAC_INDATA_UNDERFLOW;
   2062     }
   2063 
   2064     m_AACDecInfo->compressionRatio = (float)(AACGetOutputSamps()) * 2 / (inptr - inbuf);
   2065 
   2066     /* update pointers */
   2067     m_AACDecInfo->frameCount++;
   2068     *bytesLeft -= (inptr - inbuf);
   2069     inbuf = inptr;
   2070 
   2071     return ERR_AAC_NONE;
   2072 }
   2073 /***********************************************************************************************************************
   2074  * Function:    DecodeLPCCoefs
   2075  *
   2076  * Description: decode LPC coefficients for TNS
   2077  *
   2078  * Inputs:      order of TNS filter
   2079  *              resolution of coefficients (3 or 4 bits)
   2080  *              coefficients unpacked from bitstream
   2081  *              scratch buffer (b) of size >= order
   2082  *
   2083  * Outputs:     LPC coefficients in Q(FBITS_LPC_COEFS), in 'a'
   2084  *
   2085  * Return:      none
   2086  *
   2087  * Notes:       assumes no guard bits in input transform coefficients
   2088  *              a[i] = Q(FBITS_LPC_COEFS), don't store a0 = 1.0
   2089  *                (so a[0] = first delay tap, etc.)
   2090  *              max abs(a[i]) < log2(order), so for max order = 20 a[i] < 4.4
   2091  *                (up to 3 bits of gain) so a[i] has at least 31 - FBITS_LPC_COEFS - 3
   2092  *                guard bits
   2093  *              to ensure no intermediate overflow in all-pole filter, set
   2094  *                FBITS_LPC_COEFS such that number of guard bits >= log2(max order)
   2095  **********************************************************************************************************************/
   2096 void DecodeLPCCoefs(int order, int res, int8_t *filtCoef, int *a, int *b)
   2097 {
   2098     int i, m, t;
   2099     const uint32_t *invQuantTab;
   2100 
   2101     if (res == 3)            invQuantTab = invQuant3;
   2102     else if (res == 4)       invQuantTab = invQuant4;
   2103     else                    return;
   2104 
   2105     for (m = 0; m < order; m++) {
   2106         t = invQuantTab[filtCoef[m] & 0x0f];    /* t = Q31 */
   2107         for (i = 0; i < m; i++)
   2108             b[i] = a[i] - (MULSHIFT32(t, a[m-i-1]) << 1);
   2109         for (i = 0; i < m; i++)
   2110             a[i] = b[i];
   2111         a[m] = t >> (31 - FBITS_LPC_COEFS);
   2112     }
   2113 }
   2114 
   2115 /***********************************************************************************************************************
   2116  * Function:    FilterRegion
   2117  *
   2118  * Description: apply LPC filter to one region of coefficients
   2119  *
   2120  * Inputs:      number of transform coefficients in this region
   2121  *              direction flag (forward = 1, backward = -1)
   2122  *              order of filter
   2123  *              'size' transform coefficients
   2124  *              'order' LPC coefficients in Q(FBITS_LPC_COEFS)
   2125  *              scratch buffer for history (must be >= order samples long)
   2126  *
   2127  * Outputs:     filtered transform coefficients
   2128  *
   2129  * Return:      guard bit mask (OR of abs value of all filtered transform coefs)
   2130  *
   2131  * Notes:       assumes no guard bits in input transform coefficients
   2132  *              gains 0 int bits
   2133  *              history buffer does not need to be preserved between regions
   2134  **********************************************************************************************************************/
   2135 int FilterRegion(int size, int dir, int order, int *audioCoef, int *a, int *hist)
   2136 {
   2137     int i, j, y, hi32, inc, gbMask;
   2138     U64 sum64;
   2139 
   2140     /* init history to 0 every time */
   2141     for (i = 0; i < order; i++)
   2142         hist[i] = 0;
   2143 
   2144     sum64.w64 = 0;     /* avoid warning */
   2145     gbMask = 0;
   2146     inc = (dir ? -1 : 1);
   2147     do {
   2148         /* sum64 = a0*y[n] = 1.0*y[n] */
   2149         y = *audioCoef;
   2150         sum64.r.hi32 = y >> (32 - FBITS_LPC_COEFS);
   2151         sum64.r.lo32 = y << FBITS_LPC_COEFS;
   2152 
   2153         /* sum64 += (a1*y[n-1] + a2*y[n-2] + ... + a[order-1]*y[n-(order-1)]) */
   2154         for (j = order - 1; j > 0; j--) {
   2155             sum64.w64 = MADD64(sum64.w64, hist[j], a[j]);
   2156             hist[j] = hist[j-1];
   2157         }
   2158         sum64.w64 = MADD64(sum64.w64, hist[0], a[0]);
   2159         y = (sum64.r.hi32 << (32 - FBITS_LPC_COEFS)) | (sum64.r.lo32 >> FBITS_LPC_COEFS);
   2160 
   2161         /* clip output (rare) */
   2162         hi32 = sum64.r.hi32;
   2163         if ((hi32 >> 31) != (hi32 >> (FBITS_LPC_COEFS-1)))
   2164             y = (hi32 >> 31) ^ 0x7fffffff;
   2165 
   2166         hist[0] = y;
   2167         *audioCoef = y;
   2168         audioCoef += inc;
   2169         gbMask |= FASTABS(y);
   2170     } while (--size);
   2171 
   2172     return gbMask;
   2173 }
   2174 
   2175 /***********************************************************************************************************************
   2176  * Function:    TNSFilter
   2177  *
   2178  * Description: apply temporal noise shaping, if enabled
   2179  *
   2180  * Inputs:      index of current channel
   2181  *
   2182  * Outputs:     updated transform coefficients
   2183  *              updated minimum guard bit count for this channel
   2184  *
   2185  * Return:      0 if successful, -1 if error
   2186  **********************************************************************************************************************/
   2187 int TNSFilter(int ch)
   2188 {
   2189     int win, winLen, nWindows, nSFB, filt, bottom, top, order, maxOrder, dir;
   2190     int start, end, size, tnsMaxBand, numFilt, gbMask;
   2191     int *audioCoef;
   2192     uint8_t *filtLength, *filtOrder, *filtRes, *filtDir;
   2193     int8_t *filtCoef;
   2194     const uint16_t *tnsMaxBandTab;
   2195     const uint16_t *sfbTab;
   2196     ICSInfo_t *icsInfo;
   2197     TNSInfo_t *ti;
   2198 
   2199     icsInfo = (ch == 1 && m_PSInfoBase->commonWin == 1) ? &(m_PSInfoBase->icsInfo[0]) : &(m_PSInfoBase->icsInfo[ch]);
   2200     ti = &m_PSInfoBase->tnsInfo[ch];
   2201 
   2202     if (!ti->tnsDataPresent)
   2203         return 0;
   2204 
   2205     if (icsInfo->winSequence == 2) {
   2206         nWindows = NWINDOWS_SHORT;
   2207         winLen = NSAMPS_SHORT;
   2208         nSFB = sfBandTotalShort[m_PSInfoBase->sampRateIdx];
   2209         maxOrder = tnsMaxOrderShort[m_AACDecInfo->profile];
   2210         sfbTab = sfBandTabShort + sfBandTabShortOffset[m_PSInfoBase->sampRateIdx];
   2211         tnsMaxBandTab = tnsMaxBandsShort + tnsMaxBandsShortOffset[m_AACDecInfo->profile];
   2212         tnsMaxBand = tnsMaxBandTab[m_PSInfoBase->sampRateIdx];
   2213     } else {
   2214         nWindows = NWINDOWS_LONG;
   2215         winLen = NSAMPS_LONG;
   2216         nSFB = sfBandTotalLong[m_PSInfoBase->sampRateIdx];
   2217         maxOrder = tnsMaxOrderLong[m_AACDecInfo->profile];
   2218         sfbTab = sfBandTabLong + sfBandTabLongOffset[m_PSInfoBase->sampRateIdx];
   2219         tnsMaxBandTab = tnsMaxBandsLong + tnsMaxBandsLongOffset[m_AACDecInfo->profile];
   2220         tnsMaxBand = tnsMaxBandTab[m_PSInfoBase->sampRateIdx];
   2221     }
   2222 
   2223     if (tnsMaxBand > icsInfo->maxSFB)
   2224         tnsMaxBand = icsInfo->maxSFB;
   2225 
   2226     filtRes =    ti->coefRes;
   2227     filtLength = ti->length;
   2228     filtOrder =  ti->order;
   2229     filtDir =    ti->dir;
   2230     filtCoef =   ti->coef;
   2231 
   2232     gbMask = 0;
   2233     audioCoef =  m_PSInfoBase->coef[ch];
   2234     for (win = 0; win < nWindows; win++) {
   2235         bottom = nSFB;
   2236         numFilt = ti->numFilt[win];
   2237         for (filt = 0; filt < numFilt; filt++) {
   2238             top = bottom;
   2239             bottom = top - *filtLength++;
   2240             bottom = MAX(bottom, 0);
   2241             order = *filtOrder++;
   2242             order = MIN(order, maxOrder);
   2243 
   2244             if (order) {
   2245                 start = sfbTab[MIN(bottom, tnsMaxBand)];
   2246                 end   = sfbTab[MIN(top, tnsMaxBand)];
   2247                 size = end - start;
   2248                 if (size > 0) {
   2249                     dir = *filtDir++;
   2250                     if (dir)
   2251                         start = end - 1;
   2252 
   2253                     DecodeLPCCoefs(order, filtRes[win], filtCoef, m_PSInfoBase->tnsLPCBuf, m_PSInfoBase->tnsWorkBuf);
   2254                     gbMask |= FilterRegion(size, dir, order, audioCoef + start, m_PSInfoBase->tnsLPCBuf,
   2255                                                                                            m_PSInfoBase->tnsWorkBuf);
   2256                 }
   2257                 filtCoef += order;
   2258             }
   2259         }
   2260         audioCoef += winLen;
   2261     }
   2262 
   2263     /* update guard bit count if necessary */
   2264     size = CLZ(gbMask) - 1;
   2265     if (m_PSInfoBase->gbCurrent[ch] > size)
   2266         m_PSInfoBase->gbCurrent[ch] = size;
   2267 
   2268     return 0;
   2269 }
   2270 
   2271 /***********************************************************************************************************************
   2272  * Function:    DecodeSingleChannelElement
   2273  *
   2274  * Description: decode one SCE
   2275  *
   2276  * Inputs:      none
   2277  *
   2278  * Outputs:     updated element instance tag
   2279  *
   2280  * Return:      0 if successful, -1 if error
   2281  *
   2282  * Notes:       doesn't decode individual channel stream (part of DecodeNoiselessData)
   2283  **********************************************************************************************************************/
   2284 int DecodeSingleChannelElement()
   2285 {
   2286     /* read instance tag */
   2287     m_AACDecInfo->currInstTag = GetBits(NUM_INST_TAG_BITS);
   2288 
   2289     return 0;
   2290 }
   2291 
   2292 /***********************************************************************************************************************
   2293  * Function:    DecodeChannelPairElement
   2294  *
   2295  * Description: decode one CPE
   2296  *
   2297  * Inputs:       none
   2298  *
   2299  * Outputs:     updated element instance tag
   2300  *              updated commonWin
   2301  *              updated ICS info, if commonWin == 1
   2302  *              updated mid-side stereo info, if commonWin == 1
   2303  *
   2304  * Return:      0 if successful, -1 if error
   2305  *
   2306  * Notes:       doesn't decode individual channel stream (part of DecodeNoiselessData)
   2307  **********************************************************************************************************************/
   2308 int DecodeChannelPairElement()
   2309 {
   2310     int sfb, gp, maskOffset;
   2311     uint8_t currBit, *maskPtr;
   2312     ICSInfo_t *icsInfo;
   2313 
   2314 
   2315     icsInfo = m_PSInfoBase->icsInfo;
   2316 
   2317     /* read instance tag */
   2318     m_AACDecInfo->currInstTag = GetBits(NUM_INST_TAG_BITS);
   2319 
   2320     /* read common window flag and mid-side info (if present)
   2321      * store msMask bits in m_PSInfoBase->msMaskBits[] as follows:
   2322      *  long blocks -  pack bits for each SFB in range [0, maxSFB) starting with lsb of msMaskBits[0]
   2323      *  short blocks - pack bits for each SFB in range [0, maxSFB), for each group [0, 7]
   2324      * msMaskPresent = 0 means no M/S coding
   2325      *               = 1 means m_PSInfoBase->msMaskBits contains 1 bit per SFB to toggle M/S coding
   2326      *               = 2 means all SFB's are M/S coded (so m_PSInfoBase->msMaskBits is not needed)
   2327      */
   2328     m_PSInfoBase->commonWin = GetBits(1);
   2329     if (m_PSInfoBase->commonWin) {
   2330         DecodeICSInfo(icsInfo, m_PSInfoBase->sampRateIdx);
   2331         m_PSInfoBase->msMaskPresent = GetBits(2);
   2332         if (m_PSInfoBase->msMaskPresent == 1) {
   2333             maskPtr = m_PSInfoBase->msMaskBits;
   2334             *maskPtr = 0;
   2335             maskOffset = 0;
   2336             for (gp = 0; gp < icsInfo->numWinGroup; gp++) {
   2337                 for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) {
   2338                     currBit = (uint8_t)GetBits(1);
   2339                     *maskPtr |= currBit << maskOffset;
   2340                     if (++maskOffset == 8) {
   2341                         maskPtr++;
   2342                         *maskPtr = 0;
   2343                         maskOffset = 0;
   2344                     }
   2345                 }
   2346             }
   2347         }
   2348     }
   2349 
   2350     return 0;
   2351 }
   2352 
   2353 /***********************************************************************************************************************
   2354  * Function:    DecodeLFEChannelElement
   2355  *
   2356  * Description: decode one LFE
   2357  *
   2358  * Inputs:      none
   2359  *
   2360  * Outputs:     updated element instance tag
   2361  *
   2362  * Return:      0 if successful, -1 if error
   2363  *
   2364  * Notes:       doesn't decode individual channel stream (part of DecodeNoiselessData)
   2365  **********************************************************************************************************************/
   2366 int DecodeLFEChannelElement()
   2367 {
   2368     /* read instance tag */
   2369     m_AACDecInfo->currInstTag = GetBits( NUM_INST_TAG_BITS);
   2370 
   2371     return 0;
   2372 }
   2373 
   2374 /***********************************************************************************************************************
   2375  * Function:    DecodeDataStreamElement
   2376  *
   2377  * Description: decode one DSE
   2378  *
   2379  * Inputs:      none
   2380  *
   2381  * Outputs:     updated element instance tag
   2382  *              filled in data stream buffer
   2383  *
   2384  * Return:      0 if successful, -1 if error
   2385  **********************************************************************************************************************/
   2386 int DecodeDataStreamElement()
   2387 {
   2388     uint32_t byteAlign, dataCount;
   2389     uint8_t *dataBuf;
   2390 
   2391     m_AACDecInfo->currInstTag = GetBits( NUM_INST_TAG_BITS);
   2392     byteAlign = GetBits(1);
   2393     dataCount = GetBits(8);
   2394     if (dataCount == 255)
   2395         dataCount += GetBits(8);
   2396 
   2397     if (byteAlign)
   2398         ByteAlignBitstream();
   2399 
   2400     m_PSInfoBase->dataCount = dataCount;
   2401     dataBuf = m_PSInfoBase->dataBuf;
   2402     while (dataCount--)
   2403         *dataBuf++ = GetBits(8);
   2404 
   2405     return 0;
   2406 }
   2407 
   2408 /***********************************************************************************************************************
   2409  * Function:    DecodeProgramConfigElement
   2410  *
   2411  * Description: decode one PCE
   2412  *
   2413  * Inputs:      none
   2414  *
   2415  * Outputs:     filled-in ProgConfigElement_t struct
   2416  *              updated aac_BitStreamInfo_t struct
   2417  *
   2418  * Return:      0 if successful, error code (< 0) if error
   2419  *
   2420  * Notes:       #define KEEP_PCE_COMMENTS to save the comment field of the PCE
   2421  *                (otherwise we just skip it in the bitstream, to save memory)
   2422  **********************************************************************************************************************/
   2423 int DecodeProgramConfigElement(uint8_t idx)
   2424 {
   2425     int i;
   2426 
   2427     m_pce[idx]->elemInstTag =   GetBits(4);
   2428     m_pce[idx]->profile =       GetBits(2);
   2429     m_pce[idx]->sampRateIdx =   GetBits(4);
   2430     m_pce[idx]->numFCE =        GetBits(4);
   2431     m_pce[idx]->numSCE =        GetBits(4);
   2432     m_pce[idx]->numBCE =        GetBits(4);
   2433     m_pce[idx]->numLCE =        GetBits(2);
   2434     m_pce[idx]->numADE =        GetBits(3);
   2435     m_pce[idx]->numCCE =        GetBits(4);
   2436 
   2437     m_pce[idx]->monoMixdown = GetBits(1) << 4;    /* present flag */
   2438     if (m_pce[idx]->monoMixdown)
   2439         m_pce[idx]->monoMixdown |= GetBits(4);    /* element number */
   2440 
   2441     m_pce[idx]->stereoMixdown = GetBits(1) << 4;    /* present flag */
   2442     if (m_pce[idx]->stereoMixdown)
   2443         m_pce[idx]->stereoMixdown  |= GetBits(4);    /* element number */
   2444 
   2445     m_pce[idx]->matrixMixdown = GetBits(1) << 4;    /* present flag */
   2446     if (m_pce[idx]->matrixMixdown) {
   2447         m_pce[idx]->matrixMixdown  |= GetBits(2) << 1;    /* index */
   2448         m_pce[idx]->matrixMixdown  |= GetBits(1);            /* pseudo-surround enable */
   2449     }
   2450 
   2451     for (i = 0; i < m_pce[idx]->numFCE; i++) {
   2452         m_pce[idx]->fce[i]  = GetBits(1) << 4;    /* is_cpe flag */
   2453         m_pce[idx]->fce[i] |= GetBits(4);            /* tag select */
   2454     }
   2455 
   2456     for (i = 0; i < m_pce[idx]->numSCE; i++) {
   2457         m_pce[idx]->sce[i]  = GetBits(1) << 4;    /* is_cpe flag */
   2458         m_pce[idx]->sce[i] |= GetBits(4);            /* tag select */
   2459     }
   2460 
   2461     for (i = 0; i < m_pce[idx]->numBCE; i++) {
   2462         m_pce[idx]->bce[i]  = GetBits(1) << 4;    /* is_cpe flag */
   2463         m_pce[idx]->bce[i] |= GetBits(4);            /* tag select */
   2464     }
   2465 
   2466     for (i = 0; i < m_pce[idx]->numLCE; i++)
   2467         m_pce[idx]->lce[i] = GetBits(4);            /* tag select */
   2468 
   2469     for (i = 0; i < m_pce[idx]->numADE; i++)
   2470         m_pce[idx]->ade[i] = GetBits(4);            /* tag select */
   2471 
   2472     for (i = 0; i < m_pce[idx]->numCCE; i++) {
   2473         m_pce[idx]->cce[i]  = GetBits(1) << 4;    /* independent/dependent flag */
   2474         m_pce[idx]->cce[i] |= GetBits(4);            /* tag select */
   2475     }
   2476 
   2477     ByteAlignBitstream();
   2478     /* eat comment bytes and throw away */
   2479     i = GetBits(8);
   2480     while (i--)
   2481         GetBits(8);
   2482 
   2483     return 0;
   2484 }
   2485 
   2486 /***********************************************************************************************************************
   2487  * Function:    DecodeFillElement
   2488  *
   2489  * Description: decode one fill element
   2490  *
   2491  * Inputs:      none
   2492  *                (14496-3, table 4.4.11)
   2493  *
   2494  * Outputs:     updated element instance tag
   2495  *              unpacked extension payload
   2496  *
   2497  * Return:      0 if successful, -1 if error
   2498  **********************************************************************************************************************/
   2499 int DecodeFillElement()
   2500 {
   2501     unsigned int fillCount;
   2502     uint8_t *fillBuf;
   2503 
   2504     fillCount = GetBits(4);
   2505     if (fillCount == 15)
   2506         fillCount += (GetBits(8) - 1);
   2507 
   2508     m_PSInfoBase->fillCount = fillCount;
   2509     fillBuf = m_PSInfoBase->fillBuf;
   2510     while (fillCount--)
   2511         *fillBuf++ = GetBits(8);
   2512 
   2513     m_AACDecInfo->currInstTag = -1;    /* fill elements don't have instance tag */
   2514     m_AACDecInfo->fillExtType = 0;
   2515 
   2516 #ifdef AAC_ENABLE_SBR
   2517     /* check for SBR
   2518      * aacDecInfo->sbrEnabled is sticky (reset each raw_data_block), so for multichannel
   2519      *    need to verify that all SCE/CPE/ICCE have valid SBR fill element following, and
   2520      *    must upsample by 2 for LFE
   2521      */
   2522     if (m_PSInfoBase->fillCount > 0) {
   2523         m_AACDecInfo->fillExtType = (int)((m_PSInfoBase->fillBuf[0] >> 4) & 0x0f);
   2524         if (m_AACDecInfo->fillExtType == EXT_SBR_DATA || m_AACDecInfo->fillExtType == EXT_SBR_DATA_CRC)
   2525             m_AACDecInfo->sbrEnabled = 1;
   2526     }
   2527 #endif
   2528 
   2529 
   2530     m_AACDecInfo->fillBuf = m_PSInfoBase->fillBuf;
   2531     m_AACDecInfo->fillCount = m_PSInfoBase->fillCount;
   2532 
   2533     return 0;
   2534 }
   2535 
   2536 /***********************************************************************************************************************
   2537  * Function:    DecodeNextElement
   2538  *
   2539  * Description: decode next syntactic element in AAC frame
   2540  *
   2541  * Inputs:      double pointer to buffer containing next element
   2542  *              pointer to bit offset
   2543  *              pointer to number of valid bits remaining in buf
   2544  *
   2545  * Outputs:     type of element decoded (aacDecInfo->currBlockID)
   2546  *              type of element decoded last time (aacDecInfo->prevBlockID)
   2547  *              updated aacDecInfo state, depending on which element was decoded
   2548  *              updated buffer pointer
   2549  *              updated bit offset
   2550  *              updated number of available bits
   2551  *
   2552  * Return:      0 if successful, error code (< 0) if error
   2553  **********************************************************************************************************************/
   2554 int DecodeNextElement(uint8_t **buf, int *bitOffset, int *bitsAvail)
   2555 {
   2556     int err, bitsUsed;
   2557 
   2558     /* init bitstream reader */
   2559     SetBitstreamPointer((*bitsAvail + 7) >> 3, *buf);
   2560     GetBits(*bitOffset);
   2561 
   2562     m_AACDecInfo->prevBlockID = m_AACDecInfo->currBlockID;
   2563     m_AACDecInfo->currBlockID = GetBits(NUM_SYN_ID_BITS);
   2564 
   2565     /* set defaults (could be overwritten by DecodeXXXElement(), depending on currBlockID) */
   2566     m_PSInfoBase->commonWin = 0;
   2567 
   2568     err = 0;
   2569     switch (m_AACDecInfo->currBlockID) {
   2570     case AAC_ID_SCE:
   2571         err = DecodeSingleChannelElement();
   2572         break;
   2573     case AAC_ID_CPE:
   2574         err = DecodeChannelPairElement();
   2575         break;
   2576     case AAC_ID_CCE:
   2577         break;
   2578     case AAC_ID_LFE:
   2579         err = DecodeLFEChannelElement();
   2580         break;
   2581     case AAC_ID_DSE:
   2582         err = DecodeDataStreamElement();
   2583         break;
   2584     case AAC_ID_PCE:
   2585         err = DecodeProgramConfigElement(0);
   2586         break;
   2587     case AAC_ID_FIL:
   2588         err = DecodeFillElement();
   2589         break;
   2590     case AAC_ID_END:
   2591         break;
   2592     }
   2593     if (err)
   2594         return ERR_AAC_SYNTAX_ELEMENT;
   2595 
   2596     /* update bitstream reader */
   2597     bitsUsed = CalcBitsUsed(*buf, *bitOffset);
   2598     *buf += (bitsUsed + *bitOffset) >> 3;
   2599     *bitOffset = (bitsUsed + *bitOffset) & 0x07;
   2600     *bitsAvail -= bitsUsed;
   2601 
   2602     if (*bitsAvail < 0)
   2603         return ERR_AAC_INDATA_UNDERFLOW;
   2604 
   2605     return ERR_AAC_NONE;
   2606 }
   2607 
   2608 /***********************************************************************************************************************
   2609  * Function:    PreMultiply
   2610  *
   2611  * Description: pre-twiddle stage of DCT4
   2612  *
   2613  * Inputs:      table index (for transform size)
   2614  *              buffer of nmdct samples
   2615  *
   2616  * Outputs:     processed samples in same buffer
   2617  *
   2618  * Return:      none
   2619  *
   2620  * Notes:       minimum 1 GB in, 2 GB out, gains 5 (short) or 8 (long) frac bits
   2621  *              i.e. gains 2-7= -5 int bits (short) or 2-10 = -8 int bits (long)
   2622  *              normalization by -1/N is rolled into tables here (see trigtabs.c)
   2623  *              uses 3-mul, 3-add butterflies instead of 4-mul, 2-add
   2624  **********************************************************************************************************************/
   2625 void PreMultiply(int tabidx, int *zbuf1)
   2626 {
   2627     int i, nmdct, ar1, ai1, ar2, ai2, z1, z2;
   2628     int t, cms2, cps2a, sin2a, cps2b, sin2b;
   2629     int *zbuf2;
   2630     const uint32_t *csptr;
   2631 
   2632     nmdct = nmdctTab[tabidx];
   2633     zbuf2 = zbuf1 + nmdct - 1;
   2634     csptr = cos4sin4tab + cos4sin4tabOffset[tabidx];
   2635 
   2636     /* whole thing should fit in registers - verify that compiler does this */
   2637     for (i = nmdct >> 2; i != 0; i--) {
   2638         /* cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) */
   2639         cps2a = *csptr++;
   2640         sin2a = *csptr++;
   2641         cps2b = *csptr++;
   2642         sin2b = *csptr++;
   2643 
   2644         ar1 = *(zbuf1 + 0);
   2645         ai2 = *(zbuf1 + 1);
   2646         ai1 = *(zbuf2 + 0);
   2647         ar2 = *(zbuf2 - 1);
   2648 
   2649         /* gain 2 ints bit from MULSHIFT32 by Q30, but drop 7 or 10 int bits from table scaling of 1/M
   2650          * max per-sample gain (ignoring implicit scaling) = MAX(sin(angle)+cos(angle)) = 1.414
   2651          * i.e. gain 1 GB since worst case is sin(angle) = cos(angle) = 0.707 (Q30), gain 2 from
   2652          *   extra sign bits, and eat one in adding
   2653          */
   2654         t  = MULSHIFT32(sin2a, ar1 + ai1);
   2655         z2 = MULSHIFT32(cps2a, ai1) - t;
   2656         cms2 = cps2a - 2*sin2a;
   2657         z1 = MULSHIFT32(cms2, ar1) + t;
   2658         *zbuf1++ = z1;    /* cos*ar1 + sin*ai1 */
   2659         *zbuf1++ = z2;    /* cos*ai1 - sin*ar1 */
   2660 
   2661         t  = MULSHIFT32(sin2b, ar2 + ai2);
   2662         z2 = MULSHIFT32(cps2b, ai2) - t;
   2663         cms2 = cps2b - 2*sin2b;
   2664         z1 = MULSHIFT32(cms2, ar2) + t;
   2665         *zbuf2-- = z2;    /* cos*ai2 - sin*ar2 */
   2666         *zbuf2-- = z1;    /* cos*ar2 + sin*ai2 */
   2667     }
   2668 }
   2669 
   2670 /***********************************************************************************************************************
   2671  * Function:    PostMultiply
   2672  *
   2673  * Description: post-twiddle stage of DCT4
   2674  *
   2675  * Inputs:      table index (for transform size)
   2676  *              buffer of nmdct samples
   2677  *
   2678  * Outputs:     processed samples in same buffer
   2679  *
   2680  * Return:      none
   2681  *
   2682  * Notes:       minimum 1 GB in, 2 GB out - gains 2 int bits
   2683  *              uses 3-mul, 3-add butterflies instead of 4-mul, 2-add
   2684  **********************************************************************************************************************/
   2685 void PostMultiply(int tabidx, int *fft1)
   2686 {
   2687     int i, nmdct, ar1, ai1, ar2, ai2, skipFactor;
   2688     int t, cms2, cps2, sin2;
   2689     int *fft2;
   2690     const int *csptr;
   2691 
   2692     nmdct = nmdctTab[tabidx];
   2693     csptr = cos1sin1tab;
   2694     skipFactor = postSkip[tabidx];
   2695     fft2 = fft1 + nmdct - 1;
   2696 
   2697     /* load coeffs for first pass
   2698      * cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin)
   2699      */
   2700     cps2 = *csptr++;
   2701     sin2 = *csptr;
   2702     csptr += skipFactor;
   2703     cms2 = cps2 - 2*sin2;
   2704 
   2705     for (i = nmdct >> 2; i != 0; i--) {
   2706         ar1 = *(fft1 + 0);
   2707         ai1 = *(fft1 + 1);
   2708         ar2 = *(fft2 - 1);
   2709         ai2 = *(fft2 + 0);
   2710 
   2711         /* gain 2 ints bit from MULSHIFT32 by Q30
   2712          * max per-sample gain = MAX(sin(angle)+cos(angle)) = 1.414
   2713          * i.e. gain 1 GB since worst case is sin(angle) = cos(angle) = 0.707 (Q30), gain 2 from
   2714          *   extra sign bits, and eat one in adding
   2715          */
   2716         t = MULSHIFT32(sin2, ar1 + ai1);
   2717         *fft2-- = t - MULSHIFT32(cps2, ai1);    /* sin*ar1 - cos*ai1 */
   2718         *fft1++ = t + MULSHIFT32(cms2, ar1);    /* cos*ar1 + sin*ai1 */
   2719         cps2 = *csptr++;
   2720         sin2 = *csptr;
   2721         csptr += skipFactor;
   2722 
   2723         ai2 = -ai2;
   2724         t = MULSHIFT32(sin2, ar2 + ai2);
   2725         *fft2-- = t - MULSHIFT32(cps2, ai2);    /* sin*ar1 - cos*ai1 */
   2726         cms2 = cps2 - 2*sin2;
   2727         *fft1++ = t + MULSHIFT32(cms2, ar2);    /* cos*ar1 + sin*ai1 */
   2728     }
   2729 }
   2730 
   2731 /***********************************************************************************************************************
   2732  * Function:    PreMultiplyRescale
   2733  *
   2734  * Description: pre-twiddle stage of DCT4, with rescaling for extra guard bits
   2735  *
   2736  * Inputs:      table index (for transform size)
   2737  *              buffer of nmdct samples
   2738  *              number of guard bits to add to input before processing
   2739  *
   2740  * Outputs:     processed samples in same buffer
   2741  *
   2742  * Return:      none
   2743  *
   2744  * Notes:       see notes on PreMultiply(), above
   2745  **********************************************************************************************************************/
   2746 void PreMultiplyRescale(int tabidx, int *zbuf1, int es)
   2747 {
   2748     int i, nmdct, ar1, ai1, ar2, ai2, z1, z2;
   2749     int t, cms2, cps2a, sin2a, cps2b, sin2b;
   2750     int *zbuf2;
   2751     const uint32_t *csptr;
   2752 
   2753     nmdct = nmdctTab[tabidx];
   2754     zbuf2 = zbuf1 + nmdct - 1;
   2755     csptr = cos4sin4tab + cos4sin4tabOffset[tabidx];
   2756 
   2757     /* whole thing should fit in registers - verify that compiler does this */
   2758     for (i = nmdct >> 2; i != 0; i--) {
   2759         /* cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) */
   2760         cps2a = *csptr++;
   2761         sin2a = *csptr++;
   2762         cps2b = *csptr++;
   2763         sin2b = *csptr++;
   2764 
   2765         ar1 = *(zbuf1 + 0) >> es;
   2766         ai1 = *(zbuf2 + 0) >> es;
   2767         ai2 = *(zbuf1 + 1) >> es;
   2768 
   2769         t  = MULSHIFT32(sin2a, ar1 + ai1);
   2770         z2 = MULSHIFT32(cps2a, ai1) - t;
   2771         cms2 = cps2a - 2*sin2a;
   2772         z1 = MULSHIFT32(cms2, ar1) + t;
   2773         *zbuf1++ = z1;
   2774         *zbuf1++ = z2;
   2775 
   2776         ar2 = *(zbuf2 - 1) >> es;    /* do here to free up register used for es */
   2777 
   2778         t  = MULSHIFT32(sin2b, ar2 + ai2);
   2779         z2 = MULSHIFT32(cps2b, ai2) - t;
   2780         cms2 = cps2b - 2*sin2b;
   2781         z1 = MULSHIFT32(cms2, ar2) + t;
   2782         *zbuf2-- = z2;
   2783         *zbuf2-- = z1;
   2784 
   2785     }
   2786 }
   2787 
   2788 /***********************************************************************************************************************
   2789  * Function:    PostMultiplyRescale
   2790  *
   2791  * Description: post-twiddle stage of DCT4, with rescaling for extra guard bits
   2792  *
   2793  * Inputs:      table index (for transform size)
   2794  *              buffer of nmdct samples
   2795  *              number of guard bits to remove from output
   2796  *
   2797  * Outputs:     processed samples in same buffer
   2798  *
   2799  * Return:      none
   2800  *
   2801  * Notes:       clips output to [-2^30, 2^30 - 1], guaranteeing at least 1 guard bit
   2802  *              see notes on PostMultiply(), above
   2803  **********************************************************************************************************************/
   2804 void PostMultiplyRescale(int tabidx, int *fft1, int es)
   2805 {
   2806     int i, nmdct, ar1, ai1, ar2, ai2, skipFactor, z;
   2807     int t, cs2, sin2;
   2808     int *fft2;
   2809     const int *csptr;
   2810 
   2811     nmdct = nmdctTab[tabidx];
   2812     csptr = cos1sin1tab;
   2813     skipFactor = postSkip[tabidx];
   2814     fft2 = fft1 + nmdct - 1;
   2815 
   2816     /* load coeffs for first pass
   2817      * cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin)
   2818      */
   2819     cs2 = *csptr++;
   2820     sin2 = *csptr;
   2821     csptr += skipFactor;
   2822 
   2823     for (i = nmdct >> 2; i != 0; i--) {
   2824         ar1 = *(fft1 + 0);
   2825         ai1 = *(fft1 + 1);
   2826         ai2 = *(fft2 + 0);
   2827 
   2828         t = MULSHIFT32(sin2, ar1 + ai1);
   2829         z = t - MULSHIFT32(cs2, ai1);
   2830         {int sign = (z) >> 31; if (sign != (z) >> (30 - (es))) {(z) = sign ^ (0x3fffffff);} else {(z) = (z) << (es);}}
   2831         *fft2-- = z;
   2832         cs2 -= 2*sin2;
   2833         z = t + MULSHIFT32(cs2, ar1);
   2834         {int sign = (z) >> 31; if (sign != (z) >> (30 - (es))) {(z) = sign ^ (0x3fffffff);} else {(z) = (z) << (es);}}
   2835         *fft1++ = z;
   2836 
   2837         cs2 = *csptr++;
   2838         sin2 = *csptr;
   2839         csptr += skipFactor;
   2840 
   2841         ar2 = *fft2;
   2842         ai2 = -ai2;
   2843         t = MULSHIFT32(sin2, ar2 + ai2);
   2844         z = t - MULSHIFT32(cs2, ai2);
   2845         {int sign = (z) >> 31; if (sign != (z) >> (30 - (es))) {(z) = sign ^ (0x3fffffff);} else {(z) = (z) << (es);}}
   2846         *fft2-- = z;
   2847         cs2 -= 2*sin2;
   2848         z = t + MULSHIFT32(cs2, ar2);
   2849         {int sign = (z) >> 31; if (sign != (z) >> (30 - (es))) {(z) = sign ^ (0x3fffffff);} else {(z) = (z) << (es);}}
   2850         *fft1++ = z;
   2851         cs2 += 2*sin2;
   2852     }
   2853 }
   2854 
   2855 /***********************************************************************************************************************
   2856  * Function:    DCT4
   2857  *
   2858  * Description: type-IV DCT
   2859  *
   2860  * Inputs:      table index (for transform size)
   2861  *              buffer of nmdct samples
   2862  *              number of guard bits in the input buffer
   2863  *
   2864  * Outputs:     processed samples in same buffer
   2865  *
   2866  * Return:      none
   2867  *
   2868  * Notes:       operates in-place
   2869  *              if number of guard bits in input is < GBITS_IN_DCT4, the input is
   2870  *                scaled (>>) before the DCT4 and rescaled (<<, with clipping) after
   2871  *                the DCT4 (rare)
   2872  *              the output has FBITS_LOST_DCT4 fewer fraction bits than the input
   2873  *              the output will always have at least 1 guard bit (GBITS_IN_DCT4 >= 4)
   2874  *              int bits gained per stage (PreMul + FFT + PostMul)
   2875  *                 short blocks = (-5 + 4 + 2) = 1 total
   2876  *                 long blocks =  (-8 + 7 + 2) = 1 total
   2877  **********************************************************************************************************************/
   2878 void DCT4(int tabidx, int *coef, int gb)
   2879 {
   2880     int es;
   2881 
   2882     /* fast in-place DCT-IV - adds guard bits if necessary */
   2883     if (gb < GBITS_IN_DCT4) {
   2884         es = GBITS_IN_DCT4 - gb;
   2885         PreMultiplyRescale(tabidx, coef, es);
   2886         R4FFT(tabidx, coef);
   2887         PostMultiplyRescale(tabidx, coef, es);
   2888     } else {
   2889         PreMultiply(tabidx, coef);
   2890         R4FFT(tabidx, coef);
   2891         PostMultiply(tabidx, coef);
   2892     }
   2893 }
   2894 
   2895 /***********************************************************************************************************************
   2896  * Function:    BitReverse
   2897  *
   2898  * Description: Ken's fast in-place bit reverse, using super-small table
   2899  *
   2900  * Inputs:      buffer of samples
   2901  *              table index (for transform size)
   2902  *
   2903  * Outputs:     bit-reversed samples in same buffer
   2904  *
   2905  * Return:      none
   2906  **********************************************************************************************************************/
   2907 void BitReverse(int *inout, int tabidx)
   2908 {
   2909     int *part0, *part1;
   2910     int a,b, t;
   2911     const uint8_t* tab = bitrevtab + bitrevtabOffset[tabidx];
   2912     int nbits = nfftlog2Tab[tabidx];
   2913 
   2914     part0 = inout;
   2915     part1 = inout + (1 << nbits);
   2916 
   2917     while ((a = pgm_read_byte(tab++)) != 0) {
   2918         b = pgm_read_byte(tab++);
   2919 
   2920         t=part0[4*a+0]; part0[4*a+0]=part0[4*b+0]; part0[4*b+0]=t; /* 0xxx0 <-> 0yyy0 */
   2921         t=part0[4*a+1]; part0[4*a+1]=part0[4*b+1]; part0[4*b+1]=t;
   2922 
   2923         t=part0[4*a+2]; part0[4*a+2]=part1[4*b+0]; part1[4*b+0]=t; /* 0xxx0 <-> 0yyy0 */
   2924         t=part0[4*a+3]; part0[4*a+3]=part1[4*b+1]; part1[4*b+1]=t;
   2925 
   2926         t=part1[4*a+0]; part1[4*a+0]=part0[4*b+2]; part0[4*b+2]=t; /* 1xxx0 <-> 0yyy1 */
   2927         t=part1[4*a+1]; part1[4*a+1]=part0[4*b+3]; part0[4*b+3]=t;
   2928 
   2929         t=part1[4*a+2]; part1[4*a+2]=part1[4*b+2]; part1[4*b+2]=t; /* 1xxx1 <-> 1yyy1 */
   2930         t=part1[4*a+3]; part1[4*a+3]=part1[4*b+3]; part1[4*b+3]=t;
   2931     }
   2932 
   2933     do {
   2934         t=part0[4*a+2]; part0[4*a+2]=part1[4*a+0]; part1[4*a+0]=t; /* 0xxx1 <-> 1xxx0 */
   2935         t=part0[4*a+3]; part0[4*a+3]=part1[4*a+1]; part1[4*a+1]=t;
   2936     } while ((a = pgm_read_byte(tab++)) != 0);
   2937 
   2938 
   2939 }
   2940 
   2941 /***********************************************************************************************************************
   2942  * Function:    R4FirstPass
   2943  *
   2944  * Description: radix-4 trivial pass for decimation-in-time FFT
   2945  *
   2946  * Inputs:      buffer of (bit-reversed) samples
   2947  *              number of R4 butterflies per group (i.e. nfft / 4)
   2948  *
   2949  * Outputs:     processed samples in same buffer
   2950  *
   2951  * Return:      none
   2952  *
   2953  * Notes:       assumes 2 guard bits, gains no integer bits,
   2954  *                guard bits out = guard bits in - 2
   2955  **********************************************************************************************************************/
   2956 void R4FirstPass(int *x, int bg)
   2957 {
   2958     int ar, ai, br, bi, cr, ci, dr, di;
   2959 
   2960     for (; bg != 0; bg--) {
   2961 
   2962         ar = x[0] + x[2];
   2963         br = x[0] - x[2];
   2964         ai = x[1] + x[3];
   2965         bi = x[1] - x[3];
   2966         cr = x[4] + x[6];
   2967         dr = x[4] - x[6];
   2968         ci = x[5] + x[7];
   2969         di = x[5] - x[7];
   2970 
   2971         /* max per-sample gain = 4.0 (adding 4 inputs together) */
   2972         x[0] = ar + cr;
   2973         x[4] = ar - cr;
   2974         x[1] = ai + ci;
   2975         x[5] = ai - ci;
   2976         x[2] = br + di;
   2977         x[6] = br - di;
   2978         x[3] = bi - dr;
   2979         x[7] = bi + dr;
   2980 
   2981         x += 8;
   2982     }
   2983 }
   2984 
   2985 /***********************************************************************************************************************
   2986  * Function:    R8FirstPass
   2987  *
   2988  * Description: radix-8 trivial pass for decimation-in-time FFT
   2989  *
   2990  * Inputs:      buffer of (bit-reversed) samples
   2991  *              number of R8 butterflies per group (i.e. nfft / 8)
   2992  *
   2993  * Outputs:     processed samples in same buffer
   2994  *
   2995  * Return:      none
   2996  *
   2997  * Notes:       assumes 3 guard bits, gains 1 integer bit
   2998  *              guard bits out = guard bits in - 3 (if inputs are full scale)
   2999  *                or guard bits in - 2 (if inputs bounded to +/- sqrt(2)/2)
   3000  *              see scaling comments in code
   3001  **********************************************************************************************************************/
   3002 void R8FirstPass(int *x, int bg)
   3003 {
   3004     int ar, ai, br, bi, cr, ci, dr, di;
   3005     int sr, si, tr, ti, ur, ui, vr, vi;
   3006     int wr, wi, xr, xi, yr, yi, zr, zi;
   3007 
   3008     for (; bg != 0; bg--) {
   3009 
   3010         ar = x[0] + x[2];
   3011         br = x[0] - x[2];
   3012         ai = x[1] + x[3];
   3013         bi = x[1] - x[3];
   3014         cr = x[4] + x[6];
   3015         dr = x[4] - x[6];
   3016         ci = x[5] + x[7];
   3017         di = x[5] - x[7];
   3018 
   3019         sr = ar + cr;
   3020         ur = ar - cr;
   3021         si = ai + ci;
   3022         ui = ai - ci;
   3023         tr = br - di;
   3024         vr = br + di;
   3025         ti = bi + dr;
   3026         vi = bi - dr;
   3027 
   3028         ar = x[ 8] + x[10];
   3029         br = x[ 8] - x[10];
   3030         ai = x[ 9] + x[11];
   3031         bi = x[ 9] - x[11];
   3032         cr = x[12] + x[14];
   3033         dr = x[12] - x[14];
   3034         ci = x[13] + x[15];
   3035         di = x[13] - x[15];
   3036 
   3037         /* max gain of wr/wi/yr/yi vs input = 2
   3038          *  (sum of 4 samples >> 1)
   3039          */
   3040         wr = (ar + cr) >> 1;
   3041         yr = (ar - cr) >> 1;
   3042         wi = (ai + ci) >> 1;
   3043         yi = (ai - ci) >> 1;
   3044 
   3045         /* max gain of output vs input = 4
   3046          *  (sum of 4 samples >> 1 + sum of 4 samples >> 1)
   3047          */
   3048         x[ 0] = (sr >> 1) + wr;
   3049         x[ 8] = (sr >> 1) - wr;
   3050         x[ 1] = (si >> 1) + wi;
   3051         x[ 9] = (si >> 1) - wi;
   3052         x[ 4] = (ur >> 1) + yi;
   3053         x[12] = (ur >> 1) - yi;
   3054         x[ 5] = (ui >> 1) - yr;
   3055         x[13] = (ui >> 1) + yr;
   3056 
   3057         ar = br - di;
   3058         cr = br + di;
   3059         ai = bi + dr;
   3060         ci = bi - dr;
   3061 
   3062         /* max gain of xr/xi/zr/zi vs input = 4*sqrt(2)/2 = 2*sqrt(2)
   3063          *  (sum of 8 samples, multiply by sqrt(2)/2, implicit >> 1 from Q31)
   3064          */
   3065         xr = MULSHIFT32(SQRTHALF, ar - ai);
   3066         xi = MULSHIFT32(SQRTHALF, ar + ai);
   3067         zr = MULSHIFT32(SQRTHALF, cr - ci);
   3068         zi = MULSHIFT32(SQRTHALF, cr + ci);
   3069 
   3070         /* max gain of output vs input = (2 + 2*sqrt(2) ~= 4.83)
   3071          *  (sum of 4 samples >> 1, plus xr/xi/zr/zi with gain of 2*sqrt(2))
   3072          * in absolute terms, we have max gain of appx 9.656 (4 + 0.707*8)
   3073          *  but we also gain 1 int bit (from MULSHIFT32 or from explicit >> 1)
   3074          */
   3075         x[ 6] = (tr >> 1) - xr;
   3076         x[14] = (tr >> 1) + xr;
   3077         x[ 7] = (ti >> 1) - xi;
   3078         x[15] = (ti >> 1) + xi;
   3079         x[ 2] = (vr >> 1) + zi;
   3080         x[10] = (vr >> 1) - zi;
   3081         x[ 3] = (vi >> 1) - zr;
   3082         x[11] = (vi >> 1) + zr;
   3083 
   3084         x += 16;
   3085     }
   3086 }
   3087 
   3088 /***********************************************************************************************************************
   3089  * Function:    R4Core
   3090  *
   3091  * Description: radix-4 pass for decimation-in-time FFT
   3092  *
   3093  * Inputs:      buffer of samples
   3094  *              number of R4 butterflies per group
   3095  *              number of R4 groups per pass
   3096  *              pointer to twiddle factors tables
   3097  *
   3098  * Outputs:     processed samples in same buffer
   3099  *
   3100  * Return:      none
   3101  *
   3102  * Notes:       gain 2 integer bits per pass (see scaling comments in code)
   3103  *              min 1 GB in
   3104  *              gbOut = gbIn - 1 (short block) or gbIn - 2 (long block)
   3105  *              uses 3-mul, 3-add butterflies instead of 4-mul, 2-add
   3106  **********************************************************************************************************************/
   3107 void R4Core(int *x, int bg, int gp, int *wtab)
   3108 {
   3109     int ar, ai, br, bi, cr, ci, dr, di, tr, ti;
   3110     int wd, ws, wi;
   3111     int i, j, step;
   3112     int *xptr, *wptr;
   3113 
   3114     for (; bg != 0; gp <<= 2, bg >>= 2) {
   3115 
   3116         step = 2*gp;
   3117         xptr = x;
   3118 
   3119         /* max per-sample gain, per group < 1 + 3*sqrt(2) ~= 5.25 if inputs x are full-scale
   3120          * do 3 groups for long block, 2 groups for short block (gain 2 int bits per group)
   3121          *
   3122          * very conservative scaling:
   3123          *   group 1: max gain = 5.25,           int bits gained = 2, gb used = 1 (2^3 = 8)
   3124          *   group 2: max gain = 5.25^2 = 27.6,  int bits gained = 4, gb used = 1 (2^5 = 32)
   3125          *   group 3: max gain = 5.25^3 = 144.7, int bits gained = 6, gb used = 2 (2^8 = 256)
   3126          */
   3127         for (i = bg; i != 0; i--) {
   3128 
   3129             wptr = wtab;
   3130 
   3131             for (j = gp; j != 0; j--) {
   3132 
   3133                 ar = xptr[0];
   3134                 ai = xptr[1];
   3135                 xptr += step;
   3136 
   3137                 /* gain 2 int bits for br/bi, cr/ci, dr/di (MULSHIFT32 by Q30)
   3138                  * gain 1 net GB
   3139                  */
   3140                 ws = wptr[0];
   3141                 wi = wptr[1];
   3142                 br = xptr[0];
   3143                 bi = xptr[1];
   3144                 wd = ws + 2*wi;
   3145                 tr = MULSHIFT32(wi, br + bi);
   3146                 br = MULSHIFT32(wd, br) - tr;    /* cos*br + sin*bi */
   3147                 bi = MULSHIFT32(ws, bi) + tr;    /* cos*bi - sin*br */
   3148                 xptr += step;
   3149 
   3150                 ws = wptr[2];
   3151                 wi = wptr[3];
   3152                 cr = xptr[0];
   3153                 ci = xptr[1];
   3154                 wd = ws + 2*wi;
   3155                 tr = MULSHIFT32(wi, cr + ci);
   3156                 cr = MULSHIFT32(wd, cr) - tr;
   3157                 ci = MULSHIFT32(ws, ci) + tr;
   3158                 xptr += step;
   3159 
   3160                 ws = wptr[4];
   3161                 wi = wptr[5];
   3162                 dr = xptr[0];
   3163                 di = xptr[1];
   3164                 wd = ws + 2*wi;
   3165                 tr = MULSHIFT32(wi, dr + di);
   3166                 dr = MULSHIFT32(wd, dr) - tr;
   3167                 di = MULSHIFT32(ws, di) + tr;
   3168                 wptr += 6;
   3169 
   3170                 tr = ar;
   3171                 ti = ai;
   3172                 ar = (tr >> 2) - br;
   3173                 ai = (ti >> 2) - bi;
   3174                 br = (tr >> 2) + br;
   3175                 bi = (ti >> 2) + bi;
   3176 
   3177                 tr = cr;
   3178                 ti = ci;
   3179                 cr = tr + dr;
   3180                 ci = di - ti;
   3181                 dr = tr - dr;
   3182                 di = di + ti;
   3183 
   3184                 xptr[0] = ar + ci;
   3185                 xptr[1] = ai + dr;
   3186                 xptr -= step;
   3187                 xptr[0] = br - cr;
   3188                 xptr[1] = bi - di;
   3189                 xptr -= step;
   3190                 xptr[0] = ar - ci;
   3191                 xptr[1] = ai - dr;
   3192                 xptr -= step;
   3193                 xptr[0] = br + cr;
   3194                 xptr[1] = bi + di;
   3195                 xptr += 2;
   3196             }
   3197             xptr += 3*step;
   3198         }
   3199         wtab += 3*step;
   3200     }
   3201 }
   3202 
   3203 
   3204 /***********************************************************************************************************************
   3205  * Function:    R4FFT
   3206  *
   3207  * Description: Ken's very fast in-place radix-4 decimation-in-time FFT
   3208  *
   3209  * Inputs:      table index (for transform size)
   3210  *              buffer of samples (non bit-reversed)
   3211  *
   3212  * Outputs:     processed samples in same buffer
   3213  *
   3214  * Return:      none
   3215  *
   3216  * Notes:       assumes 5 guard bits in for nfft <= 512
   3217  *              gbOut = gbIn - 4 (assuming input is from PreMultiply)
   3218  *              gains log2(nfft) - 2 int bits total
   3219  *                so gain 7 int bits (LONG), 4 int bits (SHORT)
   3220  **********************************************************************************************************************/
   3221 void R4FFT(int tabidx, int *x)
   3222 {
   3223     int order = nfftlog2Tab[tabidx];
   3224     int nfft = nfftTab[tabidx];
   3225 
   3226     /* decimation in time */
   3227     BitReverse(x, tabidx);
   3228 
   3229     if (order & 0x1) {
   3230         /* long block: order = 9, nfft = 512 */
   3231         R8FirstPass(x, nfft >> 3);                        /* gain 1 int bit,  lose 2 GB */
   3232         R4Core(x, nfft >> 5, 8, (int *)twidTabOdd);        /* gain 6 int bits, lose 2 GB */
   3233     } else {
   3234         /* short block: order = 6, nfft = 64 */
   3235         R4FirstPass(x, nfft >> 2);                        /* gain 0 int bits, lose 2 GB */
   3236         R4Core(x, nfft >> 4, 4, (int *)twidTabEven);    /* gain 4 int bits, lose 1 GB */
   3237     }
   3238 }
   3239 
   3240 /***********************************************************************************************************************
   3241  * Function:    UnpackZeros
   3242  *
   3243  * Description: fill a section of coefficients with zeros
   3244  *
   3245  * Inputs:      number of coefficients
   3246  *
   3247  * Outputs:     nVals zeros, starting at coef
   3248  *
   3249  * Return:      none
   3250  *
   3251  * Notes:       assumes nVals is always a multiple of 4 because all scalefactor bands
   3252  *                are a multiple of 4 coefficients long
   3253  **********************************************************************************************************************/
   3254 void UnpackZeros(int nVals, int *coef)
   3255 {
   3256     while (nVals > 0) {
   3257         *coef++ = 0;
   3258         *coef++ = 0;
   3259         *coef++ = 0;
   3260         *coef++ = 0;
   3261         nVals -= 4;
   3262     }
   3263 }
   3264 
   3265 /***********************************************************************************************************************
   3266  * Function:    UnpackQuads
   3267  *
   3268  * Description: decode a section of 4-way vector Huffman coded coefficients
   3269  *
   3270  * Inputs       index of Huffman codebook
   3271  *              number of coefficients
   3272  *
   3273  * Outputs:     nVals coefficients, starting at coef
   3274  *
   3275  * Return:      none
   3276  *
   3277  * Notes:       assumes nVals is always a multiple of 4 because all scalefactor bands
   3278  *                are a multiple of 4 coefficients long
   3279  **********************************************************************************************************************/
   3280 void UnpackQuads(int cb, int nVals, int *coef)
   3281 {
   3282     int w, x, y, z, maxBits, nCodeBits, nSignBits, val;
   3283     uint32_t bitBuf;
   3284 
   3285     maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 4;
   3286     while (nVals > 0) {
   3287         /* decode quad */
   3288         bitBuf = GetBitsNoAdvance(maxBits) << (32 - maxBits);
   3289         nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET], bitBuf, &val);
   3290 
   3291         w = (((int32_t)(val) << 20) >>   29);    /* bits 11-9, sign-extend */
   3292         x = (((int32_t)(val) << 23) >>   29);    /* bits  8-6, sign-extend */
   3293         y = (((int32_t)(val) << 26) >>   29);    /* bits  5-3, sign-extend */
   3294         z = (((int32_t)(val) << 29) >>   29);    /* bits  2-0, sign-extend */
   3295 
   3296         bitBuf <<= nCodeBits;
   3297         nSignBits = (int)(((uint32_t)(val) << 17) >> 29);    /* bits 14-12, unsigned */
   3298 
   3299         AdvanceBitstream(nCodeBits + nSignBits);
   3300         if (nSignBits) {
   3301             if (w)    {w ^= ((int32_t)bitBuf >> 31); w -= ((int32_t)bitBuf >> 31); bitBuf <<= 1;}
   3302             if (x)    {x ^= ((int32_t)bitBuf >> 31); x -= ((int32_t)bitBuf >> 31); bitBuf <<= 1;}
   3303             if (y)    {y ^= ((int32_t)bitBuf >> 31); y -= ((int32_t)bitBuf >> 31); bitBuf <<= 1;}
   3304             if (z)    {z ^= ((int32_t)bitBuf >> 31); z -= ((int32_t)bitBuf >> 31); bitBuf <<= 1;}
   3305         }
   3306         *coef++ = w; *coef++ = x; *coef++ = y; *coef++ = z;
   3307         nVals -= 4;
   3308     }
   3309 }
   3310 
   3311 /***********************************************************************************************************************
   3312  * Function:    UnpackPairsNoEsc
   3313  *
   3314  * Description: decode a section of 2-way vector Huffman coded coefficients,
   3315  *                using non-esc tables (5 through 10)
   3316  *
   3317  * Inputs       index of Huffman codebook (must not be the escape codebook)
   3318  *              number of coefficients
   3319  *
   3320  * Outputs:     nVals coefficients, starting at coef
   3321  *
   3322  * Return:      none
   3323  *
   3324  * Notes:       assumes nVals is always a multiple of 2 because all scalefactor bands
   3325  *                are a multiple of 4 coefficients long
   3326  **********************************************************************************************************************/
   3327 void UnpackPairsNoEsc(int cb, int nVals, int *coef)
   3328 {
   3329     int y, z, maxBits, nCodeBits, nSignBits, val;
   3330     uint32_t bitBuf;
   3331 
   3332     maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 2;
   3333     while (nVals > 0) {
   3334         /* decode pair */
   3335         bitBuf = GetBitsNoAdvance(maxBits) << (32 - maxBits);
   3336         nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb-HUFFTAB_SPEC_OFFSET], bitBuf, &val);
   3337 
   3338         y = (((int32_t)(val) << 22) >>   27);    /* bits  9-5, sign-extend */
   3339         z = (((int32_t)(val) << 27) >>   27);    /* bits  4-0, sign-extend */
   3340 
   3341         bitBuf <<= nCodeBits;
   3342         nSignBits = (((uint32_t)(val) << 20) >> 30);    /* bits 11-10, unsigned */
   3343         AdvanceBitstream(nCodeBits + nSignBits);
   3344         if (nSignBits) {
   3345             if (y)    {y ^= ((int32_t)bitBuf >> 31); y -= ((int32_t)bitBuf >> 31); bitBuf <<= 1;}
   3346             if (z)    {z ^= ((int32_t)bitBuf >> 31); z -= ((int32_t)bitBuf >> 31); bitBuf <<= 1;}
   3347         }
   3348         *coef++ = y; *coef++ = z;
   3349         nVals -= 2;
   3350     }
   3351 }
   3352 
   3353 /***********************************************************************************************************************
   3354  * Function:    UnpackPairsEsc
   3355  *
   3356  * Description: decode a section of 2-way vector Huffman coded coefficients,
   3357  *                using esc table (11)
   3358  *
   3359  * Inputs       index of Huffman codebook (must be the escape codebook)
   3360  *              number of coefficients
   3361  *
   3362  * Outputs:     nVals coefficients, starting at coef
   3363  *
   3364  * Return:      none
   3365  *
   3366  * Notes:       assumes nVals is always a multiple of 2 because all scalefactor bands
   3367  *                are a multiple of 4 coefficients long
   3368  **********************************************************************************************************************/
   3369 void UnpackPairsEsc(int cb, int nVals, int *coef)
   3370 {
   3371     int y, z, maxBits, nCodeBits, nSignBits, n, val;
   3372     uint32_t bitBuf;
   3373 
   3374     maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 2;
   3375     while (nVals > 0) {
   3376         /* decode pair with escape value */
   3377         bitBuf = GetBitsNoAdvance(maxBits) << (32 - maxBits);
   3378         nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb-HUFFTAB_SPEC_OFFSET], bitBuf, &val);
   3379 
   3380         y = (((int32_t)(val) << 20) >>   26);    /* bits 11-6, sign-extend */
   3381         z = (((int32_t)(val) << 26) >>   26);    /* bits  5-0, sign-extend */
   3382 
   3383         bitBuf <<= nCodeBits;
   3384         nSignBits = (((uint32_t)(val) << 18) >> 30);    /* bits 13-12, unsigned */
   3385         AdvanceBitstream(nCodeBits + nSignBits);
   3386 
   3387         if (y == 16) {
   3388             n = 4;
   3389             while (GetBits(1) == 1)
   3390                 n++;
   3391             y = (1 << n) + GetBits(n);
   3392         }
   3393         if (z == 16) {
   3394             n = 4;
   3395             while (GetBits(1) == 1)
   3396                 n++;
   3397             z = (1 << n) + GetBits(n);
   3398         }
   3399 
   3400         if (nSignBits) {
   3401             if (y)    {y ^= ((int32_t)bitBuf >> 31); y -= ((int32_t)bitBuf >> 31); bitBuf <<= 1;}
   3402             if (z)    {z ^= ((int32_t)bitBuf >> 31); z -= ((int32_t)bitBuf >> 31); bitBuf <<= 1;}
   3403         }
   3404 
   3405         *coef++ = y; *coef++ = z;
   3406         nVals -= 2;
   3407     }
   3408 }
   3409 
   3410 /***********************************************************************************************************************
   3411  * Function:    DecodeSpectrumLong
   3412  *
   3413  * Description: decode transform coefficients for frame with one long block
   3414  *
   3415  * Inputs:      index of current channel
   3416  *
   3417  * Outputs:     decoded, quantized coefficients for this channel
   3418  *
   3419  * Return:      none
   3420  *
   3421  * Notes:       adds in pulse data if present
   3422  *              fills coefficient buffer with zeros in any region not coded with
   3423  *                codebook in range [1, 11] (including sfb's above sfbMax)
   3424  **********************************************************************************************************************/
   3425 void DecodeSpectrumLong(int ch)
   3426 {
   3427     int i, sfb, cb, nVals, offset;
   3428     const uint16_t *sfbTab;
   3429     uint8_t *sfbCodeBook;
   3430     int *coef;
   3431     ICSInfo_t *icsInfo;
   3432 
   3433     coef = m_PSInfoBase->coef[ch];
   3434     icsInfo = (ch == 1 && m_PSInfoBase->commonWin == 1) ? &(m_PSInfoBase->icsInfo[0]) : &(m_PSInfoBase->icsInfo[ch]);
   3435 
   3436     /* decode long block */
   3437     sfbTab = sfBandTabLong + sfBandTabLongOffset[m_PSInfoBase->sampRateIdx];
   3438     sfbCodeBook = m_PSInfoBase->sfbCodeBook[ch];
   3439     for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) {
   3440         cb = *sfbCodeBook++;
   3441         nVals = sfbTab[sfb+1] - sfbTab[sfb];
   3442 
   3443         if (cb == 0)
   3444             UnpackZeros(nVals, coef);
   3445         else if (cb <= 4)
   3446             UnpackQuads(cb, nVals, coef);
   3447         else if (cb <= 10)
   3448             UnpackPairsNoEsc(cb, nVals, coef);
   3449         else if (cb == 11)
   3450             UnpackPairsEsc(cb, nVals, coef);
   3451         else
   3452             UnpackZeros(nVals, coef);
   3453 
   3454         coef += nVals;
   3455     }
   3456 
   3457     /* fill with zeros above maxSFB */
   3458     nVals = NSAMPS_LONG - sfbTab[sfb];
   3459     UnpackZeros(nVals, coef);
   3460 
   3461     /* add pulse data, if present */
   3462     if (m_pulseInfo[ch].pulseDataPresent) {
   3463         coef = m_PSInfoBase->coef[ch];
   3464         offset = sfbTab[m_pulseInfo[ch].startSFB];
   3465         for (i = 0; i < m_pulseInfo[ch].numPulse; i++) {
   3466             offset += m_pulseInfo[ch].offset[i];
   3467             if (coef[offset] > 0)
   3468                 coef[offset] += m_pulseInfo[ch].amp[i];
   3469             else
   3470                 coef[offset] -= m_pulseInfo[ch].amp[i];
   3471         }
   3472         ASSERT(offset < NSAMPS_LONG);
   3473     }
   3474 }
   3475 
   3476 /***********************************************************************************************************************
   3477  * Function:    DecodeSpectrumShort
   3478  *
   3479  * Description: decode transform coefficients for frame with eight short blocks
   3480  *
   3481  * Inputs:      index of current channel
   3482  *
   3483  * Outputs:     decoded, quantized coefficients for this channel
   3484  *
   3485  * Return:      none
   3486  *
   3487  * Notes:       fills coefficient buffer with zeros in any region not coded with
   3488  *                codebook in range [1, 11] (including sfb's above sfbMax)
   3489  *              deinterleaves window groups into 8 windows
   3490  **********************************************************************************************************************/
   3491 void DecodeSpectrumShort(int ch)
   3492 {
   3493     int gp, cb, nVals=0, win, offset, sfb;
   3494     const uint16_t *sfbTab;
   3495     uint8_t *sfbCodeBook;
   3496     int *coef;
   3497     ICSInfo_t *icsInfo;
   3498 
   3499     coef = m_PSInfoBase->coef[ch];
   3500     icsInfo = (ch == 1 && m_PSInfoBase->commonWin == 1) ? &(m_PSInfoBase->icsInfo[0]) : &(m_PSInfoBase->icsInfo[ch]);
   3501 
   3502     /* decode short blocks, deinterleaving in-place */
   3503     sfbTab = sfBandTabShort + sfBandTabShortOffset[m_PSInfoBase->sampRateIdx];
   3504     sfbCodeBook = m_PSInfoBase->sfbCodeBook[ch];
   3505     for (gp = 0; gp < icsInfo->numWinGroup; gp++) {
   3506         for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) {
   3507             nVals = sfbTab[sfb+1] - sfbTab[sfb];
   3508             cb = *sfbCodeBook++;
   3509 
   3510             for (win = 0; win < icsInfo->winGroupLen[gp]; win++) {
   3511                 offset = win*NSAMPS_SHORT;
   3512                 if (cb == 0)
   3513                     UnpackZeros(nVals, coef + offset);
   3514                 else if (cb <= 4)
   3515                     UnpackQuads(cb, nVals, coef + offset);
   3516                 else if (cb <= 10)
   3517                     UnpackPairsNoEsc(cb, nVals, coef + offset);
   3518                 else if (cb == 11)
   3519                     UnpackPairsEsc(cb, nVals, coef + offset);
   3520                 else
   3521                     UnpackZeros(nVals, coef + offset);
   3522             }
   3523             coef += nVals;
   3524         }
   3525 
   3526         /* fill with zeros above maxSFB */
   3527         for (win = 0; win < icsInfo->winGroupLen[gp]; win++) {
   3528             offset = win*NSAMPS_SHORT;
   3529             nVals = NSAMPS_SHORT - sfbTab[sfb];
   3530             UnpackZeros(nVals, coef + offset);
   3531         }
   3532         coef += nVals;
   3533         coef += (icsInfo->winGroupLen[gp] - 1)*NSAMPS_SHORT;
   3534     }
   3535 
   3536     ASSERT(coef == m_PSInfoBase->coef[ch] + NSAMPS_LONG);
   3537 }
   3538 
   3539 #ifndef AAC_ENABLE_SBR
   3540 /***********************************************************************************************************************
   3541  * Function:    DecWindowOverlap
   3542  *
   3543  * Description: apply synthesis window, do overlap-add, clip to 16-bit PCM,
   3544  *                for winSequence LONG-LONG
   3545  *
   3546  * Inputs:      input buffer (output of type-IV DCT)
   3547  *              overlap buffer (saved from last time)
   3548  *              number of channels
   3549  *              window type (sin or KBD) for input buffer
   3550  *              window type (sin or KBD) for overlap buffer
   3551  *
   3552  * Outputs:     one channel, one frame of 16-bit PCM, interleaved by nChans
   3553  *
   3554  * Return:      none
   3555  *
   3556  * Notes:       this processes one channel at a time, but skips every other sample in
   3557  *                the output buffer (pcm) for stereo interleaving
   3558  *              this should fit in registers on ARM
   3559  *
   3560  **********************************************************************************************************************/
   3561 void DecWindowOverlap(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev)
   3562 {
   3563     int in, w0, w1, f0, f1;
   3564     int *buf1, *over1;
   3565     short *pcm1;
   3566     const int *wndCurr, *wndPrev;
   3567 
   3568     buf0 += (1024 >> 1);
   3569     buf1  = buf0  - 1;
   3570     pcm1  = pcm0 + (1024 - 1) * nChans;
   3571     over1 = over0 + 1024 - 1;
   3572 
   3573     wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]);
   3574     if (winTypeCurr == winTypePrev) {
   3575         /* cut window loads in half since current and overlap sections use same symmetric window */
   3576         do {
   3577             w0 = *wndPrev++;
   3578             w1 = *wndPrev++;
   3579             in = *buf0++;
   3580 
   3581             f0 = MULSHIFT32(w0, in);
   3582             f1 = MULSHIFT32(w1, in);
   3583 
   3584             in = *over0;
   3585             *pcm0 = CLIPTOSHORT( (in - f0 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3586             pcm0 += nChans;
   3587 
   3588             in = *over1;
   3589             *pcm1 = CLIPTOSHORT( (in + f1 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3590             pcm1 -= nChans;
   3591 
   3592             in = *buf1--;
   3593             *over1-- = MULSHIFT32(w0, in);
   3594             *over0++ = MULSHIFT32(w1, in);
   3595         } while (over0 < over1);
   3596     } else {
   3597         /* different windows for current and overlap parts - should still fit in registers on ARM w/o stack spill */
   3598         wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]);
   3599         do {
   3600             w0 = *wndPrev++;
   3601             w1 = *wndPrev++;
   3602             in = *buf0++;
   3603 
   3604             f0 = MULSHIFT32(w0, in);
   3605             f1 = MULSHIFT32(w1, in);
   3606 
   3607             in = *over0;
   3608             *pcm0 = CLIPTOSHORT( (in - f0 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3609             pcm0 += nChans;
   3610 
   3611             in = *over1;
   3612             *pcm1 = CLIPTOSHORT( (in + f1 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3613             pcm1 -= nChans;
   3614 
   3615             w0 = *wndCurr++;
   3616             w1 = *wndCurr++;
   3617             in = *buf1--;
   3618 
   3619             *over1-- = MULSHIFT32(w0, in);
   3620             *over0++ = MULSHIFT32(w1, in);
   3621         } while (over0 < over1);
   3622     }
   3623 }
   3624 
   3625 /***********************************************************************************************************************
   3626  * Function:    DecWindowOverlapLongStart
   3627  *
   3628  * Description: apply synthesis window, do overlap-add, clip to 16-bit PCM,
   3629  *                for winSequence LONG-START
   3630  *
   3631  * Inputs:      input buffer (output of type-IV DCT)
   3632  *              overlap buffer (saved from last time)
   3633  *              number of channels
   3634  *              window type (sin or KBD) for input buffer
   3635  *              window type (sin or KBD) for overlap buffer
   3636  *
   3637  * Outputs:     one channel, one frame of 16-bit PCM, interleaved by nChans
   3638  *
   3639  * Return:      none
   3640  *
   3641  * Notes:       this processes one channel at a time, but skips every other sample in
   3642  *                the output buffer (pcm) for stereo interleaving
   3643  *              this should fit in registers on ARM
   3644  **********************************************************************************************************************/
   3645 void DecWindowOverlapLongStart(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev)
   3646 {
   3647     int i,  in, w0, w1, f0, f1;
   3648     int *buf1, *over1;
   3649     short *pcm1;
   3650     const int *wndPrev, *wndCurr;
   3651 
   3652     buf0 += (1024 >> 1);
   3653     buf1  = buf0  - 1;
   3654     pcm1  = pcm0 + (1024 - 1) * nChans;
   3655     over1 = over0 + 1024 - 1;
   3656 
   3657     wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]);
   3658     i = 448;    /* 2 outputs, 2 overlaps per loop */
   3659     do {
   3660         w0 = *wndPrev++;
   3661         w1 = *wndPrev++;
   3662         in = *buf0++;
   3663 
   3664         f0 = MULSHIFT32(w0, in);
   3665         f1 = MULSHIFT32(w1, in);
   3666 
   3667         in = *over0;
   3668         *pcm0 = CLIPTOSHORT( (in - f0 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3669         pcm0 += nChans;
   3670 
   3671         in = *over1;
   3672         *pcm1 = CLIPTOSHORT( (in + f1 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3673         pcm1 -= nChans;
   3674 
   3675         in = *buf1--;
   3676 
   3677         *over1-- = 0;        /* Wn = 0 for n = (2047, 2046, ... 1600) */
   3678         *over0++ = in >> 1;    /* Wn = 1 for n = (1024, 1025, ... 1471) */
   3679     } while (--i);
   3680 
   3681     wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]);
   3682 
   3683     /* do 64 more loops - 2 outputs, 2 overlaps per loop */
   3684     do {
   3685         w0 = *wndPrev++;
   3686         w1 = *wndPrev++;
   3687         in = *buf0++;
   3688 
   3689         f0 = MULSHIFT32(w0, in);
   3690         f1 = MULSHIFT32(w1, in);
   3691 
   3692         in = *over0;
   3693         *pcm0 = CLIPTOSHORT( (in - f0 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3694         pcm0 += nChans;
   3695 
   3696         in = *over1;
   3697         *pcm1 = CLIPTOSHORT( (in + f1 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3698         pcm1 -= nChans;
   3699 
   3700         w0 = *wndCurr++;    /* W[0], W[1], ... --> W[255], W[254], ... */
   3701         w1 = *wndCurr++;    /* W[127], W[126], ... --> W[128], W[129], ... */
   3702         in = *buf1--;
   3703 
   3704         *over1-- = MULSHIFT32(w0, in);    /* Wn = short window for n = (1599, 1598, ... , 1536) */
   3705         *over0++ = MULSHIFT32(w1, in);    /* Wn = short window for n = (1472, 1473, ... , 1535) */
   3706     } while (over0 < over1);
   3707 }
   3708 
   3709 /***********************************************************************************************************************
   3710  * Function:    DecWindowOverlapLongStop
   3711  *
   3712  * Description: apply synthesis window, do overlap-add, clip to 16-bit PCM,
   3713  *                for winSequence LONG-STOP
   3714  *
   3715  * Inputs:      input buffer (output of type-IV DCT)
   3716  *              overlap buffer (saved from last time)
   3717  *              number of channels
   3718  *              window type (sin or KBD) for input buffer
   3719  *              window type (sin or KBD) for overlap buffer
   3720  *
   3721  * Outputs:     one channel, one frame of 16-bit PCM, interleaved by nChans
   3722  *
   3723  * Return:      none
   3724  *
   3725  * Notes:       this processes one channel at a time, but skips every other sample in
   3726  *                the output buffer (pcm) for stereo interleaving
   3727  *              this should fit in registers on ARM
   3728  **********************************************************************************************************************/
   3729 void DecWindowOverlapLongStop(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev)
   3730 {
   3731     int i, in, w0, w1, f0, f1;
   3732     int *buf1, *over1;
   3733     short *pcm1;
   3734     const int *wndPrev, *wndCurr;
   3735 
   3736     buf0 += (1024 >> 1);
   3737     buf1  = buf0  - 1;
   3738     pcm1  = pcm0 + (1024 - 1) * nChans;
   3739     over1 = over0 + 1024 - 1;
   3740 
   3741     wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]);
   3742     wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]);
   3743 
   3744     i = 448;    /* 2 outputs, 2 overlaps per loop */
   3745     do {
   3746         /* Wn = 0 for n = (0, 1, ... 447) */
   3747         /* Wn = 1 for n = (576, 577, ... 1023) */
   3748         in = *buf0++;
   3749         f1 = in >> 1;    /* scale since skipping multiply by Q31 */
   3750 
   3751         in = *over0;
   3752         *pcm0 = CLIPTOSHORT( (in + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3753         pcm0 += nChans;
   3754 
   3755         in = *over1;
   3756         *pcm1 = CLIPTOSHORT( (in + f1 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3757         pcm1 -= nChans;
   3758 
   3759         w0 = *wndCurr++;
   3760         w1 = *wndCurr++;
   3761         in = *buf1--;
   3762 
   3763         *over1-- = MULSHIFT32(w0, in);
   3764         *over0++ = MULSHIFT32(w1, in);
   3765     } while (--i);
   3766 
   3767     /* do 64 more loops - 2 outputs, 2 overlaps per loop */
   3768     do {
   3769         w0 = *wndPrev++;    /* W[0], W[1], ...W[63] */
   3770         w1 = *wndPrev++;    /* W[127], W[126], ... W[64] */
   3771         in = *buf0++;
   3772 
   3773         f0 = MULSHIFT32(w0, in);
   3774         f1 = MULSHIFT32(w1, in);
   3775 
   3776         in = *over0;
   3777         *pcm0 = CLIPTOSHORT( (in - f0 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3778         pcm0 += nChans;
   3779 
   3780         in = *over1;
   3781         *pcm1 = CLIPTOSHORT( (in + f1 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3782         pcm1 -= nChans;
   3783 
   3784         w0 = *wndCurr++;
   3785         w1 = *wndCurr++;
   3786         in = *buf1--;
   3787 
   3788         *over1-- = MULSHIFT32(w0, in);
   3789         *over0++ = MULSHIFT32(w1, in);
   3790     } while (over0 < over1);
   3791 }
   3792 
   3793 /***********************************************************************************************************************
   3794  * Function:    DecWindowOverlapShort
   3795  *
   3796  * Description: apply synthesis window, do overlap-add, clip to 16-bit PCM,
   3797  *                for winSequence EIGHT-SHORT (does all 8 short blocks)
   3798  *
   3799  * Inputs:      input buffer (output of type-IV DCT)
   3800  *              overlap buffer (saved from last time)
   3801  *              number of channels
   3802  *              window type (sin or KBD) for input buffer
   3803  *              window type (sin or KBD) for overlap buffer
   3804  *
   3805  * Outputs:     one channel, one frame of 16-bit PCM, interleaved by nChans
   3806  *
   3807  * Return:      none
   3808  *
   3809  * Notes:       this processes one channel at a time, but skips every other sample in
   3810  *                the output buffer (pcm) for stereo interleaving
   3811  *              this should fit in registers on ARM
   3812  **********************************************************************************************************************/
   3813 void DecWindowOverlapShort(int *buf0, int *over0, short *pcm0, int nChans, int winTypeCurr, int winTypePrev)
   3814 {
   3815     int i, in, w0, w1, f0, f1;
   3816     int *buf1, *over1;
   3817     short *pcm1;
   3818     const int *wndPrev, *wndCurr;
   3819 
   3820     wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]);
   3821     wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]);
   3822 
   3823     /* pcm[0-447] = 0 + overlap[0-447] */
   3824     i = 448;
   3825     do {
   3826         f0 = *over0++;
   3827         f1 = *over0++;
   3828         *pcm0 = CLIPTOSHORT( (f0 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );    pcm0 += nChans;
   3829         *pcm0 = CLIPTOSHORT( (f1 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );    pcm0 += nChans;
   3830         i -= 2;
   3831     } while (i);
   3832 
   3833     /* pcm[448-575] = Wp[0-127] * block0[0-127] + overlap[448-575] */
   3834     pcm1  = pcm0 + (128 - 1) * nChans;
   3835     over1 = over0 + 128 - 1;
   3836     buf0 += 64;
   3837     buf1  = buf0  - 1;
   3838     do {
   3839         w0 = *wndPrev++;    /* W[0], W[1], ...W[63] */
   3840         w1 = *wndPrev++;    /* W[127], W[126], ... W[64] */
   3841         in = *buf0++;
   3842 
   3843         f0 = MULSHIFT32(w0, in);
   3844         f1 = MULSHIFT32(w1, in);
   3845 
   3846         in = *over0;
   3847         *pcm0 = CLIPTOSHORT( (in - f0 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3848         pcm0 += nChans;
   3849 
   3850         in = *over1;
   3851         *pcm1 = CLIPTOSHORT( (in + f1 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3852         pcm1 -= nChans;
   3853 
   3854         w0 = *wndCurr++;
   3855         w1 = *wndCurr++;
   3856         in = *buf1--;
   3857 
   3858         /* save over0/over1 for next short block, in the slots just vacated */
   3859         *over1-- = MULSHIFT32(w0, in);
   3860         *over0++ = MULSHIFT32(w1, in);
   3861     } while (over0 < over1);
   3862 
   3863     /* pcm[576-703] = Wc[128-255] * block0[128-255] + Wc[0-127] * block1[0-127] + overlap[576-703]
   3864      * pcm[704-831] = Wc[128-255] * block1[128-255] + Wc[0-127] * block2[0-127] + overlap[704-831]
   3865      * pcm[832-959] = Wc[128-255] * block2[128-255] + Wc[0-127] * block3[0-127] + overlap[832-959]
   3866      */
   3867     for (i = 0; i < 3; i++) {
   3868         pcm0 += 64 * nChans;
   3869         pcm1 = pcm0 + (128 - 1) * nChans;
   3870         over0 += 64;
   3871         over1 = over0 + 128 - 1;
   3872         buf0 += 64;
   3873         buf1 = buf0 - 1;
   3874         wndCurr -= 128;
   3875 
   3876         do {
   3877             w0 = *wndCurr++;    /* W[0], W[1], ...W[63] */
   3878             w1 = *wndCurr++;    /* W[127], W[126], ... W[64] */
   3879             in = *buf0++;
   3880 
   3881             f0 = MULSHIFT32(w0, in);
   3882             f1 = MULSHIFT32(w1, in);
   3883 
   3884             in  = *(over0 - 128);    /* from last short block */
   3885             in += *(over0 + 0);        /* from last full frame */
   3886             *pcm0 = CLIPTOSHORT( (in - f0 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3887             pcm0 += nChans;
   3888 
   3889             in  = *(over1 - 128);    /* from last short block */
   3890             in += *(over1 + 0);        /* from last full frame */
   3891             *pcm1 = CLIPTOSHORT( (in + f1 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3892             pcm1 -= nChans;
   3893 
   3894             /* save over0/over1 for next short block, in the slots just vacated */
   3895             in = *buf1--;
   3896             *over1-- = MULSHIFT32(w0, in);
   3897             *over0++ = MULSHIFT32(w1, in);
   3898         } while (over0 < over1);
   3899     }
   3900 
   3901     /* pcm[960-1023] = Wc[128-191] * block3[128-191] + Wc[0-63]   * block4[0-63] + overlap[960-1023]
   3902      * over[0-63]    = Wc[192-255] * block3[192-255] + Wc[64-127] * block4[64-127]
   3903      */
   3904     pcm0 += 64 * nChans;
   3905     over0 -= 832;                /* points at overlap[64] */
   3906     over1 = over0 + 128 - 1;    /* points at overlap[191] */
   3907     buf0 += 64;
   3908     buf1 = buf0 - 1;
   3909     wndCurr -= 128;
   3910     do {
   3911         w0 = *wndCurr++;    /* W[0], W[1], ...W[63] */
   3912         w1 = *wndCurr++;    /* W[127], W[126], ... W[64] */
   3913         in = *buf0++;
   3914 
   3915         f0 = MULSHIFT32(w0, in);
   3916         f1 = MULSHIFT32(w1, in);
   3917 
   3918         in  = *(over0 + 768);    /* from last short block */
   3919         in += *(over0 + 896);    /* from last full frame */
   3920         *pcm0 = CLIPTOSHORT( (in - f0 + (1 << (FBITS_OUT_IMDCT-1))) >> FBITS_OUT_IMDCT );
   3921         pcm0 += nChans;
   3922 
   3923         in  = *(over1 + 768);    /* from last short block */
   3924         *(over1 - 128) = in + f1;
   3925 
   3926         in = *buf1--;
   3927         *over1-- = MULSHIFT32(w0, in);    /* save in overlap[128-191] */
   3928         *over0++ = MULSHIFT32(w1, in);    /* save in overlap[64-127] */
   3929     } while (over0 < over1);
   3930 
   3931     /* over0 now points at overlap[128] */
   3932 
   3933     /* over[64-191]   = Wc[128-255] * block4[128-255] + Wc[0-127] * block5[0-127]
   3934      * over[192-319]  = Wc[128-255] * block5[128-255] + Wc[0-127] * block6[0-127]
   3935      * over[320-447]  = Wc[128-255] * block6[128-255] + Wc[0-127] * block7[0-127]
   3936      * over[448-576]  = Wc[128-255] * block7[128-255]
   3937      */
   3938     for (i = 0; i < 3; i++) {
   3939         over0 += 64;
   3940         over1 = over0 + 128 - 1;
   3941         buf0 += 64;
   3942         buf1 = buf0 - 1;
   3943         wndCurr -= 128;
   3944         do {
   3945             w0 = *wndCurr++;    /* W[0], W[1], ...W[63] */
   3946             w1 = *wndCurr++;    /* W[127], W[126], ... W[64] */
   3947             in = *buf0++;
   3948 
   3949             f0 = MULSHIFT32(w0, in);
   3950             f1 = MULSHIFT32(w1, in);
   3951 
   3952             /* from last short block */
   3953             *(over0 - 128) -= f0;
   3954             *(over1 - 128)+= f1;
   3955 
   3956             in = *buf1--;
   3957             *over1-- = MULSHIFT32(w0, in);
   3958             *over0++ = MULSHIFT32(w1, in);
   3959         } while (over0 < over1);
   3960     }
   3961 
   3962     /* over[576-1024] = 0 */
   3963     i = 448;
   3964     over0 += 64;
   3965     do {
   3966         *over0++ = 0;
   3967         *over0++ = 0;
   3968         *over0++ = 0;
   3969         *over0++ = 0;
   3970         i -= 4;
   3971     } while (i);
   3972 }
   3973 
   3974 #endif  /* !AAC_ENABLE_SBR */
   3975 
   3976 /***********************************************************************************************************************
   3977  * Function:    IMDCT
   3978  *
   3979  * Description: inverse transform and convert to 16-bit PCM
   3980  *
   3981  * Inputs:      index of current channel (0 for SCE/LFE, 0 or 1 for CPE)
   3982  *              output channel (range = [0, nChans-1])
   3983  *
   3984  * Outputs:     complete frame of decoded PCM, after inverse transform
   3985  *
   3986  * Return:      0 if successful, -1 if error
   3987  *
   3988  * Notes:       If AAC_ENABLE_SBR is defined at compile time then window + overlap
   3989  *                does NOT clip to 16-bit PCM and does NOT interleave channels
   3990  *              If AAC_ENABLE_SBR is NOT defined at compile time, then window + overlap
   3991  *                does clip to 16-bit PCM and interleaves channels
   3992  *              If SBR is enabled at compile time, but we don't know whether it is
   3993  *                actually used for this frame (e.g. the first frame of a stream),
   3994  *                we need to produce both clipped 16-bit PCM in outbuf AND
   3995  *                unclipped 32-bit PCM in the SBR input buffer. In this case we make
   3996  *                a separate pass over the 32-bit PCM to produce 16-bit PCM output.
   3997  *                This inflicts a slight performance hit when decoding non-SBR files.
   3998  **********************************************************************************************************************/
   3999 int IMDCT(int ch, int chOut, short *outbuf)
   4000 {
   4001     int i;
   4002     ICSInfo_t *icsInfo;
   4003 
   4004     icsInfo = (ch == 1 && m_PSInfoBase->commonWin == 1) ? &(m_PSInfoBase->icsInfo[0]) : &(m_PSInfoBase->icsInfo[ch]);
   4005     outbuf += chOut;
   4006 
   4007     /* optimized type-IV DCT (operates inplace) */
   4008     if (icsInfo->winSequence == 2) {
   4009         /* 8 short blocks */
   4010         for (i = 0; i < 8; i++)
   4011             DCT4(0, m_PSInfoBase->coef[ch] + i*128, m_PSInfoBase->gbCurrent[ch]);
   4012     } else {
   4013         /* 1 long block */
   4014         DCT4(1, m_PSInfoBase->coef[ch], m_PSInfoBase->gbCurrent[ch]);
   4015     }
   4016 
   4017 #ifdef AAC_ENABLE_SBR
   4018     /* window, overlap-add, don't clip to short (send to SBR decoder)
   4019      * store the decoded 32-bit samples in top half (second AAC_MAX_NSAMPS samples) of coef buffer
   4020      */
   4021     if (icsInfo->winSequence == 0)
   4022         DecWindowOverlapNoClip(m_PSInfoBase->coef[ch], m_PSInfoBase->overlap[chOut],
   4023                                m_PSInfoBase->sbrWorkBuf[ch], icsInfo->winShape, m_PSInfoBase->prevWinShape[chOut]);
   4024     else if (icsInfo->winSequence == 1)
   4025         DecWindowOverlapLongStartNoClip(m_PSInfoBase->coef[ch], m_PSInfoBase->overlap[chOut],
   4026                                         m_PSInfoBase->sbrWorkBuf[ch], icsInfo->winShape, m_PSInfoBase->prevWinShape[chOut]);
   4027     else if (icsInfo->winSequence == 2)
   4028         DecWindowOverlapShortNoClip(m_PSInfoBase->coef[ch], m_PSInfoBase->overlap[chOut],
   4029                                     m_PSInfoBase->sbrWorkBuf[ch], icsInfo->winShape, m_PSInfoBase->prevWinShape[chOut]);
   4030     else if (icsInfo->winSequence == 3)
   4031         DecWindowOverlapLongStopNoClip(m_PSInfoBase->coef[ch], m_PSInfoBase->overlap[chOut],
   4032                                        m_PSInfoBase->sbrWorkBuf[ch], icsInfo->winShape, m_PSInfoBase->prevWinShape[chOut]);
   4033 
   4034     if (!m_AACDecInfo->sbrEnabled) {
   4035         for (i = 0; i < AAC_MAX_NSAMPS; i++) {
   4036             *outbuf = CLIPTOSHORT((m_PSInfoBase->sbrWorkBuf[ch][i] + RND_VAL) >> FBITS_OUT_IMDCT);
   4037             outbuf += m_AACDecInfo->nChans;
   4038         }
   4039     }
   4040 
   4041     m_AACDecInfo->rawSampleBuf[ch] = m_PSInfoBase->sbrWorkBuf[ch];
   4042     m_AACDecInfo->rawSampleBytes = sizeof(int);
   4043     m_AACDecInfo->rawSampleFBits = FBITS_OUT_IMDCT;
   4044 #else
   4045     /* window, overlap-add, round to PCM - optimized for each window sequence */
   4046     if (icsInfo->winSequence == 0)
   4047         DecWindowOverlap(m_PSInfoBase->coef[ch], m_PSInfoBase->overlap[chOut], outbuf, m_AACDecInfo->nChans,
   4048                                                                   icsInfo->winShape, m_PSInfoBase->prevWinShape[chOut]);
   4049     else if (icsInfo->winSequence == 1)
   4050         DecWindowOverlapLongStart(m_PSInfoBase->coef[ch], m_PSInfoBase->overlap[chOut], outbuf, m_AACDecInfo->nChans,
   4051                                                                   icsInfo->winShape, m_PSInfoBase->prevWinShape[chOut]);
   4052     else if (icsInfo->winSequence == 2)
   4053         DecWindowOverlapShort(m_PSInfoBase->coef[ch], m_PSInfoBase->overlap[chOut], outbuf, m_AACDecInfo->nChans,
   4054                                                                   icsInfo->winShape, m_PSInfoBase->prevWinShape[chOut]);
   4055     else if (icsInfo->winSequence == 3)
   4056         DecWindowOverlapLongStop(m_PSInfoBase->coef[ch], m_PSInfoBase->overlap[chOut], outbuf, m_AACDecInfo->nChans,
   4057                                                                   icsInfo->winShape, m_PSInfoBase->prevWinShape[chOut]);
   4058 
   4059     m_AACDecInfo->rawSampleBuf[ch] = 0;
   4060     m_AACDecInfo->rawSampleBytes = 0;
   4061     m_AACDecInfo->rawSampleFBits = 0;
   4062 #endif
   4063 
   4064     m_PSInfoBase->prevWinShape[chOut] = icsInfo->winShape;
   4065 
   4066     return 0;
   4067 }
   4068 
   4069 /***********************************************************************************************************************
   4070  * Function:    DecodeICSInfo
   4071  *
   4072  * Description: decode individual channel stream info
   4073  *
   4074  * Inputs:      sample rate index
   4075  *
   4076  * Outputs:     updated icsInfo struct
   4077  *
   4078  * Return:      none
   4079  **********************************************************************************************************************/
   4080 void DecodeICSInfo(ICSInfo_t *icsInfo, int sampRateIdx)
   4081 {
   4082     int sfb, g, mask;
   4083 
   4084     icsInfo->icsResBit =      GetBits(1);
   4085     icsInfo->winSequence =    GetBits(2);
   4086     icsInfo->winShape =       GetBits(1);
   4087     if (icsInfo->winSequence == 2) {
   4088         /* short block */
   4089         icsInfo->maxSFB =     GetBits(4);
   4090         icsInfo->sfGroup =    GetBits(7);
   4091         icsInfo->numWinGroup =    1;
   4092         icsInfo->winGroupLen[0] = 1;
   4093         mask = 0x40;    /* start with bit 6 */
   4094         for (g = 0; g < 7; g++) {
   4095             if (icsInfo->sfGroup & mask)    {
   4096                 icsInfo->winGroupLen[icsInfo->numWinGroup - 1]++;
   4097             } else {
   4098                 icsInfo->numWinGroup++;
   4099                 icsInfo->winGroupLen[icsInfo->numWinGroup - 1] = 1;
   4100             }
   4101             mask >>= 1;
   4102         }
   4103     } else {
   4104         /* long block */
   4105         icsInfo->maxSFB =               GetBits(6);
   4106         icsInfo->predictorDataPresent = GetBits(1);
   4107         if (icsInfo->predictorDataPresent) {
   4108             icsInfo->predictorReset =   GetBits(1);
   4109             if (icsInfo->predictorReset)
   4110                 icsInfo->predictorResetGroupNum = GetBits(5);
   4111             for (sfb = 0; sfb < MIN(icsInfo->maxSFB, predSFBMax[sampRateIdx]); sfb++)
   4112                 icsInfo->predictionUsed[sfb] = GetBits(1);
   4113         }
   4114         icsInfo->numWinGroup = 1;
   4115         icsInfo->winGroupLen[0] = 1;
   4116     }
   4117 }
   4118 
   4119 /***********************************************************************************************************************
   4120  * Function:    DecodeSectionData
   4121  *
   4122  * Description: decode section data (scale factor band groupings and
   4123  *                associated Huffman codebooks)
   4124  *
   4125  * Inputs:      window sequence (short or long blocks)
   4126  *              number of window groups (1 for long blocks, 1-8 for short blocks)
   4127  *              max coded scalefactor band
   4128  *
   4129  * Outputs:     index of Huffman codebook for each scalefactor band in each section
   4130  *
   4131  * Return:      none
   4132  *
   4133  * Notes:       sectCB, sectEnd, sfbCodeBook, ordered by window groups for short blocks
   4134  **********************************************************************************************************************/
   4135 void DecodeSectionData(int winSequence, int numWinGrp, int maxSFB, uint8_t *sfbCodeBook)
   4136 {
   4137     int g, cb, sfb;
   4138     int sectLen, sectLenBits, sectLenIncr, sectEscapeVal;
   4139 
   4140     sectLenBits = (winSequence == 2 ? 3 : 5);
   4141     sectEscapeVal = (1 << sectLenBits) - 1;
   4142 
   4143     for (g = 0; g < numWinGrp; g++) {
   4144         sfb = 0;
   4145         while (sfb < maxSFB) {
   4146             cb = GetBits(4);    /* next section codebook */
   4147             sectLen = 0;
   4148             do {
   4149                 sectLenIncr = GetBits(sectLenBits);
   4150                 sectLen += sectLenIncr;
   4151             } while (sectLenIncr == sectEscapeVal);
   4152 
   4153             sfb += sectLen;
   4154             while (sectLen--)
   4155                 *sfbCodeBook++ = (uint8_t)cb;
   4156         }
   4157         ASSERT(sfb == maxSFB);
   4158     }
   4159 }
   4160 
   4161 /***********************************************************************************************************************
   4162  * Function:    DecodeOneScaleFactor
   4163  *
   4164  * Description: decode one scalefactor using scalefactor Huffman codebook
   4165  *
   4166  * Inputs:      none
   4167  *
   4168  * Outputs:     none
   4169  *
   4170  * Return:      one decoded scalefactor, including index_offset of -60
   4171  **********************************************************************************************************************/
   4172 int DecodeOneScaleFactor()
   4173 {
   4174     int nBits, val;
   4175     uint32_t bitBuf;
   4176 
   4177     /* decode next scalefactor from bitstream */
   4178     bitBuf = GetBitsNoAdvance(huffTabScaleFactInfo.maxBits) << (32 - huffTabScaleFactInfo.maxBits);
   4179     nBits = DecodeHuffmanScalar(huffTabScaleFact, &huffTabScaleFactInfo, bitBuf, &val);
   4180     AdvanceBitstream(nBits);
   4181     return val;
   4182 }
   4183 
   4184 /***********************************************************************************************************************
   4185  * Function:    DecodeScaleFactors
   4186  *
   4187  * Description: decode scalefactors, PNS energy, and intensity stereo weights
   4188  *
   4189  * Inputs:      number of window groups (1 for long blocks, 1-8 for short blocks)
   4190  *              max coded scalefactor band
   4191  *              global gain (starting value for differential scalefactor coding)
   4192  *              index of Huffman codebook for each scalefactor band in each section
   4193  *
   4194  * Outputs:     decoded scalefactor for each section
   4195  *
   4196  * Return:      none
   4197  *
   4198  * Notes:       sfbCodeBook, scaleFactors ordered by window groups for short blocks
   4199  *              for section with codebook 13, scaleFactors buffer has decoded PNS
   4200  *                energy instead of regular scalefactor
   4201  *              for section with codebook 14 or 15, scaleFactors buffer has intensity
   4202  *                stereo weight instead of regular scalefactor
   4203  **********************************************************************************************************************/
   4204 void DecodeScaleFactors(int numWinGrp, int maxSFB, int globalGain,
   4205                                uint8_t *sfbCodeBook, short *scaleFactors)
   4206 {
   4207     int g, sfbCB, nrg, npf, val, sf, is;
   4208 
   4209     /* starting values for differential coding */
   4210     sf = globalGain;
   4211     is = 0;
   4212     nrg = globalGain - 90 - 256;
   4213     npf = 1;
   4214 
   4215     for (g = 0; g < numWinGrp * maxSFB; g++) {
   4216         sfbCB = *sfbCodeBook++;
   4217 
   4218         if (sfbCB  == 14 || sfbCB == 15) {
   4219             /* intensity stereo - differential coding */
   4220             val = DecodeOneScaleFactor();
   4221             is += val;
   4222             *scaleFactors++ = (short)is;
   4223         } else if (sfbCB == 13) {
   4224             /* PNS - first energy is directly coded, rest are Huffman coded (npf = noise_pcm_flag) */
   4225             if (npf) {
   4226                 val = GetBits(9);
   4227                 npf = 0;
   4228             } else {
   4229                 val = DecodeOneScaleFactor();
   4230             }
   4231             nrg += val;
   4232             *scaleFactors++ = (short)nrg;
   4233         } else if (sfbCB >= 1 && sfbCB <= 11) {
   4234             /* regular (non-zero) region - differential coding */
   4235             val = DecodeOneScaleFactor();
   4236             sf += val;
   4237             *scaleFactors++ = (short)sf;
   4238         } else {
   4239             /* inactive scalefactor band if codebook 0 */
   4240             *scaleFactors++ = 0;
   4241         }
   4242     }
   4243 }
   4244 
   4245 /***********************************************************************************************************************
   4246  * Function:    DecodePulseInfo
   4247  *
   4248  * Description: decode pulse information
   4249  *
   4250  * Inputs:      none
   4251  *
   4252  * Outputs:     updated PulseInfo_t struct
   4253  *
   4254  * Return:      none
   4255  **********************************************************************************************************************/
   4256 void DecodePulseInfo(uint8_t ch)
   4257 {
   4258     int i;
   4259 
   4260     m_pulseInfo[ch].numPulse = GetBits(2) + 1;        /* add 1 here */
   4261     m_pulseInfo[ch].startSFB = GetBits(6);
   4262     for (i = 0; i < m_pulseInfo[ch].numPulse; i++) {
   4263         m_pulseInfo[ch].offset[i] = GetBits(5);
   4264         m_pulseInfo[ch].amp[i] = GetBits(4);
   4265     }
   4266 }
   4267 
   4268 /***********************************************************************************************************************
   4269  * Function:    DecodeTNSInfo
   4270  *
   4271  * Description: decode TNS filter information
   4272  *
   4273  * Inputs:      window sequence (short or long blocks)
   4274  *
   4275  * Outputs:     updated TNSInfo_t struct
   4276  *              buffer of decoded (signed) TNS filter coefficients
   4277  *
   4278  * Return:      none
   4279  **********************************************************************************************************************/
   4280 void DecodeTNSInfo(int winSequence, TNSInfo_t *ti, int8_t *tnsCoef)
   4281 {
   4282     int i, w, f, coefBits, compress;
   4283     int8_t c, s, n;
   4284     uint8_t *filtLength, *filtOrder, *filtDir;
   4285 
   4286     filtLength = ti->length;
   4287     filtOrder =  ti->order;
   4288     filtDir =    ti->dir;
   4289 
   4290     if (winSequence == 2) {
   4291         /* short blocks */
   4292         for (w = 0; w < NWINDOWS_SHORT; w++) {
   4293             ti->numFilt[w] = GetBits(1);
   4294             if (ti->numFilt[w]) {
   4295                 ti->coefRes[w] = GetBits(1) + 3;
   4296                 *filtLength =    GetBits(4);
   4297                 *filtOrder =     GetBits(3);
   4298                 if (*filtOrder) {
   4299                     *filtDir++ =      GetBits(1);
   4300                     compress =        GetBits(1);
   4301                     coefBits = (int)ti->coefRes[w] - compress;    /* 2, 3, or 4 */
   4302                     s = sgnMask[coefBits - 2];
   4303                     n = negMask[coefBits - 2];
   4304                     for (i = 0; i < *filtOrder; i++) {
   4305                         c = GetBits(coefBits);
   4306                         if (c & s)    c |= n;
   4307                         *tnsCoef++ = c;
   4308                     }
   4309                 }
   4310                 filtLength++;
   4311                 filtOrder++;
   4312             }
   4313         }
   4314     } else {
   4315         /* long blocks */
   4316         ti->numFilt[0] = GetBits(2);
   4317         if (ti->numFilt[0])
   4318             ti->coefRes[0] = GetBits(1) + 3;
   4319         for (f = 0; f < ti->numFilt[0]; f++) {
   4320             *filtLength =      GetBits(6);
   4321             *filtOrder =       GetBits(5);
   4322             if (*filtOrder) {
   4323                 *filtDir++ =     GetBits(1);
   4324                 compress =       GetBits(1);
   4325                 coefBits = (int)ti->coefRes[0] - compress;    /* 2, 3, or 4 */
   4326                 s = sgnMask[coefBits - 2];
   4327                 n = negMask[coefBits - 2];
   4328                 for (i = 0; i < *filtOrder; i++) {
   4329                     c = GetBits(coefBits);
   4330                     if (c & s)    c |= n;
   4331                     *tnsCoef++ = c;
   4332                 }
   4333             }
   4334             filtLength++;
   4335             filtOrder++;
   4336         }
   4337     }
   4338 }
   4339 
   4340 /* bitstream field lengths for gain control data:
   4341  *   gainBits[winSequence][0] = maxWindow (how many gain windows there are)
   4342  *   gainBits[winSequence][1] = locBitsZero (bits for alocCode if window == 0)
   4343  *   gainBits[winSequence][2] = locBits (bits for alocCode if window != 0)
   4344  */
   4345 static const uint8_t gainBits[4][3] = {
   4346     {1, 5, 5},  /* long */
   4347     {2, 4, 2},  /* start */
   4348     {8, 2, 2},  /* short */
   4349     {2, 4, 5},  /* stop */
   4350 };
   4351 
   4352 /***********************************************************************************************************************
   4353  * Function:    DecodeGainControlInfo
   4354  *
   4355  * Description: decode gain control information (SSR profile only)
   4356  *
   4357  * Inputs:      window sequence (short or long blocks)
   4358  *
   4359  * Outputs:     updated GainControlInfo_t struct
   4360  *
   4361  * Return:      none
   4362  **********************************************************************************************************************/
   4363 void DecodeGainControlInfo(int winSequence, GainControlInfo_t *gi)
   4364 {
   4365     int bd, wd, ad;
   4366     int locBits, locBitsZero, maxWin;
   4367 
   4368     gi->maxBand = GetBits(2);
   4369     maxWin =      (int)gainBits[winSequence][0];
   4370     locBitsZero = (int)gainBits[winSequence][1];
   4371     locBits =     (int)gainBits[winSequence][2];
   4372 
   4373     for (bd = 1; bd <= gi->maxBand; bd++) {
   4374         for (wd = 0; wd < maxWin; wd++) {
   4375             gi->adjNum[bd][wd] = GetBits(3);
   4376             for (ad = 0; ad < gi->adjNum[bd][wd]; ad++) {
   4377                 gi->alevCode[bd][wd][ad] = GetBits(4);
   4378                 gi->alocCode[bd][wd][ad] = GetBits(wd == 0 ? locBitsZero : locBits);
   4379             }
   4380         }
   4381     }
   4382 }
   4383 
   4384 /***********************************************************************************************************************
   4385  * Function:    DecodeICS
   4386  *
   4387  * Description: decode individual channel stream
   4388  *
   4389  * Inputs:      index of current channel
   4390  *
   4391  * Outputs:     updated section data, scale factor data, pulse data, TNS data,
   4392  *                and gain control data
   4393  *
   4394  * Return:      none
   4395  **********************************************************************************************************************/
   4396 void DecodeICS(int ch)
   4397 {
   4398     int globalGain;
   4399     ICSInfo_t *icsInfo;
   4400     TNSInfo_t *ti;
   4401     GainControlInfo_t *gi;
   4402 
   4403     icsInfo = (ch == 1 && m_PSInfoBase->commonWin == 1) ? &(m_PSInfoBase->icsInfo[0]) : &(m_PSInfoBase->icsInfo[ch]);
   4404 
   4405     globalGain = GetBits(8);
   4406     if (!m_PSInfoBase->commonWin)
   4407         DecodeICSInfo(icsInfo, m_PSInfoBase->sampRateIdx);
   4408 
   4409     DecodeSectionData(icsInfo->winSequence, icsInfo->numWinGroup, icsInfo->maxSFB, m_PSInfoBase->sfbCodeBook[ch]);
   4410 
   4411     DecodeScaleFactors(icsInfo->numWinGroup, icsInfo->maxSFB, globalGain, m_PSInfoBase->sfbCodeBook[ch],
   4412                                                                                         m_PSInfoBase->scaleFactors[ch]);
   4413 
   4414     m_pulseInfo[ch].pulseDataPresent = GetBits(1);
   4415     if (m_pulseInfo[ch].pulseDataPresent)
   4416         DecodePulseInfo(ch);
   4417 
   4418     ti = &m_PSInfoBase->tnsInfo[ch];
   4419     ti->tnsDataPresent = GetBits(1);
   4420     if (ti->tnsDataPresent)
   4421         DecodeTNSInfo(icsInfo->winSequence, ti, ti->coef);
   4422 
   4423     gi = &m_PSInfoBase->gainControlInfo[ch];
   4424     gi->gainControlDataPresent = GetBits(1);
   4425     if (gi->gainControlDataPresent)
   4426         DecodeGainControlInfo(icsInfo->winSequence, gi);
   4427 }
   4428 
   4429 /***********************************************************************************************************************
   4430  * Function:    DecodeNoiselessData
   4431  *
   4432  * Description: decode noiseless data (side info and transform coefficients)
   4433  *
   4434  * Inputs:      double pointer to buffer pointing to start of individual channel stream
   4435  *                (14496-3, table 4.4.24)
   4436  *              pointer to bit offset
   4437  *              pointer to number of valid bits remaining in buf
   4438  *              index of current channel
   4439  *
   4440  * Outputs:     updated global gain, section data, scale factor data, pulse data,
   4441  *                TNS data, gain control data, and spectral data
   4442  *
   4443  * Return:      0 if successful, error code (< 0) if error
   4444  **********************************************************************************************************************/
   4445 int DecodeNoiselessData(uint8_t **buf, int *bitOffset, int *bitsAvail, int ch)
   4446 {
   4447     int bitsUsed;
   4448     ICSInfo_t *icsInfo;
   4449 
   4450     icsInfo = (ch == 1 && m_PSInfoBase->commonWin == 1) ? &(m_PSInfoBase->icsInfo[0]) : &(m_PSInfoBase->icsInfo[ch]);
   4451 
   4452     SetBitstreamPointer((*bitsAvail+7) >> 3, *buf);
   4453     GetBits(*bitOffset);
   4454 
   4455     DecodeICS(ch);
   4456 
   4457     if (icsInfo->winSequence == 2)
   4458         DecodeSpectrumShort(ch);
   4459     else
   4460         DecodeSpectrumLong(ch);
   4461 
   4462     bitsUsed = CalcBitsUsed(*buf, *bitOffset);
   4463     *buf += ((bitsUsed + *bitOffset) >> 3);
   4464     *bitOffset = ((bitsUsed + *bitOffset) & 0x07);
   4465     *bitsAvail -= bitsUsed;
   4466 
   4467     m_AACDecInfo->sbDeinterleaveReqd[ch] = 0;
   4468     m_AACDecInfo->tnsUsed |= m_PSInfoBase->tnsInfo[ch].tnsDataPresent;    /* set flag if TNS used for any channel */
   4469 
   4470     return ERR_AAC_NONE;
   4471 }
   4472 /***********************************************************************************************************************
   4473  * Function:    DecodeHuffmanScalar
   4474  *
   4475  * Description: decode one Huffman symbol from bitstream
   4476  *
   4477  * Inputs:      pointers to Huffman table and info struct
   4478  *              left-aligned bit buffer with >= huffTabInfo->maxBits bits
   4479  *
   4480  * Outputs:     decoded symbol in *val
   4481  *
   4482  * Return:      number of bits in symbol
   4483  *
   4484  * Notes:       assumes canonical Huffman codes:
   4485  *                first CW always 0, we have "count" CW's of length "nBits" bits
   4486  *                starting CW for codes of length nBits+1 =
   4487  *                  (startCW[nBits] + count[nBits]) << 1
   4488  *                if there are no codes at nBits, then we just keep << 1 each time
   4489  *                  (since count[nBits] = 0)
   4490  **********************************************************************************************************************/
   4491 int DecodeHuffmanScalar(const signed short *huffTab, const HuffInfo_t *huffTabInfo, uint32_t bitBuf, int32_t *val)
   4492 {
   4493     uint32_t count, start, shift, t;
   4494     const uint8_t *countPtr;
   4495     const signed short *map;
   4496 
   4497     map = huffTab + huffTabInfo->offset;
   4498     countPtr = huffTabInfo->count;
   4499 
   4500     start = 0;
   4501     count = 0;
   4502     shift = 32;
   4503     do {
   4504         start += count;
   4505         start <<= 1;
   4506         map += count;
   4507         count = *countPtr++;
   4508         shift--;
   4509         t = (bitBuf >> shift) - start;
   4510     } while (t >= count);
   4511 
   4512     *val = (int32_t)map[t];
   4513     return (countPtr - huffTabInfo->count);
   4514 }
   4515 
   4516 /***********************************************************************************************************************
   4517 * Function:    UnpackADTSHeader
   4518 *
   4519 * Description: parse the ADTS frame header and initialize decoder state, Audio Data Transport Stream
   4520 *
   4521 * Inputs:      double pointer to buffer with complete ADTS frame header (byte aligned)
   4522 *                header size = 7 bytes, plus 2 if CRC
   4523 *
   4524 * Outputs:     filled in ADTS struct
   4525 *              updated buffer pointer
   4526 *              updated bit offset
   4527 *              updated number of available bits
   4528 *
   4529 * Return:      0 if successful, error code (< 0) if error
   4530 *              verify that fixed fields don't change between frames
   4531 ***********************************************************************************************************************/
   4532 int UnpackADTSHeader(uint8_t **buf, int *bitOffset, int *bitsAvail)
   4533 {
   4534     int bitsUsed;
   4535 
   4536     /* init bitstream reader */
   4537     SetBitstreamPointer((*bitsAvail + 7) >> 3, *buf);
   4538     GetBits(*bitOffset);
   4539 
   4540     /* verify that first 12 bits of header are syncword */
   4541     if (GetBits(12) != 0x0fff) {
   4542         return ERR_AAC_INVALID_ADTS_HEADER;
   4543     }
   4544 
   4545     /* fixed fields - should not change from frame to frame */
   4546     m_fhADTS.id =               GetBits(1);
   4547     m_fhADTS.layer =            GetBits(2);
   4548     m_fhADTS.protectBit =       GetBits(1);
   4549     m_fhADTS.profile =          GetBits(2);
   4550     m_fhADTS.sampRateIdx =      GetBits(4);
   4551     m_fhADTS.privateBit =       GetBits(1);
   4552     m_fhADTS.channelConfig =    GetBits(3);
   4553     m_fhADTS.origCopy =         GetBits(1);
   4554     m_fhADTS.home =             GetBits(1);
   4555 
   4556     /* variable fields - can change from frame to frame */
   4557     m_fhADTS.copyBit =          GetBits(1);
   4558     m_fhADTS.copyStart =        GetBits(1);
   4559     m_fhADTS.frameLength =      GetBits(13);
   4560     m_fhADTS.bufferFull =       GetBits(11);
   4561     m_fhADTS.numRawDataBlocks = GetBits(2) + 1;
   4562 
   4563     /* note - MPEG4 spec, correction 1 changes how CRC is handled when protectBit == 0 and numRawDataBlocks > 1 */
   4564     if (m_fhADTS.protectBit == 0)
   4565         m_fhADTS.crcCheckWord = GetBits(16);
   4566 
   4567     /* byte align */
   4568     ByteAlignBitstream();    /* should always be aligned anyway */
   4569 
   4570     /* check validity of header */
   4571     if (m_fhADTS.layer != 0 || m_fhADTS.profile != AAC_PROFILE_LC ||
   4572         m_fhADTS.sampRateIdx >= NUM_SAMPLE_RATES || m_fhADTS.channelConfig >= NUM_DEF_CHAN_MAPS)
   4573         return ERR_AAC_INVALID_ADTS_HEADER;
   4574 
   4575 #ifndef AAC_ENABLE_MPEG4
   4576     if (m_fhADTS.id != 1)
   4577         return ERR_AAC_MPEG4_UNSUPPORTED;
   4578 #endif
   4579 
   4580 
   4581     /* update codec info */
   4582     m_PSInfoBase->sampRateIdx = m_fhADTS.sampRateIdx;
   4583     if (!m_PSInfoBase->useImpChanMap)
   4584         m_PSInfoBase->nChans = channelMapTab[m_fhADTS.channelConfig];
   4585 
   4586     /* syntactic element fields will be read from bitstream for each element */
   4587     m_AACDecInfo->prevBlockID = AAC_ID_INVALID;
   4588     m_AACDecInfo->currBlockID = AAC_ID_INVALID;
   4589     m_AACDecInfo->currInstTag = -1;
   4590 
   4591     /* fill in user-accessible data */
   4592     m_AACDecInfo->bitRate = 0;
   4593     m_AACDecInfo->nChans = m_PSInfoBase->nChans;
   4594     m_AACDecInfo->sampRate = sampRateTab[m_PSInfoBase->sampRateIdx];
   4595     m_AACDecInfo->id = m_fhADTS.id;
   4596     m_AACDecInfo->profile = m_fhADTS.profile;
   4597     m_AACDecInfo->sbrEnabled = 0;
   4598     m_AACDecInfo->adtsBlocksLeft = m_fhADTS.numRawDataBlocks;
   4599 
   4600     /* update bitstream reader */
   4601     bitsUsed = CalcBitsUsed(*buf, *bitOffset);
   4602     *buf += (bitsUsed + *bitOffset) >> 3;
   4603     *bitOffset = (bitsUsed + *bitOffset) & 0x07;
   4604     *bitsAvail -= bitsUsed ;
   4605     if (*bitsAvail < 0)
   4606         return ERR_AAC_INDATA_UNDERFLOW;
   4607 
   4608     return ERR_AAC_NONE;
   4609 }
   4610 
   4611 /***********************************************************************************************************************
   4612 * Function:    GetADTSChannelMapping
   4613 *
   4614 * Description: determine the number of channels from implicit mapping rules
   4615 *
   4616 * Inputs:      pointer to start of raw_data_block
   4617 *              bit offset
   4618 *              bits available
   4619 *
   4620 * Outputs:     updated number of channels
   4621 *
   4622 * Return:      0 if successful, error code (< 0) if error
   4623 *
   4624 * Notes:       calculates total number of channels using rules in 14496-3, 4.5.1.2.1
   4625 *              does not attempt to deduce speaker geometry
   4626 ***********************************************************************************************************************/
   4627 int GetADTSChannelMapping(uint8_t *buf, int bitOffset, int bitsAvail)
   4628 {
   4629     int ch, nChans, elementChans, err;
   4630 
   4631     nChans = 0;
   4632     do {
   4633         /* parse next syntactic element */
   4634         err = DecodeNextElement(&buf, &bitOffset, &bitsAvail);
   4635         if (err)
   4636             return err;
   4637 
   4638         elementChans = elementNumChans[m_AACDecInfo->currBlockID];
   4639         nChans += elementChans;
   4640 
   4641         for (ch = 0; ch < elementChans; ch++) {
   4642             err = DecodeNoiselessData(&buf, &bitOffset, &bitsAvail, ch);
   4643             if (err)
   4644                 return err;
   4645         }
   4646     } while (m_AACDecInfo->currBlockID != AAC_ID_END);
   4647 
   4648     if (nChans <= 0)
   4649         return ERR_AAC_CHANNEL_MAP;
   4650 
   4651     /* update number of channels in codec state and user-accessible info structs */
   4652     m_PSInfoBase->nChans = nChans;
   4653     m_AACDecInfo->nChans = m_PSInfoBase->nChans;
   4654     m_PSInfoBase->useImpChanMap = 1;
   4655 
   4656     return ERR_AAC_NONE;
   4657 }
   4658 
   4659 /***********************************************************************************************************************
   4660 * Function:    GetNumChannelsADIF
   4661 *
   4662 * Description: get number of channels from program config elements in an ADIF file
   4663 *
   4664 * Inputs:      array of filled-in program config element structures
   4665 *              number of PCE's
   4666 *
   4667 * Outputs:     none
   4668 *
   4669 * Return:      total number of channels in file
   4670 *              -1 if error (invalid number of PCE's or unsupported mode)
   4671 ***********************************************************************************************************************/
   4672 int GetNumChannelsADIF(int nPCE)
   4673 {
   4674     int i, j, nChans;
   4675 
   4676     if (nPCE < 1 || nPCE > MAX_NUM_PCE_ADIF)
   4677         return -1;
   4678 
   4679     nChans = 0;
   4680     for (i = 0; i < nPCE; i++) {
   4681         /* for now: only support LC, no channel coupling */
   4682         if (m_pce[i]->profile != AAC_PROFILE_LC || m_pce[i]->numCCE > 0)
   4683             return -1;
   4684 
   4685         /* add up number of channels in all channel elements (assume all single-channel) */
   4686        nChans += m_pce[i]->numFCE;
   4687        nChans += m_pce[i]->numSCE;
   4688        nChans += m_pce[i]->numBCE;
   4689        nChans += m_pce[i]->numLCE;
   4690 
   4691         /* add one more for every element which is a channel pair */
   4692        for (j = 0; j < m_pce[i]->numFCE; j++) {
   4693            if ((m_pce[i]->fce[j] & 0x10) >> 4)  /* bit 4 = SCE/CPE flag */
   4694                nChans++;
   4695        }
   4696        for (j = 0; j < m_pce[i]->numSCE; j++) {
   4697            if ((m_pce[i]->sce[j] & 0x10) >> 4)  /* bit 4 = SCE/CPE flag */
   4698                nChans++;
   4699        }
   4700        for (j = 0; j < m_pce[i]->numBCE; j++) {
   4701            if ((m_pce[i]->bce[j] & 0x10) >> 4)  /* bit 4 = SCE/CPE flag */
   4702                nChans++;
   4703        }
   4704 
   4705     }
   4706 
   4707     return nChans;
   4708 }
   4709 
   4710 /***********************************************************************************************************************
   4711 * Function:    GetSampleRateIdxADIF
   4712 *
   4713 * Description: get sampling rate index from program config elements in an ADIF file
   4714 *
   4715 * Inputs:      array of filled-in program config element structures
   4716 *              number of PCE's
   4717 *
   4718 * Outputs:     none
   4719 *
   4720 * Return:      sample rate of file
   4721 *              -1 if error (invalid number of PCE's or sample rate mismatch)
   4722 ***********************************************************************************************************************/
   4723 int GetSampleRateIdxADIF(int nPCE)
   4724 {
   4725     int i, idx;
   4726 
   4727     if (nPCE < 1 || nPCE > MAX_NUM_PCE_ADIF)
   4728         return -1;
   4729 
   4730     /* make sure all PCE's have the same sample rate */
   4731     idx = m_pce[0]->sampRateIdx;
   4732     for (i = 1; i < nPCE; i++) {
   4733         if (m_pce[i]->sampRateIdx != idx)
   4734             return -1;
   4735     }
   4736 
   4737     return idx;
   4738 }
   4739 
   4740 /***********************************************************************************************************************
   4741 * Function:    UnpackADIFHeader
   4742 *
   4743 * Description: parse the ADIF file header and initialize decoder state
   4744 *
   4745 * Inputs:      double pointer to buffer with complete ADIF header
   4746 *                (starting at 'A' in 'ADIF' tag)
   4747 *              pointer to bit offset
   4748 *              pointer to number of valid bits remaining in inbuf
   4749 *
   4750 * Outputs:     filled-in ADIF struct
   4751 *              updated buffer pointer
   4752 *              updated bit offset
   4753 *              updated number of available bits
   4754 *
   4755 * Return:      0 if successful, error code (< 0) if error
   4756 ***********************************************************************************************************************/
   4757 int UnpackADIFHeader(uint8_t **buf, int *bitOffset, int *bitsAvail)
   4758 {
   4759     uint8_t i;
   4760     int bitsUsed;
   4761 
   4762     /* init bitstream reader */
   4763     SetBitstreamPointer((*bitsAvail + 7) >> 3, *buf);
   4764     GetBits(*bitOffset);
   4765 
   4766     /* verify that first 32 bits of header are "ADIF" */
   4767     if (GetBits(8) != 'A' || GetBits(8) != 'D' || GetBits(8) != 'I' || GetBits(8) != 'F')
   4768         return ERR_AAC_INVALID_ADIF_HEADER;
   4769 
   4770     /* read ADIF header fields */
   4771     m_fhADIF.copyBit = GetBits(1);
   4772     if (m_fhADIF.copyBit) {
   4773         for (i = 0; i < ADIF_COPYID_SIZE; i++)
   4774             m_fhADIF.copyID[i] = GetBits(8);
   4775     }
   4776     m_fhADIF.origCopy = GetBits(1);
   4777     m_fhADIF.home =     GetBits(1);
   4778     m_fhADIF.bsType =   GetBits(1);
   4779     m_fhADIF.bitRate =  GetBits(23);
   4780     m_fhADIF.numPCE =   GetBits(4) + 1;    /* add 1 (so range = [1, 16]) */
   4781     if (m_fhADIF.bsType == 0)
   4782         m_fhADIF.bufferFull = GetBits(20);
   4783 
   4784     /* parse all program config elements */
   4785     for (i = 0; i < m_fhADIF.numPCE; i++)
   4786         DecodeProgramConfigElement(i);
   4787 
   4788     /* byte align */
   4789     ByteAlignBitstream();
   4790 
   4791     /* update codec info */
   4792     m_PSInfoBase->nChans = GetNumChannelsADIF(m_fhADIF.numPCE);
   4793     m_PSInfoBase->sampRateIdx = GetSampleRateIdxADIF(m_fhADIF.numPCE);
   4794 
   4795     /* check validity of header */
   4796     if (m_PSInfoBase->nChans < 0 || m_PSInfoBase->sampRateIdx < 0 || m_PSInfoBase->sampRateIdx >= NUM_SAMPLE_RATES)
   4797         return ERR_AAC_INVALID_ADIF_HEADER;
   4798 
   4799     /* syntactic element fields will be read from bitstream for each element */
   4800     m_AACDecInfo->prevBlockID = AAC_ID_INVALID;
   4801     m_AACDecInfo->currBlockID = AAC_ID_INVALID;
   4802     m_AACDecInfo->currInstTag = -1;
   4803 
   4804     /* fill in user-accessible data */
   4805     m_AACDecInfo->bitRate = 0;
   4806     m_AACDecInfo->nChans = m_PSInfoBase->nChans;
   4807     m_AACDecInfo->sampRate = sampRateTab[m_PSInfoBase->sampRateIdx];
   4808     m_AACDecInfo->profile = m_pce[0]->profile;
   4809     m_AACDecInfo->sbrEnabled = 0;
   4810 
   4811     /* update bitstream reader */
   4812     bitsUsed = CalcBitsUsed(*buf, *bitOffset);
   4813     *buf += (bitsUsed + *bitOffset) >> 3;
   4814     *bitOffset = (bitsUsed + *bitOffset) & 0x07;
   4815     *bitsAvail -= bitsUsed ;
   4816     if (*bitsAvail < 0)
   4817         return ERR_AAC_INDATA_UNDERFLOW;
   4818 
   4819     return ERR_AAC_NONE;
   4820 }
   4821 
   4822 /***********************************************************************************************************************
   4823 * Function:    SetRawBlockParams
   4824 *
   4825 * Description: set internal state variables for decoding a stream of raw data blocks
   4826 *
   4827 * Inputs:      flag indicating source of parameters (from previous headers or passed
   4828 *                explicitly by caller)
   4829 *              number of channels
   4830 *              sample rate
   4831 *              profile ID
   4832 *
   4833 * Outputs:     updated state variables in aacDecInfo
   4834 *
   4835 * Return:      0 if successful, error code (< 0) if error
   4836 *
   4837 * Notes:       if copyLast == 1, then m_PSInfoBase->nChans, m_PSInfoBase->sampRateIdx, and
   4838 *                aacDecInfo->profile are not changed (it's assumed that we already
   4839 *                set them, such as by a previous call to UnpackADTSHeader())
   4840 *              if copyLast == 0, then the parameters we passed in are used instead
   4841 ***********************************************************************************************************************/
   4842 int SetRawBlockParams(int copyLast, int nChans, int sampRate, int profile)
   4843 {
   4844     int idx;
   4845 
   4846     if (!copyLast) {
   4847         m_AACDecInfo->profile = profile;
   4848         m_PSInfoBase->nChans = nChans;
   4849         for (idx = 0; idx < NUM_SAMPLE_RATES; idx++) {
   4850             if (sampRate == sampRateTab[idx]) {
   4851                 m_PSInfoBase->sampRateIdx = idx;
   4852                 break;
   4853             }
   4854         }
   4855         if (idx == NUM_SAMPLE_RATES)
   4856             return ERR_AAC_INVALID_FRAME;
   4857     }
   4858     m_AACDecInfo->nChans = m_PSInfoBase->nChans;
   4859     m_AACDecInfo->sampRate = sampRateTab[m_PSInfoBase->sampRateIdx];
   4860 
   4861     /* check validity of header */
   4862     if (m_PSInfoBase->sampRateIdx >= NUM_SAMPLE_RATES || m_PSInfoBase->sampRateIdx < 0 ||
   4863         m_AACDecInfo->profile != AAC_PROFILE_LC)
   4864         return ERR_AAC_RAWBLOCK_PARAMS;
   4865 
   4866     return ERR_AAC_NONE;
   4867 }
   4868 
   4869 /***********************************************************************************************************************
   4870 * Function:    PrepareRawBlock
   4871 *
   4872 * Description: reset per-block state variables for raw blocks (no ADTS/ADIF headers)
   4873 *
   4874 * Inputs:      none
   4875 *
   4876 * Outputs:     updated state variables in aacDecInfo
   4877 *
   4878 * Return:      0 if successful, error code (< 0) if error
   4879 ***********************************************************************************************************************/
   4880 int PrepareRawBlock()
   4881 {
   4882     /* syntactic element fields will be read from bitstream for each element */
   4883     m_AACDecInfo->prevBlockID = AAC_ID_INVALID;
   4884     m_AACDecInfo->currBlockID = AAC_ID_INVALID;
   4885     m_AACDecInfo->currInstTag = -1;
   4886 
   4887     /* fill in user-accessible data */
   4888     m_AACDecInfo->bitRate = 0;
   4889     m_AACDecInfo->sbrEnabled = 0;
   4890 
   4891     return ERR_AAC_NONE;
   4892 }
   4893 
   4894 /***********************************************************************************************************************
   4895  * Function:    DequantBlock
   4896  *
   4897  * Description: dequantize one block of transform coefficients (in-place)
   4898  *
   4899  * Inputs:      quantized transform coefficients, range = [0, 8191]
   4900  *              number of samples to dequantize
   4901  *              scalefactor for this block of data, range = [0, 256]
   4902  *
   4903  * Outputs:     dequantized transform coefficients in Q(FBITS_OUT_DQ_OFF)
   4904  *
   4905  * Return:      guard bit mask (OR of abs value of all dequantized coefs)
   4906  *
   4907  * Notes:       applies dequant formula y = pow(x, 4.0/3.0) * pow(2, (scale - 100)/4.0)
   4908  *                * pow(2, FBITS_OUT_DQ_OFF)
   4909  *              clips outputs to Q(FBITS_OUT_DQ_OFF)
   4910  *              output has no minimum number of guard bits
   4911  **********************************************************************************************************************/
   4912 int DequantBlock(int *inbuf, int nSamps, int scale)
   4913 {
   4914     int iSamp, scalef, scalei, x, y, gbMask, shift, tab4[4];
   4915     const uint32_t *tab16, *coef;
   4916 
   4917     if (nSamps <= 0)
   4918         return 0;
   4919 
   4920     scale -= SF_OFFSET;    /* new range = [-100, 156] */
   4921 
   4922     /* with two's complement numbers, scalei/scalef factorization works for pos and neg values of scale:
   4923      *  [+4...+7] >> 2 = +1, [ 0...+3] >> 2 = 0, [-4...-1] >> 2 = -1, [-8...-5] >> 2 = -2 ...
   4924      *  (-1 & 0x3) = 3, (-2 & 0x3) = 2, (-3 & 0x3) = 1, (0 & 0x3) = 0
   4925      *
   4926      * Example: 2^(-5/4) = 2^(-1) * 2^(-1/4) = 2^-2 * 2^(3/4)
   4927      */
   4928     tab16 = pow43_14[scale & 0x3];
   4929     scalef = pow14[scale & 0x3];
   4930     scalei = (scale >> 2) + FBITS_OUT_DQ_OFF;
   4931 
   4932     /* cache first 4 values:
   4933      * tab16[j] = Q28 for j = [0,3]
   4934      * tab4[x] = x^(4.0/3.0) * 2^(0.25*scale), Q(FBITS_OUT_DQ_OFF)
   4935      */
   4936     shift = 28 - scalei;
   4937     if (shift > 31) {
   4938         tab4[0] = tab4[1] = tab4[2] = tab4[3] = 0;
   4939     } else if (shift <= 0) {
   4940         shift = -shift;
   4941         if (shift > 31)
   4942             shift = 31;
   4943         for (x = 0; x < 4; x++) {
   4944             y = tab16[x];
   4945             if (y > (0x7fffffff >> shift))
   4946                 y = 0x7fffffff;        /* clip (rare) */
   4947             else
   4948                 y <<= shift;
   4949             tab4[x] = y;
   4950         }
   4951     } else {
   4952         tab4[0] = 0;
   4953         tab4[1] = tab16[1] >> shift;
   4954         tab4[2] = tab16[2] >> shift;
   4955         tab4[3] = tab16[3] >> shift;
   4956     }
   4957 
   4958     gbMask = 0;
   4959     do {
   4960         iSamp = *inbuf;
   4961         x = FASTABS(iSamp);
   4962 
   4963         if (x < 4) {
   4964             y = tab4[x];
   4965         } else  {
   4966 
   4967             if (x < 16) {
   4968                 /* result: y = Q25 (tab16 = Q25) */
   4969                 y = tab16[x];
   4970                 shift = 25 - scalei;
   4971             } else if (x < 64) {
   4972                 /* result: y = Q21 (pow43tab[j] = Q23, scalef = Q30) */
   4973                 y = pow43[x-16];
   4974                 shift = 21 - scalei;
   4975                 y = MULSHIFT32(y, scalef);
   4976             } else {
   4977                 /* normalize to [0x40000000, 0x7fffffff]
   4978                  * input x = [64, 8191] = [64, 2^13-1]
   4979                  * ranges:
   4980                  *  shift = 7:   64 -  127
   4981                  *  shift = 6:  128 -  255
   4982                  *  shift = 5:  256 -  511
   4983                  *  shift = 4:  512 - 1023
   4984                  *  shift = 3: 1024 - 2047
   4985                  *  shift = 2: 2048 - 4095
   4986                  *  shift = 1: 4096 - 8191
   4987                  */
   4988                 x <<= 17;
   4989                 shift = 0;
   4990                 if (x < 0x08000000)
   4991                     x <<= 4, shift += 4;
   4992                 if (x < 0x20000000)
   4993                     x <<= 2, shift += 2;
   4994                 if (x < 0x40000000)
   4995                     x <<= 1, shift += 1;
   4996 
   4997                 coef = (x < SQRTHALF) ? poly43lo : poly43hi;
   4998 
   4999                 /* polynomial */
   5000                 y = coef[0];
   5001                 y = MULSHIFT32(y, x) + coef[1];
   5002                 y = MULSHIFT32(y, x) + coef[2];
   5003                 y = MULSHIFT32(y, x) + coef[3];
   5004                 y = MULSHIFT32(y, x) + coef[4];
   5005                 y = MULSHIFT32(y, pow2frac[shift]) << 3;
   5006 
   5007                 /* fractional scale
   5008                  * result: y = Q21 (pow43tab[j] = Q23, scalef = Q30)
   5009                  */
   5010                 y = MULSHIFT32(y, scalef);    /* now y is Q24 */
   5011                 shift = 24 - scalei - pow2exp[shift];
   5012             }
   5013 
   5014             /* integer scale */
   5015             if (shift <= 0) {
   5016                 shift = -shift;
   5017                 if (shift > 31)
   5018                     shift = 31;
   5019 
   5020                 if (y > (0x7fffffff >> shift))
   5021                     y = 0x7fffffff;        /* clip (rare) */
   5022                 else
   5023                     y <<= shift;
   5024             } else {
   5025                 if (shift > 31)
   5026                     shift = 31;
   5027                 y >>= shift;
   5028             }
   5029         }
   5030 
   5031         /* sign and store (gbMask used to count GB's) */
   5032         gbMask |= y;
   5033 
   5034         /* apply sign */
   5035         iSamp >>= 31;
   5036         y ^= iSamp;
   5037         y -= iSamp;
   5038 
   5039         *inbuf++ = y;
   5040     } while (--nSamps);
   5041 
   5042     return gbMask;
   5043 }
   5044 
   5045 /***********************************************************************************************************************
   5046  * Function:    AACDequantize
   5047  *
   5048  * Description: dequantize all transform coefficients for one channel
   5049  *
   5050  * Inputs:      index of current channel
   5051  *
   5052  * Outputs:     dequantized coefficients, including short-block deinterleaving
   5053  *              flags indicating if intensity and/or PNS is active
   5054  *              minimum guard bit count for dequantized coefficients
   5055  *
   5056  * Return:      0 if successful, error code (< 0) if error
   5057  **********************************************************************************************************************/
   5058 int AACDequantize(int ch)
   5059 {
   5060     int gp, cb, sfb, win, width, nSamps, gbMask;
   5061     int *coef;
   5062     const uint16_t *sfbTab;
   5063     uint8_t *sfbCodeBook;
   5064     short *scaleFactors;
   5065     ICSInfo_t *icsInfo;
   5066 
   5067     icsInfo = (ch == 1 && m_PSInfoBase->commonWin == 1) ? &(m_PSInfoBase->icsInfo[0]) : &(m_PSInfoBase->icsInfo[ch]);
   5068 
   5069     if (icsInfo->winSequence == 2) {
   5070         sfbTab = sfBandTabShort + sfBandTabShortOffset[m_PSInfoBase->sampRateIdx];
   5071         nSamps = NSAMPS_SHORT;
   5072     } else {
   5073         sfbTab = sfBandTabLong + sfBandTabLongOffset[m_PSInfoBase->sampRateIdx];
   5074         nSamps = NSAMPS_LONG;
   5075     }
   5076     coef = m_PSInfoBase->coef[ch];
   5077     sfbCodeBook = m_PSInfoBase->sfbCodeBook[ch];
   5078     scaleFactors = m_PSInfoBase->scaleFactors[ch];
   5079 
   5080     m_PSInfoBase->intensityUsed[ch] = 0;
   5081     m_PSInfoBase->pnsUsed[ch] = 0;
   5082     gbMask = 0;
   5083     for (gp = 0; gp < icsInfo->numWinGroup; gp++) {
   5084         for (win = 0; win < icsInfo->winGroupLen[gp]; win++) {
   5085             for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) {
   5086                 /* dequantize one scalefactor band (not necessary if codebook is intensity or PNS)
   5087                  * for zero codebook, still run dequantizer in case non-zero pulse data was added
   5088                  */
   5089                 cb = (int)(sfbCodeBook[sfb]);
   5090                 width = sfbTab[sfb+1] - sfbTab[sfb];
   5091                 if (cb >= 0 && cb <= 11)
   5092                     gbMask |= DequantBlock(coef, width, scaleFactors[sfb]);
   5093                 else if (cb == 13)
   5094                     m_PSInfoBase->pnsUsed[ch] = 1;
   5095                 else if (cb == 14 || cb == 15)
   5096                     m_PSInfoBase->intensityUsed[ch] = 1;    /* should only happen if ch == 1 */
   5097                 coef += width;
   5098             }
   5099             coef += (nSamps - sfbTab[icsInfo->maxSFB]);
   5100         }
   5101         sfbCodeBook += icsInfo->maxSFB;
   5102         scaleFactors += icsInfo->maxSFB;
   5103     }
   5104     m_AACDecInfo->pnsUsed |= m_PSInfoBase->pnsUsed[ch];    /* set flag if PNS used for any channel */
   5105 
   5106     /* calculate number of guard bits in dequantized data */
   5107     m_PSInfoBase->gbCurrent[ch] = CLZ(gbMask) - 1;
   5108 
   5109     return ERR_AAC_NONE;
   5110 }
   5111 
   5112 /***********************************************************************************************************************
   5113  * Function:    DeinterleaveShortBlocks
   5114  *
   5115  * Description: deinterleave transform coefficients in short blocks for one channel
   5116  *
   5117  * Inputs:      index of current channel
   5118  *
   5119  * Outputs:     deinterleaved coefficients (window groups into 8 separate windows)
   5120  *
   5121  * Return:      0 if successful, error code (< 0) if error
   5122  *
   5123  * Notes:       only necessary if deinterleaving not part of Huffman decoding
   5124  **********************************************************************************************************************/
   5125 int DeinterleaveShortBlocks(int ch)
   5126 {
   5127 //    (void)aacDecInfo;
   5128 //    (void)ch;
   5129     /* not used for this implementation - short block deinterleaving performed during Huffman decoding */
   5130     return ERR_AAC_NONE;
   5131 }
   5132 
   5133 /***********************************************************************************************************************
   5134  * Function:    Get32BitVal
   5135  *
   5136  * Description: generate 32-bit unsigned random number
   5137  *
   5138  * Inputs:      last number calculated (seed, first time through)
   5139  *
   5140  * Outputs:     new number, saved in *last
   5141  *
   5142  * Return:      32-bit number, uniformly distributed between [0, 2^32)
   5143  *
   5144  * Notes:       uses simple linear congruential generator
   5145  **********************************************************************************************************************/
   5146 unsigned int Get32BitVal(unsigned int *last)
   5147 {
   5148     uint32_t r = *last;
   5149 
   5150     /* use same coefs as MPEG reference code (classic LCG)
   5151      * use unsigned multiply to force reliable wraparound behavior in C (mod 2^32)
   5152      */
   5153     r = (1664525U * r) + 1013904223U;
   5154     *last = r;
   5155 
   5156     return r;
   5157 }
   5158 
   5159 /***********************************************************************************************************************
   5160  * Function:    InvRootR
   5161  *
   5162  * Description: use Newton's method to solve for x = 1/sqrt(r)
   5163  *
   5164  * Inputs:      r in Q30 format, range = [0.25, 1] (normalize inputs to this range)
   5165  *
   5166  * Outputs:     none
   5167  *
   5168  * Return:      x = Q29, range = (1, 2)
   5169  *
   5170  * Notes:       guaranteed to converge and not overflow for any r in this range
   5171  *
   5172  *              xn+1  = xn - f(xn)/f'(xn)
   5173  *              f(x)  = 1/sqrt(r) - x = 0 (find root)
   5174  *                    = 1/x^2 - r
   5175  *              f'(x) = -2/x^3
   5176  *
   5177  *              so xn+1 = xn/2 * (3 - r*xn^2)
   5178  *
   5179  *              NUM_ITER_INVSQRT = 3, maxDiff = 1.3747e-02
   5180  *              NUM_ITER_INVSQRT = 4, maxDiff = 3.9832e-04
   5181  **********************************************************************************************************************/
   5182 int InvRootR(int r)
   5183 {
   5184     int i, xn, t;
   5185 
   5186     /* use linear equation for initial guess
   5187      * x0 = -2*r + 3 (so x0 always >= correct answer in range [0.25, 1))
   5188      * xn = Q29 (at every step)
   5189      */
   5190     xn = (MULSHIFT32(r, X0_COEF_2) << 2) + X0_OFF_2;
   5191 
   5192     for (i = 0; i < NUM_ITER_INVSQRT; i++) {
   5193         t = MULSHIFT32(xn, xn);                    /* Q26 = Q29*Q29 */
   5194         t = Q26_3 - (MULSHIFT32(r, t) << 2);    /* Q26 = Q26 - (Q31*Q26 << 1) */
   5195         xn = MULSHIFT32(xn, t) << (6 - 1);        /* Q29 = (Q29*Q26 << 6), and -1 for division by 2 */
   5196     }
   5197 
   5198     /* clip to range (1.0, 2.0)
   5199      * (because of rounding, this can converge to xn slightly > 2.0 when r is near 0.25)
   5200      */
   5201     if (xn >> 30)
   5202         xn = (1 << 30) - 1;
   5203 
   5204     return xn;
   5205 }
   5206 
   5207 /***********************************************************************************************************************
   5208  * Function:    ScaleNoiseVector
   5209  *
   5210  * Description: apply scaling to vector of noise coefficients for one scalefactor band
   5211  *
   5212  * Inputs:      unscaled coefficients
   5213  *              number of coefficients in vector (one scalefactor band of coefs)
   5214  *              scalefactor for this band (i.e. noise energy)
   5215  *
   5216  * Outputs:     nVals coefficients in Q(FBITS_OUT_DQ_OFF)
   5217  *
   5218  * Return:      guard bit mask (OR of abs value of all noise coefs)
   5219  **********************************************************************************************************************/
   5220 int ScaleNoiseVector(int *coef, int nVals, int sf)
   5221 {
   5222 
   5223 /* pow(2, i/4.0) for i = [0,1,2,3], format = Q30 */
   5224 static const int pow14[4] PROGMEM = {
   5225     0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65
   5226 };
   5227 
   5228     int i, c, spec, energy, sq, scalef, scalei, invSqrtEnergy, z, gbMask;
   5229 
   5230     energy = 0;
   5231     for (i = 0; i < nVals; i++) {
   5232         spec = coef[i];
   5233 
   5234         /* max nVals = max SFB width = 96, so energy can gain < 2^7 bits in accumulation */
   5235         sq = (spec * spec) >> 8;        /* spec*spec range = (-2^30, 2^30) */
   5236         energy += sq;
   5237     }
   5238 
   5239     /* unless nVals == 1 (or the number generator is broken...), this should not happen */
   5240     if (energy == 0)
   5241         return 0;    /* coef[i] must = 0 for i = [0, nVals-1], so gbMask = 0 */
   5242 
   5243     /* pow(2, sf/4) * pow(2, FBITS_OUT_DQ_OFF) */
   5244     scalef = pow14[sf & 0x3];
   5245     scalei = (sf >> 2) + FBITS_OUT_DQ_OFF;
   5246 
   5247     /* energy has implied factor of 2^-8 since we shifted the accumulator
   5248      * normalize energy to range [0.25, 1.0), calculate 1/sqrt(1), and denormalize
   5249      *   i.e. divide input by 2^(30-z) and convert to Q30
   5250      *        output of 1/sqrt(i) now has extra factor of 2^((30-z)/2)
   5251      *        for energy > 0, z is an even number between 0 and 28
   5252      * final scaling of invSqrtEnergy:
   5253      *  2^(15 - z/2) to compensate for implicit 2^(30-z) factor in input
   5254      *  +4 to compensate for implicit 2^-8 factor in input
   5255      */
   5256     z = CLZ(energy) - 2;                    /* energy has at least 2 leading zeros (see acc loop) */
   5257     z &= 0xfffffffe;                        /* force even */
   5258     invSqrtEnergy = InvRootR(energy << z);    /* energy << z must be in range [0x10000000, 0x40000000] */
   5259     scalei -= (15 - z/2 + 4);                /* nInt = 1/sqrt(energy) in Q29 */
   5260 
   5261     /* normalize for final scaling */
   5262     z = CLZ(invSqrtEnergy) - 1;
   5263     invSqrtEnergy <<= z;
   5264     scalei -= (z - 3 - 2);    /* -2 for scalef, z-3 for invSqrtEnergy */
   5265     scalef = MULSHIFT32(scalef, invSqrtEnergy);    /* scalef (input) = Q30, invSqrtEnergy = Q29 * 2^z */
   5266     gbMask = 0;
   5267 
   5268     if (scalei < 0) {
   5269         scalei = -scalei;
   5270         if (scalei > 31)
   5271             scalei = 31;
   5272         for (i = 0; i < nVals; i++) {
   5273             c = MULSHIFT32(coef[i], scalef) >> scalei;
   5274             gbMask |= FASTABS(c);
   5275             coef[i] = c;
   5276         }
   5277     } else {
   5278         /* for scalei <= 16, no clipping possible (coef[i] is < 2^15 before scaling)
   5279          * for scalei > 16, just saturate exponent (rare)
   5280          *   scalef is close to full-scale (since we normalized invSqrtEnergy)
   5281          * remember, we are just producing noise here
   5282          */
   5283         if (scalei > 16)
   5284             scalei = 16;
   5285         for (i = 0; i < nVals; i++) {
   5286             c = MULSHIFT32(coef[i] << scalei, scalef);
   5287             coef[i] = c;
   5288             gbMask |= FASTABS(c);
   5289         }
   5290     }
   5291 
   5292     return gbMask;
   5293 }
   5294 
   5295 /***********************************************************************************************************************
   5296  * Function:    GenerateNoiseVector
   5297  *
   5298  * Description: create vector of noise coefficients for one scalefactor band
   5299  *
   5300  * Inputs:      seed for number generator
   5301  *              number of coefficients to generate
   5302  *
   5303  * Outputs:     buffer of nVals coefficients, range = [-2^15, 2^15)
   5304  *              updated seed for number generator
   5305  *
   5306  * Return:      none
   5307  **********************************************************************************************************************/
   5308 void GenerateNoiseVector(int *coef, int *last, int nVals)
   5309 {
   5310     int i;
   5311 
   5312     for (i = 0; i < nVals; i++)
   5313         coef[i] = ((int32_t)Get32BitVal((uint32_t *)last)) >> 16;
   5314 }
   5315 
   5316 /***********************************************************************************************************************
   5317  * Function:    CopyNoiseVector
   5318  *
   5319  * Description: copy vector of noise coefficients for one scalefactor band from L to R
   5320  *
   5321  * Inputs:      buffer of left coefficients
   5322  *              number of coefficients to copy
   5323  *
   5324  * Outputs:     buffer of right coefficients
   5325  *
   5326  * Return:      none
   5327  **********************************************************************************************************************/
   5328 void CopyNoiseVector(int *coefL, int *coefR, int nVals)
   5329 {
   5330     int i;
   5331 
   5332     for (i = 0; i < nVals; i++)
   5333         coefR[i] = coefL[i];
   5334 }
   5335 
   5336 /***********************************************************************************************************************
   5337  * Function:    PNS
   5338  *
   5339  * Description: apply perceptual noise substitution, if enabled (MPEG-4 only)
   5340  *
   5341  * Inputs:      index of current channel
   5342  *
   5343  * Outputs:     shaped noise in scalefactor bands where PNS is active
   5344  *              updated minimum guard bit count for this channel
   5345  *
   5346  * Return:      0 if successful, -1 if error
   5347  **********************************************************************************************************************/
   5348 int PNS(int ch)
   5349 {
   5350     int gp, sfb, win, width, nSamps, gb, gbMask;
   5351     int *coef;
   5352     const uint16_t *sfbTab;
   5353     uint8_t *sfbCodeBook;
   5354     short *scaleFactors;
   5355     int msMaskOffset, checkCorr, genNew;
   5356     uint8_t msMask;
   5357     uint8_t *msMaskPtr;
   5358     ICSInfo_t *icsInfo;
   5359 
   5360     icsInfo = (ch == 1 && m_PSInfoBase->commonWin == 1) ? &(m_PSInfoBase->icsInfo[0]) : &(m_PSInfoBase->icsInfo[ch]);
   5361 
   5362     if (!m_PSInfoBase->pnsUsed[ch])
   5363         return 0;
   5364 
   5365     if (icsInfo->winSequence == 2) {
   5366         sfbTab = sfBandTabShort + sfBandTabShortOffset[m_PSInfoBase->sampRateIdx];
   5367         nSamps = NSAMPS_SHORT;
   5368     } else {
   5369         sfbTab = sfBandTabLong + sfBandTabLongOffset[m_PSInfoBase->sampRateIdx];
   5370         nSamps = NSAMPS_LONG;
   5371     }
   5372     coef = m_PSInfoBase->coef[ch];
   5373     sfbCodeBook = m_PSInfoBase->sfbCodeBook[ch];
   5374     scaleFactors = m_PSInfoBase->scaleFactors[ch];
   5375     checkCorr = (m_AACDecInfo->currBlockID == AAC_ID_CPE && m_PSInfoBase->commonWin == 1 ? 1 : 0);
   5376 
   5377     gbMask = 0;
   5378     for (gp = 0; gp < icsInfo->numWinGroup; gp++) {
   5379         for (win = 0; win < icsInfo->winGroupLen[gp]; win++) {
   5380             msMaskPtr = m_PSInfoBase->msMaskBits + ((gp*icsInfo->maxSFB) >> 3);
   5381             msMaskOffset = ((gp*icsInfo->maxSFB) & 0x07);
   5382             msMask = (*msMaskPtr++) >> msMaskOffset;
   5383 
   5384             for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) {
   5385                 width = sfbTab[sfb+1] - sfbTab[sfb];
   5386                 if (sfbCodeBook[sfb] == 13) {
   5387                     if (ch == 0) {
   5388                         /* generate new vector, copy into ch 1 if it's possible that the channels will be correlated
   5389                          * if ch 1 has PNS enabled for this SFB but it's uncorrelated (i.e. ms_used == 0),
   5390                          *    the copied values will be overwritten when we process ch 1
   5391                          */
   5392                         GenerateNoiseVector(coef, &m_PSInfoBase->pnsLastVal, width);
   5393                         if (checkCorr && m_PSInfoBase->sfbCodeBook[1][gp*icsInfo->maxSFB + sfb] == 13)
   5394                             CopyNoiseVector(coef, m_PSInfoBase->coef[1] + (coef - m_PSInfoBase->coef[0]), width);
   5395                     } else {
   5396                         /* generate new vector if no correlation between channels */
   5397                         genNew = 1;
   5398                         if (checkCorr && m_PSInfoBase->sfbCodeBook[0][gp*icsInfo->maxSFB + sfb] == 13) {
   5399                             if((m_PSInfoBase->msMaskPresent==1 && (msMask & 0x01)) || m_PSInfoBase->msMaskPresent == 2 )
   5400                                 genNew = 0;
   5401                         }
   5402                         if (genNew)
   5403                             GenerateNoiseVector(coef, &m_PSInfoBase->pnsLastVal, width);
   5404                     }
   5405                     gbMask |= ScaleNoiseVector(coef, width, m_PSInfoBase->scaleFactors[ch][gp*icsInfo->maxSFB + sfb]);
   5406                 }
   5407                 coef += width;
   5408 
   5409                 /* get next mask bit (should be branchless on ARM) */
   5410                 msMask >>= 1;
   5411                 if (++msMaskOffset == 8) {
   5412                     msMask = *msMaskPtr++;
   5413                     msMaskOffset = 0;
   5414                 }
   5415             }
   5416             coef += (nSamps - sfbTab[icsInfo->maxSFB]);
   5417         }
   5418         sfbCodeBook += icsInfo->maxSFB;
   5419         scaleFactors += icsInfo->maxSFB;
   5420     }
   5421 
   5422     /* update guard bit count if necessary */
   5423     gb = CLZ(gbMask) - 1;
   5424     if (m_PSInfoBase->gbCurrent[ch] > gb)
   5425         m_PSInfoBase->gbCurrent[ch] = gb;
   5426 
   5427     return 0;
   5428 }
   5429 
   5430 /***********************************************************************************************************************
   5431  * Function:    GetSampRateIdx
   5432  *
   5433  * Description: get index of given sample rate
   5434  *
   5435  * Inputs:      sample rate (in Hz)
   5436  *
   5437  * Outputs:     none
   5438  *
   5439  * Return:      index of sample rate (table 1.15 in 14496-3:2001(E))
   5440  *              -1 if sample rate not found in table
   5441  **********************************************************************************************************************/
   5442 int GetSampRateIdx(int sampRate)
   5443 {
   5444     int idx;
   5445 
   5446     for (idx = 0; idx < NUM_SAMPLE_RATES; idx++) {
   5447         if (sampRate == sampRateTab[idx])
   5448             return idx;
   5449     }
   5450 
   5451     return -1;
   5452 }
   5453 
   5454 /***********************************************************************************************************************
   5455  * Function:    StereoProcessGroup
   5456  *
   5457  * Description: apply mid-side and intensity stereo to group of transform coefficients
   5458  *
   5459  * Inputs:      dequantized transform coefficients for both channels
   5460  *              pointer to appropriate scalefactor band table
   5461  *              mid-side mask enabled flag
   5462  *              buffer with mid-side mask (one bit for each scalefactor band)
   5463  *              bit offset into mid-side mask buffer
   5464  *              max coded scalefactor band
   5465  *              buffer of codebook indices for right channel
   5466  *              buffer of scalefactors for right channel, range = [0, 256]
   5467  *
   5468  * Outputs:     updated transform coefficients in Q(FBITS_OUT_DQ_OFF)
   5469  *              updated minimum guard bit count for both channels
   5470  *
   5471  * Return:      none
   5472  *
   5473  * Notes:       assume no guard bits in input
   5474  *              gains 0 int bits
   5475  **********************************************************************************************************************/
   5476 void StereoProcessGroup(int *coefL, int *coefR, const uint16_t *sfbTab,
   5477                               int msMaskPres, uint8_t *msMaskPtr, int msMaskOffset, int maxSFB,
   5478                               uint8_t *cbRight, short *sfRight, int *gbCurrent)
   5479 {
   5480 //fb
   5481 static const uint32_t pow14[2][4] PROGMEM = {
   5482     { 0xc0000000, 0xb3e407d7, 0xa57d8666, 0x945d819b },
   5483     { 0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65 }
   5484 };
   5485 
   5486     int sfb, width, cbIdx, sf, cl, cr, scalef, scalei;
   5487     int gbMaskL, gbMaskR;
   5488     uint8_t msMask;
   5489 
   5490     msMask = (*msMaskPtr++) >> msMaskOffset;
   5491     gbMaskL = 0;
   5492     gbMaskR = 0;
   5493 
   5494     for (sfb = 0; sfb < maxSFB; sfb++) {
   5495         width = sfbTab[sfb+1] - sfbTab[sfb];    /* assume >= 0 (see sfBandTabLong/sfBandTabShort) */
   5496         cbIdx = cbRight[sfb];
   5497 
   5498         if (cbIdx == 14 || cbIdx == 15) {
   5499             /* intensity stereo */
   5500             if (msMaskPres == 1 && (msMask & 0x01))
   5501                 cbIdx ^= 0x01;                /* invert_intensity(): 14 becomes 15, or 15 becomes 14 */
   5502             sf = -sfRight[sfb];                /* negative since we use identity 0.5^(x) = 2^(-x) (see spec) */
   5503             cbIdx &= 0x01;                    /* choose - or + scale factor */
   5504             scalef = pow14[cbIdx][sf & 0x03];
   5505             scalei = (sf >> 2) + 2;            /* +2 to compensate for scalef = Q30 */
   5506 
   5507             if (scalei > 0) {
   5508                 if (scalei > 30)
   5509                     scalei = 30;
   5510                 do {
   5511                     cr = MULSHIFT32(*coefL++, scalef);
   5512                     {int sign = (cr) >> 31; if (sign != (cr) >> (31-scalei))  {(cr) = sign ^ ((1 << (31-scalei)) - 1);}}
   5513                     cr <<= scalei;
   5514                     gbMaskR |= FASTABS(cr);
   5515                     *coefR++ = cr;
   5516                 } while (--width);
   5517             } else {
   5518                 scalei = -scalei;
   5519                 if (scalei > 31)
   5520                     scalei = 31;
   5521                 do {
   5522                     cr = MULSHIFT32(*coefL++, scalef) >> scalei;
   5523                     gbMaskR |= FASTABS(cr);
   5524                     *coefR++ = cr;
   5525                 } while (--width);
   5526             }
   5527         } else if ( cbIdx != 13 && ((msMaskPres == 1 && (msMask & 0x01)) || msMaskPres == 2) ) {
   5528             /* mid-side stereo (assumes no GB in inputs) */
   5529             do {
   5530                 cl = *coefL;
   5531                 cr = *coefR;
   5532 
   5533                 if ( (FASTABS(cl) | FASTABS(cr)) >> 30 ) {
   5534                     /* avoid overflow (rare) */
   5535                     cl >>= 1;
   5536                     sf = cl + (cr >> 1);
   5537                     {int sign = (sf) >> 31; if (sign != (sf) >> (30))  {(sf) = sign ^ ((1 << (30)) - 1);}}
   5538                     sf <<= 1;
   5539                     cl = cl - (cr >> 1);
   5540                     {int sign = (cl) >> 31; if (sign != (cl) >> (30))  {(cl) = sign ^ ((1 << (30)) - 1);}}
   5541                     cl <<= 1;
   5542                 } else {
   5543                     /* usual case */
   5544                     sf = cl + cr;
   5545                     cl -= cr;
   5546                 }
   5547 
   5548                 *coefL++ = sf;
   5549                 gbMaskL |= FASTABS(sf);
   5550                 *coefR++ = cl;
   5551                 gbMaskR |= FASTABS(cl);
   5552             } while (--width);
   5553 
   5554         } else {
   5555             /* nothing to do */
   5556             coefL += width;
   5557             coefR += width;
   5558         }
   5559 
   5560         /* get next mask bit (should be branchless on ARM) */
   5561         msMask >>= 1;
   5562         if (++msMaskOffset == 8) {
   5563             msMask = *msMaskPtr++;
   5564             msMaskOffset = 0;
   5565         }
   5566     }
   5567 
   5568     cl = CLZ(gbMaskL) - 1;
   5569     if (gbCurrent[0] > cl)
   5570         gbCurrent[0] = cl;
   5571 
   5572     cr = CLZ(gbMaskR) - 1;
   5573     if (gbCurrent[1] > cr)
   5574         gbCurrent[1] = cr;
   5575 
   5576     return;
   5577 }
   5578 
   5579 /***********************************************************************************************************************
   5580  * Function:    StereoProcess
   5581  *
   5582  * Description: apply mid-side and intensity stereo, if enabled
   5583  *
   5584  * Inputs:      none
   5585  *
   5586  * Outputs:     updated transform coefficients in Q(FBITS_OUT_DQ_OFF)
   5587  *              updated minimum guard bit count for both channels
   5588  *
   5589  * Return:      0 if successful, -1 if error
   5590  **********************************************************************************************************************/
   5591 int StereoProcess()
   5592 {
   5593     ICSInfo_t *icsInfo;
   5594     int gp, win, nSamps, msMaskOffset;
   5595     int *coefL, *coefR;
   5596     uint8_t *msMaskPtr;
   5597     const uint16_t *sfbTab;
   5598 
   5599 
   5600     /* mid-side and intensity stereo require common_window == 1 (see MPEG4 spec, Correction 2, 2004) */
   5601     if (m_PSInfoBase->commonWin != 1 || m_AACDecInfo->currBlockID != AAC_ID_CPE)
   5602         return 0;
   5603 
   5604     /* nothing to do */
   5605     if (!m_PSInfoBase->msMaskPresent && !m_PSInfoBase->intensityUsed[1])
   5606         return 0;
   5607 
   5608     icsInfo = &(m_PSInfoBase->icsInfo[0]);
   5609     if (icsInfo->winSequence == 2) {
   5610         sfbTab = sfBandTabShort + sfBandTabShortOffset[m_PSInfoBase->sampRateIdx];
   5611         nSamps = NSAMPS_SHORT;
   5612     } else {
   5613         sfbTab = sfBandTabLong + sfBandTabLongOffset[m_PSInfoBase->sampRateIdx];
   5614         nSamps = NSAMPS_LONG;
   5615     }
   5616     coefL = m_PSInfoBase->coef[0];
   5617     coefR = m_PSInfoBase->coef[1];
   5618 
   5619     /* do fused mid-side/intensity processing for each block (one long or eight short) */
   5620     msMaskOffset = 0;
   5621     msMaskPtr = m_PSInfoBase->msMaskBits;
   5622     for (gp = 0; gp < icsInfo->numWinGroup; gp++) {
   5623         for (win = 0; win < icsInfo->winGroupLen[gp]; win++) {
   5624             StereoProcessGroup(coefL, coefR, sfbTab, m_PSInfoBase->msMaskPresent,
   5625                 msMaskPtr, msMaskOffset, icsInfo->maxSFB, m_PSInfoBase->sfbCodeBook[1] + gp*icsInfo->maxSFB,
   5626                 m_PSInfoBase->scaleFactors[1] + gp*icsInfo->maxSFB, m_PSInfoBase->gbCurrent);
   5627             coefL += nSamps;
   5628             coefR += nSamps;
   5629         }
   5630         /* we use one bit per sfb, so there are maxSFB bits for each window group */
   5631         msMaskPtr += (msMaskOffset + icsInfo->maxSFB) >> 3;
   5632         msMaskOffset = (msMaskOffset + icsInfo->maxSFB) & 0x07;
   5633     }
   5634 
   5635     ASSERT(coefL == m_PSInfoBase->coef[0] + 1024);
   5636     ASSERT(coefR == m_PSInfoBase->coef[1] + 1024);
   5637 
   5638     return 0;
   5639 }
   5640 
   5641 /***********************************************************************************************************************
   5642  * Function:    RatioPowInv
   5643  *
   5644  * Description: use Taylor (MacLaurin) series expansion to calculate (a/b) ^ (1/c)
   5645  *
   5646  * Inputs:      a = [1, 64], b = [1, 64], c = [1, 64], a >= b
   5647  *
   5648  * Outputs:     none
   5649  *
   5650  * Return:      y = Q24, range ~= [0.015625, 64]
   5651  **********************************************************************************************************************/
   5652 int RatioPowInv(int a, int b, int c)
   5653 {
   5654     int lna, lnb, i, p, t, y;
   5655 
   5656     if (a < 1 || b < 1 || c < 1 || a > 64 || b > 64 || c > 64 || a < b)
   5657         return 0;
   5658 
   5659     lna = MULSHIFT32(log2Tab[a], LOG2_EXP_INV) << 1;    /* ln(a), Q28 */
   5660     lnb = MULSHIFT32(log2Tab[b], LOG2_EXP_INV) << 1;    /* ln(b), Q28 */
   5661     p = (lna - lnb) / c;    /* Q28 */
   5662 
   5663     /* sum in Q24 */
   5664     y = (1 << 24);
   5665     t = p >> 4;        /* t = p^1 * 1/1! (Q24)*/
   5666     y += t;
   5667 
   5668     for (i = 2; i <= NUM_TERMS_RPI; i++) {
   5669         t = MULSHIFT32(invTab[i-1], t) << 2;
   5670         t = MULSHIFT32(p, t) << 4;    /* t = p^i * 1/i! (Q24) */
   5671         y += t;
   5672     }
   5673 
   5674     return y;
   5675 }
   5676 
   5677 /***********************************************************************************************************************
   5678  * Function:    SqrtFix
   5679  *
   5680  * Description: use binary search to calculate sqrt(q)
   5681  *
   5682  * Inputs:      q = Q30
   5683  *              number of fraction bits in input
   5684  *
   5685  * Outputs:     number of fraction bits in output
   5686  *
   5687  * Return:      lo = Q(fBitsOut)
   5688  *
   5689  * Notes:       absolute precision varies depending on fBitsIn
   5690  *              normalizes input to range [0x200000000, 0x7fffffff] and takes
   5691  *                floor(sqrt(input)), and sets fBitsOut appropriately
   5692  **********************************************************************************************************************/
   5693 int SqrtFix(int q, int fBitsIn, int *fBitsOut)
   5694 {
   5695     int z, lo, hi, mid;
   5696 
   5697     if (q <= 0) {
   5698         *fBitsOut = fBitsIn;
   5699         return 0;
   5700     }
   5701 
   5702     /* force even fBitsIn */
   5703     z = fBitsIn & 0x01;
   5704     q >>= z;
   5705     fBitsIn -= z;
   5706 
   5707     /* for max precision, normalize to [0x20000000, 0x7fffffff] */
   5708     z = (CLZ(q) - 1);
   5709     z >>= 1;
   5710     q <<= (2*z);
   5711 
   5712     /* choose initial bounds */
   5713     lo = 1;
   5714     if (q >= 0x10000000)
   5715         lo = 16384;    /* (int)sqrt(0x10000000) */
   5716     hi = 46340;        /* (int)sqrt(0x7fffffff) */
   5717 
   5718     /* do binary search with 32x32->32 multiply test */
   5719     do {
   5720         mid = (lo + hi) >> 1;
   5721         if (mid*mid > q)
   5722             hi = mid - 1;
   5723         else
   5724             lo = mid + 1;
   5725     } while (hi >= lo);
   5726     lo--;
   5727 
   5728     *fBitsOut = ((fBitsIn + 2*z) >> 1);
   5729     return lo;
   5730 }
   5731 
   5732 /***********************************************************************************************************************
   5733  * Function:    InvRNormalized
   5734  *
   5735  * Description: use Newton's method to solve for x = 1/r
   5736  *
   5737  * Inputs:      r = Q31, range = [0.5, 1) (normalize your inputs to this range)
   5738  *
   5739  * Outputs:     none
   5740  *
   5741  * Return:      x = Q29, range ~= [1.0, 2.0]
   5742  *
   5743  * Notes:       guaranteed to converge and not overflow for any r in [0.5, 1)
   5744  *
   5745  *              xn+1  = xn - f(xn)/f'(xn)
   5746  *              f(x)  = 1/r - x = 0 (find root)
   5747  *                    = 1/x - r
   5748  *              f'(x) = -1/x^2
   5749  *
   5750  *              so xn+1 = xn - (1/xn - r) / (-1/xn^2)
   5751  *                      = xn * (2 - r*xn)
   5752  *
   5753  *              NUM_ITER_IRN = 2, maxDiff = 6.2500e-02 (precision of about 4 bits)
   5754  *              NUM_ITER_IRN = 3, maxDiff = 3.9063e-03 (precision of about 8 bits)
   5755  *              NUM_ITER_IRN = 4, maxDiff = 1.5288e-05 (precision of about 16 bits)
   5756  *              NUM_ITER_IRN = 5, maxDiff = 3.0034e-08 (precision of about 24 bits)
   5757  **********************************************************************************************************************/
   5758 int InvRNormalized(int r)
   5759 {
   5760     int i, xn, t;
   5761 
   5762     /* r =   [0.5, 1.0)
   5763      * 1/r = (1.0, 2.0]
   5764      *   so use 1.5 as initial guess
   5765      */
   5766     xn = Q28_15;
   5767 
   5768     /* xn = xn*(2.0 - r*xn) */
   5769     for (i = NUM_ITER_IRN; i != 0; i--) {
   5770         t = MULSHIFT32(r, xn);            /* Q31*Q29 = Q28 */
   5771         t = Q28_2 - t;                    /* Q28 */
   5772         xn = MULSHIFT32(xn, t) << 4;    /* Q29*Q28 << 4 = Q29 */
   5773     }
   5774 
   5775     return xn;
   5776 }
   5777 
   5778 
   5779 
   5780 /***********************************************************************************************************************
   5781  * Function:    BitReverse32
   5782  *
   5783  * Description: Ken's fast in-place bit reverse
   5784  *
   5785  * Inputs:      buffer of 32 complex samples
   5786  *
   5787  * Outputs:     bit-reversed samples in same buffer
   5788  *
   5789  * Return:      none
   5790 ***********************************************************************************************************************/
   5791 void BitReverse32(int *inout)
   5792 {
   5793     int t;
   5794     t=inout[2] ; inout[2]=inout[32]; inout[32]=t;
   5795     t=inout[3] ; inout[3]=inout[33]; inout[33]=t;
   5796 
   5797     t=inout[4] ; inout[4]=inout[16]; inout[16]=t;
   5798     t=inout[5] ; inout[5]=inout[17]; inout[17]=t;
   5799 
   5800     t=inout[6] ; inout[6]=inout[48]; inout[48]=t;
   5801     t=inout[7] ; inout[7]=inout[49]; inout[49]=t;
   5802 
   5803     t=inout[10]; inout[10]=inout[40]; inout[40]=t;
   5804     t=inout[11]; inout[11]=inout[41]; inout[41]=t;
   5805 
   5806     t=inout[12]; inout[12]=inout[24]; inout[24]=t;
   5807     t=inout[13]; inout[13]=inout[25]; inout[25]=t;
   5808 
   5809     t=inout[14]; inout[14]=inout[56]; inout[56]=t;
   5810     t=inout[15]; inout[15]=inout[57]; inout[57]=t;
   5811 
   5812     t=inout[18]; inout[18]=inout[36]; inout[36]=t;
   5813     t=inout[19]; inout[19]=inout[37]; inout[37]=t;
   5814 
   5815     t=inout[22]; inout[22]=inout[52]; inout[52]=t;
   5816     t=inout[23]; inout[23]=inout[53]; inout[53]=t;
   5817 
   5818     t=inout[26]; inout[26]=inout[44]; inout[44]=t;
   5819     t=inout[27]; inout[27]=inout[45]; inout[45]=t;
   5820 
   5821     t=inout[30]; inout[30]=inout[60]; inout[60]=t;
   5822     t=inout[31]; inout[31]=inout[61]; inout[61]=t;
   5823 
   5824     t=inout[38]; inout[38]=inout[50]; inout[50]=t;
   5825     t=inout[39]; inout[39]=inout[51]; inout[51]=t;
   5826 
   5827     t=inout[46]; inout[46]=inout[58]; inout[58]=t;
   5828     t=inout[47]; inout[47]=inout[59]; inout[59]=t;
   5829 
   5830 }
   5831 
   5832 /***********************************************************************************************************************
   5833  * Function:    R8FirstPass32
   5834  *
   5835  * Description: radix-8 trivial pass for decimation-in-time FFT (log2(N) = 5)
   5836  *
   5837  * Inputs:      buffer of (bit-reversed) samples
   5838  *
   5839  * Outputs:     processed samples in same buffer
   5840  *
   5841  * Return:      none
   5842  *
   5843  * Notes:       assumes 3 guard bits, gains 1 integer bit
   5844  *              guard bits out = guard bits in - 3 (if inputs are full scale)
   5845  *                or guard bits in - 2 (if inputs bounded to +/- sqrt(2)/2)
   5846  *              see scaling comments in fft.c for base AAC
   5847  *              should compile with no stack spills on ARM (verify compiled output)
   5848  *              current instruction count (per pass): 16 LDR, 16 STR, 4 SMULL, 61 ALU
   5849  **********************************************************************************************************************/
   5850 void R8FirstPass32(int *r0)
   5851 {
   5852     int r1, r2, r3, r4, r5, r6, r7;
   5853     int r8, r9, r10, r11, r12, r14;
   5854 
   5855     /* number of passes = fft size / 8 = 32 / 8 = 4 */
   5856     r1 = (32 >> 3);
   5857     do {
   5858 
   5859         r2 = r0[8];
   5860         r3 = r0[9];
   5861         r4 = r0[10];
   5862         r5 = r0[11];
   5863         r6 = r0[12];
   5864         r7 = r0[13];
   5865         r8 = r0[14];
   5866         r9 = r0[15];
   5867 
   5868         r10 = r2 + r4;
   5869         r11 = r3 + r5;
   5870         r12 = r6 + r8;
   5871         r14 = r7 + r9;
   5872 
   5873         r2 -= r4;
   5874         r3 -= r5;
   5875         r6 -= r8;
   5876         r7 -= r9;
   5877 
   5878         r4 = r2 - r7;
   5879         r5 = r2 + r7;
   5880         r8 = r3 - r6;
   5881         r9 = r3 + r6;
   5882 
   5883         r2 = r4 - r9;
   5884         r3 = r4 + r9;
   5885         r6 = r5 - r8;
   5886         r7 = r5 + r8;
   5887 
   5888         r2 = MULSHIFT32(SQRTHALF, r2);    /* can use r4, r5, r8, or r9 for constant and lo32 scratch reg */
   5889         r3 = MULSHIFT32(SQRTHALF, r3);
   5890         r6 = MULSHIFT32(SQRTHALF, r6);
   5891         r7 = MULSHIFT32(SQRTHALF, r7);
   5892 
   5893         r4 = r10 + r12;
   5894         r5 = r10 - r12;
   5895         r8 = r11 + r14;
   5896         r9 = r11 - r14;
   5897 
   5898         r10 = r0[0];
   5899         r11 = r0[2];
   5900         r12 = r0[4];
   5901         r14 = r0[6];
   5902 
   5903         r10 += r11;
   5904         r12 += r14;
   5905 
   5906         r4 >>= 1;
   5907         r10 += r12;
   5908         r4 += (r10 >> 1);
   5909         r0[ 0] = r4;
   5910         r4 -= (r10 >> 1);
   5911         r4 = (r10 >> 1) - r4;
   5912         r0[ 8] = r4;
   5913 
   5914         r9 >>= 1;
   5915         r10 -= 2*r12;
   5916         r4 = (r10 >> 1) + r9;
   5917         r0[ 4] = r4;
   5918         r4 = (r10 >> 1) - r9;
   5919         r0[12] = r4;
   5920         r10 += r12;
   5921 
   5922         r10 -= 2*r11;
   5923         r12 -= 2*r14;
   5924 
   5925         r4 =  r0[1];
   5926         r9 =  r0[3];
   5927         r11 = r0[5];
   5928         r14 = r0[7];
   5929 
   5930         r4 += r9;
   5931         r11 += r14;
   5932 
   5933         r8 >>= 1;
   5934         r4 += r11;
   5935         r8 += (r4 >> 1);
   5936         r0[ 1] = r8;
   5937         r8 -= (r4 >> 1);
   5938         r8 = (r4 >> 1) - r8;
   5939         r0[ 9] = r8;
   5940 
   5941         r5 >>= 1;
   5942         r4 -= 2*r11;
   5943         r8 = (r4 >> 1) - r5;
   5944         r0[ 5] = r8;
   5945         r8 = (r4 >> 1) + r5;
   5946         r0[13] = r8;
   5947         r4 += r11;
   5948 
   5949         r4 -= 2*r9;
   5950         r11 -= 2*r14;
   5951 
   5952         r9 = r10 - r11;
   5953         r10 += r11;
   5954         r14 = r4 + r12;
   5955         r4 -= r12;
   5956 
   5957         r5 = (r10 >> 1) + r7;
   5958         r8 = (r4 >> 1) - r6;
   5959         r0[ 2] = r5;
   5960         r0[ 3] = r8;
   5961 
   5962         r5 = (r9 >> 1) - r2;
   5963         r8 = (r14 >> 1) - r3;
   5964         r0[ 6] = r5;
   5965         r0[ 7] = r8;
   5966 
   5967         r5 = (r10 >> 1) - r7;
   5968         r8 = (r4 >> 1) + r6;
   5969         r0[10] = r5;
   5970         r0[11] = r8;
   5971 
   5972         r5 = (r9 >> 1) + r2;
   5973         r8 = (r14 >> 1) + r3;
   5974         r0[14] = r5;
   5975         r0[15] = r8;
   5976 
   5977         r0 += 16;
   5978         r1--;
   5979     } while (r1 != 0);
   5980 }
   5981 
   5982 /***********************************************************************************************************************
   5983  * Function:    R4Core32
   5984  *
   5985  * Description: radix-4 pass for 32-point decimation-in-time FFT
   5986  *
   5987  * Inputs:      buffer of samples
   5988  *
   5989  * Outputs:     processed samples in same buffer
   5990  *
   5991  * Return:      none
   5992  *
   5993  * Notes:       gain 2 integer bits
   5994  *              guard bits out = guard bits in - 1 (if inputs are full scale)
   5995  *              see scaling comments in fft.c for base AAC
   5996  *              uses 3-mul, 3-add butterflies instead of 4-mul, 2-add
   5997  *              should compile with no stack spills on ARM (verify compiled output)
   5998  *              current instruction count (per pass): 16 LDR, 16 STR, 4 SMULL, 61 ALU
   5999  **********************************************************************************************************************/
   6000 void R4Core32(int *r0)
   6001 {
   6002     int r2, r3, r4, r5, r6, r7;
   6003     int r8, r9, r10, r12, r14;
   6004     int *r1;
   6005 
   6006     r1 = (int *)twidTabOdd32;
   6007     r10 = 8;
   6008     do {
   6009         /* can use r14 for lo32 scratch register in all MULSHIFT32 */
   6010         r2 = r1[0];
   6011         r3 = r1[1];
   6012         r4 = r0[16];
   6013         r5 = r0[17];
   6014         r12 = r4 + r5;
   6015         r12 = MULSHIFT32(r3, r12);
   6016         r5  = MULSHIFT32(r2, r5) + r12;
   6017         r2 += 2*r3;
   6018         r4  = MULSHIFT32(r2, r4) - r12;
   6019 
   6020         r2 = r1[2];
   6021         r3 = r1[3];
   6022         r6 = r0[32];
   6023         r7 = r0[33];
   6024         r12 = r6 + r7;
   6025         r12 = MULSHIFT32(r3, r12);
   6026         r7  = MULSHIFT32(r2, r7) + r12;
   6027         r2 += 2*r3;
   6028         r6  = MULSHIFT32(r2, r6) - r12;
   6029 
   6030         r2 = r1[4];
   6031         r3 = r1[5];
   6032         r8 = r0[48];
   6033         r9 = r0[49];
   6034         r12 = r8 + r9;
   6035         r12 = MULSHIFT32(r3, r12);
   6036         r9  = MULSHIFT32(r2, r9) + r12;
   6037         r2 += 2*r3;
   6038         r8  = MULSHIFT32(r2, r8) - r12;
   6039 
   6040         r2 = r0[0];
   6041         r3 = r0[1];
   6042 
   6043         r12 = r6 + r8;
   6044         r8  = r6 - r8;
   6045         r14 = r9 - r7;
   6046         r9  = r9 + r7;
   6047 
   6048         r6 = (r2 >> 2) - r4;
   6049         r7 = (r3 >> 2) - r5;
   6050         r4 += (r2 >> 2);
   6051         r5 += (r3 >> 2);
   6052 
   6053         r2 = r4 + r12;
   6054         r3 = r5 + r9;
   6055         r0[0] = r2;
   6056         r0[1] = r3;
   6057         r2 = r6 - r14;
   6058         r3 = r7 - r8;
   6059         r0[16] = r2;
   6060         r0[17] = r3;
   6061         r2 = r4 - r12;
   6062         r3 = r5 - r9;
   6063         r0[32] = r2;
   6064         r0[33] = r3;
   6065         r2 = r6 + r14;
   6066         r3 = r7 + r8;
   6067         r0[48] = r2;
   6068         r0[49] = r3;
   6069 
   6070         r0 += 2;
   6071         r1 += 6;
   6072         r10--;
   6073     } while (r10 != 0);
   6074 }
   6075 
   6076 /***********************************************************************************************************************
   6077  * Function:    FFT32C
   6078  *
   6079  * Description: Ken's very fast in-place radix-4 decimation-in-time FFT
   6080  *
   6081  * Inputs:      buffer of 32 complex samples (before bit-reversal)
   6082  *
   6083  * Outputs:     processed samples in same buffer
   6084  *
   6085  * Return:      none
   6086  *
   6087  * Notes:       assumes 3 guard bits in, gains 3 integer bits
   6088  *              guard bits out = guard bits in - 2
   6089  *              (guard bit analysis includes assumptions about steps immediately
   6090  *               before and after, i.e. PreMul and PostMul for DCT)
   6091  **********************************************************************************************************************/
   6092 void FFT32C(int *x)
   6093 {
   6094     /* decimation in time */
   6095     BitReverse32(x);
   6096 
   6097     /* 32-point complex FFT */
   6098     R8FirstPass32(x);    /* gain 1 int bit,  lose 2 GB (making assumptions about input) */
   6099     R4Core32(x);        /* gain 2 int bits, lose 0 GB (making assumptions about input) */
   6100 }
   6101 
   6102 /***********************************************************************************************************************
   6103  * Function:    CVKernel1
   6104  *
   6105  * Description: kernel of covariance matrix calculation for p01, p11, p12, p22
   6106  *
   6107  * Inputs:      buffer of low-freq samples, starting at time index = 0,
   6108  *                freq index = patch subband
   6109  *
   6110  * Outputs:     64-bit accumulators for p01re, p01im, p12re, p12im, p11re, p22re
   6111  *                stored in accBuf
   6112  *
   6113  * Return:      none
   6114  *
   6115  * Notes:       this is carefully written to be efficient on ARM
   6116  *              use the assembly code version in sbrcov.s when building for ARM!
   6117  **********************************************************************************************************************/
   6118 void CVKernel1(int *XBuf, int *accBuf)
   6119 {
   6120     U64 p01re, p01im, p12re, p12im, p11re, p22re;
   6121     int n, x0re, x0im, x1re, x1im;
   6122 
   6123     x0re = XBuf[0];
   6124     x0im = XBuf[1];
   6125     XBuf += (2*64);
   6126     x1re = XBuf[0];
   6127     x1im = XBuf[1];
   6128     XBuf += (2*64);
   6129 
   6130     p01re.w64 = p01im.w64 = 0;
   6131     p12re.w64 = p12im.w64 = 0;
   6132     p11re.w64 = 0;
   6133     p22re.w64 = 0;
   6134 
   6135     p12re.w64 = MADD64(p12re.w64,  x1re, x0re);
   6136     p12re.w64 = MADD64(p12re.w64,  x1im, x0im);
   6137     p12im.w64 = MADD64(p12im.w64,  x0re, x1im);
   6138     p12im.w64 = MADD64(p12im.w64, -x0im, x1re);
   6139     p22re.w64 = MADD64(p22re.w64,  x0re, x0re);
   6140     p22re.w64 = MADD64(p22re.w64,  x0im, x0im);
   6141     for (n = (NUM_TIME_SLOTS*SAMPLES_PER_SLOT + 6); n != 0; n--) {
   6142         /* 4 input, 3*2 acc, 1 ptr, 1 loop counter = 12 registers (use same for x0im, -x0im) */
   6143         x0re = x1re;
   6144         x0im = x1im;
   6145         x1re = XBuf[0];
   6146         x1im = XBuf[1];
   6147 
   6148         p01re.w64 = MADD64(p01re.w64,  x1re, x0re);
   6149         p01re.w64 = MADD64(p01re.w64,  x1im, x0im);
   6150         p01im.w64 = MADD64(p01im.w64,  x0re, x1im);
   6151         p01im.w64 = MADD64(p01im.w64, -x0im, x1re);
   6152         p11re.w64 = MADD64(p11re.w64,  x0re, x0re);
   6153         p11re.w64 = MADD64(p11re.w64,  x0im, x0im);
   6154 
   6155         XBuf += (2*64);
   6156     }
   6157     /* these can be derived by slight changes to account for boundary conditions */
   6158     p12re.w64 += p01re.w64;
   6159     p12re.w64 = MADD64(p12re.w64, x1re, -x0re);
   6160     p12re.w64 = MADD64(p12re.w64, x1im, -x0im);
   6161     p12im.w64 += p01im.w64;
   6162     p12im.w64 = MADD64(p12im.w64, x0re, -x1im);
   6163     p12im.w64 = MADD64(p12im.w64, x0im,  x1re);
   6164     p22re.w64 += p11re.w64;
   6165     p22re.w64 = MADD64(p22re.w64, x0re, -x0re);
   6166     p22re.w64 = MADD64(p22re.w64, x0im, -x0im);
   6167 
   6168     accBuf[0]  = p01re.r.lo32;    accBuf[1]  = p01re.r.hi32;
   6169     accBuf[2]  = p01im.r.lo32;    accBuf[3]  = p01im.r.hi32;
   6170     accBuf[4]  = p11re.r.lo32;    accBuf[5]  = p11re.r.hi32;
   6171     accBuf[6]  = p12re.r.lo32;    accBuf[7]  = p12re.r.hi32;
   6172     accBuf[8]  = p12im.r.lo32;    accBuf[9]  = p12im.r.hi32;
   6173     accBuf[10] = p22re.r.lo32;    accBuf[11] = p22re.r.hi32;
   6174 }
   6175 
   6176 /***********************************************************************************************************************
   6177  * Function:    CVKernel2
   6178  *
   6179  * Description: kernel of covariance matrix calculation for p02
   6180  *
   6181  * Inputs:      buffer of low-freq samples, starting at time index = 0,
   6182  *                freq index = patch subband
   6183  *
   6184  * Outputs:     64-bit accumulators for p02re, p02im stored in accBuf
   6185  *
   6186  * Return:      none
   6187  *
   6188  * Notes:       this is carefully written to be efficient on ARM
   6189  *              use the assembly code version in sbrcov.s when building for ARM!
   6190  **********************************************************************************************************************/
   6191 void CVKernel2(int *XBuf, int *accBuf)
   6192 {
   6193     U64 p02re, p02im;
   6194     int n, x0re, x0im, x1re, x1im, x2re, x2im;
   6195 
   6196     p02re.w64 = p02im.w64 = 0;
   6197 
   6198     x0re = XBuf[0];
   6199     x0im = XBuf[1];
   6200     XBuf += (2*64);
   6201     x1re = XBuf[0];
   6202     x1im = XBuf[1];
   6203     XBuf += (2*64);
   6204 
   6205     for (n = (NUM_TIME_SLOTS*SAMPLES_PER_SLOT + 6); n != 0; n--) {
   6206         /* 6 input, 2*2 acc, 1 ptr, 1 loop counter = 12 registers (use same for x0im, -x0im) */
   6207         x2re = XBuf[0];
   6208         x2im = XBuf[1];
   6209 
   6210         p02re.w64 = MADD64(p02re.w64,  x2re, x0re);
   6211         p02re.w64 = MADD64(p02re.w64,  x2im, x0im);
   6212         p02im.w64 = MADD64(p02im.w64,  x0re, x2im);
   6213         p02im.w64 = MADD64(p02im.w64, -x0im, x2re);
   6214 
   6215         x0re = x1re;
   6216         x0im = x1im;
   6217         x1re = x2re;
   6218         x1im = x2im;
   6219         XBuf += (2*64);
   6220     }
   6221 
   6222     accBuf[0] = p02re.r.lo32;
   6223     accBuf[1] = p02re.r.hi32;
   6224     accBuf[2] = p02im.r.lo32;
   6225     accBuf[3] = p02im.r.hi32;
   6226 }
   6227 
   6228 /***********************************************************************************************************************
   6229  * Function:    SetBitstreamPointer
   6230  *
   6231  * Description: initialize bitstream reader
   6232  *
   6233  * Inputs:      number of bytes in bitstream
   6234  *              pointer to byte-aligned buffer of data to read from
   6235  *
   6236  * Outputs:     initialized bitstream info struct
   6237  *
   6238  * Return:      none
   6239  **********************************************************************************************************************/
   6240 void SetBitstreamPointer(int nBytes, uint8_t *buf)
   6241 {
   6242     /* init bitstream */
   6243     m_aac_BitStreamInfo.bytePtr = buf;
   6244     m_aac_BitStreamInfo.iCache = 0;        /* 4-byte uint32_t */
   6245     m_aac_BitStreamInfo.cachedBits = 0;    /* i.e. zero bits in cache */
   6246     m_aac_BitStreamInfo.nBytes = nBytes;
   6247 }
   6248 
   6249 /***********************************************************************************************************************
   6250  * Function:    RefillBitstreamCache
   6251  *
   6252  * Description: read new data from bitstream buffer into 32-bit cache
   6253  *
   6254  * Inputs:      none
   6255  *
   6256  * Outputs:     updated bitstream info struct
   6257  *
   6258  * Return:      none
   6259  *
   6260  * Notes:       only call when iCache is completely drained (resets bitOffset to 0)
   6261  *              always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer)
   6262  *              stores data as big-endian in cache, regardless of machine endian-ness
   6263  **********************************************************************************************************************/
   6264 //Optimized for REV16, REV32 (FB)
   6265 inline void RefillBitstreamCache()
   6266 {
   6267     int nBytes = m_aac_BitStreamInfo.nBytes;
   6268     if (nBytes >= 4) {
   6269         /* optimize for common case, independent of machine endian-ness */
   6270         m_aac_BitStreamInfo.iCache  = (*m_aac_BitStreamInfo.bytePtr++) << 24;
   6271         m_aac_BitStreamInfo.iCache |= (*m_aac_BitStreamInfo.bytePtr++) << 16;
   6272         m_aac_BitStreamInfo.iCache |= (*m_aac_BitStreamInfo.bytePtr++) <<  8;
   6273         m_aac_BitStreamInfo.iCache |= (*m_aac_BitStreamInfo.bytePtr++);
   6274 
   6275         m_aac_BitStreamInfo.cachedBits = 32;
   6276         m_aac_BitStreamInfo.nBytes -= 4;
   6277     } else {
   6278         m_aac_BitStreamInfo.iCache = 0;
   6279         while (nBytes--) {
   6280             m_aac_BitStreamInfo.iCache |= (*m_aac_BitStreamInfo.bytePtr++);
   6281             m_aac_BitStreamInfo.iCache <<= 8;
   6282         }
   6283         m_aac_BitStreamInfo.iCache <<= ((3 - m_aac_BitStreamInfo.nBytes)*8);
   6284         m_aac_BitStreamInfo.cachedBits = 8*m_aac_BitStreamInfo.nBytes;
   6285         m_aac_BitStreamInfo.nBytes = 0;
   6286     }
   6287 }
   6288 
   6289 /***********************************************************************************************************************
   6290  * Function:    GetBits
   6291  *
   6292  * Description: get bits from bitstream, advance bitstream pointer
   6293  *
   6294  * Inputs:      pointer to initialized aac_BitStreamInfo_t struct
   6295  *              number of bits to get from bitstream
   6296  *
   6297  * Outputs:     updated bitstream info struct
   6298  *
   6299  * Return:      the next nBits bits of data from bitstream buffer
   6300  *
   6301  * Notes:       nBits must be in range [0, 31], nBits outside this range masked by 0x1f
   6302  *              for speed, does not indicate error if you overrun bit buffer
   6303  *              if nBits == 0, returns 0
   6304  **********************************************************************************************************************/
   6305 unsigned int GetBits(int nBits)
   6306 {
   6307     uint32_t data, lowBits;
   6308 
   6309     nBits &= 0x1f;                          /* nBits mod 32 to avoid unpredictable results like >> by negative amount */
   6310     data = m_aac_BitStreamInfo.iCache >> (31 - nBits);        /* unsigned >> so zero-extend */
   6311     data >>= 1;                                         /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */
   6312     m_aac_BitStreamInfo.iCache <<= nBits;                    /* left-justify cache */
   6313     m_aac_BitStreamInfo.cachedBits -= nBits;                 /* how many bits have we drawn from the cache so far */
   6314 
   6315     /* if we cross an int boundary, refill the cache */
   6316     if (m_aac_BitStreamInfo.cachedBits < 0) {
   6317         lowBits = -m_aac_BitStreamInfo.cachedBits;
   6318         RefillBitstreamCache();
   6319         data |= m_aac_BitStreamInfo.iCache >> (32 - lowBits);        /* get the low-order bits */
   6320 
   6321         m_aac_BitStreamInfo.cachedBits -= lowBits;            /* how many bits have we drawn from the cache so far */
   6322         m_aac_BitStreamInfo.iCache <<= lowBits;            /* left-justify cache */
   6323     }
   6324 
   6325     return data;
   6326 }
   6327 
   6328 /***********************************************************************************************************************
   6329  * Function:    GetBitsNoAdvance
   6330  *
   6331  * Description: get bits from bitstream, do not advance bitstream pointer
   6332  *
   6333  * Inputs:      pointer to initialized aac_BitStreamInfo_t struct
   6334  *              number of bits to get from bitstream
   6335  *
   6336  * Outputs:     none (state of aac_BitStreamInfo_t struct left unchanged)
   6337  *
   6338  * Return:      the next nBits bits of data from bitstream buffer
   6339  *
   6340  * Notes:       nBits must be in range [0, 31], nBits outside this range masked by 0x1f
   6341  *              for speed, does not indicate error if you overrun bit buffer
   6342  *              if nBits == 0, returns 0
   6343  **********************************************************************************************************************/
   6344 unsigned int GetBitsNoAdvance(int nBits)
   6345 {
   6346     uint8_t *buf;
   6347     uint32_t data, iCache;
   6348     int32_t lowBits;
   6349 
   6350     nBits &= 0x1f;                          /* nBits mod 32 to avoid unpredictable results like >> by negative amount */
   6351     data = m_aac_BitStreamInfo.iCache >> (31 - nBits);        /* unsigned >> so zero-extend */
   6352     data >>= 1;                                         /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */
   6353     lowBits = nBits - m_aac_BitStreamInfo.cachedBits;        /* how many bits do we have left to read */
   6354 
   6355     /* if we cross an int boundary, read next bytes in buffer */
   6356     if (lowBits > 0) {
   6357         iCache = 0;
   6358         buf = m_aac_BitStreamInfo.bytePtr;
   6359         while (lowBits > 0) {
   6360             iCache <<= 8;
   6361             if (buf < m_aac_BitStreamInfo.bytePtr + m_aac_BitStreamInfo.nBytes)
   6362                 iCache |= (uint32_t)*buf++;
   6363             lowBits -= 8;
   6364         }
   6365         lowBits = -lowBits;
   6366         data |= iCache >> lowBits;
   6367     }
   6368 
   6369     return data;
   6370 }
   6371 
   6372 /***********************************************************************************************************************
   6373  * Function:    AdvanceBitstream
   6374  *
   6375  * Description: move bitstream pointer ahead
   6376  *
   6377  * Inputs:      number of bits to advance bitstream
   6378  *
   6379  * Outputs:     updated bitstream info struct
   6380  *
   6381  * Return:      none
   6382  *
   6383  * Notes:       generally used following GetBitsNoAdvance(bsi, maxBits)
   6384  **********************************************************************************************************************/
   6385 void AdvanceBitstream(int nBits)
   6386 {
   6387     nBits &= 0x1f;
   6388     if (nBits > m_aac_BitStreamInfo.cachedBits) {
   6389         nBits -= m_aac_BitStreamInfo.cachedBits;
   6390         RefillBitstreamCache();
   6391     }
   6392     m_aac_BitStreamInfo.iCache <<= nBits;
   6393     m_aac_BitStreamInfo.cachedBits -= nBits;
   6394 }
   6395 
   6396 /***********************************************************************************************************************
   6397  * Function:    CalcBitsUsed
   6398  *
   6399  * Description: calculate how many bits have been read from bitstream
   6400  *
   6401  * Inputs:      pointer to start of bitstream buffer
   6402  *              bit offset into first byte of startBuf (0-7)
   6403  *
   6404  * Outputs:     none
   6405  *
   6406  * Return:      number of bits read from bitstream, as offset from startBuf:startOffset
   6407  **********************************************************************************************************************/
   6408 int CalcBitsUsed(uint8_t *startBuf, int startOffset) {
   6409 
   6410     int bitsUsed;
   6411 
   6412     bitsUsed  = (m_aac_BitStreamInfo.bytePtr - startBuf) * 8;
   6413     bitsUsed -= m_aac_BitStreamInfo.cachedBits;
   6414     bitsUsed -= startOffset;
   6415 
   6416     return bitsUsed;
   6417 }
   6418 /***********************************************************************************************************************
   6419  * Function:    ByteAlignBitstream
   6420  *
   6421  * Description: bump bitstream pointer to start of next byte
   6422  *
   6423  * Inputs:      none
   6424  *
   6425  * Outputs:     byte-aligned bitstream aac_BitStreamInfo_t struct
   6426  *
   6427  * Return:      none
   6428  *
   6429  * Notes:       if bitstream is already byte-aligned, do nothing
   6430  **********************************************************************************************************************/
   6431 void ByteAlignBitstream(){
   6432 
   6433     int offset;
   6434 
   6435     offset = m_aac_BitStreamInfo.cachedBits & 0x07;
   6436     AdvanceBitstream(offset);
   6437 }
   6438 
   6439 #ifdef AAC_ENABLE_SBR
   6440 
   6441 /**************************************************************************************
   6442  * Function:    InitSBRState
   6443  *
   6444  * Description: initialize PSInfoSBR struct at start of stream or after flush
   6445  *
   6446  * Inputs:      valid AACDecInfo struct
   6447  *
   6448  * Outputs:     PSInfoSBR struct with proper initial state
   6449  *
   6450  * Return:      none
   6451  **************************************************************************************/
   6452 void InitSBRState() {
   6453 
   6454     int i, ch;
   6455     uint8_t *c;
   6456 
   6457     if (!m_PSInfoSBR)
   6458         return;
   6459 
   6460     /* clear SBR state structure */
   6461     c = (uint8_t *)m_PSInfoSBR;
   6462     for (i = 0; i < (int)sizeof(m_PSInfoSBR); i++)
   6463         *c++ = 0;
   6464 
   6465     /* initialize non-zero state variables */
   6466     for (ch = 0; ch < AAC_MAX_NCHANS; ch++) {
   6467         m_PSInfoSBR->sbrChan[ch].reset = 1;
   6468         m_PSInfoSBR->sbrChan[ch].laPrev = -1;
   6469     }
   6470 }
   6471 #endif
   6472 
   6473 /***********************************************************************************************************************
   6474  * Function:    DecodeSBRBitstream
   6475  *
   6476  * Description: decode sideband information for SBR
   6477  *
   6478  * Inputs:      base output channel (range = [0, nChans-1])
   6479  *
   6480  * Outputs:     initialized state structs (SBRHdr, SBRGrid, SBRFreq, SBRChan)
   6481  *
   6482  * Return:      0 if successful, error code (< 0) if error
   6483  *
   6484  * Notes:       SBR payload should be in aacDecInfo->fillBuf
   6485  *              returns with no error if fill buffer is not an SBR extension block,
   6486  *                or if current block is not a fill block (e.g. for LFE upsampling)
   6487  **********************************************************************************************************************/
   6488 int DecodeSBRBitstream(int chBase) {
   6489 
   6490     int headerFlag;
   6491 
   6492     if(m_AACDecInfo->currBlockID != AAC_ID_FIL
   6493             || (m_AACDecInfo->fillExtType != EXT_SBR_DATA && m_AACDecInfo->fillExtType != EXT_SBR_DATA_CRC))
   6494         return ERR_AAC_NONE;
   6495 
   6496     SetBitstreamPointer(m_AACDecInfo->fillCount, m_AACDecInfo->fillBuf);
   6497     if(GetBits(4) != (unsigned int) m_AACDecInfo->fillExtType) return ERR_AAC_SBR_BITSTREAM;
   6498 
   6499     if(m_AACDecInfo->fillExtType == EXT_SBR_DATA_CRC) m_PSInfoSBR->crcCheckWord = GetBits(10);
   6500 
   6501     headerFlag = GetBits(1);
   6502     if(headerFlag) {
   6503         /* get sample rate index for output sample rate (2x base rate) */
   6504         m_PSInfoSBR->sampRateIdx = GetSampRateIdx(2 * m_AACDecInfo->sampRate);
   6505         if(m_PSInfoSBR->sampRateIdx < 0 || m_PSInfoSBR->sampRateIdx >= NUM_SAMPLE_RATES)
   6506             return ERR_AAC_SBR_BITSTREAM;
   6507         else if(m_PSInfoSBR->sampRateIdx >= NUM_SAMPLE_RATES_SBR) return ERR_AAC_SBR_SINGLERATE_UNSUPPORTED;
   6508 
   6509         /* reset flag = 1 if header values changed */
   6510         if(UnpackSBRHeader(&(m_PSInfoSBR->sbrHdr[chBase]))) m_PSInfoSBR->sbrChan[chBase].reset = 1;
   6511 
   6512         /* first valid SBR header should always trigger CalcFreqTables(), since psi->reset was set in InitSBR() */
   6513         if(m_PSInfoSBR->sbrChan[chBase].reset)
   6514             CalcFreqTables(&(m_PSInfoSBR->sbrHdr[chBase + 0]), &(m_PSInfoSBR->sbrFreq[chBase]),
   6515                     m_PSInfoSBR->sampRateIdx);
   6516 
   6517         /* copy and reset state to right channel for CPE */
   6518         if(m_AACDecInfo->prevBlockID == AAC_ID_CPE)
   6519             m_PSInfoSBR->sbrChan[chBase + 1].reset = m_PSInfoSBR->sbrChan[chBase + 0].reset;
   6520     }
   6521 
   6522     /* if no header has been received, upsample only */
   6523     if(m_PSInfoSBR->sbrHdr[chBase].count == 0) return ERR_AAC_NONE;
   6524 
   6525     if(m_AACDecInfo->prevBlockID == AAC_ID_SCE) {
   6526         UnpackSBRSingleChannel(chBase);
   6527     }
   6528     else if(m_AACDecInfo->prevBlockID == AAC_ID_CPE) {
   6529         UnpackSBRChannelPair(chBase);
   6530     }
   6531     else {
   6532         return ERR_AAC_SBR_BITSTREAM;
   6533     }
   6534 
   6535     ByteAlignBitstream();
   6536 
   6537     return ERR_AAC_NONE;
   6538 }
   6539 
   6540 #ifdef AAC_ENABLE_SBR
   6541 
   6542 /***********************************************************************************************************************
   6543  * Function:    DecodeSBRData
   6544  *
   6545  * Description: apply SBR to one frame of PCM data
   6546  *
   6547  * Inputs:      1024 samples of decoded 32-bit PCM, before SBR
   6548  *              size of input PCM samples (must be 4 bytes)
   6549  *              number of fraction bits in input PCM samples
   6550  *              base output channel (range = [0, nChans-1])
   6551  *              initialized state structs (SBRHdr, SBRGrid, SBRFreq, SBRChan)
   6552  *
   6553  * Outputs:     2048 samples of decoded 16-bit PCM, after SBR
   6554  *
   6555  * Return:      0 if successful, error code (< 0) if error
   6556  **********************************************************************************************************************/
   6557 int DecodeSBRData(int chBase, short *outbuf) {
   6558 
   6559     int k, l, ch, chBlock, qmfaBands, qmfsBands;
   6560     int upsampleOnly, gbIdx, gbMask;
   6561     int *inbuf;
   6562     short *outptr;
   6563 
   6564     SBRHeader *sbrHdr;
   6565     SBRGrid *sbrGrid;
   6566     SBRFreq *sbrFreq;
   6567     SBRChan *sbrChan;
   6568 
   6569     /* same header and freq tables for both channels in CPE */
   6570     sbrHdr = &(m_PSInfoSBR->sbrHdr[chBase]);
   6571     sbrFreq = &(m_PSInfoSBR->sbrFreq[chBase]);
   6572 
   6573     /* upsample only if we haven't received an SBR header yet or if we have an LFE block */
   6574     if(m_AACDecInfo->currBlockID == AAC_ID_LFE) {
   6575         chBlock = 1;
   6576         upsampleOnly = 1;
   6577     }
   6578     else if(m_AACDecInfo->currBlockID == AAC_ID_FIL) {
   6579         if(m_AACDecInfo->prevBlockID == AAC_ID_SCE)
   6580             chBlock = 1;
   6581         else if(m_AACDecInfo->prevBlockID == AAC_ID_CPE)
   6582             chBlock = 2;
   6583         else
   6584             return ERR_AAC_NONE;
   6585 
   6586         upsampleOnly = (sbrHdr->count == 0 ? 1 : 0);
   6587         if(m_AACDecInfo->fillExtType != EXT_SBR_DATA && m_AACDecInfo->fillExtType != EXT_SBR_DATA_CRC)
   6588             return ERR_AAC_NONE;
   6589     }
   6590     else {
   6591         /* ignore non-SBR blocks */
   6592         return ERR_AAC_NONE;
   6593     }
   6594 
   6595     if(upsampleOnly) {
   6596         sbrFreq->kStart = 32;
   6597         sbrFreq->numQMFBands = 0;
   6598     }
   6599 
   6600     for(ch = 0; ch < chBlock; ch++) {
   6601         sbrGrid = &(m_PSInfoSBR->sbrGrid[chBase + ch]);
   6602         sbrChan = &(m_PSInfoSBR->sbrChan[chBase + ch]);
   6603 
   6604         if(m_AACDecInfo->rawSampleBuf[ch] == 0 || m_AACDecInfo->rawSampleBytes != 4) return ERR_AAC_SBR_PCM_FORMAT;
   6605         inbuf = (int*) m_AACDecInfo->rawSampleBuf[ch];
   6606         outptr = outbuf + chBase + ch;
   6607 
   6608         /* restore delay buffers (could use ring buffer or keep in temp buffer for nChans == 1) */
   6609         for(l = 0; l < HF_GEN; l++) {
   6610             for(k = 0; k < 64; k++) {
   6611                 m_PSInfoSBR->XBuf[l][k][0] = m_PSInfoSBR->XBufDelay[chBase + ch][l][k][0];
   6612                 m_PSInfoSBR->XBuf[l][k][1] = m_PSInfoSBR->XBufDelay[chBase + ch][l][k][1];
   6613             }
   6614         }
   6615 
   6616         /* step 1 - analysis QMF */
   6617         qmfaBands = sbrFreq->kStart;
   6618         for(l = 0; l < 32; l++) {
   6619             gbMask = QMFAnalysis(inbuf + l * 32, m_PSInfoSBR->delayQMFA[chBase + ch], m_PSInfoSBR->XBuf[l + HF_GEN][0],
   6620                     m_AACDecInfo->rawSampleFBits, &(m_PSInfoSBR->delayIdxQMFA[chBase + ch]), qmfaBands);
   6621 
   6622             gbIdx = ((l + HF_GEN) >> 5) & 0x01;
   6623             sbrChan->gbMask[gbIdx] |= gbMask; /* gbIdx = (0 if i < 32), (1 if i >= 32) */
   6624         }
   6625 
   6626         if(upsampleOnly) {
   6627             /* no SBR - just run synthesis QMF to upsample by 2x */
   6628             qmfsBands = 32;
   6629             for(l = 0; l < 32; l++) {
   6630                 /* step 4 - synthesis QMF */
   6631                 QMFSynthesis(m_PSInfoSBR->XBuf[l + HF_ADJ][0], m_PSInfoSBR->delayQMFS[chBase + ch],
   6632                         &(m_PSInfoSBR->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, m_AACDecInfo->nChans);
   6633                 outptr += 64 * m_AACDecInfo->nChans;
   6634             }
   6635         }
   6636         else {
   6637             /* if previous frame had lower SBR starting freq than current, zero out the synthesized QMF
   6638              *   bands so they aren't used as sources for patching
   6639              * after patch generation, restore from delay buffer
   6640              * can only happen after header reset
   6641              */
   6642             for(k = sbrFreq->kStartPrev; k < sbrFreq->kStart; k++) {
   6643                 for(l = 0; l < sbrGrid->envTimeBorder[0] + HF_ADJ; l++) {
   6644                     m_PSInfoSBR->XBuf[l][k][0] = 0;
   6645                     m_PSInfoSBR->XBuf[l][k][1] = 0;
   6646                 }
   6647             }
   6648 
   6649             /* step 2 - HF generation */
   6650             GenerateHighFreq(sbrGrid, sbrFreq, sbrChan, ch);
   6651 
   6652             /* restore SBR bands that were cleared before patch generation (time slots 0, 1 no longer needed) */
   6653             for(k = sbrFreq->kStartPrev; k < sbrFreq->kStart; k++) {
   6654                 for(l = HF_ADJ; l < sbrGrid->envTimeBorder[0] + HF_ADJ; l++) {
   6655                     m_PSInfoSBR->XBuf[l][k][0] = m_PSInfoSBR->XBufDelay[chBase + ch][l][k][0];
   6656                     m_PSInfoSBR->XBuf[l][k][1] = m_PSInfoSBR->XBufDelay[chBase + ch][l][k][1];
   6657                 }
   6658             }
   6659 
   6660             /* step 3 - HF adjustment */
   6661             AdjustHighFreq(sbrHdr, sbrGrid, sbrFreq, sbrChan, ch);
   6662 
   6663             /* step 4 - synthesis QMF */
   6664             qmfsBands = sbrFreq->kStartPrev + sbrFreq->numQMFBandsPrev;
   6665             for(l = 0; l < sbrGrid->envTimeBorder[0]; l++) {
   6666                 /* if new envelope starts mid-frame, use old settings until start of first envelope in this frame */
   6667                 QMFSynthesis(m_PSInfoSBR->XBuf[l + HF_ADJ][0], m_PSInfoSBR->delayQMFS[chBase + ch],
   6668                         &(m_PSInfoSBR->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, m_AACDecInfo->nChans);
   6669                 outptr += 64 * m_AACDecInfo->nChans;
   6670             }
   6671 
   6672             qmfsBands = sbrFreq->kStart + sbrFreq->numQMFBands;
   6673             for(; l < 32; l++) {
   6674                 /* use new settings for rest of frame (usually the entire frame, unless the first envelope starts mid-frame) */
   6675                 QMFSynthesis(m_PSInfoSBR->XBuf[l + HF_ADJ][0], m_PSInfoSBR->delayQMFS[chBase + ch],
   6676                         &(m_PSInfoSBR->delayIdxQMFS[chBase + ch]), qmfsBands, outptr, m_AACDecInfo->nChans);
   6677                 outptr += 64 * m_AACDecInfo->nChans;
   6678             }
   6679         }
   6680 
   6681         /* save delay */
   6682         for(l = 0; l < HF_GEN; l++) {
   6683             for(k = 0; k < 64; k++) {
   6684                 m_PSInfoSBR->XBufDelay[chBase + ch][l][k][0] = m_PSInfoSBR->XBuf[l + 32][k][0];
   6685                 m_PSInfoSBR->XBufDelay[chBase + ch][l][k][1] = m_PSInfoSBR->XBuf[l + 32][k][1];
   6686             }
   6687         }
   6688         sbrChan->gbMask[0] = sbrChan->gbMask[1];
   6689         sbrChan->gbMask[1] = 0;
   6690 
   6691         if(sbrHdr->count > 0) sbrChan->reset = 0;
   6692     }
   6693     sbrFreq->kStartPrev = sbrFreq->kStart;
   6694     sbrFreq->numQMFBandsPrev = sbrFreq->numQMFBands;
   6695 
   6696     if(m_AACDecInfo->nChans > 0 && (chBase + ch) == m_AACDecInfo->nChans) m_PSInfoSBR->frameCount++;
   6697 
   6698     return ERR_AAC_NONE;
   6699 }
   6700 
   6701 #endif
   6702 
   6703 /***********************************************************************************************************************
   6704  * Function:    BubbleSort
   6705  *
   6706  * Description: in-place sort of uint8_ts
   6707  *
   6708  * Inputs:      buffer of elements to sort
   6709  *              number of elements to sort
   6710  *
   6711  * Outputs:     sorted buffer
   6712  *
   6713  * Return:      none
   6714  **********************************************************************************************************************/
   6715 void BubbleSort(uint8_t *v, int nItems) {
   6716 
   6717     int i;
   6718     uint8_t t;
   6719 
   6720     while(nItems >= 2) {
   6721         for(i = 0; i < nItems - 1; i++) {
   6722             if(v[i + 1] < v[i]) {
   6723                 t = v[i + 1];
   6724                 v[i + 1] = v[i];
   6725                 v[i] = t;
   6726             }
   6727         }
   6728         nItems--;
   6729     }
   6730 }
   6731 /***********************************************************************************************************************
   6732  * Function:    VMin
   6733  *
   6734  * Description: find smallest element in a buffer of uint8_ts
   6735  *
   6736  * Inputs:      buffer of elements to search
   6737  *              number of elements to search
   6738  *
   6739  * Outputs:     none
   6740  *
   6741  * Return:      smallest element in buffer
   6742  **********************************************************************************************************************/
   6743 uint8_t VMin(uint8_t *v, int nItems) {
   6744 
   6745     int i;
   6746     uint8_t vMin;
   6747 
   6748     vMin = v[0];
   6749     for(i = 1; i < nItems; i++) {
   6750         if(v[i] < vMin) vMin = v[i];
   6751     }
   6752     return vMin;
   6753 }
   6754 /***********************************************************************************************************************
   6755  * Function:    VMax
   6756  *
   6757  * Description: find largest element in a buffer of uint8_ts
   6758  *
   6759  * Inputs:      buffer of elements to search
   6760  *              number of elements to search
   6761  *
   6762  * Outputs:     none
   6763  *
   6764  * Return:      largest element in buffer
   6765  **********************************************************************************************************************/
   6766 uint8_t VMax(uint8_t *v, int nItems) {
   6767 
   6768     int i;
   6769     uint8_t vMax;
   6770 
   6771     vMax = v[0];
   6772     for(i = 1; i < nItems; i++) {
   6773         if(v[i] > vMax) vMax = v[i];
   6774     }
   6775     return vMax;
   6776 }
   6777 /***********************************************************************************************************************
   6778  * Function:    CalcFreqMasterScaleZero
   6779  *
   6780  * Description: calculate master frequency table when freqScale == 0
   6781  *                (4.6.18.3.2.1, figure 4.39)
   6782  *
   6783  * Inputs:      alterScale flag
   6784  *              index of first QMF subband in master freq table (k0)
   6785  *              index of last QMF subband (k2)
   6786  *
   6787  * Outputs:     master frequency table
   6788  *
   6789  * Return:      number of bands in master frequency table
   6790  *
   6791  * Notes:       assumes k2 - k0 <= 48 and k2 >= k0 (4.6.18.3.6)
   6792  **********************************************************************************************************************/
   6793 int CalcFreqMasterScaleZero(uint8_t *freqMaster, int alterScale, int k0, int k2) {
   6794 
   6795     int nMaster, k, nBands, k2Achieved, dk, vDk[64], k2Diff;
   6796 
   6797     if(alterScale) {
   6798         dk = 2;
   6799         nBands = 2 * ((k2 - k0 + 2) >> 2);
   6800     }
   6801     else {
   6802         dk = 1;
   6803         nBands = 2 * ((k2 - k0) >> 1);
   6804     }
   6805 
   6806     if(nBands <= 0) return 0;
   6807 
   6808     k2Achieved = k0 + nBands * dk;
   6809     k2Diff = k2 - k2Achieved;
   6810     for(k = 0; k < nBands; k++)
   6811         vDk[k] = dk;
   6812 
   6813     if(k2Diff > 0) {
   6814         k = nBands - 1;
   6815         while(k2Diff) {
   6816             vDk[k]++;
   6817             k--;
   6818             k2Diff--;
   6819         }
   6820     }
   6821     else if(k2Diff < 0) {
   6822         k = 0;
   6823         while(k2Diff) {
   6824             vDk[k]--;
   6825             k++;
   6826             k2Diff++;
   6827         }
   6828     }
   6829 
   6830     nMaster = nBands;
   6831     freqMaster[0] = k0;
   6832     for(k = 1; k <= nBands; k++)
   6833         freqMaster[k] = freqMaster[k - 1] + vDk[k - 1];
   6834 
   6835     return nMaster;
   6836 }
   6837 
   6838 /* mBandTab[i] = temp1[i] / 2 */
   6839 static const int mBandTab[3] PROGMEM = {6, 5, 4};
   6840 
   6841 /* invWarpTab[i] = 1.0 / temp2[i], Q30 (see 4.6.18.3.2.1) */
   6842 static const int invWarpTab[2] PROGMEM = {0x40000000, 0x313b13b1};
   6843 
   6844 /***********************************************************************************************************************
   6845  * Function:    CalcFreqMasterScale
   6846  *
   6847  * Description: calculate master frequency table when freqScale > 0
   6848  *                (4.6.18.3.2.1, figure 4.39)
   6849  *
   6850  * Inputs:      alterScale flag
   6851  *              freqScale flag
   6852  *              index of first QMF subband in master freq table (k0)
   6853  *              index of last QMF subband (k2)
   6854  *
   6855  * Outputs:     master frequency table
   6856  *
   6857  * Return:      number of bands in master frequency table
   6858  *
   6859  * Notes:       assumes k2 - k0 <= 48 and k2 >= k0 (4.6.18.3.6)
   6860  **********************************************************************************************************************/
   6861 int CalcFreqMaster(uint8_t *freqMaster, int freqScale, int alterScale, int k0, int k2) {
   6862 
   6863     int bands, twoRegions, k, k1, t, vLast, vCurr, pCurr;
   6864     int invWarp, nBands0, nBands1, change;
   6865     uint8_t vDk1Min, vDk0Max;
   6866     uint8_t *vDelta;
   6867 
   6868     if(freqScale < 1 || freqScale > 3) return -1;
   6869 
   6870     bands = mBandTab[freqScale - 1];
   6871     invWarp = invWarpTab[alterScale];
   6872 
   6873     /* tested for all k0 = [5, 64], k2 = [k0, 64] */
   6874     if(k2 * 10000 > 22449 * k0) {
   6875         twoRegions = 1;
   6876         k1 = 2 * k0;
   6877     }
   6878     else {
   6879         twoRegions = 0;
   6880         k1 = k2;
   6881     }
   6882 
   6883     /* tested for all k0 = [5, 64], k1 = [k0, 64], freqScale = [1,3] */
   6884     t = (log2Tab[k1] - log2Tab[k0]) >> 3; /* log2(k1/k0), Q28 to Q25 */
   6885     nBands0 = 2 * (((bands * t) + (1 << 24)) >> 25); /* multiply by bands/2, round to nearest int (mBandTab has factor of 1/2 rolled in) */
   6886 
   6887     /* tested for all valid combinations of k0, k1, nBands (from sampRate, freqScale, alterScale)
   6888      * roundoff error can be a problem with fixpt (e.g. pCurr = 12.499999 instead of 12.50003)
   6889      *   because successive multiplication always undershoots a little bit, but this
   6890      *   doesn't occur in any of the ratios we encounter from the valid k0/k1 bands in the spec
   6891      */
   6892     t = RatioPowInv(k1, k0, nBands0);
   6893     pCurr = k0 << 24;
   6894     vLast = k0;
   6895     vDelta = freqMaster + 1; /* operate in-place */
   6896     for(k = 0; k < nBands0; k++) {
   6897         pCurr = MULSHIFT32(pCurr, t) << 8; /* keep in Q24 */
   6898         vCurr = (pCurr + (1 << 23)) >> 24;
   6899         vDelta[k] = (vCurr - vLast);
   6900         vLast = vCurr;
   6901     }
   6902 
   6903     /* sort the deltas and find max delta for first region */
   6904     BubbleSort(vDelta, nBands0);
   6905     vDk0Max = VMax(vDelta, nBands0);
   6906 
   6907     /* fill master frequency table with bands from first region */
   6908     freqMaster[0] = k0;
   6909     for(k = 1; k <= nBands0; k++)
   6910         freqMaster[k] += freqMaster[k - 1];
   6911 
   6912     /* if only one region, then the table is complete */
   6913     if(!twoRegions) return nBands0;
   6914 
   6915     /* tested for all k1 = [10, 64], k2 = [k0, 64], freqScale = [1,3] */
   6916     t = (log2Tab[k2] - log2Tab[k1]) >> 3; /* log2(k1/k0), Q28 to Q25 */
   6917     t = MULSHIFT32(bands * t, invWarp) << 2; /* multiply by bands/2, divide by warp factor, keep Q25 */
   6918     nBands1 = 2 * ((t + (1 << 24)) >> 25); /* round to nearest int */
   6919 
   6920     /* see comments above for calculations in first region */
   6921     t = RatioPowInv(k2, k1, nBands1);
   6922     pCurr = k1 << 24;
   6923     vLast = k1;
   6924     vDelta = freqMaster + nBands0 + 1; /* operate in-place */
   6925     for(k = 0; k < nBands1; k++) {
   6926         pCurr = MULSHIFT32(pCurr, t) << 8; /* keep in Q24 */
   6927         vCurr = (pCurr + (1 << 23)) >> 24;
   6928         vDelta[k] = (vCurr - vLast);
   6929         vLast = vCurr;
   6930     }
   6931 
   6932     /* sort the deltas, adjusting first and last if the second region has smaller deltas than the first */
   6933     vDk1Min = VMin(vDelta, nBands1);
   6934     if(vDk1Min < vDk0Max) {
   6935         BubbleSort(vDelta, nBands1);
   6936         change = vDk0Max - vDelta[0];
   6937         if(change > ((vDelta[nBands1 - 1] - vDelta[0]) >> 1)) change = ((vDelta[nBands1 - 1] - vDelta[0]) >> 1);
   6938         vDelta[0] += change;
   6939         vDelta[nBands1 - 1] -= change;
   6940     }
   6941     BubbleSort(vDelta, nBands1);
   6942 
   6943     /* fill master frequency table with bands from second region
   6944      * Note: freqMaster[nBands0] = k1
   6945      */
   6946     for(k = 1; k <= nBands1; k++)
   6947         freqMaster[k + nBands0] += freqMaster[k + nBands0 - 1];
   6948 
   6949     return (nBands0 + nBands1);
   6950 }
   6951 /***********************************************************************************************************************
   6952  * Function:    CalcFreqHigh
   6953  *
   6954  * Description: calculate high resolution frequency table (4.6.18.3.2.2)
   6955  *
   6956  * Inputs:      master frequency table
   6957  *              number of bands in master frequency table
   6958  *              crossover band from header
   6959  *
   6960  * Outputs:     high resolution frequency table
   6961  *
   6962  * Return:      number of bands in high resolution frequency table
   6963  **********************************************************************************************************************/
   6964 int CalcFreqHigh(uint8_t *freqHigh, uint8_t *freqMaster, int nMaster, int crossOverBand) {
   6965 
   6966     int k, nHigh;
   6967 
   6968     nHigh = nMaster - crossOverBand;
   6969 
   6970     for(k = 0; k <= nHigh; k++)
   6971         freqHigh[k] = freqMaster[k + crossOverBand];
   6972 
   6973     return nHigh;
   6974 }
   6975 /***********************************************************************************************************************
   6976  * Function:    CalcFreqLow
   6977  *
   6978  * Description: calculate low resolution frequency table (4.6.18.3.2.2)
   6979  *
   6980  * Inputs:      high resolution frequency table
   6981  *              number of bands in high resolution frequency table
   6982  *
   6983  * Outputs:     low resolution frequency table
   6984  *
   6985  * Return:      number of bands in low resolution frequency table
   6986  **********************************************************************************************************************/
   6987 int CalcFreqLow(uint8_t *freqLow, uint8_t *freqHigh, int nHigh) {
   6988 
   6989     int k, nLow, oddFlag;
   6990 
   6991     nLow = nHigh - (nHigh >> 1);
   6992     freqLow[0] = freqHigh[0];
   6993     oddFlag = nHigh & 0x01;
   6994 
   6995     for(k = 1; k <= nLow; k++)
   6996         freqLow[k] = freqHigh[2 * k - oddFlag];
   6997 
   6998     return nLow;
   6999 }
   7000 /***********************************************************************************************************************
   7001  * Function:    CalcFreqNoise
   7002  *
   7003  * Description: calculate noise floor frequency table (4.6.18.3.2.2)
   7004  *
   7005  * Inputs:      low resolution frequency table
   7006  *              number of bands in low resolution frequency table
   7007  *              index of starting QMF subband for SBR (kStart)
   7008  *              index of last QMF subband (k2)
   7009  *              number of noise bands
   7010  *
   7011  * Outputs:     noise floor frequency table
   7012  *
   7013  * Return:      number of bands in noise floor frequency table
   7014  **********************************************************************************************************************/
   7015 int CalcFreqNoise(uint8_t *freqNoise, uint8_t *freqLow, int nLow, int kStart, int k2, int noiseBands) {
   7016 
   7017     int i, iLast, k, nQ, lTop, lBottom;
   7018 
   7019     lTop = log2Tab[k2];
   7020     lBottom = log2Tab[kStart];
   7021     nQ = noiseBands * ((lTop - lBottom) >> 2); /* Q28 to Q26, noiseBands = [0,3] */
   7022     nQ = (nQ + (1 << 25)) >> 26;
   7023     if(nQ < 1) nQ = 1;
   7024 
   7025     ASSERT(nQ <= MAX_NUM_NOISE_FLOOR_BANDS); /* required from 4.6.18.3.6 */
   7026 
   7027     iLast = 0;
   7028     freqNoise[0] = freqLow[0];
   7029     for(k = 1; k <= nQ; k++) {
   7030         i = iLast + (nLow - iLast) / (nQ + 1 - k); /* truncating division */
   7031         freqNoise[k] = freqLow[i];
   7032         iLast = i;
   7033     }
   7034 
   7035     return nQ;
   7036 }
   7037 /***********************************************************************************************************************
   7038  * Function:    BuildPatches
   7039  *
   7040  * Description: build high frequency patches (4.6.18.6.3)
   7041  *
   7042  * Inputs:      master frequency table
   7043  *              number of bands in low resolution frequency table
   7044  *              index of first QMF subband in master freq table (k0)
   7045  *              index of starting QMF subband for SBR (kStart)
   7046  *              number of QMF bands in high resolution frequency table
   7047  *              sample rate index
   7048  *
   7049  * Outputs:     starting subband for each patch
   7050  *              number of subbands in each patch
   7051  *
   7052  * Return:      number of patches
   7053  **********************************************************************************************************************/
   7054 int BuildPatches(uint8_t *patchNumSubbands, uint8_t *patchStartSubband, uint8_t *freqMaster, int nMaster, int k0,
   7055         int kStart, int numQMFBands, int sampRateIdx) {
   7056 
   7057     int i, j, k;
   7058     int msb, sb, usb, numPatches, goalSB, oddFlag;
   7059 
   7060     msb = k0;
   7061     usb = kStart;
   7062     numPatches = 0;
   7063     goalSB = goalSBTab[sampRateIdx];
   7064 
   7065     if(nMaster == 0) {
   7066         patchNumSubbands[0] = 0;
   7067         patchStartSubband[0] = 0;
   7068         return 0;
   7069     }
   7070 
   7071     if(goalSB < kStart + numQMFBands) {
   7072         k = 0;
   7073         for(i = 0; freqMaster[i] < goalSB; i++)
   7074             k = i + 1;
   7075     }
   7076     else {
   7077         k = nMaster;
   7078     }
   7079 
   7080     do {
   7081         j = k + 1;
   7082         do {
   7083             j--;
   7084             sb = freqMaster[j];
   7085             oddFlag = (sb - 2 + k0) & 0x01;
   7086         } while(sb > k0 - 1 + msb - oddFlag);
   7087 
   7088         patchNumSubbands[numPatches] = MAX(sb - usb, 0);
   7089         patchStartSubband[numPatches] = k0 - oddFlag - patchNumSubbands[numPatches];
   7090 
   7091         /* from MPEG reference code - slightly different from spec */
   7092         if((patchNumSubbands[numPatches] < 3) && (numPatches > 0)) break;
   7093 
   7094         if(patchNumSubbands[numPatches] > 0) {
   7095             usb = sb;
   7096             msb = sb;
   7097             numPatches++;
   7098         }
   7099         else {
   7100             msb = kStart;
   7101         }
   7102 
   7103         if(freqMaster[k] - sb < 3) k = nMaster;
   7104 
   7105     } while(sb != (kStart + numQMFBands) && numPatches <= MAX_NUM_PATCHES);
   7106 
   7107     return numPatches;
   7108 }
   7109 /***********************************************************************************************************************
   7110  * Function:    FindFreq
   7111  *
   7112  * Description: search buffer of uint8_ts for a specific value
   7113  *
   7114  * Inputs:      buffer of elements to search
   7115  *              number of elements to search
   7116  *              value to search for
   7117  *
   7118  * Outputs:     none
   7119  *
   7120  * Return:      non-zero if the value is found anywhere in the buffer, zero otherwise
   7121  **********************************************************************************************************************/
   7122 int FindFreq(uint8_t *freq, int nFreq, uint8_t val) {
   7123 
   7124     int k;
   7125 
   7126     for(k = 0; k < nFreq; k++) {
   7127         if(freq[k] == val) return 1;
   7128     }
   7129 
   7130     return 0;
   7131 }
   7132 /***********************************************************************************************************************
   7133  * Function:    RemoveFreq
   7134  *
   7135  * Description: remove one element from a buffer of uint8_ts
   7136  *
   7137  * Inputs:      buffer of elements
   7138  *              number of elements
   7139  *              index of element to remove
   7140  *
   7141  * Outputs:     new buffer of length nFreq-1
   7142  *
   7143  * Return:      none
   7144  **********************************************************************************************************************/
   7145 void RemoveFreq(uint8_t *freq, int nFreq, int removeIdx) {
   7146 
   7147     int k;
   7148 
   7149     if(removeIdx >= nFreq) return;
   7150 
   7151     for(k = removeIdx; k < nFreq - 1; k++)
   7152         freq[k] = freq[k + 1];
   7153 }
   7154 /***********************************************************************************************************************
   7155  * Function:    CalcFreqLimiter
   7156  *
   7157  * Description: calculate limiter frequency table (4.6.18.3.2.3)
   7158  *
   7159  * Inputs:      number of subbands in each patch
   7160  *              low resolution frequency table
   7161  *              number of bands in low resolution frequency table
   7162  *              index of starting QMF subband for SBR (kStart)
   7163  *              number of limiter bands
   7164  *              number of patches
   7165  *
   7166  * Outputs:     limiter frequency table
   7167  *
   7168  * Return:      number of bands in limiter frequency table
   7169  **********************************************************************************************************************/
   7170 int CalcFreqLimiter(uint8_t *freqLimiter, uint8_t *patchNumSubbands, uint8_t *freqLow, int nLow, int kStart,
   7171         int limiterBands, int numPatches) {
   7172 
   7173     int k, bands, nLimiter, nOctaves;
   7174     int limBandsPerOctave[3] = { 120, 200, 300 }; /* [1.2, 2.0, 3.0] * 100 */
   7175     uint8_t patchBorders[MAX_NUM_PATCHES + 1];
   7176 
   7177     /* simple case */
   7178     if(limiterBands == 0) {
   7179         freqLimiter[0] = freqLow[0] - kStart;
   7180         freqLimiter[1] = freqLow[nLow] - kStart;
   7181         return 1;
   7182     }
   7183 
   7184     bands = limBandsPerOctave[limiterBands - 1];
   7185     patchBorders[0] = kStart;
   7186 
   7187     /* from MPEG reference code - slightly different from spec (top border) */
   7188     for(k = 1; k < numPatches; k++)
   7189         patchBorders[k] = patchBorders[k - 1] + patchNumSubbands[k - 1];
   7190     patchBorders[k] = freqLow[nLow];
   7191 
   7192     for(k = 0; k <= nLow; k++)
   7193         freqLimiter[k] = freqLow[k];
   7194 
   7195     for(k = 1; k < numPatches; k++)
   7196         freqLimiter[k + nLow] = patchBorders[k];
   7197 
   7198     k = 1;
   7199     nLimiter = nLow + numPatches - 1;
   7200     BubbleSort(freqLimiter, nLimiter + 1);
   7201 
   7202     while(k <= nLimiter) {
   7203         nOctaves = log2Tab[freqLimiter[k]] - log2Tab[freqLimiter[k - 1]]; /* Q28 */
   7204         nOctaves = (nOctaves >> 9) * bands; /* Q19, max bands = 300 < 2^9 */
   7205         if(nOctaves < (49 << 19)) { /* compare with 0.49*100, in Q19 */
   7206             if(freqLimiter[k] == freqLimiter[k - 1] || FindFreq(patchBorders, numPatches + 1, freqLimiter[k]) == 0) {
   7207                 RemoveFreq(freqLimiter, nLimiter + 1, k);
   7208                 nLimiter--;
   7209             }
   7210             else if(FindFreq(patchBorders, numPatches + 1, freqLimiter[k - 1]) == 0) {
   7211                 RemoveFreq(freqLimiter, nLimiter + 1, k - 1);
   7212                 nLimiter--;
   7213             }
   7214             else {
   7215                 k++;
   7216             }
   7217         }
   7218         else {
   7219             k++;
   7220         }
   7221     }
   7222 
   7223     /* store limiter boundaries as offsets from kStart */
   7224     for(k = 0; k <= nLimiter; k++)
   7225         freqLimiter[k] -= kStart;
   7226 
   7227     return nLimiter;
   7228 }
   7229 /***********************************************************************************************************************
   7230  * Function:    CalcFreqTables
   7231  *
   7232  * Description: calulate master and derived frequency tables, and patches
   7233  *
   7234  * Inputs:      initialized SBRHeader struct for this SCE/CPE block
   7235  *              initialized SBRFreq struct for this SCE/CPE block
   7236  *              sample rate index of output sample rate (after SBR)
   7237  *
   7238  * Outputs:     master and derived frequency tables, and patches
   7239  *
   7240  * Return:      non-zero if error, zero otherwise
   7241  **********************************************************************************************************************/
   7242 int CalcFreqTables(SBRHeader *sbrHdr, SBRFreq *sbrFreq, int sampRateIdx) {
   7243     int k0, k2;
   7244 
   7245     k0 = k0Tab[sampRateIdx][sbrHdr->startFreq];
   7246 
   7247     if(sbrHdr->stopFreq == 14)
   7248         k2 = 2 * k0;
   7249     else if(sbrHdr->stopFreq == 15)
   7250         k2 = 3 * k0;
   7251     else
   7252         k2 = k2Tab[sampRateIdx][sbrHdr->stopFreq];
   7253     if(k2 > 64) k2 = 64;
   7254 
   7255     /* calculate master frequency table */
   7256     if(sbrHdr->freqScale == 0)
   7257         sbrFreq->nMaster = CalcFreqMasterScaleZero(sbrFreq->freqMaster, sbrHdr->alterScale, k0, k2);
   7258     else
   7259         sbrFreq->nMaster = CalcFreqMaster(sbrFreq->freqMaster, sbrHdr->freqScale, sbrHdr->alterScale, k0, k2);
   7260 
   7261     /* calculate high frequency table and related parameters */
   7262     sbrFreq->nHigh = CalcFreqHigh(sbrFreq->freqHigh, sbrFreq->freqMaster, sbrFreq->nMaster, sbrHdr->crossOverBand);
   7263     sbrFreq->numQMFBands = sbrFreq->freqHigh[sbrFreq->nHigh] - sbrFreq->freqHigh[0];
   7264     sbrFreq->kStart = sbrFreq->freqHigh[0];
   7265 
   7266     /* calculate low frequency table */
   7267     sbrFreq->nLow = CalcFreqLow(sbrFreq->freqLow, sbrFreq->freqHigh, sbrFreq->nHigh);
   7268 
   7269     /* calculate noise floor frequency table */
   7270     sbrFreq->numNoiseFloorBands = CalcFreqNoise(sbrFreq->freqNoise, sbrFreq->freqLow, sbrFreq->nLow, sbrFreq->kStart,
   7271             k2, sbrHdr->noiseBands);
   7272 
   7273     /* calculate limiter table */
   7274     sbrFreq->numPatches = BuildPatches(sbrFreq->patchNumSubbands, sbrFreq->patchStartSubband, sbrFreq->freqMaster,
   7275             sbrFreq->nMaster, k0, sbrFreq->kStart, sbrFreq->numQMFBands, sampRateIdx);
   7276     sbrFreq->nLimiter = CalcFreqLimiter(sbrFreq->freqLimiter, sbrFreq->patchNumSubbands, sbrFreq->freqLow,
   7277             sbrFreq->nLow, sbrFreq->kStart, sbrHdr->limiterBands, sbrFreq->numPatches);
   7278 
   7279     return 0;
   7280 }
   7281 /***********************************************************************************************************************
   7282  * Function:    EstimateEnvelope
   7283  *
   7284  * Description: estimate power of generated HF QMF bands in one time-domain envelope
   7285  *                (4.6.18.7.3)
   7286  *
   7287  * Inputs:      initialized PSInfoSBR struct
   7288  *              initialized SBRHeader struct for this SCE/CPE block
   7289  *              initialized SBRGrid struct for this channel
   7290  *              initialized SBRFreq struct for this SCE/CPE block
   7291  *              index of current envelope
   7292  *
   7293  * Outputs:     power of each QMF subband, stored as integer (Q0) * 2^N, N >= 0
   7294  *
   7295  * Return:      none
   7296  **********************************************************************************************************************/
   7297 void EstimateEnvelope(SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, int env) {
   7298 
   7299     int i, m, iStart, iEnd, xre, xim, nScale, expMax;
   7300     int p, n, mStart, mEnd, invFact, t;
   7301     int *XBuf;
   7302     U64 eCurr;
   7303     uint8_t *freqBandTab;
   7304 
   7305     /* estimate current envelope */
   7306     iStart = sbrGrid->envTimeBorder[env] + HF_ADJ;
   7307     iEnd = sbrGrid->envTimeBorder[env + 1] + HF_ADJ;
   7308     if(sbrGrid->freqRes[env]) {
   7309         n = sbrFreq->nHigh;
   7310         freqBandTab = sbrFreq->freqHigh;
   7311     }
   7312     else {
   7313         n = sbrFreq->nLow;
   7314         freqBandTab = sbrFreq->freqLow;
   7315     }
   7316 
   7317     /* ADS should inline MADD64 (smlal) properly, but check to make sure */
   7318     expMax = 0;
   7319     if(sbrHdr->interpFreq) {
   7320         for(m = 0; m < sbrFreq->numQMFBands; m++) {
   7321             eCurr.w64 = 0;
   7322             XBuf = m_PSInfoSBR->XBuf[iStart][sbrFreq->kStart + m];
   7323             for(i = iStart; i < iEnd; i++) {
   7324                 /* scale to int before calculating power (precision not critical, and avoids overflow) */
   7325                 xre = (*XBuf) >> FBITS_OUT_QMFA;
   7326                 XBuf += 1;
   7327                 xim = (*XBuf) >> FBITS_OUT_QMFA;
   7328                 XBuf += (2 * 64 - 1);
   7329                 eCurr.w64 = MADD64(eCurr.w64, xre, xre);
   7330                 eCurr.w64 = MADD64(eCurr.w64, xim, xim);
   7331             }
   7332 
   7333             /* eCurr.w64 is now Q(64 - 2*FBITS_OUT_QMFA) (64-bit word)
   7334              * if energy is too big to fit in 32-bit word (> 2^31) scale down by power of 2
   7335              */
   7336             nScale = 0;
   7337             if(eCurr.r.hi32) {
   7338                 nScale = (32 - CLZ(eCurr.r.hi32)) + 1;
   7339                 t = (int) (eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */
   7340                 t |= eCurr.r.hi32 << (32 - nScale);
   7341             }
   7342             else if(eCurr.r.lo32 >> 31) {
   7343                 nScale = 1;
   7344                 t = (int) (eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */
   7345             }
   7346             else {
   7347                 t = (int) eCurr.r.lo32;
   7348             }
   7349 
   7350             invFact = invBandTab[(iEnd - iStart) - 1];
   7351             m_PSInfoSBR->eCurr[m] = MULSHIFT32(t, invFact);
   7352             m_PSInfoSBR->eCurrExp[m] = nScale + 1; /* +1 for invFact = Q31 */
   7353             if(m_PSInfoSBR->eCurrExp[m] > expMax) expMax = m_PSInfoSBR->eCurrExp[m];
   7354         }
   7355     }
   7356     else {
   7357         for(p = 0; p < n; p++) {
   7358             mStart = freqBandTab[p];
   7359             mEnd = freqBandTab[p + 1];
   7360             eCurr.w64 = 0;
   7361             for(i = iStart; i < iEnd; i++) {
   7362                 XBuf = m_PSInfoSBR->XBuf[i][mStart];
   7363                 for(m = mStart; m < mEnd; m++) {
   7364                     xre = (*XBuf++) >> FBITS_OUT_QMFA;
   7365                     xim = (*XBuf++) >> FBITS_OUT_QMFA;
   7366                     eCurr.w64 = MADD64(eCurr.w64, xre, xre);
   7367                     eCurr.w64 = MADD64(eCurr.w64, xim, xim);
   7368                 }
   7369             }
   7370 
   7371             nScale = 0;
   7372             if(eCurr.r.hi32) {
   7373                 nScale = (32 - CLZ(eCurr.r.hi32)) + 1;
   7374                 t = (int) (eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */
   7375                 t |= eCurr.r.hi32 << (32 - nScale);
   7376             }
   7377             else if(eCurr.r.lo32 >> 31) {
   7378                 nScale = 1;
   7379                 t = (int) (eCurr.r.lo32 >> nScale); /* logical (unsigned) >> */
   7380             }
   7381             else {
   7382                 t = (int) eCurr.r.lo32;
   7383             }
   7384 
   7385             invFact = invBandTab[(iEnd - iStart) - 1];
   7386             invFact = MULSHIFT32(invBandTab[(mEnd - mStart) - 1], invFact) << 1;
   7387             t = MULSHIFT32(t, invFact);
   7388 
   7389             for(m = mStart; m < mEnd; m++) {
   7390                 m_PSInfoSBR->eCurr[m - sbrFreq->kStart] = t;
   7391                 m_PSInfoSBR->eCurrExp[m - sbrFreq->kStart] = nScale + 1; /* +1 for invFact = Q31 */
   7392             }
   7393             if(m_PSInfoSBR->eCurrExp[mStart - sbrFreq->kStart] > expMax)
   7394                 expMax = m_PSInfoSBR->eCurrExp[mStart - sbrFreq->kStart];
   7395         }
   7396     }
   7397     m_PSInfoSBR->eCurrExpMax = expMax;
   7398 }
   7399 /***********************************************************************************************************************
   7400  * Function:    GetSMapped
   7401  *
   7402  * Description: calculate SMapped (4.6.18.7.2)
   7403  *
   7404  * Inputs:      initialized SBRGrid struct for this channel
   7405  *              initialized SBRFreq struct for this SCE/CPE block
   7406  *              initialized SBRChan struct for this channel
   7407  *              index of current envelope
   7408  *              index of current QMF band
   7409  *              la flag for this envelope
   7410  *
   7411  * Outputs:     none
   7412  *
   7413  * Return:      1 if a sinusoid is present in this band, 0 if not
   7414  **********************************************************************************************************************/
   7415 int GetSMapped(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int band, int la) {
   7416 
   7417     int bandStart, bandEnd, oddFlag, r;
   7418 
   7419     if (sbrGrid->freqRes[env]) {
   7420         /* high resolution */
   7421         bandStart = band;
   7422         bandEnd = band+1;
   7423     } else {
   7424         /* low resolution (see CalcFreqLow() for mapping) */
   7425         oddFlag = sbrFreq->nHigh & 0x01;
   7426         bandStart = (band > 0 ? 2*band - oddFlag : 0);      /* starting index for freqLow[band] */
   7427         bandEnd = 2*(band+1) - oddFlag;                     /* ending index for freqLow[band+1] */
   7428     }
   7429 
   7430     /* sMapped = 1 if sIndexMapped == 1 for any frequency in this band */
   7431     for (band = bandStart; band < bandEnd; band++) {
   7432         if (sbrChan->addHarmonic[1][band]) {
   7433             r = ((sbrFreq->freqHigh[band+1] + sbrFreq->freqHigh[band]) >> 1);
   7434             if (env >= la || sbrChan->addHarmonic[0][r] == 1)
   7435                 return 1;
   7436         }
   7437     }
   7438     return 0;
   7439 }
   7440 
   7441 #define GBOOST_MAX  0x2830afd3  /* Q28, 1.584893192 squared */
   7442 #define ACC_SCALE   6
   7443 
   7444 /* squared version of table in 4.6.18.7.5 */   /* Q30 (0x80000000 = sentinel for GMAX) */
   7445 static const uint32_t limGainTab[4] PROGMEM = {0x20138ca7, 0x40000000, 0x7fb27dce, 0x80000000};
   7446 
   7447 /***********************************************************************************************************************
   7448  * Function:    CalcMaxGain
   7449  *
   7450  * Description: calculate max gain in one limiter band (4.6.18.7.5)
   7451  *
   7452  * Inputs:      initialized SBRHeader struct for this SCE/CPE block
   7453  *              initialized SBRGrid struct for this channel
   7454  *              initialized SBRFreq struct for this SCE/CPE block
   7455  *              index of current channel (0 for SCE, 0 or 1 for CPE)
   7456  *              index of current envelope
   7457  *              index of current limiter band
   7458  *              number of fraction bits in dequantized envelope
   7459  *                (max = Q(FBITS_OUT_DQ_ENV - 6) = Q23, can go negative)
   7460  *
   7461  * Outputs:     updated gainMax, gainMaxFBits, and sumEOrigMapped in PSInfoSBR struct
   7462  *
   7463  * Return:      none
   7464  **********************************************************************************************************************/
   7465 void CalcMaxGain(SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, int ch, int env, int lim, int fbitsDQ) {
   7466 
   7467     int m, mStart, mEnd, q, z, r;
   7468     int sumEOrigMapped, sumECurr, gainMax, eOMGainMax, envBand;
   7469     uint8_t eCurrExpMax;
   7470     uint8_t *freqBandTab;
   7471 
   7472     mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */
   7473     mEnd = sbrFreq->freqLimiter[lim + 1];
   7474     freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow);
   7475 
   7476     /* calculate max gain to apply to signal in this limiter band */
   7477     sumECurr = 0;
   7478     sumEOrigMapped = 0;
   7479     eCurrExpMax = m_PSInfoSBR->eCurrExpMax;
   7480     eOMGainMax = m_PSInfoSBR->eOMGainMax;
   7481     envBand = m_PSInfoSBR->envBand;
   7482     for(m = mStart; m < mEnd; m++) {
   7483         /* map current QMF band to appropriate envelope band */
   7484         if(m == freqBandTab[envBand + 1] - sbrFreq->kStart) {
   7485             envBand++;
   7486             eOMGainMax = m_PSInfoSBR->envDataDequant[ch][env][envBand] >> ACC_SCALE; /* summing max 48 bands */
   7487         }
   7488         sumEOrigMapped += eOMGainMax;
   7489 
   7490         /* easy test for overflow on ARM */
   7491         sumECurr += (m_PSInfoSBR->eCurr[m] >> (eCurrExpMax - m_PSInfoSBR->eCurrExp[m]));
   7492         if(sumECurr >> 30) {
   7493             sumECurr >>= 1;
   7494             eCurrExpMax++;
   7495         }
   7496     }
   7497     m_PSInfoSBR->eOMGainMax = eOMGainMax;
   7498     m_PSInfoSBR->envBand = envBand;
   7499 
   7500     m_PSInfoSBR->gainMaxFBits = 30; /* Q30 tables */
   7501     if(sumECurr == 0) {
   7502         /* any non-zero numerator * 1/EPS_0 is > G_MAX */
   7503         gainMax = (sumEOrigMapped == 0 ? (int) limGainTab[sbrHdr->limiterGains] : (int) 0x80000000);
   7504     }
   7505     else if(sumEOrigMapped == 0) {
   7506         /* 1/(any non-zero denominator) * EPS_0 * limGainTab[x] is appx. 0 */
   7507         gainMax = 0;
   7508     }
   7509     else {
   7510         /* sumEOrigMapped = Q(fbitsDQ - ACC_SCALE), sumECurr = Q(-eCurrExpMax) */
   7511         gainMax = limGainTab[sbrHdr->limiterGains];
   7512         if(sbrHdr->limiterGains != 3) {
   7513             q = MULSHIFT32(sumEOrigMapped, gainMax); /* Q(fbitsDQ - ACC_SCALE - 2), gainMax = Q30  */
   7514             z = CLZ(sumECurr) - 1;
   7515             r = InvRNormalized(sumECurr << z); /* in =  Q(z - eCurrExpMax), out = Q(29 + 31 - z + eCurrExpMax) */
   7516             gainMax = MULSHIFT32(q, r); /* Q(29 + 31 - z + eCurrExpMax + fbitsDQ - ACC_SCALE - 2 - 32) */
   7517             m_PSInfoSBR->gainMaxFBits = 26 - z + eCurrExpMax + fbitsDQ - ACC_SCALE;
   7518         }
   7519     }
   7520     m_PSInfoSBR->sumEOrigMapped = sumEOrigMapped;
   7521     m_PSInfoSBR->gainMax = gainMax;
   7522 }
   7523 /***********************************************************************************************************************
   7524  * Function:    CalcNoiseDivFactors
   7525  *
   7526  * Description: calculate 1/(1+Q) and Q/(1+Q) (4.6.18.7.4; 4.6.18.7.5)
   7527  *
   7528  * Inputs:      dequantized noise floor scalefactor
   7529  *
   7530  * Outputs:     1/(1+Q) and Q/(1+Q), format = Q31
   7531  *
   7532  * Return:      none
   7533  **********************************************************************************************************************/
   7534 void CalcNoiseDivFactors(int q, int *qp1Inv, int *qqp1Inv) {
   7535 
   7536     int z, qp1, t, s;
   7537 
   7538     /* 1 + Q_orig */
   7539     qp1 = (q >> 1);
   7540     qp1 += (1 << (FBITS_OUT_DQ_NOISE - 1)); /* >> 1 to avoid overflow when adding 1.0 */
   7541     z = CLZ(qp1) - 1; /* z <= 31 - FBITS_OUT_DQ_NOISE */
   7542     qp1 <<= z; /* Q(FBITS_OUT_DQ_NOISE + z) = Q31 * 2^-(31 - (FBITS_OUT_DQ_NOISE + z)) */
   7543     t = InvRNormalized(qp1) << 1; /* Q30 * 2^(31 - (FBITS_OUT_DQ_NOISE + z)), guaranteed not to overflow */
   7544 
   7545     /* normalize to Q31 */
   7546     s = (31 - (FBITS_OUT_DQ_NOISE - 1) - z - 1); /* clearly z >= 0, z <= (30 - (FBITS_OUT_DQ_NOISE - 1)) */
   7547     *qp1Inv = (t >> s); /* s = [0, 31 - FBITS_OUT_DQ_NOISE] */
   7548     *qqp1Inv = MULSHIFT32(t, q) << (32 - FBITS_OUT_DQ_NOISE - s);
   7549 }
   7550 /***********************************************************************************************************************
   7551  * Function:    CalcComponentGains
   7552  *
   7553  * Description: calculate gain of envelope, sinusoids, and noise in one limiter band
   7554  *                (4.6.18.7.5)
   7555  *
   7556  * Inputs:      initialized SBRHeader struct for this SCE/CPE block
   7557  *              initialized SBRGrid struct for this channel
   7558  *              initialized SBRFreq struct for this SCE/CPE block
   7559  *              initialized SBRChan struct for this channel
   7560  *              index of current channel (0 for SCE, 0 or 1 for CPE)
   7561  *              index of current envelope
   7562  *              index of current limiter band
   7563  *              number of fraction bits in dequantized envelope
   7564  *
   7565  * Outputs:     gains for envelope, sinusoids and noise
   7566  *              number of fraction bits for envelope gain
   7567  *              sum of the total gain for each component in this band
   7568  *              other updated state variables
   7569  *
   7570  * Return:      none
   7571  **********************************************************************************************************************/
   7572 void CalcComponentGains(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env, int lim, int fbitsDQ) {
   7573 
   7574     int d, m, mStart, mEnd, q, qm, noiseFloor, sIndexMapped;
   7575     int shift, eCurr, maxFlag, gainMax, gainMaxFBits;
   7576     int gain, sm, z, r, fbitsGain, gainScale;
   7577     uint8_t *freqBandTab;
   7578 
   7579     mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */
   7580     mEnd = sbrFreq->freqLimiter[lim + 1];
   7581 
   7582     gainMax = m_PSInfoSBR->gainMax;
   7583     gainMaxFBits = m_PSInfoSBR->gainMaxFBits;
   7584 
   7585     d = (env == m_PSInfoSBR->la || env == sbrChan->laPrev ? 0 : 1);
   7586     freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow);
   7587 
   7588     /* figure out which noise floor this envelope is in (only 1 or 2 noise floors allowed) */
   7589     noiseFloor = 0;
   7590     if(sbrGrid->numNoiseFloors == 2 && sbrGrid->noiseTimeBorder[1] <= sbrGrid->envTimeBorder[env]) noiseFloor++;
   7591 
   7592     m_PSInfoSBR->sumECurrGLim = 0;
   7593     m_PSInfoSBR->sumSM = 0;
   7594     m_PSInfoSBR->sumQM = 0;
   7595     /* calculate energy of noise to add in this limiter band */
   7596     for(m = mStart; m < mEnd; m++) {
   7597         if(m == sbrFreq->freqNoise[m_PSInfoSBR->noiseFloorBand + 1] - sbrFreq->kStart) {
   7598             /* map current QMF band to appropriate noise floor band (NOTE: freqLimiter[0] == freqLow[0] = freqHigh[0]) */
   7599             m_PSInfoSBR->noiseFloorBand++;
   7600             CalcNoiseDivFactors(m_PSInfoSBR->noiseDataDequant[ch][noiseFloor][m_PSInfoSBR->noiseFloorBand],
   7601                     &(m_PSInfoSBR->qp1Inv), &(m_PSInfoSBR->qqp1Inv));
   7602         }
   7603         if(m == sbrFreq->freqHigh[m_PSInfoSBR->highBand + 1] - sbrFreq->kStart) m_PSInfoSBR->highBand++;
   7604         if(m == freqBandTab[m_PSInfoSBR->sBand + 1] - sbrFreq->kStart) {
   7605             m_PSInfoSBR->sBand++;
   7606             m_PSInfoSBR->sMapped = GetSMapped(sbrGrid, sbrFreq, sbrChan, env, m_PSInfoSBR->sBand, m_PSInfoSBR->la);
   7607         }
   7608 
   7609         /* get sIndexMapped for this QMF subband */
   7610         sIndexMapped = 0;
   7611         r = ((sbrFreq->freqHigh[m_PSInfoSBR->highBand + 1] + sbrFreq->freqHigh[m_PSInfoSBR->highBand]) >> 1);
   7612         if(m + sbrFreq->kStart == r) {
   7613             /* r = center frequency, deltaStep = (env >= la || sIndexMapped'(r, numEnv'-1) == 1) */
   7614             if(env >= m_PSInfoSBR->la || sbrChan->addHarmonic[0][r] == 1) sIndexMapped =
   7615                     sbrChan->addHarmonic[1][m_PSInfoSBR->highBand];
   7616         }
   7617 
   7618         /* save sine flags from last envelope in this frame:
   7619          *   addHarmonic[0][0...63] = saved sine present flag from previous frame, for each QMF subband
   7620          *   addHarmonic[1][0...nHigh-1] = addHarmonic bit from current frame, for each high-res frequency band
   7621          * from MPEG reference code - slightly different from spec
   7622          *   (sIndexMapped'(m,LE'-1) can still be 0 when numEnv == psi->la)
   7623          */
   7624         if(env == sbrGrid->numEnv - 1) {
   7625             if(m + sbrFreq->kStart == r)
   7626                 sbrChan->addHarmonic[0][m + sbrFreq->kStart] = sbrChan->addHarmonic[1][m_PSInfoSBR->highBand];
   7627             else
   7628                 sbrChan->addHarmonic[0][m + sbrFreq->kStart] = 0;
   7629         }
   7630 
   7631         gain = m_PSInfoSBR->envDataDequant[ch][env][m_PSInfoSBR->sBand];
   7632         qm = MULSHIFT32(gain, m_PSInfoSBR->qqp1Inv) << 1;
   7633         sm = (sIndexMapped ? MULSHIFT32(gain, m_PSInfoSBR->qp1Inv) << 1 : 0);
   7634 
   7635         /* three cases: (sMapped == 0 && delta == 1), (sMapped == 0 && delta == 0), (sMapped == 1) */
   7636         if(d == 1 && m_PSInfoSBR->sMapped == 0)
   7637             gain = MULSHIFT32(m_PSInfoSBR->qp1Inv, gain) << 1;
   7638         else if(m_PSInfoSBR->sMapped != 0) gain = MULSHIFT32(m_PSInfoSBR->qqp1Inv, gain) << 1;
   7639 
   7640         /* gain, qm, sm = Q(fbitsDQ), gainMax = Q(fbitsGainMax) */
   7641         eCurr = m_PSInfoSBR->eCurr[m];
   7642         if(eCurr) {
   7643             z = CLZ(eCurr) - 1;
   7644             r = InvRNormalized(eCurr << z); /* in = Q(z - eCurrExp), out = Q(29 + 31 - z + eCurrExp) */
   7645             gainScale = MULSHIFT32(gain, r); /* out = Q(29 + 31 - z + eCurrExp + fbitsDQ - 32) */
   7646             fbitsGain = 29 + 31 - z + m_PSInfoSBR->eCurrExp[m] + fbitsDQ - 32;
   7647         }
   7648         else {
   7649             /* if eCurr == 0, then gain is unchanged (divide by EPS = 1) */
   7650             gainScale = gain;
   7651             fbitsGain = fbitsDQ;
   7652         }
   7653 
   7654         /* see if gain for this band exceeds max gain */
   7655         maxFlag = 0;
   7656         if(gainMax != (int) 0x80000000) {
   7657             if(fbitsGain >= gainMaxFBits) {
   7658                 shift = MIN(fbitsGain - gainMaxFBits, 31);
   7659                 maxFlag = ((gainScale >> shift) > gainMax ? 1 : 0);
   7660             }
   7661             else {
   7662                 shift = MIN(gainMaxFBits - fbitsGain, 31);
   7663                 maxFlag = (gainScale > (gainMax >> shift) ? 1 : 0);
   7664             }
   7665         }
   7666 
   7667         if(maxFlag) {
   7668             /* gainScale > gainMax, calculate ratio with 32/16 division */
   7669             q = 0;
   7670             r = gainScale; /* guaranteed > 0, else maxFlag could not have been set */
   7671             z = CLZ(r);
   7672             if(z < 16) {
   7673                 q = 16 - z;
   7674                 r >>= q; /* out = Q(fbitsGain - q) */
   7675             }
   7676 
   7677             z = CLZ(gainMax) - 1;
   7678             r = (gainMax << z) / r; /* out = Q((fbitsGainMax + z) - (fbitsGain - q)) */
   7679             q = (gainMaxFBits + z) - (fbitsGain - q); /* r = Q(q) */
   7680             if(q > 30) {
   7681                 r >>= MIN(q - 30, 31);
   7682             }
   7683             else {
   7684                 z = MIN(30 - q, 30);
   7685                 r = CLIP_2N_SHIFT30(r, z); /* let r = Q30 since range = [0.0, 1.0) (clip to 0x3fffffff = 0.99999) */
   7686             }
   7687 
   7688             qm = MULSHIFT32(qm, r) << 2;
   7689             gain = MULSHIFT32(gain, r) << 2;
   7690             m_PSInfoSBR->gLimBuf[m] = gainMax;
   7691             m_PSInfoSBR->gLimFbits[m] = gainMaxFBits;
   7692         }
   7693         else {
   7694             m_PSInfoSBR->gLimBuf[m] = gainScale;
   7695             m_PSInfoSBR->gLimFbits[m] = fbitsGain;
   7696         }
   7697 
   7698         /* sumSM, sumQM, sumECurrGLim = Q(fbitsDQ - ACC_SCALE) */
   7699         m_PSInfoSBR->smBuf[m] = sm;
   7700         m_PSInfoSBR->sumSM += (sm >> ACC_SCALE);
   7701 
   7702         m_PSInfoSBR->qmLimBuf[m] = qm;
   7703         if(env != m_PSInfoSBR->la && env != sbrChan->laPrev && sm == 0) m_PSInfoSBR->sumQM += (qm >> ACC_SCALE);
   7704 
   7705         /* eCurr * gain^2 same as gain^2, before division by eCurr
   7706          * (but note that gain != 0 even if eCurr == 0, since it's divided by eps)
   7707          */
   7708         if(eCurr) m_PSInfoSBR->sumECurrGLim += (gain >> ACC_SCALE);
   7709     }
   7710 }
   7711 /***********************************************************************************************************************
   7712  * Function:    ApplyBoost
   7713  *
   7714  * Description: calculate and apply boost factor for envelope, sinusoids, and noise
   7715  *                in this limiter band (4.6.18.7.5)
   7716  *
   7717  * Inputs:      initialized SBRFreq struct for this SCE/CPE block
   7718  *              index of current limiter band
   7719  *              number of fraction bits in dequantized envelope
   7720  *
   7721  * Outputs:     envelope gain, sinusoids and noise after scaling by gBoost
   7722  *              format = Q(FBITS_GLIM_BOOST) for envelope gain,
   7723  *                     = Q(FBITS_QLIM_BOOST) for noise
   7724  *                     = Q(FBITS_OUT_QMFA) for sinusoids
   7725  *
   7726  * Return:      none
   7727  *
   7728  * Notes:       after scaling, each component has at least 1 GB
   7729  **********************************************************************************************************************/
   7730 void ApplyBoost(SBRFreq *sbrFreq, int lim, int fbitsDQ) {
   7731 
   7732     int m, mStart, mEnd, q, z, r;
   7733     int sumEOrigMapped, gBoost;
   7734 
   7735     mStart = sbrFreq->freqLimiter[lim]; /* these are offsets from kStart */
   7736     mEnd = sbrFreq->freqLimiter[lim + 1];
   7737 
   7738     sumEOrigMapped = m_PSInfoSBR->sumEOrigMapped >> 1;
   7739     r = (m_PSInfoSBR->sumECurrGLim >> 1) + (m_PSInfoSBR->sumSM >> 1) + (m_PSInfoSBR->sumQM >> 1); /* 1 GB fine (sm and qm are mutually exclusive in acc) */
   7740     if(r < (1 << (31 - 28))) {
   7741         /* any non-zero numerator * 1/EPS_0 is > GBOOST_MAX
   7742          * round very small r to zero to avoid scaling problems
   7743          */
   7744         gBoost = (sumEOrigMapped == 0 ? (1 << 28) : GBOOST_MAX);
   7745         z = 0;
   7746     }
   7747     else if(sumEOrigMapped == 0) {
   7748         /* 1/(any non-zero denominator) * EPS_0 is appx. 0 */
   7749         gBoost = 0;
   7750         z = 0;
   7751     }
   7752     else {
   7753         /* numerator (sumEOrigMapped) and denominator (r) have same Q format (before << z) */
   7754         z = CLZ(r) - 1; /* z = [0, 27] */
   7755         r = InvRNormalized(r << z);
   7756         gBoost = MULSHIFT32(sumEOrigMapped, r);
   7757     }
   7758 
   7759     /* gBoost = Q(28 - z) */
   7760     if(gBoost > (GBOOST_MAX >> z)) {
   7761         gBoost = GBOOST_MAX;
   7762         z = 0;
   7763     }
   7764     gBoost <<= z; /* gBoost = Q28, minimum 1 GB */
   7765 
   7766     /* convert gain, noise, sinusoids to fixed Q format, clipping if necessary
   7767      *   (rare, usually only happens at very low bitrates, introduces slight
   7768      *    distortion into final HF mapping, but should be inaudible)
   7769      */
   7770     for(m = mStart; m < mEnd; m++) {
   7771         /* let gLimBoost = Q24, since in practice the max values are usually 16 to 20
   7772          *   unless limiterGains == 3 (limiter off) and eCurr ~= 0 (i.e. huge gain, but only
   7773          *   because the envelope has 0 power anyway)
   7774          */
   7775         q = MULSHIFT32(m_PSInfoSBR->gLimBuf[m], gBoost) << 2; /* Q(gLimFbits) * Q(28) --> Q(gLimFbits[m]-2) */
   7776         r = SqrtFix(q, m_PSInfoSBR->gLimFbits[m] - 2, &z);
   7777         z -= FBITS_GLIM_BOOST;
   7778         if(z >= 0) {
   7779             m_PSInfoSBR->gLimBoost[m] = r >> MIN(z, 31);
   7780         }
   7781         else {
   7782             z = MIN(30, -z);
   7783             r = CLIP_2N_SHIFT30(r, z);
   7784             m_PSInfoSBR->gLimBoost[m] = r;
   7785         }
   7786 
   7787         q = MULSHIFT32(m_PSInfoSBR->qmLimBuf[m], gBoost) << 2; /* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */
   7788         r = SqrtFix(q, fbitsDQ - 2, &z);
   7789         z -= FBITS_QLIM_BOOST; /* << by 14, since integer sqrt of x < 2^16, and we want to leave 1 GB */
   7790         if(z >= 0) {
   7791             m_PSInfoSBR->qmLimBoost[m] = r >> MIN(31, z);
   7792         }
   7793         else {
   7794             z = MIN(30, -z);
   7795             r = CLIP_2N_SHIFT30(r, z);
   7796             m_PSInfoSBR->qmLimBoost[m] = r;
   7797         }
   7798 
   7799         q = MULSHIFT32(m_PSInfoSBR->smBuf[m], gBoost) << 2; /* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */
   7800         r = SqrtFix(q, fbitsDQ - 2, &z);
   7801         z -= FBITS_OUT_QMFA; /* justify for adding to signal (xBuf) later */
   7802         if(z >= 0) {
   7803             m_PSInfoSBR->smBoost[m] = r >> MIN(31, z);
   7804         }
   7805         else {
   7806             z = MIN(30, -z);
   7807             r = CLIP_2N_SHIFT30(r, z);
   7808             m_PSInfoSBR->smBoost[m] = r;
   7809         }
   7810     }
   7811 }
   7812 /***********************************************************************************************************************
   7813  * Function:    CalcGain
   7814  *
   7815  * Description: calculate and apply proper gain to HF components in one envelope
   7816  *                (4.6.18.7.5)
   7817  *
   7818  * Inputs:      initialized SBRHeader struct for this SCE/CPE block
   7819  *              initialized SBRGrid struct for this channel
   7820  *              initialized SBRFreq struct for this SCE/CPE block
   7821  *              initialized SBRChan struct for this channel
   7822  *              index of current channel (0 for SCE, 0 or 1 for CPE)
   7823  *              index of current envelope
   7824  *
   7825  * Outputs:     envelope gain, sinusoids and noise after scaling
   7826  *
   7827  * Return:      none
   7828  **********************************************************************************************************************/
   7829 void CalcGain(SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env) {
   7830 
   7831     int lim, fbitsDQ;
   7832 
   7833     /* initialize to -1 so that mapping limiter bands to env/noise bands works right on first pass */
   7834     m_PSInfoSBR->envBand = -1;
   7835     m_PSInfoSBR->noiseFloorBand = -1;
   7836     m_PSInfoSBR->sBand = -1;
   7837     m_PSInfoSBR->highBand = -1;
   7838 
   7839     fbitsDQ = (FBITS_OUT_DQ_ENV - m_PSInfoSBR->envDataDequantScale[ch][env]); /* Q(29 - optional scalefactor) */
   7840     for(lim = 0; lim < sbrFreq->nLimiter; lim++) {
   7841         /* the QMF bands are divided into lim regions (consecutive, non-overlapping) */
   7842         CalcMaxGain(sbrHdr, sbrGrid, sbrFreq, ch, env, lim, fbitsDQ);
   7843         CalcComponentGains(sbrGrid, sbrFreq, sbrChan, ch, env, lim, fbitsDQ);
   7844         ApplyBoost(sbrFreq, lim, fbitsDQ);
   7845     }
   7846 }
   7847 
   7848 /* hSmooth table from 4.7.18.7.6, format = Q31 */
   7849 static const int hSmoothCoef[MAX_NUM_SMOOTH_COEFS] PROGMEM = { 0x2aaaaaab, 0x2697a512, 0x1becfa68, 0x0ebdb043,
   7850         0x04130598, };
   7851 
   7852 /***********************************************************************************************************************
   7853  * Function:    MapHF
   7854  *
   7855  * Description: map HF components to proper QMF bands, with optional gain smoothing
   7856  *                filter (4.6.18.7.6)
   7857  *
   7858  * Inputs:      initialized SBRHeader struct for this SCE/CPE block
   7859  *              initialized SBRGrid struct for this channel
   7860  *              initialized SBRFreq struct for this SCE/CPE block
   7861  *              initialized SBRChan struct for this channel
   7862  *              index of current envelope
   7863  *              reset flag (can be non-zero for first envelope only)
   7864  *
   7865  * Outputs:     complete reconstructed subband QMF samples for this envelope
   7866  *
   7867  * Return:      none
   7868  *
   7869  * Notes:       ensures that output has >= MIN_GBITS_IN_QMFS guard bits,
   7870  *                so it's not necessary to check anything in the synth QMF
   7871  **********************************************************************************************************************/
   7872 void MapHF(SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int hfReset) {
   7873 
   7874     int noiseTabIndex, sinIndex, gainNoiseIndex, hSL;
   7875     int i, iStart, iEnd, m, idx, j, s, n, smre, smim;
   7876     int gFilt, qFilt, xre, xim, gbMask, gbIdx;
   7877     int *XBuf;
   7878 
   7879     noiseTabIndex = sbrChan->noiseTabIndex;
   7880     sinIndex = sbrChan->sinIndex;
   7881     gainNoiseIndex = sbrChan->gainNoiseIndex; /* oldest entries in filter delay buffer */
   7882 
   7883     if(hfReset) noiseTabIndex = 2; /* starts at 1, double since complex */
   7884     hSL = (sbrHdr->smoothMode ? 0 : 4);
   7885 
   7886     if(hfReset) {
   7887         for(i = 0; i < hSL; i++) {
   7888             for(m = 0; m < sbrFreq->numQMFBands; m++) {
   7889                 sbrChan->gTemp[gainNoiseIndex][m] = m_PSInfoSBR->gLimBoost[m];
   7890                 sbrChan->qTemp[gainNoiseIndex][m] = m_PSInfoSBR->qmLimBoost[m];
   7891             }
   7892             gainNoiseIndex++;
   7893             if(gainNoiseIndex == MAX_NUM_SMOOTH_COEFS) gainNoiseIndex = 0;
   7894         } ASSERT(env == 0); /* should only be reset when env == 0 */
   7895     }
   7896 
   7897     iStart = sbrGrid->envTimeBorder[env];
   7898     iEnd = sbrGrid->envTimeBorder[env + 1];
   7899     for(i = iStart; i < iEnd; i++) {
   7900         /* save new values in temp buffers (delay)
   7901          * we only store MAX_NUM_SMOOTH_COEFS most recent values,
   7902          *   so don't keep storing the same value over and over
   7903          */
   7904         if(i - iStart < MAX_NUM_SMOOTH_COEFS) {
   7905             for(m = 0; m < sbrFreq->numQMFBands; m++) {
   7906                 sbrChan->gTemp[gainNoiseIndex][m] = m_PSInfoSBR->gLimBoost[m];
   7907                 sbrChan->qTemp[gainNoiseIndex][m] = m_PSInfoSBR->qmLimBoost[m];
   7908             }
   7909         }
   7910 
   7911         /* see 4.6.18.7.6 */
   7912         XBuf = m_PSInfoSBR->XBuf[i + HF_ADJ][sbrFreq->kStart];
   7913         gbMask = 0;
   7914         for(m = 0; m < sbrFreq->numQMFBands; m++) {
   7915             if(env == m_PSInfoSBR->la || env == sbrChan->laPrev) {
   7916                 /* no smoothing filter for gain, and qFilt = 0 (only need to do once) */
   7917                 if(i == iStart) {
   7918                     m_PSInfoSBR->gFiltLast[m] = sbrChan->gTemp[gainNoiseIndex][m];
   7919                     m_PSInfoSBR->qFiltLast[m] = 0;
   7920                 }
   7921             }
   7922             else if(hSL == 0) {
   7923                 /* no smoothing filter for gain, (only need to do once) */
   7924                 if(i == iStart) {
   7925                     m_PSInfoSBR->gFiltLast[m] = sbrChan->gTemp[gainNoiseIndex][m];
   7926                     m_PSInfoSBR->qFiltLast[m] = sbrChan->qTemp[gainNoiseIndex][m];
   7927                 }
   7928             }
   7929             else {
   7930                 /* apply smoothing filter to gain and noise (after MAX_NUM_SMOOTH_COEFS, it's always the same) */
   7931                 if(i - iStart < MAX_NUM_SMOOTH_COEFS) {
   7932                     gFilt = 0;
   7933                     qFilt = 0;
   7934                     idx = gainNoiseIndex;
   7935                     for(j = 0; j < MAX_NUM_SMOOTH_COEFS; j++) {
   7936                         /* sum(abs(hSmoothCoef[j])) for all j < 1.0 */
   7937                         gFilt += MULSHIFT32(sbrChan->gTemp[idx][m], hSmoothCoef[j]);
   7938                         qFilt += MULSHIFT32(sbrChan->qTemp[idx][m], hSmoothCoef[j]);
   7939                         idx--;
   7940                         if(idx < 0) idx += MAX_NUM_SMOOTH_COEFS;
   7941                     }
   7942                     m_PSInfoSBR->gFiltLast[m] = gFilt << 1; /* restore to Q(FBITS_GLIM_BOOST) (gain of filter < 1.0, so no overflow) */
   7943                     m_PSInfoSBR->qFiltLast[m] = qFilt << 1; /* restore to Q(FBITS_QLIM_BOOST) */
   7944                 }
   7945             }
   7946 
   7947             if(m_PSInfoSBR->smBoost[m] != 0) {
   7948                 /* add scaled signal and sinusoid, don't add noise (qFilt = 0) */
   7949                 smre = m_PSInfoSBR->smBoost[m];
   7950                 smim = smre;
   7951 
   7952                 /* sinIndex:  [0] xre += sm   [1] xim += sm*s   [2] xre -= sm   [3] xim -= sm*s  */
   7953                 s = (sinIndex >> 1); /* if 2 or 3, flip sign to subtract sm */
   7954                 s <<= 31;
   7955                 smre ^= (s >> 31);
   7956                 smre -= (s >> 31);
   7957                 s ^= ((m + sbrFreq->kStart) << 31);
   7958                 smim ^= (s >> 31);
   7959                 smim -= (s >> 31);
   7960 
   7961                 /* if sinIndex == 0 or 2, smim = 0; if sinIndex == 1 or 3, smre = 0 */
   7962                 s = sinIndex << 31;
   7963                 smim &= (s >> 31);
   7964                 s ^= 0x80000000;
   7965                 smre &= (s >> 31);
   7966 
   7967                 noiseTabIndex += 2; /* noise filtered by 0, but still need to bump index */
   7968             }
   7969             else {
   7970                 /* add scaled signal and scaled noise */
   7971                 qFilt = m_PSInfoSBR->qFiltLast[m];
   7972                 n = noiseTab[noiseTabIndex++];
   7973                 smre = MULSHIFT32(n, qFilt) >> (FBITS_QLIM_BOOST - 1 - FBITS_OUT_QMFA);
   7974 
   7975                 n = noiseTab[noiseTabIndex++];
   7976                 smim = MULSHIFT32(n, qFilt) >> (FBITS_QLIM_BOOST - 1 - FBITS_OUT_QMFA);
   7977             }
   7978             noiseTabIndex &= 1023; /* 512 complex numbers */
   7979 
   7980             gFilt = m_PSInfoSBR->gFiltLast[m];
   7981             xre = MULSHIFT32(gFilt, XBuf[0]);
   7982             xim = MULSHIFT32(gFilt, XBuf[1]);
   7983             xre = CLIP_2N_SHIFT30(xre, 32 - FBITS_GLIM_BOOST);
   7984             xim = CLIP_2N_SHIFT30(xim, 32 - FBITS_GLIM_BOOST);
   7985 
   7986             xre += smre;
   7987             *XBuf++ = xre;
   7988             xim += smim;
   7989             *XBuf++ = xim;
   7990 
   7991             gbMask |= FASTABS(xre);
   7992             gbMask |= FASTABS(xim);
   7993         }
   7994         /* update circular buffer index */
   7995         gainNoiseIndex++;
   7996         if(gainNoiseIndex == MAX_NUM_SMOOTH_COEFS) gainNoiseIndex = 0;
   7997 
   7998         sinIndex++;
   7999         sinIndex &= 3;
   8000 
   8001         /* ensure MIN_GBITS_IN_QMFS guard bits in output
   8002          * almost never occurs in practice, but checking here makes synth QMF logic very simple
   8003          */
   8004         if(gbMask >> (31 - MIN_GBITS_IN_QMFS)) {
   8005             XBuf = m_PSInfoSBR->XBuf[i + HF_ADJ][sbrFreq->kStart];
   8006             for(m = 0; m < sbrFreq->numQMFBands; m++) {
   8007                 xre = XBuf[0];
   8008                 xim = XBuf[1];
   8009                 xre = CLIP_2N(xre, (31 - MIN_GBITS_IN_QMFS));
   8010                 xim = CLIP_2N(xim, (31 - MIN_GBITS_IN_QMFS));
   8011                 *XBuf++ = xre;
   8012                 *XBuf++ = xim;
   8013             }
   8014             gbMask = CLIP_2N(gbMask, (31 - MIN_GBITS_IN_QMFS));
   8015         }
   8016         gbIdx = ((i + HF_ADJ) >> 5) & 0x01;
   8017         sbrChan->gbMask[gbIdx] |= gbMask;
   8018     }
   8019     sbrChan->noiseTabIndex = noiseTabIndex;
   8020     sbrChan->sinIndex = sinIndex;
   8021     sbrChan->gainNoiseIndex = gainNoiseIndex;
   8022 }
   8023 /***********************************************************************************************************************
   8024  * Function:    AdjustHighFreq
   8025  *
   8026  * Description: adjust high frequencies and add noise and sinusoids (4.6.18.7)
   8027  *
   8028  * Inputs:      initialized SBRHeader struct for this SCE/CPE block
   8029  *              initialized SBRGrid struct for this channel
   8030  *              initialized SBRFreq struct for this SCE/CPE block
   8031  *              initialized SBRChan struct for this channel
   8032  *              index of current channel (0 for SCE, 0 or 1 for CPE)
   8033  *
   8034  * Outputs:     complete reconstructed subband QMF samples for this channel
   8035  *
   8036  * Return:      none
   8037  **********************************************************************************************************************/
   8038 void AdjustHighFreq(SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) {
   8039 
   8040     int i, env, hfReset;
   8041     uint8_t frameClass, pointer;
   8042 
   8043     frameClass = sbrGrid->frameClass;
   8044     pointer  = sbrGrid->pointer;
   8045 
   8046     /* derive la from table 4.159 */
   8047     if ((frameClass == SBR_GRID_FIXVAR || frameClass == SBR_GRID_VARVAR) && pointer > 0)
   8048         m_PSInfoSBR->la = sbrGrid->numEnv + 1 - pointer;
   8049     else if (frameClass == SBR_GRID_VARFIX && pointer > 1)
   8050         m_PSInfoSBR->la = pointer - 1;
   8051     else
   8052         m_PSInfoSBR->la = -1;
   8053 
   8054     /* for each envelope, estimate gain and adjust SBR QMF bands */
   8055     hfReset = sbrChan->reset;
   8056     for (env = 0; env < sbrGrid->numEnv; env++) {
   8057         EstimateEnvelope(sbrHdr, sbrGrid, sbrFreq, env);
   8058         CalcGain(sbrHdr, sbrGrid, sbrFreq, sbrChan, ch, env);
   8059         MapHF(sbrHdr, sbrGrid, sbrFreq, sbrChan, env, hfReset);
   8060         hfReset = 0;    /* only set for first envelope after header reset */
   8061     }
   8062 
   8063     /* set saved sine flags to 0 for QMF bands outside of current frequency range */
   8064     for (i = 0; i < sbrFreq->freqLimiter[0] + sbrFreq->kStart; i++)
   8065         sbrChan->addHarmonic[0][i] = 0;
   8066     for (i = sbrFreq->freqLimiter[sbrFreq->nLimiter] + sbrFreq->kStart; i < 64; i++)
   8067         sbrChan->addHarmonic[0][i] = 0;
   8068     sbrChan->addHarmonicFlag[0] = sbrChan->addHarmonicFlag[1];
   8069 
   8070     /* save la for next frame */
   8071     if (m_PSInfoSBR->la == sbrGrid->numEnv)
   8072         sbrChan->laPrev = 0;
   8073     else
   8074         sbrChan->laPrev = -1;
   8075 }
   8076 /***********************************************************************************************************************
   8077  * Function:    CalcCovariance1
   8078  *
   8079  * Description: calculate covariance matrix for p01, p12, p11, p22 (4.6.18.6.2)
   8080  *
   8081  * Inputs:      buffer of low-freq samples, starting at time index 0,
   8082  *                freq index = patch subband
   8083  *
   8084  * Outputs:     complex covariance elements p01re, p01im, p12re, p12im, p11re, p22re
   8085  *                (p11im = p22im = 0)
   8086  *              format = integer (Q0) * 2^N, with scalefactor N >= 0
   8087  *
   8088  * Return:      scalefactor N
   8089  *
   8090  * Notes:       outputs are normalized to have 1 GB (sign in at least top 2 bits)
   8091  **********************************************************************************************************************/
   8092 int CalcCovariance1(int *XBuf, int *p01reN, int *p01imN, int *p12reN, int *p12imN, int *p11reN, int *p22reN) {
   8093 
   8094     int accBuf[2*6];
   8095     int n, z, s, loShift, hiShift, gbMask;
   8096     U64 p01re, p01im, p12re, p12im, p11re, p22re;
   8097 
   8098     CVKernel1(XBuf, accBuf);
   8099     p01re.r.lo32 = accBuf[0];   p01re.r.hi32 = accBuf[1];
   8100     p01im.r.lo32 = accBuf[2];   p01im.r.hi32 = accBuf[3];
   8101     p11re.r.lo32 = accBuf[4];   p11re.r.hi32 = accBuf[5];
   8102     p12re.r.lo32 = accBuf[6];   p12re.r.hi32 = accBuf[7];
   8103     p12im.r.lo32 = accBuf[8];   p12im.r.hi32 = accBuf[9];
   8104     p22re.r.lo32 = accBuf[10];  p22re.r.hi32 = accBuf[11];
   8105 
   8106     /* 64-bit accumulators now have 2*FBITS_OUT_QMFA fraction bits
   8107      * want to scale them down to integers (32-bit signed, Q0)
   8108      *   with scale factor of 2^n, n >= 0
   8109      * leave 2 GB's for calculating determinant, so take top 30 non-zero bits
   8110      */
   8111     gbMask  = ((p01re.r.hi32) ^ (p01re.r.hi32 >> 31)) | ((p01im.r.hi32) ^ (p01im.r.hi32 >> 31));
   8112     gbMask |= ((p12re.r.hi32) ^ (p12re.r.hi32 >> 31)) | ((p12im.r.hi32) ^ (p12im.r.hi32 >> 31));
   8113     gbMask |= ((p11re.r.hi32) ^ (p11re.r.hi32 >> 31)) | ((p22re.r.hi32) ^ (p22re.r.hi32 >> 31));
   8114     if (gbMask == 0) {
   8115         s = p01re.r.hi32 >> 31; gbMask  = (p01re.r.lo32 ^ s) - s;
   8116         s = p01im.r.hi32 >> 31; gbMask |= (p01im.r.lo32 ^ s) - s;
   8117         s = p12re.r.hi32 >> 31; gbMask |= (p12re.r.lo32 ^ s) - s;
   8118         s = p12im.r.hi32 >> 31; gbMask |= (p12im.r.lo32 ^ s) - s;
   8119         s = p11re.r.hi32 >> 31; gbMask |= (p11re.r.lo32 ^ s) - s;
   8120         s = p22re.r.hi32 >> 31; gbMask |= (p22re.r.lo32 ^ s) - s;
   8121         z = 32 + CLZ(gbMask);
   8122     } else {
   8123         gbMask  = FASTABS(p01re.r.hi32) | FASTABS(p01im.r.hi32);
   8124         gbMask |= FASTABS(p12re.r.hi32) | FASTABS(p12im.r.hi32);
   8125         gbMask |= FASTABS(p11re.r.hi32) | FASTABS(p22re.r.hi32);
   8126         z = CLZ(gbMask);
   8127     }
   8128 
   8129     n = 64 - z; /* number of non-zero bits in bottom of 64-bit word */
   8130     if (n <= 30) {
   8131         loShift = (30 - n);
   8132         *p01reN = p01re.r.lo32 << loShift;  *p01imN = p01im.r.lo32 << loShift;
   8133         *p12reN = p12re.r.lo32 << loShift;  *p12imN = p12im.r.lo32 << loShift;
   8134         *p11reN = p11re.r.lo32 << loShift;  *p22reN = p22re.r.lo32 << loShift;
   8135         return -(loShift + 2*FBITS_OUT_QMFA);
   8136     } else if (n < 32 + 30) {
   8137         loShift = (n - 30);
   8138         hiShift = 32 - loShift;
   8139         *p01reN = (p01re.r.hi32 << hiShift) | (p01re.r.lo32 >> loShift);
   8140         *p01imN = (p01im.r.hi32 << hiShift) | (p01im.r.lo32 >> loShift);
   8141         *p12reN = (p12re.r.hi32 << hiShift) | (p12re.r.lo32 >> loShift);
   8142         *p12imN = (p12im.r.hi32 << hiShift) | (p12im.r.lo32 >> loShift);
   8143         *p11reN = (p11re.r.hi32 << hiShift) | (p11re.r.lo32 >> loShift);
   8144         *p22reN = (p22re.r.hi32 << hiShift) | (p22re.r.lo32 >> loShift);
   8145         return (loShift - 2*FBITS_OUT_QMFA);
   8146     } else {
   8147         hiShift = n - (32 + 30);
   8148         *p01reN = p01re.r.hi32 >> hiShift;  *p01imN = p01im.r.hi32 >> hiShift;
   8149         *p12reN = p12re.r.hi32 >> hiShift;  *p12imN = p12im.r.hi32 >> hiShift;
   8150         *p11reN = p11re.r.hi32 >> hiShift;  *p22reN = p22re.r.hi32 >> hiShift;
   8151         return (32 - 2*FBITS_OUT_QMFA - hiShift);
   8152     }
   8153 
   8154     return 0;
   8155 }
   8156 /***********************************************************************************************************************
   8157  * Function:    CalcCovariance2
   8158  *
   8159  * Description: calculate covariance matrix for p02 (4.6.18.6.2)
   8160  *
   8161  * Inputs:      buffer of low-freq samples, starting at time index = 0,
   8162  *                freq index = patch subband
   8163  *
   8164  * Outputs:     complex covariance element p02re, p02im
   8165  *              format = integer (Q0) * 2^N, with scalefactor N >= 0
   8166  *
   8167  * Return:      scalefactor N
   8168  *
   8169  * Notes:       outputs are normalized to have 1 GB (sign in at least top 2 bits)
   8170  **********************************************************************************************************************/
   8171 int CalcCovariance2(int *XBuf, int *p02reN, int *p02imN) {
   8172 
   8173     U64 p02re, p02im;
   8174     int n, z, s, loShift, hiShift, gbMask;
   8175     int accBuf[2*2];
   8176 
   8177     CVKernel2(XBuf, accBuf);
   8178     p02re.r.lo32 = accBuf[0];
   8179     p02re.r.hi32 = accBuf[1];
   8180     p02im.r.lo32 = accBuf[2];
   8181     p02im.r.hi32 = accBuf[3];
   8182 
   8183     /* 64-bit accumulators now have 2*FBITS_OUT_QMFA fraction bits
   8184      * want to scale them down to integers (32-bit signed, Q0)
   8185      *   with scale factor of 2^n, n >= 0
   8186      * leave 1 GB for calculating determinant, so take top 30 non-zero bits
   8187      */
   8188     gbMask  = ((p02re.r.hi32) ^ (p02re.r.hi32 >> 31)) | ((p02im.r.hi32) ^ (p02im.r.hi32 >> 31));
   8189     if (gbMask == 0) {
   8190         s = p02re.r.hi32 >> 31; gbMask  = (p02re.r.lo32 ^ s) - s;
   8191         s = p02im.r.hi32 >> 31; gbMask |= (p02im.r.lo32 ^ s) - s;
   8192         z = 32 + CLZ(gbMask);
   8193     } else {
   8194         gbMask  = FASTABS(p02re.r.hi32) | FASTABS(p02im.r.hi32);
   8195         z = CLZ(gbMask);
   8196     }
   8197     n = 64 - z; /* number of non-zero bits in bottom of 64-bit word */
   8198 
   8199     if (n <= 30) {
   8200         loShift = (30 - n);
   8201         *p02reN = p02re.r.lo32 << loShift;
   8202         *p02imN = p02im.r.lo32 << loShift;
   8203         return -(loShift + 2*FBITS_OUT_QMFA);
   8204     } else if (n < 32 + 30) {
   8205         loShift = (n - 30);
   8206         hiShift = 32 - loShift;
   8207         *p02reN = (p02re.r.hi32 << hiShift) | (p02re.r.lo32 >> loShift);
   8208         *p02imN = (p02im.r.hi32 << hiShift) | (p02im.r.lo32 >> loShift);
   8209         return (loShift - 2*FBITS_OUT_QMFA);
   8210     } else {
   8211         hiShift = n - (32 + 30);
   8212         *p02reN = p02re.r.hi32 >> hiShift;
   8213         *p02imN = p02im.r.hi32 >> hiShift;
   8214         return (32 - 2*FBITS_OUT_QMFA - hiShift);
   8215     }
   8216 
   8217     return 0;
   8218 }
   8219 /***********************************************************************************************************************
   8220  * Function:    CalcLPCoefs
   8221  *
   8222  * Description: calculate linear prediction coefficients for one subband (4.6.18.6.2)
   8223  *
   8224  * Inputs:      buffer of low-freq samples, starting at time index = 0,
   8225  *                freq index = patch subband
   8226  *              number of guard bits in input sample buffer
   8227  *
   8228  * Outputs:     complex LP coefficients a0re, a0im, a1re, a1im, format = Q29
   8229  *
   8230  * Return:      none
   8231  *
   8232  * Notes:       output coefficients (a0re, a0im, a1re, a1im) clipped to range (-4, 4)
   8233  *              if the comples coefficients have magnitude >= 4.0, they are all
   8234  *                set to 0 (see spec)
   8235  **********************************************************************************************************************/
   8236 void CalcLPCoefs(int *XBuf, int *a0re, int *a0im, int *a1re, int *a1im, int gb) {
   8237 
   8238     int zFlag, n1, n2, nd, d, dInv, tre, tim;
   8239     int p01re, p01im, p02re, p02im, p12re, p12im, p11re, p22re;
   8240 
   8241     /* pre-scale to avoid overflow - probably never happens in practice (see QMFA)
   8242      *   max bit growth per accumulator = 38*2 = 76 mul-adds (X * X)
   8243      *   using 64-bit MADD, so if X has n guard bits, X*X has 2n+1 guard bits
   8244      *   gain 1 extra sign bit per multiply, so ensure ceil(log2(76/2) / 2) = 3 guard bits on inputs
   8245      */
   8246     if (gb < 3) {
   8247         nd = 3 - gb;
   8248         for (n1 = (NUM_TIME_SLOTS*SAMPLES_PER_SLOT + 6 + 2); n1 != 0; n1--) {
   8249             XBuf[0] >>= nd; XBuf[1] >>= nd;
   8250             XBuf += (2*64);
   8251         }
   8252         XBuf -= (2*64*(NUM_TIME_SLOTS*SAMPLES_PER_SLOT + 6 + 2));
   8253     }
   8254 
   8255     /* calculate covariance elements */
   8256     n1 = CalcCovariance1(XBuf, &p01re, &p01im, &p12re, &p12im, &p11re, &p22re);
   8257     n2 = CalcCovariance2(XBuf, &p02re, &p02im);
   8258 
   8259     /* normalize everything to larger power of 2 scalefactor, call it n1 */
   8260     if (n1 < n2) {
   8261         nd = MIN(n2 - n1, 31);
   8262         p01re >>= nd;   p01im >>= nd;
   8263         p12re >>= nd;   p12im >>= nd;
   8264         p11re >>= nd;   p22re >>= nd;
   8265         n1 = n2;
   8266     } else if (n1 > n2) {
   8267         nd = MIN(n1 - n2, 31);
   8268         p02re >>= nd;   p02im >>= nd;
   8269     }
   8270 
   8271     /* calculate determinant of covariance matrix (at least 1 GB in pXX) */
   8272     d = MULSHIFT32(p12re, p12re) + MULSHIFT32(p12im, p12im);
   8273     d = MULSHIFT32(d, RELAX_COEF) << 1;
   8274     d = MULSHIFT32(p11re, p22re) - d;
   8275     ASSERT(d >= 0); /* should never be < 0 */
   8276 
   8277     zFlag = 0;
   8278     *a0re = *a0im = 0;
   8279     *a1re = *a1im = 0;
   8280     if (d > 0) {
   8281         /* input =   Q31  d    = Q(-2*n1 - 32 + nd) = Q31 * 2^(31 + 2*n1 + 32 - nd)
   8282          * inverse = Q29  dInv = Q29 * 2^(-31 - 2*n1 - 32 + nd) = Q(29 + 31 + 2*n1 + 32 - nd)
   8283          *
   8284          * numerator has same Q format as d, since it's sum of normalized squares
   8285          * so num * inverse = Q(-2*n1 - 32) * Q(29 + 31 + 2*n1 + 32 - nd)
   8286          *                  = Q(29 + 31 - nd), drop low 32 in MULSHIFT32
   8287          *                  = Q(29 + 31 - 32 - nd) = Q(28 - nd)
   8288          */
   8289         nd = CLZ(d) - 1;
   8290         d <<= nd;
   8291         dInv = InvRNormalized(d);
   8292 
   8293         /* 1 GB in pXX */
   8294         tre = MULSHIFT32(p01re, p12re) - MULSHIFT32(p01im, p12im) - MULSHIFT32(p02re, p11re);
   8295         tre = MULSHIFT32(tre, dInv);
   8296         tim = MULSHIFT32(p01re, p12im) + MULSHIFT32(p01im, p12re) - MULSHIFT32(p02im, p11re);
   8297         tim = MULSHIFT32(tim, dInv);
   8298 
   8299         /* if d is extremely small, just set coefs to 0 (would have poor precision anyway) */
   8300         if (nd > 28 || (FASTABS(tre) >> (28 - nd)) >= 4 || (FASTABS(tim) >> (28 - nd)) >= 4) {
   8301             zFlag = 1;
   8302         } else {
   8303             *a1re = tre << (FBITS_LPCOEFS - 28 + nd);   /* i.e. convert Q(28 - nd) to Q(29) */
   8304             *a1im = tim << (FBITS_LPCOEFS - 28 + nd);
   8305         }
   8306     }
   8307 
   8308     if (p11re) {
   8309         /* input =   Q31  p11re = Q(-n1 + nd) = Q31 * 2^(31 + n1 - nd)
   8310          * inverse = Q29  dInv  = Q29 * 2^(-31 - n1 + nd) = Q(29 + 31 + n1 - nd)
   8311          *
   8312          * numerator is Q(-n1 - 3)
   8313          * so num * inverse = Q(-n1 - 3) * Q(29 + 31 + n1 - nd)
   8314          *                  = Q(29 + 31 - 3 - nd), drop low 32 in MULSHIFT32
   8315          *                  = Q(29 + 31 - 3 - 32 - nd) = Q(25 - nd)
   8316          */
   8317         nd = CLZ(p11re) - 1;    /* assume positive */
   8318         p11re <<= nd;
   8319         dInv = InvRNormalized(p11re);
   8320 
   8321         /* a1re, a1im = Q29, so scaled by (n1 + 3) */
   8322         tre = (p01re >> 3) + MULSHIFT32(p12re, *a1re) + MULSHIFT32(p12im, *a1im);
   8323         tre = -MULSHIFT32(tre, dInv);
   8324         tim = (p01im >> 3) - MULSHIFT32(p12im, *a1re) + MULSHIFT32(p12re, *a1im);
   8325         tim = -MULSHIFT32(tim, dInv);
   8326 
   8327         if (nd > 25 || (FASTABS(tre) >> (25 - nd)) >= 4 || (FASTABS(tim) >> (25 - nd)) >= 4) {
   8328             zFlag = 1;
   8329         } else {
   8330             *a0re = tre << (FBITS_LPCOEFS - 25 + nd);   /* i.e. convert Q(25 - nd) to Q(29) */
   8331             *a0im = tim << (FBITS_LPCOEFS - 25 + nd);
   8332         }
   8333     }
   8334 
   8335     /* see 4.6.18.6.2 - if magnitude of a0 or a1 >= 4 then a0 = a1 = 0
   8336      * i.e. a0re < 4, a0im < 4, a1re < 4, a1im < 4
   8337      * Q29*Q29 = Q26
   8338      */
   8339     if (zFlag || MULSHIFT32(*a0re, *a0re) + MULSHIFT32(*a0im, *a0im) >= MAG_16 || MULSHIFT32(*a1re, *a1re) + MULSHIFT32(*a1im, *a1im) >= MAG_16) {
   8340         *a0re = *a0im = 0;
   8341         *a1re = *a1im = 0;
   8342     }
   8343 
   8344     /* no need to clip - we never changed the XBuf data, just used it to calculate a0 and a1 */
   8345     if (gb < 3) {
   8346         nd = 3 - gb;
   8347         for (n1 = (NUM_TIME_SLOTS*SAMPLES_PER_SLOT + 6 + 2); n1 != 0; n1--) {
   8348             XBuf[0] <<= nd; XBuf[1] <<= nd;
   8349             XBuf += (2*64);
   8350         }
   8351     }
   8352 }
   8353 /***********************************************************************************************************************
   8354  * Function:    GenerateHighFreq
   8355  *
   8356  * Description: generate high frequencies with SBR (4.6.18.6)
   8357  *
   8358  * Inputs:      initialized SBRGrid struct for this channel
   8359  *              initialized SBRFreq struct for this SCE/CPE block
   8360  *              initialized SBRChan struct for this channel
   8361  *              index of current channel (0 for SCE, 0 or 1 for CPE)
   8362  *
   8363  * Outputs:     new high frequency samples starting at frequency kStart
   8364  *
   8365  * Return:      none
   8366  **********************************************************************************************************************/
   8367 void GenerateHighFreq(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) {
   8368 
   8369     int band, newBW, c, t, gb, gbMask, gbIdx;
   8370     int currPatch, p, x, k, g, i, iStart, iEnd, bw, bwsq;
   8371     int a0re, a0im, a1re, a1im;
   8372     int x1re, x1im, x2re, x2im;
   8373     int ACCre, ACCim;
   8374     int *XBufLo, *XBufHi;
   8375     (void) ch;
   8376 
   8377     /* calculate array of chirp factors */
   8378     for (band = 0; band < sbrFreq->numNoiseFloorBands; band++) {
   8379         c = sbrChan->chirpFact[band];   /* previous (bwArray') */
   8380         newBW = newBWTab[sbrChan->invfMode[0][band]][sbrChan->invfMode[1][band]];
   8381 
   8382         /* weighted average of new and old (can't overflow - total gain = 1.0) */
   8383         if (newBW < c)
   8384             t = MULSHIFT32(newBW, 0x60000000) + MULSHIFT32(0x20000000, c);  /* new is smaller: 0.75*new + 0.25*old */
   8385         else
   8386             t = MULSHIFT32(newBW, 0x74000000) + MULSHIFT32(0x0c000000, c);  /* new is larger: 0.90625*new + 0.09375*old */
   8387         t <<= 1;
   8388 
   8389         if (t < 0x02000000) /* below 0.015625, clip to 0 */
   8390             t = 0;
   8391         if (t > 0x7f800000) /* clip to 0.99609375 */
   8392             t = 0x7f800000;
   8393 
   8394         /* save curr as prev for next time */
   8395         sbrChan->chirpFact[band] = t;
   8396         sbrChan->invfMode[0][band] = sbrChan->invfMode[1][band];
   8397     }
   8398 
   8399     iStart = sbrGrid->envTimeBorder[0] + HF_ADJ;
   8400     iEnd =   sbrGrid->envTimeBorder[sbrGrid->numEnv] + HF_ADJ;
   8401 
   8402     /* generate new high freqs from low freqs, patches, and chirp factors */
   8403     k = sbrFreq->kStart;
   8404     g = 0;
   8405     bw = sbrChan->chirpFact[g];
   8406     bwsq = MULSHIFT32(bw, bw) << 1;
   8407 
   8408     gbMask = (sbrChan->gbMask[0] | sbrChan->gbMask[1]); /* older 32 | newer 8 */
   8409     gb = CLZ(gbMask) - 1;
   8410 
   8411     for (currPatch = 0; currPatch < sbrFreq->numPatches; currPatch++) {
   8412         for (x = 0; x < sbrFreq->patchNumSubbands[currPatch]; x++) {
   8413             /* map k to corresponding noise floor band */
   8414             if (k >= sbrFreq->freqNoise[g+1]) {
   8415                 g++;
   8416                 bw = sbrChan->chirpFact[g];     /* Q31 */
   8417                 bwsq = MULSHIFT32(bw, bw) << 1; /* Q31 */
   8418             }
   8419 
   8420             p = sbrFreq->patchStartSubband[currPatch] + x;  /* low QMF band */
   8421             XBufHi = m_PSInfoSBR->XBuf[iStart][k];
   8422             if (bw) {
   8423                 CalcLPCoefs(m_PSInfoSBR->XBuf[0][p], &a0re, &a0im, &a1re, &a1im, gb);
   8424 
   8425                 a0re = MULSHIFT32(bw, a0re);    /* Q31 * Q29 = Q28 */
   8426                 a0im = MULSHIFT32(bw, a0im);
   8427                 a1re = MULSHIFT32(bwsq, a1re);
   8428                 a1im = MULSHIFT32(bwsq, a1im);
   8429 
   8430                 XBufLo = m_PSInfoSBR->XBuf[iStart-2][p];
   8431 
   8432                 x2re = XBufLo[0];   /* RE{XBuf[n-2]} */
   8433                 x2im = XBufLo[1];   /* IM{XBuf[n-2]} */
   8434                 XBufLo += (64*2);
   8435 
   8436                 x1re = XBufLo[0];   /* RE{XBuf[n-1]} */
   8437                 x1im = XBufLo[1];   /* IM{XBuf[n-1]} */
   8438                 XBufLo += (64*2);
   8439 
   8440                 for (i = iStart; i < iEnd; i++) {
   8441                     /* a0re/im, a1re/im are Q28 with at least 1 GB,
   8442                      *   so the summing for AACre/im is fine (1 GB in, plus 1 from MULSHIFT32)
   8443                      */
   8444                     ACCre = MULSHIFT32(x2re, a1re) - MULSHIFT32(x2im, a1im);
   8445                     ACCim = MULSHIFT32(x2re, a1im) + MULSHIFT32(x2im, a1re);
   8446                     x2re = x1re;
   8447                     x2im = x1im;
   8448 
   8449                     ACCre += MULSHIFT32(x1re, a0re) - MULSHIFT32(x1im, a0im);
   8450                     ACCim += MULSHIFT32(x1re, a0im) + MULSHIFT32(x1im, a0re);
   8451                     x1re = XBufLo[0];   /* RE{XBuf[n]} */
   8452                     x1im = XBufLo[1];   /* IM{XBuf[n]} */
   8453                     XBufLo += (64*2);
   8454 
   8455                     /* lost 4 fbits when scaling by a0re/im, a1re/im (Q28) */
   8456                     ACCre = CLIP_2N_SHIFT30(ACCre, 4);
   8457                     ACCre += x1re;
   8458                     ACCim = CLIP_2N_SHIFT30(ACCim, 4);
   8459                     ACCim += x1im;
   8460 
   8461                     XBufHi[0] = ACCre;
   8462                     XBufHi[1] = ACCim;
   8463                     XBufHi += (64*2);
   8464 
   8465                     /* update guard bit masks */
   8466                     gbMask  = FASTABS(ACCre);
   8467                     gbMask |= FASTABS(ACCim);
   8468                     gbIdx = (i >> 5) & 0x01;    /* 0 if i < 32, 1 if i >= 32 */
   8469                     sbrChan->gbMask[gbIdx] |= gbMask;
   8470                 }
   8471             } else {
   8472                 XBufLo = (int *)m_PSInfoSBR->XBuf[iStart][p];
   8473                 for (i = iStart; i < iEnd; i++) {
   8474                     XBufHi[0] = XBufLo[0];
   8475                     XBufHi[1] = XBufLo[1];
   8476                     XBufLo += (64*2);
   8477                     XBufHi += (64*2);
   8478                 }
   8479             }
   8480             k++;    /* high QMF band */
   8481         }
   8482     }
   8483 }
   8484 /***********************************************************************************************************************
   8485  * Function:    DecodeHuffmanScalar
   8486  *
   8487  * Description: decode one Huffman symbol from bitstream
   8488  *
   8489  * Inputs:      pointers to Huffman table and info struct
   8490  *              left-aligned bit buffer with >= huffTabInfo->maxBits bits
   8491  *
   8492  * Outputs:     decoded symbol in *val
   8493  *
   8494  * Return:      number of bits in symbol
   8495  *
   8496  * Notes:       assumes canonical Huffman codes:
   8497  *                first CW always 0, we have "count" CW's of length "nBits" bits
   8498  *                starting CW for codes of length nBits+1 =
   8499  *                  (startCW[nBits] + count[nBits]) << 1
   8500  *                if there are no codes at nBits, then we just keep << 1 each time
   8501  *                  (since count[nBits] = 0)
   8502  **********************************************************************************************************************/
   8503 int DecodeHuffmanScalar(const signed int *huffTab, const HuffInfo_t *huffTabInfo, unsigned int bitBuf,
   8504         signed int *val) {
   8505 
   8506     unsigned int count, start, shift, t;
   8507     const uint8_t *countPtr;
   8508     const signed int /*short*/*map;
   8509 
   8510     map = huffTab + huffTabInfo->offset;
   8511     countPtr = huffTabInfo->count;
   8512 
   8513     start = 0;
   8514     count = 0;
   8515     shift = 32;
   8516     do {
   8517         start += count;
   8518         start <<= 1;
   8519         map += count;
   8520         count = *countPtr++;
   8521         shift--;
   8522         t = (bitBuf >> shift) - start;
   8523     } while(t >= count);
   8524 
   8525     *val = (signed int) map[t];
   8526     return (countPtr - huffTabInfo->count);
   8527 }
   8528 /***********************************************************************************************************************
   8529  * Function:    DecodeOneSymbol
   8530  *
   8531  * Description: dequantize one Huffman symbol from bitstream,
   8532  *                using table huffTabSBR[huffTabIndex]
   8533  *
   8534  * Inputs:      index of Huffman table
   8535  *
   8536  * Outputs:     bitstream advanced by number of bits in codeword
   8537  *
   8538  * Return:      one decoded symbol
   8539  **********************************************************************************************************************/
   8540 int DecodeOneSymbol(int huffTabIndex) {
   8541 
   8542     int nBits, val;
   8543     unsigned int bitBuf;
   8544     const HuffInfo_t *hi;
   8545 
   8546     hi = &(huffTabSBRInfo[huffTabIndex]);
   8547 
   8548     bitBuf = GetBitsNoAdvance(hi->maxBits) << (32 - hi->maxBits);
   8549     nBits = DecodeHuffmanScalar(huffTabSBR, hi, bitBuf, &val);
   8550     AdvanceBitstream(nBits);
   8551 
   8552     return val;
   8553 }
   8554 
   8555 /* [1.0, sqrt(2)], format = Q29 (one guard bit for decoupling) */
   8556 static const int envDQTab[2] PROGMEM = {0x20000000, 0x2d413ccc};
   8557 
   8558 /***********************************************************************************************************************
   8559  * Function:    DequantizeEnvelope
   8560  *
   8561  * Description: dequantize envelope scalefactors
   8562  *
   8563  * Inputs:      number of scalefactors to process
   8564  *              amplitude resolution flag for this frame (0 or 1)
   8565  *              quantized envelope scalefactors
   8566  *
   8567  * Outputs:     dequantized envelope scalefactors
   8568  *
   8569  * Return:      extra int bits in output (6 + expMax)
   8570  *              in other words, output format = Q(FBITS_OUT_DQ_ENV - (6 + expMax))
   8571  *
   8572  * Notes:       dequantized scalefactors have at least 2 GB
   8573  **********************************************************************************************************************/
   8574 int DequantizeEnvelope(int nBands, int ampRes, int8_t *envQuant, int *envDequant) {
   8575 
   8576     int exp, expMax, i, scalei;
   8577 
   8578     if(nBands <= 0) return 0;
   8579 
   8580     /* scan for largest dequant value (do separately from envelope decoding to keep code cleaner) */
   8581     expMax = 0;
   8582     for(i = 0; i < nBands; i++) {
   8583         if(envQuant[i] > expMax) expMax = envQuant[i];
   8584     }
   8585 
   8586     /* dequantized envelope gains
   8587      *   envDequant = 64*2^(envQuant / alpha) = 2^(6 + envQuant / alpha)
   8588      *     if ampRes == 0, alpha = 2 and range of envQuant = [0, 127]
   8589      *     if ampRes == 1, alpha = 1 and range of envQuant = [0, 63]
   8590      * also if coupling is on, envDequant is scaled by something in range [0, 2]
   8591      * so range of envDequant = [2^6, 2^69] (no coupling), [2^6, 2^70] (with coupling)
   8592      *
   8593      * typical range (from observation) of envQuant/alpha = [0, 27] --> largest envQuant ~= 2^33
   8594      * output: Q(29 - (6 + expMax))
   8595      *
   8596      * reference: 14496-3:2001(E)/4.6.18.3.5 and 14496-4:200X/FPDAM8/5.6.5.1.2.1.5
   8597      */
   8598     if(ampRes) {
   8599         do {
   8600             exp = *envQuant++;
   8601             scalei = MIN(expMax - exp, 31);
   8602             *envDequant++ = envDQTab[0] >> scalei;
   8603         } while(--nBands);
   8604 
   8605         return (6 + expMax);
   8606     }
   8607     else {
   8608         expMax >>= 1;
   8609         do {
   8610             exp = *envQuant++;
   8611             scalei = MIN(expMax - (exp >> 1), 31);
   8612             *envDequant++ = envDQTab[exp & 0x01] >> scalei;
   8613         } while(--nBands);
   8614 
   8615         return (6 + expMax);
   8616     }
   8617 
   8618 }
   8619 /***********************************************************************************************************************
   8620  * Function:    DequantizeNoise
   8621  *
   8622  * Description: dequantize noise scalefactors
   8623  *
   8624  * Inputs:      number of scalefactors to process
   8625  *              quantized noise scalefactors
   8626  *
   8627  * Outputs:     dequantized noise scalefactors, format = Q(FBITS_OUT_DQ_NOISE)
   8628  *
   8629  * Return:      none
   8630  *
   8631  * Notes:       dequantized scalefactors have at least 2 GB
   8632  **********************************************************************************************************************/
   8633 void DequantizeNoise(int nBands, int8_t *noiseQuant, int *noiseDequant) {
   8634 
   8635     int exp, scalei;
   8636 
   8637     if(nBands <= 0) return;
   8638 
   8639     /* dequantize noise floor gains (4.6.18.3.5):
   8640      *   noiseDequant = 2^(NOISE_FLOOR_OFFSET - noiseQuant)
   8641      *
   8642      * range of noiseQuant = [0, 30] (see 4.6.18.3.6), NOISE_FLOOR_OFFSET = 6
   8643      *   so range of noiseDequant = [2^-24, 2^6]
   8644      */
   8645     do {
   8646         exp = *noiseQuant++;
   8647         scalei = NOISE_FLOOR_OFFSET - exp + FBITS_OUT_DQ_NOISE; /* 6 + 24 - exp, exp = [0,30] */
   8648 
   8649         if(scalei < 0)
   8650             *noiseDequant++ = 0;
   8651         else if(scalei < 30)
   8652             *noiseDequant++ = 1 << scalei;
   8653         else
   8654             *noiseDequant++ = 0x3fffffff; /* leave 2 GB */
   8655 
   8656     } while(--nBands);
   8657 }
   8658 /***********************************************************************************************************************
   8659  * Function:    DecodeSBREnvelope
   8660  *
   8661  * Description: decode delta Huffman coded envelope scalefactors from bitstream
   8662  *
   8663  * Inputs:      initialized SBRGrid struct for this channel
   8664  *              initialized SBRFreq struct for this SCE/CPE block
   8665  *              initialized SBRChan struct for this channel
   8666  *              index of current channel (0 for SCE, 0 or 1 for CPE)
   8667  *
   8668  * Outputs:     dequantized env scalefactors for left channel (before decoupling)
   8669  *              dequantized env scalefactors for right channel (if coupling off)
   8670  *                or raw decoded env scalefactors for right channel (if coupling on)
   8671  *
   8672  * Return:      none
   8673  **********************************************************************************************************************/
   8674 void DecodeSBREnvelope(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) {
   8675 
   8676     int huffIndexTime, huffIndexFreq, env, envStartBits, band, nBands, sf, lastEnv;
   8677     int freqRes, freqResPrev, dShift, i;
   8678 
   8679     if(m_PSInfoSBR->couplingFlag && ch) {
   8680         dShift = 1;
   8681         if(sbrGrid->ampResFrame) {
   8682             huffIndexTime = HuffTabSBR_tEnv30b;
   8683             huffIndexFreq = HuffTabSBR_fEnv30b;
   8684             envStartBits = 5;
   8685         }
   8686         else {
   8687             huffIndexTime = HuffTabSBR_tEnv15b;
   8688             huffIndexFreq = HuffTabSBR_fEnv15b;
   8689             envStartBits = 6;
   8690         }
   8691     }
   8692     else {
   8693         dShift = 0;
   8694         if(sbrGrid->ampResFrame) {
   8695             huffIndexTime = HuffTabSBR_tEnv30;
   8696             huffIndexFreq = HuffTabSBR_fEnv30;
   8697             envStartBits = 6;
   8698         }
   8699         else {
   8700             huffIndexTime = HuffTabSBR_tEnv15;
   8701             huffIndexFreq = HuffTabSBR_fEnv15;
   8702             envStartBits = 7;
   8703         }
   8704     }
   8705 
   8706     /* range of envDataQuant[] = [0, 127] (see comments in DequantizeEnvelope() for reference) */
   8707     for(env = 0; env < sbrGrid->numEnv; env++) {
   8708         nBands = (sbrGrid->freqRes[env] ? sbrFreq->nHigh : sbrFreq->nLow);
   8709         freqRes = (sbrGrid->freqRes[env]);
   8710         freqResPrev = (env == 0 ? sbrGrid->freqResPrev : sbrGrid->freqRes[env - 1]);
   8711         lastEnv = (env == 0 ? sbrGrid->numEnvPrev - 1 : env - 1);
   8712         if(lastEnv < 0) lastEnv = 0; /* first frame */
   8713 
   8714         ASSERT(nBands <= MAX_QMF_BANDS);
   8715 
   8716         if(sbrChan->deltaFlagEnv[env] == 0) {
   8717             /* delta coding in freq */
   8718             sf = GetBits(envStartBits) << dShift;
   8719             sbrChan->envDataQuant[env][0] = sf;
   8720             for(band = 1; band < nBands; band++) {
   8721                 sf = DecodeOneSymbol(huffIndexFreq) << dShift;
   8722                 sbrChan->envDataQuant[env][band] = sf + sbrChan->envDataQuant[env][band - 1];
   8723             }
   8724         }
   8725         else if(freqRes == freqResPrev) {
   8726             /* delta coding in time - same freq resolution for both frames */
   8727             for(band = 0; band < nBands; band++) {
   8728                 sf = DecodeOneSymbol(huffIndexTime) << dShift;
   8729                 sbrChan->envDataQuant[env][band] = sf + sbrChan->envDataQuant[lastEnv][band];
   8730             }
   8731         }
   8732         else if(freqRes == 0 && freqResPrev == 1) {
   8733             /* delta coding in time - low freq resolution for new frame, high freq resolution for old frame */
   8734             for(band = 0; band < nBands; band++) {
   8735                 sf = DecodeOneSymbol(huffIndexTime) << dShift;
   8736                 sbrChan->envDataQuant[env][band] = sf;
   8737                 for(i = 0; i < sbrFreq->nHigh; i++) {
   8738                     if(sbrFreq->freqHigh[i] == sbrFreq->freqLow[band]) {
   8739                         sbrChan->envDataQuant[env][band] += sbrChan->envDataQuant[lastEnv][i];
   8740                         break;
   8741                     }
   8742                 }
   8743             }
   8744         }
   8745         else if(freqRes == 1 && freqResPrev == 0) {
   8746             /* delta coding in time - high freq resolution for new frame, low freq resolution for old frame */
   8747             for(band = 0; band < nBands; band++) {
   8748                 sf = DecodeOneSymbol(huffIndexTime) << dShift;
   8749                 sbrChan->envDataQuant[env][band] = sf;
   8750                 for(i = 0; i < sbrFreq->nLow; i++) {
   8751                     if(sbrFreq->freqLow[i] <= sbrFreq->freqHigh[band]
   8752                             && sbrFreq->freqHigh[band] < sbrFreq->freqLow[i + 1]) {
   8753                         sbrChan->envDataQuant[env][band] += sbrChan->envDataQuant[lastEnv][i];
   8754                         break;
   8755                     }
   8756                 }
   8757             }
   8758         }
   8759 
   8760         /* skip coupling channel */
   8761         if(ch != 1 || m_PSInfoSBR->couplingFlag != 1)
   8762             m_PSInfoSBR->envDataDequantScale[ch][env] = DequantizeEnvelope(nBands, sbrGrid->ampResFrame,
   8763                     sbrChan->envDataQuant[env], m_PSInfoSBR->envDataDequant[ch][env]);
   8764     }
   8765     sbrGrid->numEnvPrev = sbrGrid->numEnv;
   8766     sbrGrid->freqResPrev = sbrGrid->freqRes[sbrGrid->numEnv - 1];
   8767 }
   8768 /***********************************************************************************************************************
   8769  * Function:    DecodeSBRNoise
   8770  *
   8771  * Description: decode delta Huffman coded noise scalefactors from bitstream
   8772  *
   8773  * Inputs:      initialized SBRGrid struct for this channel
   8774  *              initialized SBRFreq struct for this SCE/CPE block
   8775  *              initialized SBRChan struct for this channel
   8776  *              index of current channel (0 for SCE, 0 or 1 for CPE)
   8777  *
   8778  * Outputs:     dequantized noise scalefactors for left channel (before decoupling)
   8779  *              dequantized noise scalefactors for right channel (if coupling off)
   8780  *                or raw decoded noise scalefactors for right channel (if coupling on)
   8781  *
   8782  * Return:      none
   8783  **********************************************************************************************************************/
   8784 void DecodeSBRNoise(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch) {
   8785 
   8786     int huffIndexTime, huffIndexFreq, noiseFloor, band, dShift, sf, lastNoiseFloor;
   8787 
   8788     if(m_PSInfoSBR->couplingFlag && ch) {
   8789         dShift = 1;
   8790         huffIndexTime = HuffTabSBR_tNoise30b;
   8791         huffIndexFreq = HuffTabSBR_fNoise30b;
   8792     }
   8793     else {
   8794         dShift = 0;
   8795         huffIndexTime = HuffTabSBR_tNoise30;
   8796         huffIndexFreq = HuffTabSBR_fNoise30;
   8797     }
   8798 
   8799     for(noiseFloor = 0; noiseFloor < sbrGrid->numNoiseFloors; noiseFloor++) {
   8800         lastNoiseFloor = (noiseFloor == 0 ? sbrGrid->numNoiseFloorsPrev - 1 : noiseFloor - 1);
   8801         if(lastNoiseFloor < 0) lastNoiseFloor = 0; /* first frame */
   8802 
   8803         ASSERT(sbrFreq->numNoiseFloorBands <= MAX_QMF_BANDS);
   8804 
   8805         if(sbrChan->deltaFlagNoise[noiseFloor] == 0) {
   8806             /* delta coding in freq */
   8807             sbrChan->noiseDataQuant[noiseFloor][0] = GetBits(5) << dShift;
   8808             for(band = 1; band < sbrFreq->numNoiseFloorBands; band++) {
   8809                 sf = DecodeOneSymbol(huffIndexFreq) << dShift;
   8810                 sbrChan->noiseDataQuant[noiseFloor][band] = sf + sbrChan->noiseDataQuant[noiseFloor][band - 1];
   8811             }
   8812         }
   8813         else {
   8814             /* delta coding in time */
   8815             for(band = 0; band < sbrFreq->numNoiseFloorBands; band++) {
   8816                 sf = DecodeOneSymbol(huffIndexTime) << dShift;
   8817                 sbrChan->noiseDataQuant[noiseFloor][band] = sf + sbrChan->noiseDataQuant[lastNoiseFloor][band];
   8818             }
   8819         }
   8820 
   8821         /* skip coupling channel */
   8822         if(ch != 1 || m_PSInfoSBR->couplingFlag != 1)
   8823             DequantizeNoise(sbrFreq->numNoiseFloorBands, sbrChan->noiseDataQuant[noiseFloor],
   8824                     m_PSInfoSBR->noiseDataDequant[ch][noiseFloor]);
   8825     }
   8826     sbrGrid->numNoiseFloorsPrev = sbrGrid->numNoiseFloors;
   8827 }
   8828 
   8829 /* dqTabCouple[i] = 2 / (1 + 2^(12 - i)), format = Q30 */
   8830 static const int dqTabCouple[25] PROGMEM = {
   8831     0x0007ff80, 0x000ffe00, 0x001ff802, 0x003fe010, 0x007f8080, 0x00fe03f8, 0x01f81f82, 0x03e0f83e,
   8832     0x07878788, 0x0e38e38e, 0x1999999a, 0x2aaaaaab, 0x40000000, 0x55555555, 0x66666666, 0x71c71c72,
   8833     0x78787878, 0x7c1f07c2, 0x7e07e07e, 0x7f01fc08, 0x7f807f80, 0x7fc01ff0, 0x7fe007fe, 0x7ff00200,
   8834     0x7ff80080,
   8835 };
   8836 
   8837 /***********************************************************************************************************************
   8838  * Function:    UncoupleSBREnvelope
   8839  *
   8840  * Description: scale dequantized envelope scalefactors according to channel
   8841  *                coupling rules
   8842  *
   8843  * Inputs:      initialized SBRGrid struct for this channel
   8844  *              initialized SBRFreq struct for this SCE/CPE block
   8845  *              initialized SBRChan struct for right channel including
   8846  *                quantized envelope scalefactors
   8847  *
   8848  * Outputs:     dequantized envelope data for left channel (after decoupling)
   8849  *              dequantized envelope data for right channel (after decoupling)
   8850  *
   8851  * Return:      none
   8852  **********************************************************************************************************************/
   8853 void UncoupleSBREnvelope(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChanR) {
   8854 
   8855     int env, band, nBands, scalei, E_1;
   8856 
   8857     scalei = (sbrGrid->ampResFrame ? 0 : 1);
   8858     for(env = 0; env < sbrGrid->numEnv; env++) {
   8859         nBands = (sbrGrid->freqRes[env] ? sbrFreq->nHigh : sbrFreq->nLow);
   8860         m_PSInfoSBR->envDataDequantScale[1][env] = m_PSInfoSBR->envDataDequantScale[0][env];
   8861         for(band = 0; band < nBands; band++) {
   8862             /* clip E_1 to [0, 24] (scalefactors approach 0 or 2) */
   8863             E_1 = sbrChanR->envDataQuant[env][band] >> scalei;
   8864             if(E_1 < 0) E_1 = 0;
   8865             if(E_1 > 24) E_1 = 24;
   8866 
   8867             /* envDataDequant[0] has 1 GB, so << by 2 is okay */
   8868             m_PSInfoSBR->envDataDequant[1][env][band] = MULSHIFT32(m_PSInfoSBR->envDataDequant[0][env][band],
   8869                     dqTabCouple[24 - E_1]) << 2;
   8870             m_PSInfoSBR->envDataDequant[0][env][band] = MULSHIFT32(m_PSInfoSBR->envDataDequant[0][env][band],
   8871                     dqTabCouple[E_1]) << 2;
   8872         }
   8873     }
   8874 }
   8875 /***********************************************************************************************************************
   8876  * Function:    UncoupleSBRNoise
   8877  *
   8878  * Description: scale dequantized noise floor scalefactors according to channel
   8879  *                coupling rules
   8880  *
   8881  * Inputs:      initialized SBRGrid struct for this channel
   8882  *              initialized SBRFreq struct for this SCE/CPE block
   8883  *              initialized SBRChan struct for this channel including
   8884  *                quantized noise scalefactors
   8885  *
   8886  * Outputs:     dequantized noise data for left channel (after decoupling)
   8887  *              dequantized noise data for right channel (after decoupling)
   8888  *
   8889  * Return:      none
   8890  **********************************************************************************************************************/
   8891 void UncoupleSBRNoise(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChanR) {
   8892 
   8893     int noiseFloor, band, Q_1;
   8894 
   8895     for (noiseFloor = 0; noiseFloor < sbrGrid->numNoiseFloors; noiseFloor++) {
   8896         for (band = 0; band < sbrFreq->numNoiseFloorBands; band++) {
   8897             /* Q_1 should be in range [0, 24] according to 4.6.18.3.6, but check to make sure */
   8898             Q_1 = sbrChanR->noiseDataQuant[noiseFloor][band];
   8899             if (Q_1 < 0)    Q_1 = 0;
   8900             if (Q_1 > 24)   Q_1 = 24;
   8901 
   8902             /* noiseDataDequant[0] has 1 GB, so << by 2 is okay */
   8903             m_PSInfoSBR->noiseDataDequant[1][noiseFloor][band] =
   8904                     MULSHIFT32(m_PSInfoSBR->noiseDataDequant[0][noiseFloor][band], dqTabCouple[24 - Q_1]) << 2;
   8905             m_PSInfoSBR->noiseDataDequant[0][noiseFloor][band] =
   8906                     MULSHIFT32(m_PSInfoSBR->noiseDataDequant[0][noiseFloor][band], dqTabCouple[Q_1]) << 2;
   8907         }
   8908     }
   8909 }
   8910 /***********************************************************************************************************************
   8911  * Function:    DecWindowOverlapNoClip
   8912  *
   8913  * Description: apply synthesis window, do overlap-add without clipping,
   8914  *                for winSequence LONG-LONG
   8915  *
   8916  * Inputs:      input buffer (output of type-IV DCT)
   8917  *              overlap buffer (saved from last time)
   8918  *              window type (sin or KBD) for input buffer
   8919  *              window type (sin or KBD) for overlap buffer
   8920  *
   8921  * Outputs:     one channel, one frame of 32-bit PCM, non-interleaved
   8922  *
   8923  * Return:      none
   8924  *
   8925  * Notes:       use this function when the decoded PCM is going to the SBR decoder
   8926  **********************************************************************************************************************/
   8927 void DecWindowOverlapNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) {
   8928 
   8929     int in, w0, w1, f0, f1;
   8930     int *buf1, *over1, *out1;
   8931     const int *wndPrev, *wndCurr;
   8932 
   8933     buf0 += (1024 >> 1);
   8934     buf1  = buf0  - 1;
   8935     out1  = out0 + 1024 - 1;
   8936     over1 = over0 + 1024 - 1;
   8937 
   8938     wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]);
   8939     if (winTypeCurr == winTypePrev) {
   8940         /* cut window loads in half since current and overlap sections use same symmetric window */
   8941         do {
   8942             w0 = *wndPrev++;
   8943             w1 = *wndPrev++;
   8944             in = *buf0++;
   8945 
   8946             f0 = MULSHIFT32(w0, in);
   8947             f1 = MULSHIFT32(w1, in);
   8948 
   8949             in = *over0;
   8950             *out0++ = in - f0;
   8951 
   8952             in = *over1;
   8953             *out1-- = in + f1;
   8954 
   8955             in = *buf1--;
   8956             *over1-- = MULSHIFT32(w0, in);
   8957             *over0++ = MULSHIFT32(w1, in);
   8958         } while (over0 < over1);
   8959     } else {
   8960         /* different windows for current and overlap parts - should still fit in registers on ARM w/o stack spill */
   8961         wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]);
   8962         do {
   8963             w0 = *wndPrev++;
   8964             w1 = *wndPrev++;
   8965             in = *buf0++;
   8966 
   8967             f0 = MULSHIFT32(w0, in);
   8968             f1 = MULSHIFT32(w1, in);
   8969 
   8970             in = *over0;
   8971             *out0++ = in - f0;
   8972 
   8973             in = *over1;
   8974             *out1-- = in + f1;
   8975 
   8976             w0 = *wndCurr++;
   8977             w1 = *wndCurr++;
   8978             in = *buf1--;
   8979 
   8980             *over1-- = MULSHIFT32(w0, in);
   8981             *over0++ = MULSHIFT32(w1, in);
   8982         } while (over0 < over1);
   8983     }
   8984 }
   8985 /***********************************************************************************************************************
   8986  * Function:    DecWindowOverlapLongStart
   8987  *
   8988  * Description: apply synthesis window, do overlap-add, without clipping
   8989  *                for winSequence LONG-START
   8990  *
   8991  * Inputs:      input buffer (output of type-IV DCT)
   8992  *              overlap buffer (saved from last time)
   8993  *              window type (sin or KBD) for input buffer
   8994  *              window type (sin or KBD) for overlap buffer
   8995  *
   8996  * Outputs:     one channel, one frame of 32-bit PCM, non-interleaved
   8997  *
   8998  * Return:      none
   8999  *
   9000  * Notes:       use this function when the decoded PCM is going to the SBR decoder
   9001  **********************************************************************************************************************/
   9002 void DecWindowOverlapLongStartNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) {
   9003 
   9004     int i,  in, w0, w1, f0, f1;
   9005     int *buf1, *over1, *out1;
   9006     const int *wndPrev, *wndCurr;
   9007 
   9008     buf0 += (1024 >> 1);
   9009     buf1  = buf0  - 1;
   9010     out1  = out0 + 1024 - 1;
   9011     over1 = over0 + 1024 - 1;
   9012 
   9013     wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]);
   9014     i = 448;    /* 2 outputs, 2 overlaps per loop */
   9015     do {
   9016         w0 = *wndPrev++;
   9017         w1 = *wndPrev++;
   9018         in = *buf0++;
   9019 
   9020         f0 = MULSHIFT32(w0, in);
   9021         f1 = MULSHIFT32(w1, in);
   9022 
   9023         in = *over0;
   9024         *out0++ = in - f0;
   9025 
   9026         in = *over1;
   9027         *out1-- = in + f1;
   9028 
   9029         in = *buf1--;
   9030 
   9031         *over1-- = 0;       /* Wn = 0 for n = (2047, 2046, ... 1600) */
   9032         *over0++ = in >> 1; /* Wn = 1 for n = (1024, 1025, ... 1471) */
   9033     } while (--i);
   9034 
   9035     wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]);
   9036 
   9037     /* do 64 more loops - 2 outputs, 2 overlaps per loop */
   9038     do {
   9039         w0 = *wndPrev++;
   9040         w1 = *wndPrev++;
   9041         in = *buf0++;
   9042 
   9043         f0 = MULSHIFT32(w0, in);
   9044         f1 = MULSHIFT32(w1, in);
   9045 
   9046         in = *over0;
   9047         *out0++ = in - f0;
   9048 
   9049         in = *over1;
   9050         *out1-- = in + f1;
   9051 
   9052         w0 = *wndCurr++;    /* W[0], W[1], ... --> W[255], W[254], ... */
   9053         w1 = *wndCurr++;    /* W[127], W[126], ... --> W[128], W[129], ... */
   9054         in = *buf1--;
   9055 
   9056         *over1-- = MULSHIFT32(w0, in);  /* Wn = short window for n = (1599, 1598, ... , 1536) */
   9057         *over0++ = MULSHIFT32(w1, in);  /* Wn = short window for n = (1472, 1473, ... , 1535) */
   9058     } while (over0 < over1);
   9059 }
   9060 /***********************************************************************************************************************
   9061  * Function:    DecWindowOverlapLongStop
   9062  *
   9063  * Description: apply synthesis window, do overlap-add, without clipping
   9064  *                for winSequence LONG-STOP
   9065  *
   9066  * Inputs:      input buffer (output of type-IV DCT)
   9067  *              overlap buffer (saved from last time)
   9068  *              window type (sin or KBD) for input buffer
   9069  *              window type (sin or KBD) for overlap buffer
   9070  *
   9071  * Outputs:     one channel, one frame of 32-bit PCM, non-interleaved
   9072  *
   9073  * Return:      none
   9074  *
   9075  * Notes:       use this function when the decoded PCM is going to the SBR decoder
   9076  **********************************************************************************************************************/
   9077 void DecWindowOverlapLongStopNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) {
   9078 
   9079     int i, in, w0, w1, f0, f1;
   9080     int *buf1, *over1, *out1;
   9081     const int *wndPrev, *wndCurr;
   9082 
   9083     buf0 += (1024 >> 1);
   9084     buf1  = buf0  - 1;
   9085     out1  = out0 + 1024 - 1;
   9086     over1 = over0 + 1024 - 1;
   9087 
   9088     wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]);
   9089     wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[1] : sinWindow + sinWindowOffset[1]);
   9090 
   9091     i = 448;    /* 2 outputs, 2 overlaps per loop */
   9092     do {
   9093         /* Wn = 0 for n = (0, 1, ... 447) */
   9094         /* Wn = 1 for n = (576, 577, ... 1023) */
   9095         in = *buf0++;
   9096         f1 = in >> 1;   /* scale since skipping multiply by Q31 */
   9097 
   9098         in = *over0;
   9099         *out0++ = in;
   9100 
   9101         in = *over1;
   9102         *out1-- = in + f1;
   9103 
   9104         w0 = *wndCurr++;
   9105         w1 = *wndCurr++;
   9106         in = *buf1--;
   9107 
   9108         *over1-- = MULSHIFT32(w0, in);
   9109         *over0++ = MULSHIFT32(w1, in);
   9110     } while (--i);
   9111 
   9112     /* do 64 more loops - 2 outputs, 2 overlaps per loop */
   9113     do {
   9114         w0 = *wndPrev++;    /* W[0], W[1], ...W[63] */
   9115         w1 = *wndPrev++;    /* W[127], W[126], ... W[64] */
   9116         in = *buf0++;
   9117 
   9118         f0 = MULSHIFT32(w0, in);
   9119         f1 = MULSHIFT32(w1, in);
   9120 
   9121         in = *over0;
   9122         *out0++ = in - f0;
   9123 
   9124         in = *over1;
   9125         *out1-- = in + f1;
   9126 
   9127         w0 = *wndCurr++;
   9128         w1 = *wndCurr++;
   9129         in = *buf1--;
   9130 
   9131         *over1-- = MULSHIFT32(w0, in);
   9132         *over0++ = MULSHIFT32(w1, in);
   9133     } while (over0 < over1);
   9134 }
   9135 /***********************************************************************************************************************
   9136  * Function:    DecWindowOverlapShort
   9137  *
   9138  * Description: apply synthesis window, do overlap-add, without clipping
   9139  *                for winSequence EIGHT-SHORT (does all 8 short blocks)
   9140  *
   9141  * Inputs:      input buffer (output of type-IV DCT)
   9142  *              overlap buffer (saved from last time)
   9143  *              window type (sin or KBD) for input buffer
   9144  *              window type (sin or KBD) for overlap buffer
   9145  *
   9146  * Outputs:     one channel, one frame of 32-bit PCM, non-interleaved
   9147  *
   9148  * Return:      none
   9149  *
   9150  * Notes:       use this function when the decoded PCM is going to the SBR decoder
   9151  **********************************************************************************************************************/
   9152 void DecWindowOverlapShortNoClip(int *buf0, int *over0, int *out0, int winTypeCurr, int winTypePrev) {
   9153 
   9154     int i, in, w0, w1, f0, f1;
   9155     int *buf1, *over1, *out1;
   9156     const int *wndPrev, *wndCurr;
   9157 
   9158     wndPrev = (winTypePrev == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]);
   9159     wndCurr = (winTypeCurr == 1 ? kbdWindow + kbdWindowOffset[0] : sinWindow + sinWindowOffset[0]);
   9160 
   9161     /* pcm[0-447] = 0 + overlap[0-447] */
   9162     i = 448;
   9163     do {
   9164         f0 = *over0++;
   9165         f1 = *over0++;
   9166         *out0++ = f0;
   9167         *out0++ = f1;
   9168         i -= 2;
   9169     } while (i);
   9170 
   9171     /* pcm[448-575] = Wp[0-127] * block0[0-127] + overlap[448-575] */
   9172     out1  = out0 + (128 - 1);
   9173     over1 = over0 + 128 - 1;
   9174     buf0 += 64;
   9175     buf1  = buf0  - 1;
   9176     do {
   9177         w0 = *wndPrev++;    /* W[0], W[1], ...W[63] */
   9178         w1 = *wndPrev++;    /* W[127], W[126], ... W[64] */
   9179         in = *buf0++;
   9180 
   9181         f0 = MULSHIFT32(w0, in);
   9182         f1 = MULSHIFT32(w1, in);
   9183 
   9184         in = *over0;
   9185         *out0++ = in - f0;
   9186 
   9187         in = *over1;
   9188         *out1-- = in + f1;
   9189 
   9190         w0 = *wndCurr++;
   9191         w1 = *wndCurr++;
   9192         in = *buf1--;
   9193 
   9194         /* save over0/over1 for next short block, in the slots just vacated */
   9195         *over1-- = MULSHIFT32(w0, in);
   9196         *over0++ = MULSHIFT32(w1, in);
   9197     } while (over0 < over1);
   9198 
   9199     /* pcm[576-703] = Wc[128-255] * block0[128-255] + Wc[0-127] * block1[0-127] + overlap[576-703]
   9200      * pcm[704-831] = Wc[128-255] * block1[128-255] + Wc[0-127] * block2[0-127] + overlap[704-831]
   9201      * pcm[832-959] = Wc[128-255] * block2[128-255] + Wc[0-127] * block3[0-127] + overlap[832-959]
   9202      */
   9203     for (i = 0; i < 3; i++) {
   9204         out0 += 64;
   9205         out1 = out0 + 128 - 1;
   9206         over0 += 64;
   9207         over1 = over0 + 128 - 1;
   9208         buf0 += 64;
   9209         buf1 = buf0 - 1;
   9210         wndCurr -= 128;
   9211 
   9212         do {
   9213             w0 = *wndCurr++;    /* W[0], W[1], ...W[63] */
   9214             w1 = *wndCurr++;    /* W[127], W[126], ... W[64] */
   9215             in = *buf0++;
   9216 
   9217             f0 = MULSHIFT32(w0, in);
   9218             f1 = MULSHIFT32(w1, in);
   9219 
   9220             in  = *(over0 - 128);   /* from last short block */
   9221             in += *(over0 + 0);     /* from last full frame */
   9222             *out0++ = in - f0;
   9223 
   9224             in  = *(over1 - 128);   /* from last short block */
   9225             in += *(over1 + 0);     /* from last full frame */
   9226             *out1-- = in + f1;
   9227 
   9228             /* save over0/over1 for next short block, in the slots just vacated */
   9229             in = *buf1--;
   9230             *over1-- = MULSHIFT32(w0, in);
   9231             *over0++ = MULSHIFT32(w1, in);
   9232         } while (over0 < over1);
   9233     }
   9234 
   9235     /* pcm[960-1023] = Wc[128-191] * block3[128-191] + Wc[0-63]   * block4[0-63] + overlap[960-1023]
   9236      * over[0-63]    = Wc[192-255] * block3[192-255] + Wc[64-127] * block4[64-127]
   9237      */
   9238     out0 += 64;
   9239     over0 -= 832;               /* points at overlap[64] */
   9240     over1 = over0 + 128 - 1;    /* points at overlap[191] */
   9241     buf0 += 64;
   9242     buf1 = buf0 - 1;
   9243     wndCurr -= 128;
   9244     do {
   9245         w0 = *wndCurr++;    /* W[0], W[1], ...W[63] */
   9246         w1 = *wndCurr++;    /* W[127], W[126], ... W[64] */
   9247         in = *buf0++;
   9248 
   9249         f0 = MULSHIFT32(w0, in);
   9250         f1 = MULSHIFT32(w1, in);
   9251 
   9252         in  = *(over0 + 768);   /* from last short block */
   9253         in += *(over0 + 896);   /* from last full frame */
   9254         *out0++ = in - f0;
   9255 
   9256         in  = *(over1 + 768);   /* from last short block */
   9257         *(over1 - 128) = in + f1;
   9258 
   9259         in = *buf1--;
   9260         *over1-- = MULSHIFT32(w0, in);  /* save in overlap[128-191] */
   9261         *over0++ = MULSHIFT32(w1, in);  /* save in overlap[64-127] */
   9262     } while (over0 < over1);
   9263 
   9264     /* over0 now points at overlap[128] */
   9265 
   9266     /* over[64-191]   = Wc[128-255] * block4[128-255] + Wc[0-127] * block5[0-127]
   9267      * over[192-319]  = Wc[128-255] * block5[128-255] + Wc[0-127] * block6[0-127]
   9268      * over[320-447]  = Wc[128-255] * block6[128-255] + Wc[0-127] * block7[0-127]
   9269      * over[448-576]  = Wc[128-255] * block7[128-255]
   9270      */
   9271     for (i = 0; i < 3; i++) {
   9272         over0 += 64;
   9273         over1 = over0 + 128 - 1;
   9274         buf0 += 64;
   9275         buf1 = buf0 - 1;
   9276         wndCurr -= 128;
   9277         do {
   9278             w0 = *wndCurr++;    /* W[0], W[1], ...W[63] */
   9279             w1 = *wndCurr++;    /* W[127], W[126], ... W[64] */
   9280             in = *buf0++;
   9281 
   9282             f0 = MULSHIFT32(w0, in);
   9283             f1 = MULSHIFT32(w1, in);
   9284 
   9285             /* from last short block */
   9286             *(over0 - 128) -= f0;
   9287             *(over1 - 128)+= f1;
   9288 
   9289             in = *buf1--;
   9290             *over1-- = MULSHIFT32(w0, in);
   9291             *over0++ = MULSHIFT32(w1, in);
   9292         } while (over0 < over1);
   9293     }
   9294 
   9295     /* over[576-1024] = 0 */
   9296     i = 448;
   9297     over0 += 64;
   9298     do {
   9299         *over0++ = 0;
   9300         *over0++ = 0;
   9301         *over0++ = 0;
   9302         *over0++ = 0;
   9303         i -= 4;
   9304     } while (i);
   9305 }
   9306 /***********************************************************************************************************************
   9307  * Function:    PreMultiply64
   9308  *
   9309  * Description: pre-twiddle stage of 64-point DCT-IV
   9310  *
   9311  * Inputs:      buffer of 64 samples
   9312  *
   9313  * Outputs:     processed samples in same buffer
   9314  *
   9315  * Return:      none
   9316  *
   9317  * Notes:       minimum 1 GB in, 2 GB out, gains 2 int bits
   9318  *              gbOut = gbIn + 1
   9319  *              output is limited to sqrt(2)/2 plus GB in full GB
   9320  *              uses 3-mul, 3-add butterflies instead of 4-mul, 2-add
   9321  **********************************************************************************************************************/
   9322 void PreMultiply64(int *zbuf1) {
   9323 
   9324     int i, ar1, ai1, ar2, ai2, z1, z2;
   9325     int t, cms2, cps2a, sin2a, cps2b, sin2b;
   9326     int *zbuf2;
   9327     const int *csptr;
   9328 
   9329     zbuf2 = zbuf1 + 64 - 1;
   9330     csptr = cos4sin4tab64;
   9331 
   9332     /* whole thing should fit in registers - verify that compiler does this */
   9333     for (i = 64 >> 2; i != 0; i--) {
   9334         /* cps2 = (cos+sin), sin2 = sin, cms2 = (cos-sin) */
   9335         cps2a = *csptr++;
   9336         sin2a = *csptr++;
   9337         cps2b = *csptr++;
   9338         sin2b = *csptr++;
   9339 
   9340         ar1 = *(zbuf1 + 0);
   9341         ai2 = *(zbuf1 + 1);
   9342         ai1 = *(zbuf2 + 0);
   9343         ar2 = *(zbuf2 - 1);
   9344 
   9345         /* gain 2 ints bit from MULSHIFT32 by Q30
   9346          * max per-sample gain (ignoring implicit scaling) = MAX(sin(angle)+cos(angle)) = 1.414
   9347          * i.e. gain 1 GB since worst case is sin(angle) = cos(angle) = 0.707 (Q30), gain 2 from
   9348          *   extra sign bits, and eat one in adding
   9349          */
   9350         t  = MULSHIFT32(sin2a, ar1 + ai1);
   9351         z2 = MULSHIFT32(cps2a, ai1) - t;
   9352         cms2 = cps2a - 2*sin2a;
   9353         z1 = MULSHIFT32(cms2, ar1) + t;
   9354         *zbuf1++ = z1;  /* cos*ar1 + sin*ai1 */
   9355         *zbuf1++ = z2;  /* cos*ai1 - sin*ar1 */
   9356 
   9357         t  = MULSHIFT32(sin2b, ar2 + ai2);
   9358         z2 = MULSHIFT32(cps2b, ai2) - t;
   9359         cms2 = cps2b - 2*sin2b;
   9360         z1 = MULSHIFT32(cms2, ar2) + t;
   9361         *zbuf2-- = z2;  /* cos*ai2 - sin*ar2 */
   9362         *zbuf2-- = z1;  /* cos*ar2 + sin*ai2 */
   9363     }
   9364 }
   9365 /***********************************************************************************************************************
   9366  * Function:    PostMultiply64
   9367  *
   9368  * Description: post-twiddle stage of 64-point type-IV DCT
   9369  *
   9370  * Inputs:      buffer of 64 samples
   9371  *              number of output samples to calculate
   9372  *
   9373  * Outputs:     processed samples in same buffer
   9374  *
   9375  * Return:      none
   9376  *
   9377  * Notes:       minimum 1 GB in, 2 GB out, gains 2 int bits
   9378  *              gbOut = gbIn + 1
   9379  *              output is limited to sqrt(2)/2 plus GB in full GB
   9380  *              nSampsOut is rounded up to next multiple of 4, since we calculate
   9381  *                4 samples per loop
   9382  **********************************************************************************************************************/
   9383 void PostMultiply64(int *fft1, int nSampsOut) {
   9384 
   9385     int i, ar1, ai1, ar2, ai2;
   9386     int t, cms2, cps2, sin2;
   9387     int *fft2;
   9388     const int *csptr;
   9389 
   9390     csptr = cos1sin1tab64;
   9391     fft2 = fft1 + 64 - 1;
   9392 
   9393     /* load coeffs for first pass
   9394      * cps2 = (cos+sin)/2, sin2 = sin/2, cms2 = (cos-sin)/2
   9395      */
   9396     cps2 = *csptr++;
   9397     sin2 = *csptr++;
   9398     cms2 = cps2 - 2*sin2;
   9399 
   9400     for (i = (nSampsOut + 3) >> 2; i != 0; i--) {
   9401         ar1 = *(fft1 + 0);
   9402         ai1 = *(fft1 + 1);
   9403         ar2 = *(fft2 - 1);
   9404         ai2 = *(fft2 + 0);
   9405 
   9406         /* gain 2 int bits (multiplying by Q30), max gain = sqrt(2) */
   9407         t = MULSHIFT32(sin2, ar1 + ai1);
   9408         *fft2-- = t - MULSHIFT32(cps2, ai1);
   9409         *fft1++ = t + MULSHIFT32(cms2, ar1);
   9410 
   9411         cps2 = *csptr++;
   9412         sin2 = *csptr++;
   9413 
   9414         ai2 = -ai2;
   9415         t = MULSHIFT32(sin2, ar2 + ai2);
   9416         *fft2-- = t - MULSHIFT32(cps2, ai2);
   9417         cms2 = cps2 - 2*sin2;
   9418         *fft1++ = t + MULSHIFT32(cms2, ar2);
   9419     }
   9420 }
   9421 /***********************************************************************************************************************
   9422  * Function:    QMFAnalysisConv
   9423  *
   9424  * Description: convolution kernel for analysis QMF
   9425  *
   9426  * Inputs:      pointer to coefficient table, reordered for sequential access
   9427  *              delay buffer of size 32*10 = 320 real-valued PCM samples
   9428  *              index for delay ring buffer (range = [0, 9])
   9429  *
   9430  * Outputs:     64 consecutive 32-bit samples
   9431  *
   9432  * Return:      none
   9433  *
   9434  * Notes:       this is carefully written to be efficient on ARM
   9435  *              use the assembly code version in sbrqmfak.s when building for ARM!
   9436  **********************************************************************************************************************/
   9437 void QMFAnalysisConv(int *cTab, int *delay, int dIdx, int *uBuf) {
   9438 
   9439     int k, dOff;
   9440     int *cPtr0, *cPtr1;
   9441     U64 u64lo, u64hi;
   9442 
   9443     dOff = dIdx*32 + 31;
   9444     cPtr0 = cTab;
   9445     cPtr1 = cTab + 33*5 - 1;
   9446 
   9447     /* special first pass since we need to flip sign to create cTab[384], cTab[512] */
   9448     u64lo.w64 = 0;
   9449     u64hi.w64 = 0;
   9450     u64lo.w64 = MADD64(u64lo.w64,  *cPtr0++,   delay[dOff]);    dOff -= 32; if (dOff < 0) {dOff += 320;}
   9451     u64hi.w64 = MADD64(u64hi.w64,  *cPtr0++,   delay[dOff]);    dOff -= 32; if (dOff < 0) {dOff += 320;}
   9452     u64lo.w64 = MADD64(u64lo.w64,  *cPtr0++,   delay[dOff]);    dOff -= 32; if (dOff < 0) {dOff += 320;}
   9453     u64hi.w64 = MADD64(u64hi.w64,  *cPtr0++,   delay[dOff]);    dOff -= 32; if (dOff < 0) {dOff += 320;}
   9454     u64lo.w64 = MADD64(u64lo.w64,  *cPtr0++,   delay[dOff]);    dOff -= 32; if (dOff < 0) {dOff += 320;}
   9455     u64hi.w64 = MADD64(u64hi.w64,  *cPtr1--,   delay[dOff]);    dOff -= 32; if (dOff < 0) {dOff += 320;}
   9456     u64lo.w64 = MADD64(u64lo.w64, -(*cPtr1--), delay[dOff]);    dOff -= 32; if (dOff < 0) {dOff += 320;}
   9457     u64hi.w64 = MADD64(u64hi.w64,  *cPtr1--,   delay[dOff]);    dOff -= 32; if (dOff < 0) {dOff += 320;}
   9458     u64lo.w64 = MADD64(u64lo.w64, -(*cPtr1--), delay[dOff]);    dOff -= 32; if (dOff < 0) {dOff += 320;}
   9459     u64hi.w64 = MADD64(u64hi.w64,  *cPtr1--,   delay[dOff]);    dOff -= 32; if (dOff < 0) {dOff += 320;}
   9460 
   9461     uBuf[0]  = u64lo.r.hi32;
   9462     uBuf[32] = u64hi.r.hi32;
   9463     uBuf++;
   9464     dOff--;
   9465 
   9466     /* max gain for any sample in uBuf, after scaling by cTab, ~= 0.99
   9467      * so we can just sum the uBuf values with no overflow problems
   9468      */
   9469     for (k = 1; k <= 31; k++) {
   9470         u64lo.w64 = 0;
   9471         u64hi.w64 = 0;
   9472         u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]);   dOff -= 32; if (dOff < 0) {dOff += 320;}
   9473         u64hi.w64 = MADD64(u64hi.w64, *cPtr0++, delay[dOff]);   dOff -= 32; if (dOff < 0) {dOff += 320;}
   9474         u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]);   dOff -= 32; if (dOff < 0) {dOff += 320;}
   9475         u64hi.w64 = MADD64(u64hi.w64, *cPtr0++, delay[dOff]);   dOff -= 32; if (dOff < 0) {dOff += 320;}
   9476         u64lo.w64 = MADD64(u64lo.w64, *cPtr0++, delay[dOff]);   dOff -= 32; if (dOff < 0) {dOff += 320;}
   9477         u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]);   dOff -= 32; if (dOff < 0) {dOff += 320;}
   9478         u64lo.w64 = MADD64(u64lo.w64, *cPtr1--, delay[dOff]);   dOff -= 32; if (dOff < 0) {dOff += 320;}
   9479         u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]);   dOff -= 32; if (dOff < 0) {dOff += 320;}
   9480         u64lo.w64 = MADD64(u64lo.w64, *cPtr1--, delay[dOff]);   dOff -= 32; if (dOff < 0) {dOff += 320;}
   9481         u64hi.w64 = MADD64(u64hi.w64, *cPtr1--, delay[dOff]);   dOff -= 32; if (dOff < 0) {dOff += 320;}
   9482 
   9483         uBuf[0]  = u64lo.r.hi32;
   9484         uBuf[32] = u64hi.r.hi32;
   9485         uBuf++;
   9486         dOff--;
   9487     }
   9488 }
   9489 /***********************************************************************************************************************
   9490  * Function:    QMFAnalysis
   9491  *
   9492  * Description: 32-subband analysis QMF (4.6.18.4.1)
   9493  *
   9494  * Inputs:      32 consecutive samples of decoded 32-bit PCM, format = Q(fBitsIn)
   9495  *              delay buffer of size 32*10 = 320 PCM samples
   9496  *              number of fraction bits in input PCM
   9497  *              index for delay ring buffer (range = [0, 9])
   9498  *              number of subbands to calculate (range = [0, 32])
   9499  *
   9500  * Outputs:     qmfaBands complex subband samples, format = Q(FBITS_OUT_QMFA)
   9501  *              updated delay buffer
   9502  *              updated delay index
   9503  *
   9504  * Return:      guard bit mask
   9505  *
   9506  * Notes:       output stored as RE{X0}, IM{X0}, RE{X1}, IM{X1}, ... RE{X31}, IM{X31}
   9507  *              output stored in int buffer of size 64*2 = 128
   9508  *                (zero-filled from XBuf[2*qmfaBands] to XBuf[127])
   9509  **********************************************************************************************************************/
   9510 int QMFAnalysis(int *inbuf, int *delay, int *XBuf, int fBitsIn, int *delayIdx, int qmfaBands) {
   9511 
   9512     int n, y, shift, gbMask;
   9513     int *delayPtr, *uBuf, *tBuf;
   9514 
   9515     /* use XBuf[128] as temp buffer for reordering */
   9516     uBuf = XBuf;        /* first 64 samples */
   9517     tBuf = XBuf + 64;   /* second 64 samples */
   9518 
   9519     /* overwrite oldest PCM with new PCM
   9520      * delay[n] has 1 GB after shifting (either << or >>)
   9521      */
   9522     delayPtr = delay + (*delayIdx * 32);
   9523     if (fBitsIn > FBITS_IN_QMFA) {
   9524         shift = MIN(fBitsIn - FBITS_IN_QMFA, 31);
   9525         for (n = 32; n != 0; n--) {
   9526             y = (*inbuf) >> shift;
   9527             inbuf++;
   9528             *delayPtr++ = y;
   9529         }
   9530     } else {
   9531         shift = MIN(FBITS_IN_QMFA - fBitsIn, 30);
   9532         for (n = 32; n != 0; n--) {
   9533             y = *inbuf++;
   9534             y = CLIP_2N_SHIFT30(y, shift);
   9535             *delayPtr++ = y;
   9536         }
   9537     }
   9538 
   9539     QMFAnalysisConv((int *)cTabA, delay, *delayIdx, uBuf);
   9540 
   9541     /* uBuf has at least 2 GB right now (1 from clipping to Q(FBITS_IN_QMFA), one from
   9542      *   the scaling by cTab (MULSHIFT32(*delayPtr--, *cPtr++), with net gain of < 1.0)
   9543      */
   9544     tBuf[2*0 + 0] = uBuf[0];
   9545     tBuf[2*0 + 1] = uBuf[1];
   9546     for (n = 1; n < 31; n++) {
   9547         tBuf[2*n + 0] = -uBuf[64-n];
   9548         tBuf[2*n + 1] =  uBuf[n+1];
   9549     }
   9550     tBuf[2*31 + 1] =  uBuf[32];
   9551     tBuf[2*31 + 0] = -uBuf[33];
   9552 
   9553     /* fast in-place DCT-IV - only need 2*qmfaBands output samples */
   9554     PreMultiply64(tBuf);    /* 2 GB in, 3 GB out */
   9555     FFT32C(tBuf);           /* 3 GB in, 1 GB out */
   9556     PostMultiply64(tBuf, qmfaBands*2);  /* 1 GB in, 2 GB out */
   9557 
   9558     gbMask = 0;
   9559     for (n = 0; n < qmfaBands; n++) {
   9560         XBuf[2*n+0] =  tBuf[ n + 0];    /* implicit scaling of 2 in our output Q format */
   9561         gbMask |= FASTABS(XBuf[2*n+0]);
   9562         XBuf[2*n+1] = -tBuf[63 - n];
   9563         gbMask |= FASTABS(XBuf[2*n+1]);
   9564     }
   9565 
   9566     /* fill top section with zeros for HF generation */
   9567     for (    ; n < 64; n++) {
   9568         XBuf[2*n+0] = 0;
   9569         XBuf[2*n+1] = 0;
   9570     }
   9571 
   9572     *delayIdx = (*delayIdx == NUM_QMF_DELAY_BUFS - 1 ? 0 : *delayIdx + 1);
   9573 
   9574     /* minimum of 2 GB in output */
   9575     return gbMask;
   9576 }
   9577 /***********************************************************************************************************************
   9578  * Function:    QMFSynthesisConv
   9579  *
   9580  * Description: final convolution kernel for synthesis QMF
   9581  *
   9582  * Inputs:      pointer to coefficient table, reordered for sequential access
   9583  *              delay buffer of size 64*10 = 640 complex samples (1280 ints)
   9584  *              index for delay ring buffer (range = [0, 9])
   9585  *              number of QMF subbands to process (range = [0, 64])
   9586  *              number of channels
   9587  *
   9588  * Outputs:     64 consecutive 16-bit PCM samples, interleaved by factor of nChans
   9589  *
   9590  * Return:      none
   9591  *
   9592  * Notes:       this is carefully written to be efficient on ARM
   9593  *              use the assembly code version in sbrqmfsk.s when building for ARM!
   9594  **********************************************************************************************************************/
   9595 void QMFSynthesisConv(int *cPtr, int *delay, int dIdx, short *outbuf, int nChans) {
   9596 
   9597     int k, dOff0, dOff1;
   9598     U64 sum64;
   9599 
   9600     dOff0 = (dIdx)*128;
   9601     dOff1 = dOff0 - 1;
   9602     if (dOff1 < 0)
   9603         dOff1 += 1280;
   9604 
   9605     /* scaling note: total gain of coefs (cPtr[0]-cPtr[9] for any k) is < 2.0, so 1 GB in delay values is adequate */
   9606     for (k = 0; k <= 63; k++) {
   9607         sum64.w64 = 0;
   9608         sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]);   dOff0 -= 256; if (dOff0 < 0) {dOff0 += 1280;}
   9609         sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]);   dOff1 -= 256; if (dOff1 < 0) {dOff1 += 1280;}
   9610         sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]);   dOff0 -= 256; if (dOff0 < 0) {dOff0 += 1280;}
   9611         sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]);   dOff1 -= 256; if (dOff1 < 0) {dOff1 += 1280;}
   9612         sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]);   dOff0 -= 256; if (dOff0 < 0) {dOff0 += 1280;}
   9613         sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]);   dOff1 -= 256; if (dOff1 < 0) {dOff1 += 1280;}
   9614         sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]);   dOff0 -= 256; if (dOff0 < 0) {dOff0 += 1280;}
   9615         sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]);   dOff1 -= 256; if (dOff1 < 0) {dOff1 += 1280;}
   9616         sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff0]);   dOff0 -= 256; if (dOff0 < 0) {dOff0 += 1280;}
   9617         sum64.w64 = MADD64(sum64.w64, *cPtr++, delay[dOff1]);   dOff1 -= 256; if (dOff1 < 0) {dOff1 += 1280;}
   9618 
   9619         dOff0++;
   9620         dOff1--;
   9621         *outbuf = CLIPTOSHORT((sum64.r.hi32 + RND_VAL) >> FBITS_OUT_QMFS);
   9622         outbuf += nChans;
   9623     }
   9624 }
   9625 /***********************************************************************************************************************
   9626  * Function:    QMFSynthesis
   9627  *
   9628  * Description: 64-subband synthesis QMF (4.6.18.4.2)
   9629  *
   9630  * Inputs:      64 consecutive complex subband QMF samples, format = Q(FBITS_IN_QMFS)
   9631  *              delay buffer of size 64*10 = 640 complex samples (1280 ints)
   9632  *              index for delay ring buffer (range = [0, 9])
   9633  *              number of QMF subbands to process (range = [0, 64])
   9634  *              number of channels
   9635  *
   9636  * Outputs:     64 consecutive 16-bit PCM samples, interleaved by factor of nChans
   9637  *              updated delay buffer
   9638  *              updated delay index
   9639  *
   9640  * Return:      none
   9641  *
   9642  * Notes:       assumes MIN_GBITS_IN_QMFS guard bits in input, either from
   9643  *                QMFAnalysis (if upsampling only) or from MapHF (if SBR on)
   9644  **********************************************************************************************************************/
   9645 void QMFSynthesis(int *inbuf, int *delay, int *delayIdx, int qmfsBands, short *outbuf, int nChans) {
   9646 
   9647     int n, a0, a1, b0, b1, dOff0, dOff1, dIdx;
   9648     int *tBufLo, *tBufHi;
   9649 
   9650     dIdx = *delayIdx;
   9651     tBufLo = delay + dIdx*128 + 0;
   9652     tBufHi = delay + dIdx*128 + 127;
   9653 
   9654     /* reorder inputs to DCT-IV, only use first qmfsBands (complex) samples
   9655      */
   9656     for (n = 0; n < qmfsBands >> 1; n++) {
   9657         a0 = *inbuf++;
   9658         b0 = *inbuf++;
   9659         a1 = *inbuf++;
   9660         b1 = *inbuf++;
   9661         *tBufLo++ = a0;
   9662         *tBufLo++ = a1;
   9663         *tBufHi-- = b0;
   9664         *tBufHi-- = b1;
   9665     }
   9666     if (qmfsBands & 0x01) {
   9667         a0 = *inbuf++;
   9668         b0 = *inbuf++;
   9669         *tBufLo++ = a0;
   9670         *tBufHi-- = b0;
   9671         *tBufLo++ = 0;
   9672         *tBufHi-- = 0;
   9673         n++;
   9674     }
   9675     for (     ; n < 32; n++) {
   9676         *tBufLo++ = 0;
   9677         *tBufHi-- = 0;
   9678         *tBufLo++ = 0;
   9679         *tBufHi-- = 0;
   9680     }
   9681 
   9682     tBufLo = delay + dIdx*128 + 0;
   9683     tBufHi = delay + dIdx*128 + 64;
   9684 
   9685     /* 2 GB in, 3 GB out */
   9686     PreMultiply64(tBufLo);
   9687     PreMultiply64(tBufHi);
   9688 
   9689     /* 3 GB in, 1 GB out */
   9690     FFT32C(tBufLo);
   9691     FFT32C(tBufHi);
   9692 
   9693     /* 1 GB in, 2 GB out */
   9694     PostMultiply64(tBufLo, 64);
   9695     PostMultiply64(tBufHi, 64);
   9696 
   9697     /* could fuse with PostMultiply64 to avoid separate pass */
   9698     dOff0 = dIdx*128;
   9699     dOff1 = dIdx*128 + 64;
   9700     for (n = 32; n != 0; n--) {
   9701         a0 =  (*tBufLo++);
   9702         a1 =  (*tBufLo++);
   9703         b0 =  (*tBufHi++);
   9704         b1 = -(*tBufHi++);
   9705 
   9706         delay[dOff0++] = (b0 - a0);
   9707         delay[dOff0++] = (b1 - a1);
   9708         delay[dOff1++] = (b0 + a0);
   9709         delay[dOff1++] = (b1 + a1);
   9710     }
   9711 
   9712     QMFSynthesisConv((int *)cTabS, delay, dIdx, outbuf, nChans);
   9713 
   9714     *delayIdx = (*delayIdx == NUM_QMF_DELAY_BUFS - 1 ? 0 : *delayIdx + 1);
   9715 }
   9716 /***********************************************************************************************************************
   9717  * Function:    UnpackSBRHeader
   9718  *
   9719  * Description: unpack SBR header (table 4.56)
   9720  *
   9721  * Inputs:      BitStreamInfo struct pointing to start of SBR header
   9722  *
   9723  * Outputs:     initialized SBRHeader struct for this SCE/CPE block
   9724  *
   9725  * Return:      non-zero if frame reset is triggered, zero otherwise
   9726  **********************************************************************************************************************/
   9727 int UnpackSBRHeader(SBRHeader *sbrHdr) {
   9728 
   9729     SBRHeader sbrHdrPrev;
   9730 
   9731     /* save previous values so we know whether to reset decoder */
   9732     sbrHdrPrev.startFreq =     sbrHdr->startFreq;
   9733     sbrHdrPrev.stopFreq =      sbrHdr->stopFreq;
   9734     sbrHdrPrev.freqScale =     sbrHdr->freqScale;
   9735     sbrHdrPrev.alterScale =    sbrHdr->alterScale;
   9736     sbrHdrPrev.crossOverBand = sbrHdr->crossOverBand;
   9737     sbrHdrPrev.noiseBands =    sbrHdr->noiseBands;
   9738 
   9739     sbrHdr->ampRes =        GetBits(1);
   9740     sbrHdr->startFreq =     GetBits(4);
   9741     sbrHdr->stopFreq =      GetBits(4);
   9742     sbrHdr->crossOverBand = GetBits(3);
   9743     sbrHdr->resBitsHdr =    GetBits(2);
   9744     sbrHdr->hdrExtra1 =     GetBits(1);
   9745     sbrHdr->hdrExtra2 =     GetBits(1);
   9746 
   9747     if (sbrHdr->hdrExtra1) {
   9748         sbrHdr->freqScale =    GetBits(2);
   9749         sbrHdr->alterScale =   GetBits(1);
   9750         sbrHdr->noiseBands =   GetBits(2);
   9751     } else {
   9752         /* defaults */
   9753         sbrHdr->freqScale =    2;
   9754         sbrHdr->alterScale =   1;
   9755         sbrHdr->noiseBands =   2;
   9756     }
   9757 
   9758     if (sbrHdr->hdrExtra2) {
   9759         sbrHdr->limiterBands = GetBits(2);
   9760         sbrHdr->limiterGains = GetBits(2);
   9761         sbrHdr->interpFreq =   GetBits(1);
   9762         sbrHdr->smoothMode =   GetBits(1);
   9763     } else {
   9764         /* defaults */
   9765         sbrHdr->limiterBands = 2;
   9766         sbrHdr->limiterGains = 2;
   9767         sbrHdr->interpFreq =   1;
   9768         sbrHdr->smoothMode =   1;
   9769     }
   9770     sbrHdr->count++;
   9771 
   9772     /* if any of these have changed from previous frame, reset the SBR module */
   9773     if (sbrHdr->startFreq != sbrHdrPrev.startFreq || sbrHdr->stopFreq != sbrHdrPrev.stopFreq ||
   9774         sbrHdr->freqScale != sbrHdrPrev.freqScale || sbrHdr->alterScale != sbrHdrPrev.alterScale ||
   9775         sbrHdr->crossOverBand != sbrHdrPrev.crossOverBand || sbrHdr->noiseBands != sbrHdrPrev.noiseBands
   9776         )
   9777         return -1;
   9778     else
   9779         return 0;
   9780 }
   9781 
   9782 /* cLog2[i] = ceil(log2(i)) (disregard i == 0) */
   9783 static const uint8_t cLog2[9] = {0, 0, 1, 2, 2, 3, 3, 3, 3};
   9784 /***********************************************************************************************************************
   9785  * Function:    UnpackSBRGrid
   9786  *
   9787  * Description: unpack SBR grid (table 4.62)
   9788  *
   9789  * Inputs:      BitStreamInfo struct pointing to start of SBR grid
   9790  *              initialized SBRHeader struct for this SCE/CPE block
   9791  *
   9792  * Outputs:     initialized SBRGrid struct for this channel
   9793  *
   9794  * Return:      none
   9795  **********************************************************************************************************************/
   9796 void UnpackSBRGrid(SBRHeader *sbrHdr, SBRGrid *sbrGrid) {
   9797 
   9798     int numEnvRaw, env, rel, pBits, border, middleBorder = 0;
   9799     uint8_t relBordLead[MAX_NUM_ENV], relBordTrail[MAX_NUM_ENV];
   9800     uint8_t relBorder0[3], relBorder1[3], relBorder[3];
   9801     uint8_t numRelBorder0, numRelBorder1, numRelBorder, numRelLead = 0, numRelTrail;
   9802     uint8_t absBordLead = 0, absBordTrail = 0, absBorder;
   9803 
   9804     sbrGrid->ampResFrame = sbrHdr->ampRes;
   9805     sbrGrid->frameClass = GetBits(2);
   9806     switch(sbrGrid->frameClass){
   9807 
   9808         case SBR_GRID_FIXFIX:
   9809             numEnvRaw = GetBits(2);
   9810             sbrGrid->numEnv = (1 << numEnvRaw);
   9811             if(sbrGrid->numEnv == 1) sbrGrid->ampResFrame = 0;
   9812 
   9813             ASSERT(sbrGrid->numEnv == 1 || sbrGrid->numEnv == 2 || sbrGrid->numEnv == 4);
   9814 
   9815             sbrGrid->freqRes[0] = GetBits(1);
   9816             for(env = 1; env < sbrGrid->numEnv; env++)
   9817                 sbrGrid->freqRes[env] = sbrGrid->freqRes[0];
   9818 
   9819             absBordLead = 0;
   9820             absBordTrail = NUM_TIME_SLOTS;
   9821             numRelLead = sbrGrid->numEnv - 1;
   9822             numRelTrail = 0;
   9823 
   9824             /* numEnv = 1, 2, or 4 */
   9825             if(sbrGrid->numEnv == 1)
   9826                 border = NUM_TIME_SLOTS / 1;
   9827             else if(sbrGrid->numEnv == 2)
   9828                 border = NUM_TIME_SLOTS / 2;
   9829             else
   9830                 border = NUM_TIME_SLOTS / 4;
   9831 
   9832             for(rel = 0; rel < numRelLead; rel++)
   9833                 relBordLead[rel] = border;
   9834 
   9835             middleBorder = (sbrGrid->numEnv >> 1);
   9836 
   9837             break;
   9838 
   9839         case SBR_GRID_FIXVAR:
   9840             absBorder = GetBits(2) + NUM_TIME_SLOTS;
   9841             numRelBorder = GetBits(2);
   9842             sbrGrid->numEnv = numRelBorder + 1;
   9843             for(rel = 0; rel < numRelBorder; rel++)
   9844                 relBorder[rel] = 2 * GetBits(2) + 2;
   9845 
   9846             pBits = cLog2[sbrGrid->numEnv + 1];
   9847             sbrGrid->pointer = GetBits(pBits);
   9848 
   9849             for(env = sbrGrid->numEnv - 1; env >= 0; env--)
   9850                 sbrGrid->freqRes[env] = GetBits(1);
   9851 
   9852             absBordLead = 0;
   9853             absBordTrail = absBorder;
   9854             numRelLead = 0;
   9855             numRelTrail = numRelBorder;
   9856 
   9857             for(rel = 0; rel < numRelTrail; rel++)
   9858                 relBordTrail[rel] = relBorder[rel];
   9859 
   9860             if(sbrGrid->pointer > 1)
   9861                 middleBorder = sbrGrid->numEnv + 1 - sbrGrid->pointer;
   9862             else
   9863                 middleBorder = sbrGrid->numEnv - 1;
   9864 
   9865             break;
   9866 
   9867         case SBR_GRID_VARFIX:
   9868             absBorder = GetBits(2);
   9869             numRelBorder = GetBits(2);
   9870             sbrGrid->numEnv = numRelBorder + 1;
   9871             for(rel = 0; rel < numRelBorder; rel++)
   9872                 relBorder[rel] = 2 * GetBits(2) + 2;
   9873 
   9874             pBits = cLog2[sbrGrid->numEnv + 1];
   9875             sbrGrid->pointer = GetBits(pBits);
   9876 
   9877             for(env = 0; env < sbrGrid->numEnv; env++)
   9878                 sbrGrid->freqRes[env] = GetBits(1);
   9879 
   9880             absBordLead = absBorder;
   9881             absBordTrail = NUM_TIME_SLOTS;
   9882             numRelLead = numRelBorder;
   9883             numRelTrail = 0;
   9884 
   9885             for(rel = 0; rel < numRelLead; rel++)
   9886                 relBordLead[rel] = relBorder[rel];
   9887 
   9888             if(sbrGrid->pointer == 0)
   9889                 middleBorder = 1;
   9890             else if(sbrGrid->pointer == 1)
   9891                 middleBorder = sbrGrid->numEnv - 1;
   9892             else
   9893                 middleBorder = sbrGrid->pointer - 1;
   9894 
   9895             break;
   9896 
   9897         case SBR_GRID_VARVAR:
   9898             absBordLead = GetBits(2); /* absBorder0 */
   9899             absBordTrail = GetBits(2) + NUM_TIME_SLOTS; /* absBorder1 */
   9900             numRelBorder0 = GetBits(2);
   9901             numRelBorder1 = GetBits(2);
   9902 
   9903             sbrGrid->numEnv = numRelBorder0 + numRelBorder1 + 1;
   9904             ASSERT(sbrGrid->numEnv <= 5);
   9905 
   9906             for(rel = 0; rel < numRelBorder0; rel++)
   9907                 relBorder0[rel] = 2 * GetBits(2) + 2;
   9908 
   9909             for(rel = 0; rel < numRelBorder1; rel++)
   9910                 relBorder1[rel] = 2 * GetBits(2) + 2;
   9911 
   9912             pBits = cLog2[numRelBorder0 + numRelBorder1 + 2];
   9913             sbrGrid->pointer = GetBits(pBits);
   9914 
   9915             for(env = 0; env < sbrGrid->numEnv; env++)
   9916                 sbrGrid->freqRes[env] = GetBits(1);
   9917 
   9918             numRelLead = numRelBorder0;
   9919             numRelTrail = numRelBorder1;
   9920 
   9921             for(rel = 0; rel < numRelLead; rel++)
   9922                 relBordLead[rel] = relBorder0[rel];
   9923 
   9924             for(rel = 0; rel < numRelTrail; rel++)
   9925                 relBordTrail[rel] = relBorder1[rel];
   9926 
   9927             if(sbrGrid->pointer > 1)
   9928                 middleBorder = sbrGrid->numEnv + 1 - sbrGrid->pointer;
   9929             else
   9930                 middleBorder = sbrGrid->numEnv - 1;
   9931 
   9932             break;
   9933     }
   9934 
   9935     /* build time border vector */
   9936     sbrGrid->envTimeBorder[0] = absBordLead * SAMPLES_PER_SLOT;
   9937 
   9938     rel = 0;
   9939     border = absBordLead;
   9940     for(env = 1; env <= numRelLead; env++) {
   9941         border += relBordLead[rel++];
   9942         sbrGrid->envTimeBorder[env] = border * SAMPLES_PER_SLOT;
   9943     }
   9944 
   9945     rel = 0;
   9946     border = absBordTrail;
   9947     for(env = sbrGrid->numEnv - 1; env > numRelLead; env--) {
   9948         border -= relBordTrail[rel++];
   9949         sbrGrid->envTimeBorder[env] = border * SAMPLES_PER_SLOT;
   9950     }
   9951 
   9952     sbrGrid->envTimeBorder[sbrGrid->numEnv] = absBordTrail * SAMPLES_PER_SLOT;
   9953 
   9954     if(sbrGrid->numEnv > 1) {
   9955         sbrGrid->numNoiseFloors = 2;
   9956         sbrGrid->noiseTimeBorder[0] = sbrGrid->envTimeBorder[0];
   9957         sbrGrid->noiseTimeBorder[1] = sbrGrid->envTimeBorder[middleBorder];
   9958         sbrGrid->noiseTimeBorder[2] = sbrGrid->envTimeBorder[sbrGrid->numEnv];
   9959     }
   9960     else {
   9961         sbrGrid->numNoiseFloors = 1;
   9962         sbrGrid->noiseTimeBorder[0] = sbrGrid->envTimeBorder[0];
   9963         sbrGrid->noiseTimeBorder[1] = sbrGrid->envTimeBorder[1];
   9964     }
   9965 }
   9966 /***********************************************************************************************************************
   9967  * Function:    UnpackDeltaTimeFreq
   9968  *
   9969  * Description: unpack time/freq flags for delta coding of SBR envelopes (table 4.63)
   9970  *
   9971  * Inputs:      BitStreamInfo struct pointing to start of dt/df flags
   9972  *              number of envelopes
   9973  *              number of noise floors
   9974  *
   9975  * Outputs:     delta flags for envelope and noise floors
   9976  *
   9977  * Return:      none
   9978  **********************************************************************************************************************/
   9979 void UnpackDeltaTimeFreq(int numEnv, uint8_t *deltaFlagEnv, int numNoiseFloors, uint8_t *deltaFlagNoise) {
   9980 
   9981     int env, noiseFloor;
   9982 
   9983     for (env = 0; env < numEnv; env++)
   9984         deltaFlagEnv[env] = GetBits(1);
   9985 
   9986     for (noiseFloor = 0; noiseFloor < numNoiseFloors; noiseFloor++)
   9987         deltaFlagNoise[noiseFloor] = GetBits(1);
   9988 }
   9989 /***********************************************************************************************************************
   9990  * Function:    UnpackInverseFilterMode
   9991  *
   9992  * Description: unpack invf flags for chirp factor calculation (table 4.64)
   9993  *
   9994  * Inputs:      BitStreamInfo struct pointing to start of invf flags
   9995  *              number of noise floor bands
   9996  *
   9997  * Outputs:     invf flags for noise floor bands
   9998  *
   9999  * Return:      none
  10000  **********************************************************************************************************************/
  10001 void UnpackInverseFilterMode(int numNoiseFloorBands, uint8_t *mode) {
  10002 
  10003     int n;
  10004 
  10005     for (n = 0; n < numNoiseFloorBands; n++)
  10006         mode[n] = GetBits(2);
  10007 }
  10008 /***********************************************************************************************************************
  10009  * Function:    UnpackSinusoids
  10010  *
  10011  * Description: unpack sinusoid (harmonic) flags for each SBR subband (table 4.67)
  10012  *
  10013  * Inputs:      BitStreamInfo struct pointing to start of sinusoid flags
  10014  *              number of high resolution SBR subbands (nHigh)
  10015  *
  10016  * Outputs:     sinusoid flags for each SBR subband, zero-filled above nHigh
  10017  *
  10018  * Return:      none
  10019  **********************************************************************************************************************/
  10020 void UnpackSinusoids(int nHigh, int addHarmonicFlag, uint8_t *addHarmonic) {
  10021 
  10022     int n;
  10023 
  10024     n = 0;
  10025     if(addHarmonicFlag) {
  10026         for(; n < nHigh; n++)
  10027             addHarmonic[n] = GetBits(1);
  10028     }
  10029 
  10030     /* zero out unused bands */
  10031     for(; n < MAX_QMF_BANDS; n++)
  10032         addHarmonic[n] = 0;
  10033 }
  10034 /***********************************************************************************************************************
  10035  * Function:    CopyCouplingGrid
  10036  *
  10037  * Description: copy grid parameters from left to right for channel coupling
  10038  *
  10039  * Inputs:      initialized SBRGrid struct for left channel
  10040  *
  10041  * Outputs:     initialized SBRGrid struct for right channel
  10042  *
  10043  * Return:      none
  10044  **********************************************************************************************************************/
  10045 void CopyCouplingGrid(SBRGrid *sbrGridLeft, SBRGrid *sbrGridRight) {
  10046 
  10047     int env, noiseFloor;
  10048 
  10049     sbrGridRight->frameClass = sbrGridLeft->frameClass;
  10050     sbrGridRight->ampResFrame = sbrGridLeft->ampResFrame;
  10051     sbrGridRight->pointer = sbrGridLeft->pointer;
  10052 
  10053     sbrGridRight->numEnv = sbrGridLeft->numEnv;
  10054     for(env = 0; env < sbrGridLeft->numEnv; env++) {
  10055         sbrGridRight->envTimeBorder[env] = sbrGridLeft->envTimeBorder[env];
  10056         sbrGridRight->freqRes[env] = sbrGridLeft->freqRes[env];
  10057     }
  10058     sbrGridRight->envTimeBorder[env] = sbrGridLeft->envTimeBorder[env]; /* borders are [0, numEnv] inclusive */
  10059 
  10060     sbrGridRight->numNoiseFloors = sbrGridLeft->numNoiseFloors;
  10061     for(noiseFloor = 0; noiseFloor <= sbrGridLeft->numNoiseFloors; noiseFloor++)
  10062         sbrGridRight->noiseTimeBorder[noiseFloor] = sbrGridLeft->noiseTimeBorder[noiseFloor];
  10063 
  10064     /* numEnvPrev, numNoiseFloorsPrev, freqResPrev are updated in DecodeSBREnvelope() and DecodeSBRNoise() */
  10065 }
  10066 /***********************************************************************************************************************
  10067  * Function:    CopyCouplingInverseFilterMode
  10068  *
  10069  * Description: copy invf flags from left to right for channel coupling
  10070  *
  10071  * Inputs:      invf flags for left channel
  10072  *              number of noise floor bands
  10073  *
  10074  * Outputs:     invf flags for right channel
  10075  *
  10076  * Return:      none
  10077  **********************************************************************************************************************/
  10078 void CopyCouplingInverseFilterMode(int numNoiseFloorBands, uint8_t *modeLeft, uint8_t *modeRight) {
  10079 
  10080     int band;
  10081 
  10082     for(band = 0; band < numNoiseFloorBands; band++)
  10083         modeRight[band] = modeLeft[band];
  10084 }
  10085 /***********************************************************************************************************************
  10086  * Function:    UnpackSBRSingleChannel
  10087  *
  10088  * Description: unpack sideband info (grid, delta flags, invf flags, envelope and
  10089  *                noise floor configuration, sinusoids) for a single channel
  10090  *
  10091  * Inputs:      BitStreamInfo struct pointing to start of sideband info
  10092  *              initialized PSInfoSBR struct (after parsing SBR header and building
  10093  *                frequency tables)
  10094  *              base output channel (range = [0, nChans-1])
  10095  *
  10096  * Outputs:     updated PSInfoSBR struct (SBRGrid and SBRChan)
  10097  *
  10098  * Return:      none
  10099  **********************************************************************************************************************/
  10100 void UnpackSBRSingleChannel(int chBase) {
  10101 
  10102     int bitsLeft;
  10103     SBRHeader *sbrHdr = &(m_PSInfoSBR->sbrHdr[chBase]);
  10104     SBRGrid *sbrGridL = &(m_PSInfoSBR->sbrGrid[chBase + 0]);
  10105     SBRFreq *sbrFreq = &(m_PSInfoSBR->sbrFreq[chBase]);
  10106     SBRChan *sbrChanL = &(m_PSInfoSBR->sbrChan[chBase + 0]);
  10107 
  10108     m_PSInfoSBR->dataExtra = GetBits(1);
  10109     if(m_PSInfoSBR->dataExtra) m_PSInfoSBR->resBitsData = GetBits(4);
  10110 
  10111     UnpackSBRGrid(sbrHdr, sbrGridL);
  10112     UnpackDeltaTimeFreq(sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise);
  10113     UnpackInverseFilterMode(sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]);
  10114 
  10115     DecodeSBREnvelope(sbrGridL, sbrFreq, sbrChanL, 0);
  10116     DecodeSBRNoise(sbrGridL, sbrFreq, sbrChanL, 0);
  10117 
  10118     sbrChanL->addHarmonicFlag[1] = GetBits(1);
  10119     UnpackSinusoids(sbrFreq->nHigh, sbrChanL->addHarmonicFlag[1], sbrChanL->addHarmonic[1]);
  10120 
  10121     m_PSInfoSBR->extendedDataPresent = GetBits(1);
  10122     if(m_PSInfoSBR->extendedDataPresent) {
  10123         m_PSInfoSBR->extendedDataSize = GetBits(4);
  10124         if(m_PSInfoSBR->extendedDataSize == 15) m_PSInfoSBR->extendedDataSize += GetBits(8);
  10125 
  10126         bitsLeft = 8 * m_PSInfoSBR->extendedDataSize;
  10127 
  10128         /* get ID, unpack extension info, do whatever is necessary with it... */
  10129         while(bitsLeft > 0) {
  10130             GetBits(8);
  10131             bitsLeft -= 8;
  10132         }
  10133     }
  10134 }
  10135 /***********************************************************************************************************************
  10136  * Function:    UnpackSBRChannelPair
  10137  *
  10138  * Description: unpack sideband info (grid, delta flags, invf flags, envelope and
  10139  *                noise floor configuration, sinusoids) for a channel pair
  10140  *
  10141  * Inputs:      base output channel (range = [0, nChans-1])
  10142  *
  10143  * Outputs:     updated PSInfoSBR struct (SBRGrid and SBRChan for both channels)
  10144  *
  10145  * Return:      none
  10146  **********************************************************************************************************************/
  10147 void UnpackSBRChannelPair(int chBase) {
  10148 
  10149     int bitsLeft;
  10150     SBRHeader *sbrHdr = &(m_PSInfoSBR->sbrHdr[chBase]);
  10151     SBRGrid *sbrGridL = &(m_PSInfoSBR->sbrGrid[chBase + 0]), *sbrGridR = &(m_PSInfoSBR->sbrGrid[chBase + 1]);
  10152     SBRFreq *sbrFreq = &(m_PSInfoSBR->sbrFreq[chBase]);
  10153     SBRChan *sbrChanL = &(m_PSInfoSBR->sbrChan[chBase + 0]), *sbrChanR = &(m_PSInfoSBR->sbrChan[chBase + 1]);
  10154 
  10155     m_PSInfoSBR->dataExtra = GetBits(1);
  10156     if(m_PSInfoSBR->dataExtra) {
  10157         m_PSInfoSBR->resBitsData = GetBits(4);
  10158         m_PSInfoSBR->resBitsData = GetBits(4);
  10159     }
  10160 
  10161     m_PSInfoSBR->couplingFlag = GetBits(1);
  10162     if(m_PSInfoSBR->couplingFlag) {
  10163         UnpackSBRGrid(sbrHdr, sbrGridL);
  10164         CopyCouplingGrid(sbrGridL, sbrGridR);
  10165 
  10166         UnpackDeltaTimeFreq(sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors,
  10167                 sbrChanL->deltaFlagNoise);
  10168         UnpackDeltaTimeFreq(sbrGridR->numEnv, sbrChanR->deltaFlagEnv, sbrGridR->numNoiseFloors,
  10169                 sbrChanR->deltaFlagNoise);
  10170 
  10171         UnpackInverseFilterMode(sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]);
  10172         CopyCouplingInverseFilterMode(sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1], sbrChanR->invfMode[1]);
  10173 
  10174         DecodeSBREnvelope(sbrGridL, sbrFreq, sbrChanL, 0);
  10175         DecodeSBRNoise(sbrGridL, sbrFreq, sbrChanL, 0);
  10176         DecodeSBREnvelope(sbrGridR, sbrFreq, sbrChanR, 1);
  10177         DecodeSBRNoise(sbrGridR, sbrFreq, sbrChanR, 1);
  10178 
  10179         /* pass RIGHT sbrChan struct */
  10180         UncoupleSBREnvelope(sbrGridL, sbrFreq, sbrChanR);
  10181         UncoupleSBRNoise(sbrGridL, sbrFreq, sbrChanR);
  10182 
  10183     }
  10184     else {
  10185         UnpackSBRGrid(sbrHdr, sbrGridL);
  10186         UnpackSBRGrid(sbrHdr, sbrGridR);
  10187         UnpackDeltaTimeFreq(sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors,
  10188                 sbrChanL->deltaFlagNoise);
  10189         UnpackDeltaTimeFreq(sbrGridR->numEnv, sbrChanR->deltaFlagEnv, sbrGridR->numNoiseFloors,
  10190                 sbrChanR->deltaFlagNoise);
  10191         UnpackInverseFilterMode(sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]);
  10192         UnpackInverseFilterMode(sbrFreq->numNoiseFloorBands, sbrChanR->invfMode[1]);
  10193 
  10194         DecodeSBREnvelope(sbrGridL, sbrFreq, sbrChanL, 0);
  10195         DecodeSBREnvelope(sbrGridR, sbrFreq, sbrChanR, 1);
  10196         DecodeSBRNoise(sbrGridL, sbrFreq, sbrChanL, 0);
  10197         DecodeSBRNoise(sbrGridR, sbrFreq, sbrChanR, 1);
  10198     }
  10199 
  10200     sbrChanL->addHarmonicFlag[1] = GetBits(1);
  10201     UnpackSinusoids(sbrFreq->nHigh, sbrChanL->addHarmonicFlag[1], sbrChanL->addHarmonic[1]);
  10202 
  10203     sbrChanR->addHarmonicFlag[1] = GetBits(1);
  10204     UnpackSinusoids(sbrFreq->nHigh, sbrChanR->addHarmonicFlag[1], sbrChanR->addHarmonic[1]);
  10205 
  10206     m_PSInfoSBR->extendedDataPresent = GetBits(1);
  10207     if(m_PSInfoSBR->extendedDataPresent) {
  10208         m_PSInfoSBR->extendedDataSize = GetBits(4);
  10209         if(m_PSInfoSBR->extendedDataSize == 15) m_PSInfoSBR->extendedDataSize += GetBits(8);
  10210 
  10211         bitsLeft = 8 * m_PSInfoSBR->extendedDataSize;
  10212 
  10213         /* get ID, unpack extension info, do whatever is necessary with it... */
  10214         while(bitsLeft > 0) {
  10215             GetBits(8);
  10216             bitsLeft -= 8;
  10217         }
  10218     }
  10219 }