diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 446e6e6b3b..18956b0767 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -40,6 +40,7 @@ OBJS = ac3_parser.o                                                     \
        d3d11va.o                                                        \
        decode.o                                                         \
        dirac.o                                                          \
+       dolby_e_parser.o                                                 \
        dv_profile.o                                                     \
        encode.o                                                         \
        imgconvert.o                                                     \
diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c
index 6bb817ec5c..74388f43d1 100644
--- a/libavcodec/dolby_e.c
+++ b/libavcodec/dolby_e.c
@@ -28,13 +28,14 @@
 #include "put_bits.h"
 #include "parser.h"
 #include "dolby_e.h"
+#include "dolby_edec.h"
+#include "dolby_e_parser_internal.h"
 #include "fft.h"
 
 static int skip_input(DBEContext *s, int nb_words)
 {
     if (nb_words > s->input_size) {
-        if (s->avctx)
-            av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n");
+        av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -65,8 +66,7 @@ static int convert_input(DBEContext *s, int nb_words, int key)
     av_assert0(nb_words <= 1024u);
 
     if (nb_words > s->input_size) {
-        if (s->avctx)
-            av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n");
+        av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -92,69 +92,6 @@ static int convert_input(DBEContext *s, int nb_words, int key)
     return init_get_bits(&s->gb, s->buffer, nb_words * s->word_bits);
 }
 
-static int parse_metadata(DBEContext *s, DolbyEHeaderInfo *hdr)
-{
-    int i, ret, key, mtd_size;
-
-    if ((key = parse_key(s)) < 0)
-        return key;
-    if ((ret = convert_input(s, 1, key)) < 0)
-        return ret;
-
-    skip_bits(&s->gb, 4);
-    mtd_size = get_bits(&s->gb, 10);
-    if (!mtd_size) {
-        if (s->avctx)
-            av_log(s->avctx, AV_LOG_ERROR, "Invalid metadata size\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    if ((ret = convert_input(s, mtd_size, key)) < 0)
-        return ret;
-
-    skip_bits(&s->gb, 14);
-    hdr->prog_conf = get_bits(&s->gb, 6);
-    if (hdr->prog_conf > MAX_PROG_CONF) {
-        if (s->avctx)
-            av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    hdr->nb_channels = nb_channels_tab[hdr->prog_conf];
-    hdr->nb_programs = nb_programs_tab[hdr->prog_conf];
-
-    hdr->fr_code      = get_bits(&s->gb, 4);
-    hdr->fr_code_orig = get_bits(&s->gb, 4);
-    if (!sample_rate_tab[hdr->fr_code] ||
-        !sample_rate_tab[hdr->fr_code_orig]) {
-        if (s->avctx)
-            av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    skip_bits_long(&s->gb, 88);
-    for (i = 0; i < hdr->nb_channels; i++)
-        hdr->ch_size[i] = get_bits(&s->gb, 10);
-    hdr->mtd_ext_size = get_bits(&s->gb, 8);
-    hdr->meter_size   = get_bits(&s->gb, 8);
-
-    skip_bits_long(&s->gb, 10 * hdr->nb_programs);
-    for (i = 0; i < hdr->nb_channels; i++) {
-        hdr->rev_id[i]     = get_bits(&s->gb,  4);
-        skip_bits1(&s->gb);
-        hdr->begin_gain[i] = get_bits(&s->gb, 10);
-        hdr->end_gain[i]   = get_bits(&s->gb, 10);
-    }
-
-    if (get_bits_left(&s->gb) < 0) {
-        if (s->avctx)
-            av_log(s->avctx, AV_LOG_ERROR, "Read past end of metadata\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    return skip_input(s, mtd_size + 1);
-}
-
 static int parse_metadata_ext(DBEDecodeContext *s1)
 {
     DBEContext *s = &s1->dectx;
@@ -603,73 +540,6 @@ static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
     return 0;
 }
 
-static int dolby_e_sync(DBEContext *s, const uint8_t *buf, int buf_size)
-{
-    int hdr;
-
-    if (buf_size < 3)
-        return AVERROR_INVALIDDATA;
-
-    hdr = AV_RB24(buf);
-    if ((hdr & 0xfffffe) == 0x7888e) {
-        s->word_bits = 24;
-    } else if ((hdr & 0xffffe0) == 0x788e0) {
-        s->word_bits = 20;
-    } else if ((hdr & 0xfffe00) == 0x78e00) {
-        s->word_bits = 16;
-    } else {
-        if (s->avctx)
-            av_log(s->avctx, AV_LOG_ERROR, "Invalid frame header\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    s->word_bytes  = s->word_bits + 7 >> 3;
-    s->input       = buf + s->word_bytes;
-    s->input_size  = buf_size / s->word_bytes - 1;
-    s->key_present = hdr >> 24 - s->word_bits & 1;
-
-    return 0;
-}
-
-static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx,
-                        const uint8_t **poutbuf, int *poutbuf_size,
-                        const uint8_t *buf, int buf_size)
-{
-    DBEParseContext *s1 = s2->priv_data;
-    DBEContext *s = &s1->dectx;
-    int ret;
-
-    if ((ret = dolby_e_sync(s, buf, buf_size)) < 0)
-        goto end;
-
-    if ((ret = parse_metadata(s, &s1->metadata)) < 0)
-        goto end;
-
-    s2->duration = FRAME_SAMPLES;
-    switch (s1->metadata.nb_channels) {
-    case 4:
-        avctx->channel_layout = AV_CH_LAYOUT_4POINT0;
-        break;
-    case 6:
-        avctx->channel_layout = AV_CH_LAYOUT_5POINT1;
-        break;
-    case 8:
-        avctx->channel_layout = AV_CH_LAYOUT_7POINT1;
-        break;
-    }
-
-    avctx->channels    = s1->metadata.nb_channels;
-    avctx->sample_rate = sample_rate_tab[s1->metadata.fr_code];
-    avctx->sample_fmt  = AV_SAMPLE_FMT_FLTP;
-
-end:
-    /* always return the full packet. this parser isn't doing any splitting or
-       combining, only packet analysis */
-    *poutbuf      = buf;
-    *poutbuf_size = buf_size;
-    return buf_size;
-}
-
 static int dolby_e_decode_frame(AVCodecContext *avctx, void *data,
                                 int *got_frame_ptr, AVPacket *avpkt)
 {
@@ -677,10 +547,10 @@ static int dolby_e_decode_frame(AVCodecContext *avctx, void *data,
     DBEContext *s = &s1->dectx;
     int i, j, ret;
 
-    if ((ret = dolby_e_sync(s, avpkt->data, avpkt->size)) < 0)
+    if ((ret = ff_dolby_e_parse_init(s, avpkt->data, avpkt->size)) < 0)
         return ret;
 
-    if ((ret = parse_metadata(s, &s1->metadata)) < 0)
+    if ((ret = ff_dolby_e_parse_header(s, &s1->metadata)) < 0)
         return ret;
 
     if (s1->metadata.nb_programs > 1 && !s1->metadata.multi_prog_warned) {
@@ -853,13 +723,6 @@ static av_cold int dolby_e_init(AVCodecContext *avctx)
     return 0;
 }
 
-AVCodecParser ff_dolby_e_parser = {
-    .codec_ids      = { AV_CODEC_ID_DOLBY_E },
-    .priv_data_size = sizeof(DBEParseContext),
-    .parser_parse   = dolby_e_parse,
-    .parser_close   = ff_parse_close,
-};
-
 AVCodec ff_dolby_e_decoder = {
     .name           = "dolby_e",
     .long_name      = NULL_IF_CONFIG_SMALL("Dolby E"),
diff --git a/libavcodec/dolby_e.h b/libavcodec/dolby_e.h
index 2c012e93d1..855d978bc2 100644
--- a/libavcodec/dolby_e.h
+++ b/libavcodec/dolby_e.h
@@ -21,59 +21,18 @@
 #ifndef AVCODEC_DOLBY_E_H
 #define AVCODEC_DOLBY_E_H
 
-#include "libavutil/float_dsp.h"
-#include "libavutil/libm.h"
-#include "libavutil/mem_internal.h"
-
-#include "internal.h"
 #include "get_bits.h"
-#include "kbdwin.h"
-#include "fft.h"
 
 #define FRAME_SAMPLES   1792
 
 #define MAX_PROG_CONF   23
 #define MAX_PROGRAMS    8
 #define MAX_CHANNELS    8
-#define MAX_SEGMENTS    2
-
-#define MAX_GROUPS      8
-#define MAX_EXPONENTS   304
-#define MAX_MANTISSAS   1024
-
-#define MAX_MSTR_EXP    2
-#define MAX_BIAS_EXP    50
-
-typedef struct DBEGroup {
-    uint8_t         nb_exponent;
-    uint8_t         nb_bias_exp[MAX_MSTR_EXP];
-    uint16_t        exp_ofs;
-    uint16_t        mnt_ofs;
-    const uint8_t   *nb_mantissa;
-    uint8_t         imdct_idx;
-    uint8_t         imdct_phs;
-    uint16_t        win_len;
-    uint16_t        dst_ofs;
-    uint16_t        win_ofs;
-    uint16_t        src_ofs;
-} DBEGroup;
-
-typedef struct DBEChannel {
-    int     gr_code;
-    int     bw_code;
-
-    int         nb_groups;
-    int         nb_mstr_exp;
-    DBEGroup    groups[MAX_GROUPS];
-
-    int     exp_strategy[MAX_GROUPS];
-    int     exponents[MAX_EXPONENTS];
-    int     bap[MAX_EXPONENTS];
-    int     idx[MAX_EXPONENTS];
-
-    DECLARE_ALIGNED(32, float, mantissas)[MAX_MANTISSAS];
-} DBEChannel;
 
+/**
+ * @struct DBEContext
+ * Dolby E reading context used by decoder and parser.
+ */
 typedef struct DBEContext {
     void        *avctx;
     GetBitContext   gb;
@@ -119,557 +78,8 @@ typedef struct DolbyEHeaderInfo {
     /** @} */
 } DolbyEHeaderInfo;
 
-typedef struct DBEParseContext {
-    ParseContext pc;
-    DBEContext dectx;
-
-    DolbyEHeaderInfo metadata;
-} DBEParseContext;
-
-typedef struct DBEDecodeContext {
-    AVCodecContext  *avctx;
-    DBEContext  dectx;
-
-    DolbyEHeaderInfo metadata;
-
-    DBEChannel  channels[MAX_SEGMENTS][MAX_CHANNELS];
-
-    DECLARE_ALIGNED(32, float, history)[MAX_CHANNELS][256];
-
-    FFTContext          imdct[3];
-    AVFloatDSPContext   *fdsp;
-} DBEDecodeContext;
-
-static const uint8_t nb_programs_tab[MAX_PROG_CONF + 1] = {
-    2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1, 2, 3, 3, 4, 5, 6, 1, 2, 3, 4, 1, 1
-};
-
-static const uint8_t nb_channels_tab[MAX_PROG_CONF + 1] = {
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 8, 8
-};
-
-static const int8_t lfe_channel_tab[MAX_PROG_CONF + 1] = {
-     5,  5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  5, 5
-};
-
-static const uint8_t ch_reorder_4[4] = { 0, 2, 1, 3 };
-static const uint8_t ch_reorder_6[6] = { 0, 2, 4, 1, 3, 5 };
-static const uint8_t ch_reorder_8[8] = { 0, 2, 6, 4, 1, 3, 7, 5 };
-static const uint8_t ch_reorder_n[8] = { 0, 2, 4, 6, 1, 3, 5, 7 };
-
 static const uint16_t sample_rate_tab[16] = {
     0, 42965, 43008, 44800, 53706, 53760
 };
 
-static const uint8_t nb_groups_tab[4] = { 1, 8, 7, 1 };
-
-static const uint8_t nb_mstr_exp_tab[4] = { 2, 2, 2, 1 };
-
-static const uint8_t nb_mantissa_38[38] = {
-     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
-     2,  2,  2,  2,  2,  2,  3,  3,  3,  4,  4,  4,  5,  5,  6,  6,
-     7,  8,  9, 10, 11, 12,
-};
-
-static const uint8_t nb_mantissa_44[44] = {
-     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,
-     2,  2,  2,  2,  2,  3,  3,  3,  3,  4,  4,  5,  5,  6,  7,  7,
-     8,  9, 10, 11, 12, 13, 15, 16, 18, 20, 22, 25,
-};
-
-static const uint8_t nb_mantissa_50[50] = {
-     1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  3,  3,  3,
-     3,  4,  4,  5,  5,  6,  6,  7,  8,  9,  9, 10, 12, 13, 14, 16,
-    18, 19, 22, 24, 27, 29, 32, 36, 40, 44, 49, 54, 60, 66, 74, 82,
-    90, 100,
-};
-
-static const uint8_t imdct_bits_tab[3] = { 8, 9, 11 };
-
-static const DBEGroup grp_tab_0[1] = {
-    { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 },
-};
-
-static const DBEGroup grp_tab_1[8] = {
-    { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 },
-    { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 },
-    { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 },
-    { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 },
-    { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 },
-    { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 },
-    { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 704, 0, 0 },
-    { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 1, 256, 832, 0, 0 },
-};
-
-static const DBEGroup grp_tab_2[7] = {
-    { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 },
-    { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 },
-    { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 },
-    { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 },
-    { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 },
-    { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 },
-    { 44, { 19, 25 }, 228, 768, nb_mantissa_44, 1, 1, 448, 704, 960, 64 },
-};
-
-static const DBEGroup grp_tab_3[1] = {
-    { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 },
-};
-
-static const DBEGroup grp_tab_4[1] = {
-    { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 },
-};
-
-static const DBEGroup grp_tab_5[8] = {
-    { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 1, 256, 64, 0, 0 },
-    { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 192, 0, 0 },
-    { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 },
-    { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 },
-    { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 },
-    { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 },
-    { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 },
-    { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 },
-};
-
-static const DBEGroup grp_tab_6[7] = {
-    { 44, { 19, 25 }, 0, 0, nb_mantissa_44, 1, 1, 448, 0, 3264, 0 },
-    { 38, { 12, 26 }, 44, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 },
-    { 38, { 12, 26 }, 82, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 },
-    { 38, { 12, 26 }, 120, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 },
-    { 38, { 12, 26 }, 158, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 },
-    { 38, { 12, 26 }, 196, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 },
-    { 38, { 12, 26 }, 234, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 },
-};
-
-static const DBEGroup grp_tab_7[1] = {
-    { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 },
-};
-
-static const DBEGroup *const frm_ofs_tab[2][4] = {
-    { grp_tab_0, grp_tab_1, grp_tab_2, grp_tab_3 },
-    { grp_tab_4, grp_tab_5, grp_tab_6, grp_tab_7 }
-};
-
-static const uint8_t mantissa_size1[16][4] = {
-    {  0,  0,  0,  0 }, {  2,  1,  1,  1 }, {  3,  2,  1,  1 }, {  4,  3,  2,  1 },
-    {  5,  4,  3,  2 }, {  6,  5,  4,  3 }, {  7,  6,  5,  4 }, {  8,  7,  6,  5 },
-    {  9,  8,  7,  6 }, { 10,  9,  8,  7 }, { 11, 10,  9,  8 }, { 12, 11, 10,  9 },
-    { 13, 12, 11, 10 }, { 14, 13, 12, 11 }, { 15, 14, 13, 12 }, { 16, 15, 14, 13 },
-};
-
-static const uint8_t mantissa_size2[16][4] = {
-    {  0,  0,  0,  0 }, {  2,  1,  2,  2 }, {  3,  2,  3,  3 }, {  4,  3,  4,  4 },
-    {  5,  4,  5,  5 }, {  6,  5,  6,  6 }, {  7,  6,  7,  7 }, {  8,  7,  8,  8 },
-    {  9,  8,  9,  9 }, { 10,  9, 10, 10 }, { 11, 10, 11, 11 }, { 12, 11, 12, 12 },
-    { 13, 12, 13, 13 }, { 14, 13, 14, 14 }, { 15, 14, 15, 15 }, { 16, 15, 16, 16 },
-};
-
-static const float start_window[192] = {
-    0.00161569379826, 0.00185748233347, 0.00198562758548, 0.00207834078104,
-    0.00215717748523, 0.00223067096393, 0.00230299213147, 0.00237651215396,
-    0.00245275561606, 0.00253281402069, 0.00261754673613, 0.00270768786168,
-    0.00280390761895, 0.00290684998656, 0.00301715751161, 0.00313548872798,
-    0.00326253122934, 0.00339901215995, 0.00354570716636, 0.00370344845023,
-    0.00387313232586, 0.00405572653911, 0.00425227750970, 0.00446391759265,
-    0.00469187240551, 0.00493746822816, 0.00520213944619, 0.00548743597507,
-    0.00579503056737, 0.00612672586953, 0.00648446105606, 0.00687031782873,
-    0.00728652552677, 0.00773546505205, 0.00821967127415, 0.00874183354619,
-    0.00930479393832, 0.00991154278653, 0.01056521116692, 0.01126905994567,
-    0.01202646513050, 0.01284089936559, 0.01371590957417, 0.01465509096066,
-    0.01566205783408, 0.01674041199523, 0.01789370972358, 0.01912542867865,
-    0.02043893626265, 0.02183746113793, 0.02332406961796, 0.02490164852364,
-    0.02657289580178, 0.02834031974193, 0.03020624702903, 0.03217283918354,
-    0.03424211623810, 0.03641598586180, 0.03869627565015, 0.04108476601498,
-    0.04358322107390, 0.04619341515939, 0.04891715301882, 0.05175628239149,
-
-    0.05471237327267, 0.05778734733755, 0.06098291402413, 0.06430101352084,
-    0.06774345212186, 0.07131188644726, 0.07500780649199, 0.07883251748595,
-    0.08278712056651, 0.08687249228061, 0.09108926295730, 0.09543779401074,
-    0.09991815425851, 0.10453009536427, 0.10927302653894, 0.11414598865987,
-    0.11914762799220, 0.12427616972097, 0.12952939152560, 0.13490459744934,
-    0.14039859233595, 0.14600765712201, 0.15172752528722, 0.15755336077528,
-    0.16347973770491, 0.16950062219342, 0.17560935661442, 0.18179864660619,
-    0.18806055113821, 0.19438647593012, 0.20076717050010, 0.20719272909882,
-    0.21365259576030, 0.22013557367283, 0.22662983904194, 0.23312295958328,
-    0.23960191774666, 0.24605313873388, 0.25246252333253, 0.25881548554631,
-    0.26509699495987, 0.27129162373316, 0.27738359807707, 0.28335685401987,
-    0.28919509723179, 0.29488186663467, 0.30040060148455, 0.30573471157819,
-    0.31086765019993, 0.31578298939317, 0.32046449711227, 0.32489621578468,
-    0.32906254179156, 0.33294830535654, 0.33653885031840, 0.33982011325336,
-    0.34277870140679, 0.34540196889300, 0.34767809062480, 0.34959613344194,
-    0.35114612391958, 0.35231911235422, 0.35310723244504, 0.35350375621308,
-
-    0.35350314372945, 0.35310108725579, 0.35229454943591, 0.35108179521634,
-    0.34946241721522, 0.34743735430290, 0.34500890320420, 0.34218072298001,
-    0.33895783229541, 0.33534659943168, 0.33135472505060, 0.32699121776996,
-    0.32226636266000, 0.31719168282019, 0.31177989424432, 0.30604485422875,
-    0.30000150362379, 0.29366580327088, 0.28705466500775, 0.28018587766131,
-    0.27307802848095, 0.26575042049535, 0.25822298630189, 0.25051619882000,
-    0.24265097955783, 0.23464860495522, 0.22653061137548, 0.21831869932335,
-    0.21003463746705, 0.20170016703857, 0.19333690717811, 0.18496626177620,
-    0.17660932835062, 0.16828680947474, 0.16001892724986, 0.15182534128597,
-    0.14372507062477, 0.13573642000364, 0.12787691082233, 0.12016321713317,
-    0.11261110693234, 0.10523538898282, 0.09804986534955, 0.09106728977263,
-    0.08429933194438, 0.07775654768810, 0.07144835495683, 0.06538301547324,
-    0.05956762170687, 0.05400808871425, 0.04870915012107, 0.04367435714993,
-    0.03890607899172, 0.03440550179663, 0.03017262174627, 0.02620622428513,
-    0.02250383492507, 0.01906161305732, 0.01587412848221, 0.01293388032354,
-    0.01023019677288, 0.00774641320626, 0.00545109736891, 0.00325868651263,
-};
-
-static const float short_window2[192] = {
-    0.00018861094606, 0.00033433010202, 0.00050309624485, 0.00070306161748,
-    0.00093995174533, 0.00121913067128, 0.00154606505568, 0.00192647806126,
-    0.00236641248692, 0.00287225985240, 0.00345077377440, 0.00410907465023,
-    0.00485464855241, 0.00569534163219, 0.00663935063508, 0.00769520981249,
-    0.00887177436246, 0.01017820046395, 0.01162392194150, 0.01321862359335,
-    0.01497221122468, 0.01689477844427, 0.01899657030441, 0.02128794388846,
-    0.02377932597692, 0.02648116795039, 0.02940389811590, 0.03255787167130,
-    0.03595331854986, 0.03960028941437, 0.04350860009563, 0.04768777479454,
-    0.05214698838949, 0.05689500821121, 0.06194013566525, 0.06729014809766,
-    0.07295224131210, 0.07893297315602, 0.08523820859989, 0.09187306673620,
-    0.09884187012422, 0.10614809690222, 0.11379433608064, 0.12178224641797,
-    0.13011251926531, 0.13878484574660, 0.14779788861830, 0.15714925912610,
-    0.16683549914631, 0.17685206886673, 0.18719334022589, 0.19785259629099,
-    0.20882203671372, 0.22009278936030, 0.23165492816694, 0.24349749722585,
-    0.25560854105961, 0.26797514099368, 0.28058345748882, 0.29341877824732,
-    0.30646557185942, 0.31970754671026, 0.33312771482295, 0.34670846027024,
-
-    0.36043161174692, 0.37427851885723, 0.38823013163645, 0.40226708279486,
-    0.41636977214436, 0.43051845264462, 0.44469331748632, 0.45887458761470,
-    0.47304259908636, 0.48717788964798, 0.50126128392546, 0.51527397661778,
-    0.52919761310050, 0.54301436685998, 0.55670701320069, 0.57025899869448,
-    0.58365450587230, 0.59687851269542, 0.60991684638414, 0.62275623122793,
-    0.63538433005035, 0.64778977905593, 0.65996221584264, 0.67189230042379,
-    0.68357172916486, 0.69499324160511, 0.70615062019861, 0.71703868307548,
-    0.72765326998919, 0.73799122168099, 0.74805035295521, 0.75782941981995,
-    0.76732808110520, 0.77654685502339, 0.78548707118622, 0.79415081863423,
-    0.80254089047207, 0.81066072573188, 0.81851434910893, 0.82610630922734,
-    0.83344161609862, 0.84052567843230, 0.84736424144524, 0.85396332579459,
-    0.86032916822973, 0.86646816451999, 0.87238681516918, 0.87809167437532,
-    0.88358930263537, 0.88888622333073, 0.89398888356256, 0.89890361943564,
-    0.90363662591861, 0.90819393133744, 0.91258137648979, 0.91680459830070,
-    0.92086901787718, 0.92477983276087, 0.92854201312583, 0.93216030163834,
-    0.93563921662343, 0.93898305819384, 0.94219591693690, 0.94528168477979,
-
-    0.94823843319821, 0.95106834367330, 0.95377776558539, 0.95636718335775,
-    0.95883679961479, 0.96118650212341, 0.96341583179195, 0.96552395212906,
-    0.96750962060547, 0.96937116231768, 0.97110644638309, 0.97271286544154,
-    0.97418731862798, 0.97552619834964, 0.97672538116257, 0.97778022299974,
-    0.97868555895586, 0.97943570778357, 0.98002448120255, 0.98044519806866,
-    0.98069070339493, 0.98075339216123, 0.98062523779637, 0.98029782516478,
-    0.97976238784222, 0.97900984942031, 0.97803086854002, 0.97681588731895,
-    0.97535518280755, 0.97363892108474, 0.97165721358452, 0.96940017523145,
-    0.96685798395452, 0.96402094114589, 0.96087953263194, 0.95742448973047,
-    0.95364684997699, 0.94953801711660, 0.94508981997396, 0.94029456983253,
-    0.93514511597504, 0.92963489905951, 0.92375800202883, 0.91750919827624,
-    0.91088399681406, 0.90387868421832, 0.89649036314692, 0.88871698725397,
-    0.88055739234735, 0.87201132366062, 0.86307945913336, 0.85376342861693,
-    0.84406582894455, 0.83399023482637, 0.82354120554757, 0.81272428745995,
-    0.80154601230457, 0.79001389138101, 0.77813640562199, 0.76592299164227,
-    0.75338402384395, 0.74053079267526, 0.72737547915460, 0.71393112578527,
-};
-
-static const float short_window3[64] = {
-    0.00326887936450, 0.00550242900936, 0.00786846643791, 0.01045683453520,
-    0.01330402120132, 0.01643221072863, 0.01985798040609, 0.02359509464766,
-    0.02765559221954, 0.03205025893128, 0.03678884369614, 0.04188015679495,
-    0.04733210987781, 0.05315172583924, 0.05934513287609, 0.06591755045290,
-    0.07287327156378, 0.08021564389822, 0.08794705152307, 0.09606889811179,
-    0.10458159240070, 0.11348453632940, 0.12277611617809, 0.13245369691511,
-    0.14251361989876, 0.15295120402567, 0.16376075037904, 0.17493555039885,
-    0.18646789757072, 0.19834910260891, 0.21056951208995, 0.22311853047787,
-    0.23598464546683, 0.24915545655419, 0.26261770674500, 0.27635731727778,
-    0.29035942525136, 0.30460842402318, 0.31908800624032, 0.33378120935681,
-    0.34867046348260, 0.36373764140285, 0.37896411059909, 0.39433078709788,
-    0.40981819096657, 0.42540650327031, 0.44107562429959, 0.45680523287270,
-    0.47257484651351, 0.48836388230077, 0.50415171818214, 0.51991775454258,
-    0.53564147581496, 0.55130251191887, 0.56688069931047, 0.58235614142007,
-    0.59770926827271, 0.61292089506118, 0.62797227945823, 0.64284517745255,
-    0.65752189749349, 0.67198535273209, 0.68621911114984, 0.70020744337099,
-};
-
-static const uint8_t dc_code_tab[5] = { 0, 0, 0, 1, 1 };
-
-static const uint8_t ht_code_tab[5] = { 0, 0, 1, 2, 2 };
-
-static const uint8_t band_ofs_tab[3][4] = {
-    { 12, 8, 4, 0 }, { 14, 10, 6, 0 }, { 12, 8, 4, 0 }
-};
-
-static const uint8_t band_low_tab[3] = { 9, 17, 24 };
-
-static const uint16_t fast_gain_tab[8] = {
-    128, 256, 384, 512, 640, 768, 896, 1024
-};
-
-static const uint16_t slow_decay_tab[2][2] = { { 27, -1 }, { 32, 21 } };
-
-static const uint16_t misc_decay_tab[3][2][2] = {
-    { { 354, -1 }, { 425, 425 } },
-    { { 266, -1 }, { 320,  -1 } },
-    { { 213, -1 }, { 256,  -1 } }
-};
-
-static const uint16_t fast_decay_tab[3][2][2][50] = {
-    {{{
-        142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
-        142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
-        142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
-        142, 142, 142, 142, 142, 142, 142, 142,
-    }, {
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-    }}, {{
-        170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
-        170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
-        170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
-        170, 170, 170, 170, 170, 170, 170, 170,
-    }, {
-         64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
-         64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
-         64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
-         64,  64,  64,  64,  64,  64,  64,  64,
-    }}}, {{{
-        266, 266, 106, 106, 106, 106, 106, 106, 106, 106,
-        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
-        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
-        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
-        106, 106, 106, 106,
-    }, {
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,
-    }}, {{
-        319, 319, 128, 128, 128, 128, 128, 128, 128, 128,
-        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
-        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
-        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
-        128, 128, 128, 128,
-    }, {
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,
-    }}}, {{{
-        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
-        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
-        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
-        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
-        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
-    }, {
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-    }}, {{
-        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
-        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
-        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
-        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
-        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
-    }, {
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
-    }}}
-};
-
-static const uint16_t fast_gain_adj_tab[3][2][62] = {
-    {{
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   1,   2,   4,   7,  11,  16,  29,  44,  59,
-         76,  94, 116, 142, 179, 221, 252, 285, 312, 334,
-    }, {
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          2,   5,   8,  10,  15,  28,  42,  57,  75,  93,
-        115, 140, 177, 219, 247, 280, 308, 330, 427, 533,
-    }}, {{
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   2,   5,   8,  12,  21,  35,  51,  69,  89,
-        111, 138, 176, 220, 251, 284, 312, 334,
-    }, {
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   2,
-          5,   8,  11,  18,  33,  49,  65,  84, 106, 132,
-        168, 214, 245, 279, 308, 329, 427, 533,
-    }}, {{
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   1,   4,   7,  10,  17,
-         31,  47,  65,  84, 107, 134, 171, 215, 250, 283,
-        312, 334,
-    }, {
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-          0,   0,   0,   0,   3,   6,   9,  13,  27,  43,
-         60,  79, 100, 126, 160, 207, 242, 276, 307, 329,
-        427, 533,
-    }}
-};
-
-static const uint16_t slow_gain_tab[3][2][50] = {
-    {{
-        3072, 3072, 3072, 3072, 3072, 3072, 1063, 1063, 1063, 1063,
-        1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
-        1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
-        1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
-    }, {
-        3072, 3072, 3072, 3072, 3072, 3072,  850,  850,  850,  850,
-         850,  850,  850,  850,  850,  850,  850,  850,  850,  850,
-         850,  850,  850,  850,  850,  850,  850,  850,  850,  850,
-         850,  850,  850,  850,  850,  850,  850,  850,
-    }}, {{
-        3072, 1212, 1212, 1212,  999,  999,  999,  999,  999,  999,
-         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
-         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
-         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
-         999,  999,  999,  999,
-    }, {
-          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-          -1,   -1,   -1,   -1,
-    }}, {{
-        3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072,
-         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
-         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
-         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
-         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
-    }, {
-          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-    }}
-};
-
-static const uint16_t hearing_thresh_tab[3][3][50] = {
-    {{
-        1403, 1141, 1000,  959,  948,  957,  946,  925,  899,  871,
-         843,  815,  789,  766,  745,  727,  705,  687,  681,  686,
-         701,  725,  768,  854,  940, 1018, 1075, 1103, 1111, 1106,
-        1098, 1105, 1142, 1237, 1419, 1721, 2169, 2805,
-    }, {
-        1401, 1130,  995,  957,  947,  955,  941,  918,  890,  861,
-         831,  803,  777,  754,  734,  717,  698,  684,  682,  692,
-         712,  743,  798,  894,  976, 1045, 1091, 1109, 1110, 1102,
-        1098, 1116, 1174, 1300, 1526, 1884, 2401, 3072,
-    }, {
-        1393, 1086,  974,  949,  957,  941,  913,  878,  843,  808,
-         777,  750,  727,  708,  695,  686,  681,  689,  714,  752,
-         811,  888,  971, 1044, 1087, 1108, 1110, 1102, 1098, 1115,
-        1172, 1290, 1489, 1812, 2293, 2964, 3072, 3072,
-    }}, {{
-        1412, 1343, 1141, 1047, 1000,  974,  959,  951,  948,  947,
-         957,  953,  946,  936,  925,  906,  878,  850,  822,  795,
-         771,  745,  719,  700,  687,  681,  685,  701,  733,  784,
-         885,  977, 1047, 1092, 1110, 1108, 1099, 1102, 1138, 1233,
-        1413, 1711, 2157, 2797,
-    }, {
-        1412, 1336, 1130, 1040,  995,  970,  957,  950,  947,  947,
-         955,  950,  941,  930,  918,  897,  868,  838,  810,  783,
-         759,  734,  710,  693,  684,  681,  690,  712,  752,  823,
-         924, 1009, 1069, 1102, 1111, 1104, 1098, 1111, 1168, 1295,
-        1518, 1873, 2388, 3072,
-    }, {
-        1411, 1293, 1086, 1009,  974,  957,  949,  947,  957,  951,
-         941,  928,  913,  896,  878,  852,  817,  785,  756,  732,
-         713,  695,  683,  682,  689,  710,  746,  811,  906,  992,
-        1061, 1099, 1111, 1106, 1098, 1107, 1155, 1266, 1471, 1799,
-        2277, 2945, 3072, 3072,
-    }}, {{
-        1431, 1412, 1403, 1379, 1343, 1293, 1229, 1180, 1125, 1075,
-        1040, 1014,  996,  979,  965,  957,  951,  948,  947,  957,
-         951,  940,  924,  903,  877,  846,  815,  785,  753,  725,
-         702,  686,  681,  689,  714,  760,  847,  947, 1028, 1083,
-        1108, 1109, 1101, 1100, 1132, 1222, 1402, 1705, 2160, 2803,
-    }, {
-        1431, 1412, 1401, 1375, 1336, 1278, 1215, 1168, 1115, 1066,
-        1032, 1008,  991,  975,  962,  954,  950,  947,  947,  955,
-         948,  935,  916,  894,  866,  835,  803,  772,  742,  715,
-         695,  683,  683,  697,  729,  784,  887,  982, 1054, 1096,
-        1111, 1106, 1098, 1107, 1159, 1281, 1505, 1865, 2391, 3072,
-    }, {
-        1427, 1411, 1393, 1353, 1293, 1215, 1160, 1118, 1072, 1031,
-        1003,  984,  971,  960,  952,  948,  947,  957,  952,  941,
-         924,  902,  876,  847,  815,  781,  750,  723,  700,  685,
-         681,  691,  719,  766,  858,  958, 1039, 1089, 1109, 1108,
-        1099, 1102, 1141, 1245, 1442, 1766, 2250, 2930, 3072, 3072,
-    }}
-};
-
-static const int16_t lwc_gain_tab[11][7] = {
-    {   -21,  -197,  -271,  -466, 32767, 32767, 32767 },
-    {  -197,   -29,  -244,  -271,  -540, 32767, 32767 },
-    {  -271,  -244,   -29,  -249,  -271,  -593, 32767 },
-    {  -466,  -271,  -249,   -29,  -251,  -271,  -632 },
-    {  -540,  -271,  -251,   -29,  -251,  -271,  -664 },
-    {  -593,  -271,  -251,   -29,  -252,  -271,  -690 },
-    {  -632,  -271,  -252,   -29,  -252,  -271,  -711 },
-    {  -664,  -271,  -252,   -29,  -252,  -271,  -730 },
-    {  -690,  -271,  -252,   -29,  -252,  -271,  -745 },
-    {  -711,  -271,  -252,   -29,  -253,  -271,  -759 },
-    {  -730,  -271,  -253,   -29,  -253,  -271,  -771 },
-};
-
-static const int16_t lwc_adj_tab[7] = {
-    -192, -320, -448, -512, -448, -320, -192,
-};
-
-static const uint8_t log_add_tab[212] = {
-    64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 52, 51, 50,
-    49, 48, 47, 47, 46, 45, 44, 44, 43, 42, 41, 41, 40, 39, 38, 38,
-    37, 36, 36, 35, 35, 34, 33, 33, 32, 32, 31, 30, 30, 29, 29, 28,
-    28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 21,
-    20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15,
-    15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11,
-    10, 10, 10, 10, 10,  9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,
-     7,  7,  7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,
-     5,  5,  5,  5,  5,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
-     4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,
-     2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
-     2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
-     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
-     1,  1,  0,  0,
-};
-
-static const uint8_t bap_tab[64] = {
-     0,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  3,  3,  3,  3,  4,
-     4,  4,  4,  5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,
-     8,  8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11, 11, 11, 11, 12,
-    12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15,
-};
-
-static float mantissa_tab1[17][4];
-static float mantissa_tab2[17][4];
-static float mantissa_tab3[17][4];
-static float exponent_tab[50];
-static float gain_tab[1024];
-
-DECLARE_ALIGNED(32, static float, window)[3712];
-
 #endif
diff --git a/libavcodec/dolby_e_parser.c b/libavcodec/dolby_e_parser.c
new file mode 100644
index 0000000000..31275be122
--- /dev/null
+++ b/libavcodec/dolby_e_parser.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2017 foo86
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "parser.h"
+ 
+#if CONFIG_DOLBY_E_PARSER | CONFIG_DOLBY_E_DECODER
+
+#include "get_bits.h"
+#include "put_bits.h"
+#include "dolby_e_parser.h"
+#include "dolby_e_parser_internal.h"
+
+static int skip_input(DBEContext *s, int nb_words)
+{
+    if (nb_words > s->input_size) {
+        return AVERROR_INVALIDDATA;
+    }
+
+    s->input      += nb_words * s->word_bytes;
+    s->input_size -= nb_words;
+    return 0;
+}
+
+static int parse_key(DBEContext *s)
+{
+    if (s->key_present) {
+        const uint8_t *key = s->input;
+        int      ret = skip_input(s, 1);
+        if (ret < 0)
+            return ret;
+        return AV_RB24(key) >> 24 - s->word_bits;
+    }
+    return 0;
+}
+
+static int convert_input(DBEContext *s, int nb_words, int key)
+{
+    const uint8_t *src = s->input;
+    uint8_t *dst = s->buffer;
+    PutBitContext pb;
+    int i;
+
+    av_assert0(nb_words <= 1024u);
+
+    if (nb_words > s->input_size) {
+        return AVERROR_INVALIDDATA;
+    }
+
+    switch (s->word_bits) {
+    case 16:
+        for (i = 0; i < nb_words; i++, src += 2, dst += 2)
+            AV_WB16(dst, AV_RB16(src) ^ key);
+        break;
+    case 20:
+        init_put_bits(&pb, s->buffer, sizeof(s->buffer));
+        for (i = 0; i < nb_words; i++, src += 3)
+            put_bits(&pb, 20, AV_RB24(src) >> 4 ^ key);
+        flush_put_bits(&pb);
+        break;
+    case 24:
+        for (i = 0; i < nb_words; i++, src += 3, dst += 3)
+            AV_WB24(dst, AV_RB24(src) ^ key);
+        break;
+    default:
+        av_assert0(0);
+    }
+
+    return init_get_bits(&s->gb, s->buffer, nb_words * s->word_bits);
+}
+
+int ff_dolby_e_parse_init(DBEContext *s, const uint8_t *buf, int buf_size)
+{
+    int hdr;
+
+    if (buf_size < 3)
+        return AVERROR_INVALIDDATA;
+
+    hdr = AV_RB24(buf);
+    if ((hdr & 0xfffffe) == 0x7888e) {
+        s->word_bits = 24;
+    } else if ((hdr & 0xffffe0) == 0x788e0) {
+        s->word_bits = 20;
+    } else if ((hdr & 0xfffe00) == 0x78e00) {
+        s->word_bits = 16;
+    } else {
+        if (s->avctx)
+            av_log(s->avctx, AV_LOG_ERROR, "Invalid frame header\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    s->word_bytes  = s->word_bits + 7 >> 3;
+    s->input       = buf + s->word_bytes;
+    s->input_size  = buf_size / s->word_bytes - 1;
+    s->key_present = hdr >> 24 - s->word_bits & 1;
+
+    return 0;
+}
+
+int ff_dolby_e_parse_header(DBEContext *s, DolbyEHeaderInfo *hdr)
+{
+    int i, ret, key, mtd_size;
+
+    if ((key = parse_key(s)) < 0)
+        return key;
+    if ((ret = convert_input(s, 1, key)) < 0)
+        return ret;
+
+    skip_bits(&s->gb, 4);
+    mtd_size = get_bits(&s->gb, 10);
+    if (!mtd_size) {
+        if (s->avctx)
+            av_log(s->avctx, AV_LOG_ERROR, "Invalid metadata size\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((ret = convert_input(s, mtd_size, key)) < 0)
+        return ret;
+
+    skip_bits(&s->gb, 14);
+    hdr->prog_conf = get_bits(&s->gb, 6);
+    if (hdr->prog_conf > MAX_PROG_CONF) {
+        if (s->avctx)
+            av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    hdr->nb_channels = nb_channels_tab[hdr->prog_conf];
+    hdr->nb_programs = nb_programs_tab[hdr->prog_conf];
+
+    hdr->fr_code      = get_bits(&s->gb, 4);
+    hdr->fr_code_orig = get_bits(&s->gb, 4);
+    if (!sample_rate_tab[hdr->fr_code] ||
+        !sample_rate_tab[hdr->fr_code_orig]) {
+        if (s->avctx)
+            av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    skip_bits_long(&s->gb, 88);
+    for (i = 0; i < hdr->nb_channels; i++)
+        hdr->ch_size[i] = get_bits(&s->gb, 10);
+    hdr->mtd_ext_size = get_bits(&s->gb, 8);
+    hdr->meter_size   = get_bits(&s->gb, 8);
+
+    skip_bits_long(&s->gb, 10 * hdr->nb_programs);
+    for (i = 0; i < hdr->nb_channels; i++) {
+        hdr->rev_id[i]     = get_bits(&s->gb,  4);
+        skip_bits1(&s->gb);
+        hdr->begin_gain[i] = get_bits(&s->gb, 10);
+        hdr->end_gain[i]   = get_bits(&s->gb, 10);
+    }
+
+    if (get_bits_left(&s->gb) < 0) {
+        if (s->avctx)
+            av_log(s->avctx, AV_LOG_ERROR, "Read past end of metadata\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    return skip_input(s, mtd_size + 1);
+}
+#endif  /* CONFIG_DOLBY_E_PARSER | CONFIG_DOLBY_E_DECODER */
+
+#if CONFIG_DOLBY_E_PARSER
+
+static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx,
+                        const uint8_t **poutbuf, int *poutbuf_size,
+                        const uint8_t *buf, int buf_size)
+{
+    DBEParseContext *s1 = s2->priv_data;
+    DBEContext *s = &s1->dectx;
+    int ret;
+
+    if ((ret = ff_dolby_e_parse_init(s, buf, buf_size)) < 0)
+        goto end;
+
+    if ((ret = ff_dolby_e_parse_header(s, &s1->metadata)) < 0)
+        goto end;
+
+    s2->duration = FRAME_SAMPLES;
+    switch (s1->metadata.nb_channels) {
+    case 4:
+        avctx->channel_layout = AV_CH_LAYOUT_4POINT0;
+        break;
+    case 6:
+        avctx->channel_layout = AV_CH_LAYOUT_5POINT1;
+        break;
+    case 8:
+        avctx->channel_layout = AV_CH_LAYOUT_7POINT1;
+        break;
+    }
+
+    avctx->channels    = s1->metadata.nb_channels;
+    avctx->sample_rate = sample_rate_tab[s1->metadata.fr_code];
+    avctx->sample_fmt  = AV_SAMPLE_FMT_FLTP;
+
+end:
+    /* always return the full packet. this parser isn't doing any splitting or
+       combining, only packet analysis */
+    *poutbuf      = buf;
+    *poutbuf_size = buf_size;
+    return buf_size;
+}
+
+AVCodecParser ff_dolby_e_parser = {
+    .codec_ids      = { AV_CODEC_ID_DOLBY_E },
+    .priv_data_size = sizeof(DBEParseContext),
+    .parser_parse   = dolby_e_parse,
+    .parser_close   = ff_parse_close,
+};
+#endif /* CONFIG_DOLBY_E_PARSER */
\ No newline at end of file
diff --git a/libavcodec/dolby_e_parser.h b/libavcodec/dolby_e_parser.h
new file mode 100644
index 0000000000..2f9a2b2ebb
--- /dev/null
+++ b/libavcodec/dolby_e_parser.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 foo86
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_DOLBY_E_PARSER_H
+#define AVCODEC_DOLBY_E_PARSER_H
+
+#include "dolby_e.h"
+
+typedef struct DBEParseContext {
+    ParseContext pc;
+    DBEContext dectx;
+
+    DolbyEHeaderInfo metadata;
+} DBEParseContext;
+
+static const uint8_t nb_programs_tab[MAX_PROG_CONF + 1] = {
+    2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1, 2, 3, 3, 4, 5, 6, 1, 2, 3, 4, 1, 1
+};
+
+static const uint8_t nb_channels_tab[MAX_PROG_CONF + 1] = {
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 8, 8
+};
+
+#endif
diff --git a/libavcodec/dolby_e_parser_internal.h b/libavcodec/dolby_e_parser_internal.h
new file mode 100644
index 0000000000..defd1f97d6
--- /dev/null
+++ b/libavcodec/dolby_e_parser_internal.h
@@ -0,0 +1,46 @@
+/*
+ * Dolby E parser internal code
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_DOLBY_E_PARSER_INTERNAL_H
+#define AVCODEC_DOLBY_E_PARSER_INTERNAL_H
+
+#include "dolby_e.h"
+
+/**
+ * Initialize DBEContext.
+ * Set word_bits/word_bytes, input, input_size, key_present.
+ * @param[out] s DBEContext.
+ * @param[in]  buf raw input buffer.
+ * @param[in]  buf_size must be 3 bytes at least.
+ * @return Returns 0 on success, AVERROR_INVALIDDATA on error
+ */
+int ff_dolby_e_parse_init(DBEContext *s, const uint8_t *buf, int buf_size);
+
+/**
+ * Parse Dolby E metadata.
+ * Parse the header up to the end_gain element.
+ * @param[in]  s DBEContext .
+ * @param[out] hdr Pointer to struct where header info is written.
+ * @return Returns 0 on success, AVERROR_INVALIDDATA on error
+ */
+int ff_dolby_e_parse_header(DBEContext *s, DolbyEHeaderInfo *hdr);
+
+
+#endif /* AVCODEC_DOLBY_E_PARSER_INTERNAL_H */
diff --git a/libavcodec/dolby_edec.h b/libavcodec/dolby_edec.h
new file mode 100644
index 0000000000..02760bb852
--- /dev/null
+++ b/libavcodec/dolby_edec.h
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2017 foo86
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_DOLBY_EDEC_H
+#define AVCODEC_DOLBY_EDEC_H
+
+#include "libavutil/float_dsp.h"
+#include "libavutil/libm.h"
+#include "libavutil/mem_internal.h"
+
+#include "internal.h"
+#include "get_bits.h"
+#include "kbdwin.h"
+#include "fft.h"
+
+#define MAX_SEGMENTS    2
+
+#define MAX_GROUPS      8
+#define MAX_EXPONENTS   304
+#define MAX_MANTISSAS   1024
+
+#define MAX_MSTR_EXP    2
+#define MAX_BIAS_EXP    50
+
+typedef struct DBEGroup {
+    uint8_t         nb_exponent;
+    uint8_t         nb_bias_exp[MAX_MSTR_EXP];
+    uint16_t        exp_ofs;
+    uint16_t        mnt_ofs;
+    const uint8_t   *nb_mantissa;
+    uint8_t         imdct_idx;
+    uint8_t         imdct_phs;
+    uint16_t        win_len;
+    uint16_t        dst_ofs;
+    uint16_t        win_ofs;
+    uint16_t        src_ofs;
+} DBEGroup;
+
+typedef struct DBEChannel {
+    int     gr_code;
+    int     bw_code;
+
+    int         nb_groups;
+    int         nb_mstr_exp;
+    DBEGroup    groups[MAX_GROUPS];
+
+    int     exp_strategy[MAX_GROUPS];
+    int     exponents[MAX_EXPONENTS];
+    int     bap[MAX_EXPONENTS];
+    int     idx[MAX_EXPONENTS];
+
+    DECLARE_ALIGNED(32, float, mantissas)[MAX_MANTISSAS];
+} DBEChannel;
+
+typedef struct DBEDecodeContext {
+    AVCodecContext  *avctx;
+    DBEContext  dectx;
+
+    DolbyEHeaderInfo metadata;
+
+    DBEChannel  channels[MAX_SEGMENTS][MAX_CHANNELS];
+
+    DECLARE_ALIGNED(32, float, history)[MAX_CHANNELS][256];
+
+    FFTContext          imdct[3];
+    AVFloatDSPContext   *fdsp;
+} DBEDecodeContext;
+
+static const int8_t lfe_channel_tab[MAX_PROG_CONF + 1] = {
+     5,  5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  5, 5
+};
+
+static const uint8_t ch_reorder_4[4] = { 0, 2, 1, 3 };
+static const uint8_t ch_reorder_6[6] = { 0, 2, 4, 1, 3, 5 };
+static const uint8_t ch_reorder_8[8] = { 0, 2, 6, 4, 1, 3, 7, 5 };
+static const uint8_t ch_reorder_n[8] = { 0, 2, 4, 6, 1, 3, 5, 7 };
+
+
+static const uint8_t nb_groups_tab[4] = { 1, 8, 7, 1 };
+
+static const uint8_t nb_mstr_exp_tab[4] = { 2, 2, 2, 1 };
+
+static const uint8_t nb_mantissa_38[38] = {
+     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+     2,  2,  2,  2,  2,  2,  3,  3,  3,  4,  4,  4,  5,  5,  6,  6,
+     7,  8,  9, 10, 11, 12,
+};
+
+static const uint8_t nb_mantissa_44[44] = {
+     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,
+     2,  2,  2,  2,  2,  3,  3,  3,  3,  4,  4,  5,  5,  6,  7,  7,
+     8,  9, 10, 11, 12, 13, 15, 16, 18, 20, 22, 25,
+};
+
+static const uint8_t nb_mantissa_50[50] = {
+     1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  3,  3,  3,
+     3,  4,  4,  5,  5,  6,  6,  7,  8,  9,  9, 10, 12, 13, 14, 16,
+    18, 19, 22, 24, 27, 29, 32, 36, 40, 44, 49, 54, 60, 66, 74, 82,
+    90, 100,
+};
+
+static const uint8_t imdct_bits_tab[3] = { 8, 9, 11 };
+
+static const DBEGroup grp_tab_0[1] = {
+    { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 },
+};
+
+static const DBEGroup grp_tab_1[8] = {
+    { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 },
+    { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 },
+    { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 },
+    { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 },
+    { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 },
+    { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 },
+    { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 704, 0, 0 },
+    { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 1, 256, 832, 0, 0 },
+};
+
+static const DBEGroup grp_tab_2[7] = {
+    { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 },
+    { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 },
+    { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 },
+    { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 },
+    { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 },
+    { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 },
+    { 44, { 19, 25 }, 228, 768, nb_mantissa_44, 1, 1, 448, 704, 960, 64 },
+};
+
+static const DBEGroup grp_tab_3[1] = {
+    { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 },
+};
+
+static const DBEGroup grp_tab_4[1] = {
+    { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 },
+};
+
+static const DBEGroup grp_tab_5[8] = {
+    { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 1, 256, 64, 0, 0 },
+    { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 192, 0, 0 },
+    { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 },
+    { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 },
+    { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 },
+    { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 },
+    { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 },
+    { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 },
+};
+
+static const DBEGroup grp_tab_6[7] = {
+    { 44, { 19, 25 }, 0, 0, nb_mantissa_44, 1, 1, 448, 0, 3264, 0 },
+    { 38, { 12, 26 }, 44, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 },
+    { 38, { 12, 26 }, 82, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 },
+    { 38, { 12, 26 }, 120, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 },
+    { 38, { 12, 26 }, 158, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 },
+    { 38, { 12, 26 }, 196, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 },
+    { 38, { 12, 26 }, 234, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 },
+};
+
+static const DBEGroup grp_tab_7[1] = {
+    { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 },
+};
+
+static const DBEGroup *const frm_ofs_tab[2][4] = {
+    { grp_tab_0, grp_tab_1, grp_tab_2, grp_tab_3 },
+    { grp_tab_4, grp_tab_5, grp_tab_6, grp_tab_7 }
+};
+
+static const uint8_t mantissa_size1[16][4] = {
+    {  0,  0,  0,  0 }, {  2,  1,  1,  1 }, {  3,  2,  1,  1 }, {  4,  3,  2,  1 },
+    {  5,  4,  3,  2 }, {  6,  5,  4,  3 }, {  7,  6,  5,  4 }, {  8,  7,  6,  5 },
+    {  9,  8,  7,  6 }, { 10,  9,  8,  7 }, { 11, 10,  9,  8 }, { 12, 11, 10,  9 },
+    { 13, 12, 11, 10 }, { 14, 13, 12, 11 }, { 15, 14, 13, 12 }, { 16, 15, 14, 13 },
+};
+
+static const uint8_t mantissa_size2[16][4] = {
+    {  0,  0,  0,  0 }, {  2,  1,  2,  2 }, {  3,  2,  3,  3 }, {  4,  3,  4,  4 },
+    {  5,  4,  5,  5 }, {  6,  5,  6,  6 }, {  7,  6,  7,  7 }, {  8,  7,  8,  8 },
+    {  9,  8,  9,  9 }, { 10,  9, 10, 10 }, { 11, 10, 11, 11 }, { 12, 11, 12, 12 },
+    { 13, 12, 13, 13 }, { 14, 13, 14, 14 }, { 15, 14, 15, 15 }, { 16, 15, 16, 16 },
+};
+
+static const float start_window[192] = {
+    0.00161569379826, 0.00185748233347, 0.00198562758548, 0.00207834078104,
+    0.00215717748523, 0.00223067096393, 0.00230299213147, 0.00237651215396,
+    0.00245275561606, 0.00253281402069, 0.00261754673613, 0.00270768786168,
+    0.00280390761895, 0.00290684998656, 0.00301715751161, 0.00313548872798,
+    0.00326253122934, 0.00339901215995, 0.00354570716636, 0.00370344845023,
+    0.00387313232586, 0.00405572653911, 0.00425227750970, 0.00446391759265,
+    0.00469187240551, 0.00493746822816, 0.00520213944619, 0.00548743597507,
+    0.00579503056737, 0.00612672586953, 0.00648446105606, 0.00687031782873,
+    0.00728652552677, 0.00773546505205, 0.00821967127415, 0.00874183354619,
+    0.00930479393832, 0.00991154278653, 0.01056521116692, 0.01126905994567,
+    0.01202646513050, 0.01284089936559, 0.01371590957417, 0.01465509096066,
+    0.01566205783408, 0.01674041199523, 0.01789370972358, 0.01912542867865,
+    0.02043893626265, 0.02183746113793, 0.02332406961796, 0.02490164852364,
+    0.02657289580178, 0.02834031974193, 0.03020624702903, 0.03217283918354,
+    0.03424211623810, 0.03641598586180, 0.03869627565015, 0.04108476601498,
+    0.04358322107390, 0.04619341515939, 0.04891715301882, 0.05175628239149,
+
+    0.05471237327267, 0.05778734733755, 0.06098291402413, 0.06430101352084,
+    0.06774345212186, 0.07131188644726, 0.07500780649199, 0.07883251748595,
+    0.08278712056651, 0.08687249228061, 0.09108926295730, 0.09543779401074,
+    0.09991815425851, 0.10453009536427, 0.10927302653894, 0.11414598865987,
+    0.11914762799220, 0.12427616972097, 0.12952939152560, 0.13490459744934,
+    0.14039859233595, 0.14600765712201, 0.15172752528722, 0.15755336077528,
+    0.16347973770491, 0.16950062219342, 0.17560935661442, 0.18179864660619,
+    0.18806055113821, 0.19438647593012, 0.20076717050010, 0.20719272909882,
+    0.21365259576030, 0.22013557367283, 0.22662983904194, 0.23312295958328,
+    0.23960191774666, 0.24605313873388, 0.25246252333253, 0.25881548554631,
+    0.26509699495987, 0.27129162373316, 0.27738359807707, 0.28335685401987,
+    0.28919509723179, 0.29488186663467, 0.30040060148455, 0.30573471157819,
+    0.31086765019993, 0.31578298939317, 0.32046449711227, 0.32489621578468,
+    0.32906254179156, 0.33294830535654, 0.33653885031840, 0.33982011325336,
+    0.34277870140679, 0.34540196889300, 0.34767809062480, 0.34959613344194,
+    0.35114612391958, 0.35231911235422, 0.35310723244504, 0.35350375621308,
+
+    0.35350314372945, 0.35310108725579, 0.35229454943591, 0.35108179521634,
+    0.34946241721522, 0.34743735430290, 0.34500890320420, 0.34218072298001,
+    0.33895783229541, 0.33534659943168, 0.33135472505060, 0.32699121776996,
+    0.32226636266000, 0.31719168282019, 0.31177989424432, 0.30604485422875,
+    0.30000150362379, 0.29366580327088, 0.28705466500775, 0.28018587766131,
+    0.27307802848095, 0.26575042049535, 0.25822298630189, 0.25051619882000,
+    0.24265097955783, 0.23464860495522, 0.22653061137548, 0.21831869932335,
+    0.21003463746705, 0.20170016703857, 0.19333690717811, 0.18496626177620,
+    0.17660932835062, 0.16828680947474, 0.16001892724986, 0.15182534128597,
+    0.14372507062477, 0.13573642000364, 0.12787691082233, 0.12016321713317,
+    0.11261110693234, 0.10523538898282, 0.09804986534955, 0.09106728977263,
+    0.08429933194438, 0.07775654768810, 0.07144835495683, 0.06538301547324,
+    0.05956762170687, 0.05400808871425, 0.04870915012107, 0.04367435714993,
+    0.03890607899172, 0.03440550179663, 0.03017262174627, 0.02620622428513,
+    0.02250383492507, 0.01906161305732, 0.01587412848221, 0.01293388032354,
+    0.01023019677288, 0.00774641320626, 0.00545109736891, 0.00325868651263,
+};
+
+static const float short_window2[192] = {
+    0.00018861094606, 0.00033433010202, 0.00050309624485, 0.00070306161748,
+    0.00093995174533, 0.00121913067128, 0.00154606505568, 0.00192647806126,
+    0.00236641248692, 0.00287225985240, 0.00345077377440, 0.00410907465023,
+    0.00485464855241, 0.00569534163219, 0.00663935063508, 0.00769520981249,
+    0.00887177436246, 0.01017820046395, 0.01162392194150, 0.01321862359335,
+    0.01497221122468, 0.01689477844427, 0.01899657030441, 0.02128794388846,
+    0.02377932597692, 0.02648116795039, 0.02940389811590, 0.03255787167130,
+    0.03595331854986, 0.03960028941437, 0.04350860009563, 0.04768777479454,
+    0.05214698838949, 0.05689500821121, 0.06194013566525, 0.06729014809766,
+    0.07295224131210, 0.07893297315602, 0.08523820859989, 0.09187306673620,
+    0.09884187012422, 0.10614809690222, 0.11379433608064, 0.12178224641797,
+    0.13011251926531, 0.13878484574660, 0.14779788861830, 0.15714925912610,
+    0.16683549914631, 0.17685206886673, 0.18719334022589, 0.19785259629099,
+    0.20882203671372, 0.22009278936030, 0.23165492816694, 0.24349749722585,
+    0.25560854105961, 0.26797514099368, 0.28058345748882, 0.29341877824732,
+    0.30646557185942, 0.31970754671026, 0.33312771482295, 0.34670846027024,
+
+    0.36043161174692, 0.37427851885723, 0.38823013163645, 0.40226708279486,
+    0.41636977214436, 0.43051845264462, 0.44469331748632, 0.45887458761470,
+    0.47304259908636, 0.48717788964798, 0.50126128392546, 0.51527397661778,
+    0.52919761310050, 0.54301436685998, 0.55670701320069, 0.57025899869448,
+    0.58365450587230, 0.59687851269542, 0.60991684638414, 0.62275623122793,
+    0.63538433005035, 0.64778977905593, 0.65996221584264, 0.67189230042379,
+    0.68357172916486, 0.69499324160511, 0.70615062019861, 0.71703868307548,
+    0.72765326998919, 0.73799122168099, 0.74805035295521, 0.75782941981995,
+    0.76732808110520, 0.77654685502339, 0.78548707118622, 0.79415081863423,
+    0.80254089047207, 0.81066072573188, 0.81851434910893, 0.82610630922734,
+    0.83344161609862, 0.84052567843230, 0.84736424144524, 0.85396332579459,
+    0.86032916822973, 0.86646816451999, 0.87238681516918, 0.87809167437532,
+    0.88358930263537, 0.88888622333073, 0.89398888356256, 0.89890361943564,
+    0.90363662591861, 0.90819393133744, 0.91258137648979, 0.91680459830070,
+    0.92086901787718, 0.92477983276087, 0.92854201312583, 0.93216030163834,
+    0.93563921662343, 0.93898305819384, 0.94219591693690, 0.94528168477979,
+
+    0.94823843319821, 0.95106834367330, 0.95377776558539, 0.95636718335775,
+    0.95883679961479, 0.96118650212341, 0.96341583179195, 0.96552395212906,
+    0.96750962060547, 0.96937116231768, 0.97110644638309, 0.97271286544154,
+    0.97418731862798, 0.97552619834964, 0.97672538116257, 0.97778022299974,
+    0.97868555895586, 0.97943570778357, 0.98002448120255, 0.98044519806866,
+    0.98069070339493, 0.98075339216123, 0.98062523779637, 0.98029782516478,
+    0.97976238784222, 0.97900984942031, 0.97803086854002, 0.97681588731895,
+    0.97535518280755, 0.97363892108474, 0.97165721358452, 0.96940017523145,
+    0.96685798395452, 0.96402094114589, 0.96087953263194, 0.95742448973047,
+    0.95364684997699, 0.94953801711660, 0.94508981997396, 0.94029456983253,
+    0.93514511597504, 0.92963489905951, 0.92375800202883, 0.91750919827624,
+    0.91088399681406, 0.90387868421832, 0.89649036314692, 0.88871698725397,
+    0.88055739234735, 0.87201132366062, 0.86307945913336, 0.85376342861693,
+    0.84406582894455, 0.83399023482637, 0.82354120554757, 0.81272428745995,
+    0.80154601230457, 0.79001389138101, 0.77813640562199, 0.76592299164227,
+    0.75338402384395, 0.74053079267526, 0.72737547915460, 0.71393112578527,
+};
+
+static const float short_window3[64] = {
+    0.00326887936450, 0.00550242900936, 0.00786846643791, 0.01045683453520,
+    0.01330402120132, 0.01643221072863, 0.01985798040609, 0.02359509464766,
+    0.02765559221954, 0.03205025893128, 0.03678884369614, 0.04188015679495,
+    0.04733210987781, 0.05315172583924, 0.05934513287609, 0.06591755045290,
+    0.07287327156378, 0.08021564389822, 0.08794705152307, 0.09606889811179,
+    0.10458159240070, 0.11348453632940, 0.12277611617809, 0.13245369691511,
+    0.14251361989876, 0.15295120402567, 0.16376075037904, 0.17493555039885,
+    0.18646789757072, 0.19834910260891, 0.21056951208995, 0.22311853047787,
+    0.23598464546683, 0.24915545655419, 0.26261770674500, 0.27635731727778,
+    0.29035942525136, 0.30460842402318, 0.31908800624032, 0.33378120935681,
+    0.34867046348260, 0.36373764140285, 0.37896411059909, 0.39433078709788,
+    0.40981819096657, 0.42540650327031, 0.44107562429959, 0.45680523287270,
+    0.47257484651351, 0.48836388230077, 0.50415171818214, 0.51991775454258,
+    0.53564147581496, 0.55130251191887, 0.56688069931047, 0.58235614142007,
+    0.59770926827271, 0.61292089506118, 0.62797227945823, 0.64284517745255,
+    0.65752189749349, 0.67198535273209, 0.68621911114984, 0.70020744337099,
+};
+
+static const uint8_t dc_code_tab[5] = { 0, 0, 0, 1, 1 };
+
+static const uint8_t ht_code_tab[5] = { 0, 0, 1, 2, 2 };
+
+static const uint8_t band_ofs_tab[3][4] = {
+    { 12, 8, 4, 0 }, { 14, 10, 6, 0 }, { 12, 8, 4, 0 }
+};
+
+static const uint8_t band_low_tab[3] = { 9, 17, 24 };
+
+static const uint16_t fast_gain_tab[8] = {
+    128, 256, 384, 512, 640, 768, 896, 1024
+};
+
+static const uint16_t slow_decay_tab[2][2] = { { 27, -1 }, { 32, 21 } };
+
+static const uint16_t misc_decay_tab[3][2][2] = {
+    { { 354, -1 }, { 425, 425 } },
+    { { 266, -1 }, { 320,  -1 } },
+    { { 213, -1 }, { 256,  -1 } }
+};
+
+static const uint16_t fast_decay_tab[3][2][2][50] = {
+    {{{
+        142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
+        142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
+        142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
+        142, 142, 142, 142, 142, 142, 142, 142,
+    }, {
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+    }}, {{
+        170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+        170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+        170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+        170, 170, 170, 170, 170, 170, 170, 170,
+    }, {
+         64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
+         64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
+         64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
+         64,  64,  64,  64,  64,  64,  64,  64,
+    }}}, {{{
+        266, 266, 106, 106, 106, 106, 106, 106, 106, 106,
+        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+        106, 106, 106, 106,
+    }, {
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,
+    }}, {{
+        319, 319, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128,
+    }, {
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,
+    }}}, {{{
+        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+        106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+    }, {
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+    }}, {{
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+    }, {
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
+    }}}
+};
+
+static const uint16_t fast_gain_adj_tab[3][2][62] = {
+    {{
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   1,   2,   4,   7,  11,  16,  29,  44,  59,
+         76,  94, 116, 142, 179, 221, 252, 285, 312, 334,
+    }, {
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          2,   5,   8,  10,  15,  28,  42,  57,  75,  93,
+        115, 140, 177, 219, 247, 280, 308, 330, 427, 533,
+    }}, {{
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   2,   5,   8,  12,  21,  35,  51,  69,  89,
+        111, 138, 176, 220, 251, 284, 312, 334,
+    }, {
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   2,
+          5,   8,  11,  18,  33,  49,  65,  84, 106, 132,
+        168, 214, 245, 279, 308, 329, 427, 533,
+    }}, {{
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   1,   4,   7,  10,  17,
+         31,  47,  65,  84, 107, 134, 171, 215, 250, 283,
+        312, 334,
+    }, {
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+          0,   0,   0,   0,   3,   6,   9,  13,  27,  43,
+         60,  79, 100, 126, 160, 207, 242, 276, 307, 329,
+        427, 533,
+    }}
+};
+
+static const uint16_t slow_gain_tab[3][2][50] = {
+    {{
+        3072, 3072, 3072, 3072, 3072, 3072, 1063, 1063, 1063, 1063,
+        1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
+        1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
+        1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
+    }, {
+        3072, 3072, 3072, 3072, 3072, 3072,  850,  850,  850,  850,
+         850,  850,  850,  850,  850,  850,  850,  850,  850,  850,
+         850,  850,  850,  850,  850,  850,  850,  850,  850,  850,
+         850,  850,  850,  850,  850,  850,  850,  850,
+    }}, {{
+        3072, 1212, 1212, 1212,  999,  999,  999,  999,  999,  999,
+         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
+         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
+         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
+         999,  999,  999,  999,
+    }, {
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+          -1,   -1,   -1,   -1,
+    }}, {{
+        3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072,
+         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
+         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
+         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
+         999,  999,  999,  999,  999,  999,  999,  999,  999,  999,
+    }, {
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+    }}
+};
+
+static const uint16_t hearing_thresh_tab[3][3][50] = {
+    {{
+        1403, 1141, 1000,  959,  948,  957,  946,  925,  899,  871,
+         843,  815,  789,  766,  745,  727,  705,  687,  681,  686,
+         701,  725,  768,  854,  940, 1018, 1075, 1103, 1111, 1106,
+        1098, 1105, 1142, 1237, 1419, 1721, 2169, 2805,
+    }, {
+        1401, 1130,  995,  957,  947,  955,  941,  918,  890,  861,
+         831,  803,  777,  754,  734,  717,  698,  684,  682,  692,
+         712,  743,  798,  894,  976, 1045, 1091, 1109, 1110, 1102,
+        1098, 1116, 1174, 1300, 1526, 1884, 2401, 3072,
+    }, {
+        1393, 1086,  974,  949,  957,  941,  913,  878,  843,  808,
+         777,  750,  727,  708,  695,  686,  681,  689,  714,  752,
+         811,  888,  971, 1044, 1087, 1108, 1110, 1102, 1098, 1115,
+        1172, 1290, 1489, 1812, 2293, 2964, 3072, 3072,
+    }}, {{
+        1412, 1343, 1141, 1047, 1000,  974,  959,  951,  948,  947,
+         957,  953,  946,  936,  925,  906,  878,  850,  822,  795,
+         771,  745,  719,  700,  687,  681,  685,  701,  733,  784,
+         885,  977, 1047, 1092, 1110, 1108, 1099, 1102, 1138, 1233,
+        1413, 1711, 2157, 2797,
+    }, {
+        1412, 1336, 1130, 1040,  995,  970,  957,  950,  947,  947,
+         955,  950,  941,  930,  918,  897,  868,  838,  810,  783,
+         759,  734,  710,  693,  684,  681,  690,  712,  752,  823,
+         924, 1009, 1069, 1102, 1111, 1104, 1098, 1111, 1168, 1295,
+        1518, 1873, 2388, 3072,
+    }, {
+        1411, 1293, 1086, 1009,  974,  957,  949,  947,  957,  951,
+         941,  928,  913,  896,  878,  852,  817,  785,  756,  732,
+         713,  695,  683,  682,  689,  710,  746,  811,  906,  992,
+        1061, 1099, 1111, 1106, 1098, 1107, 1155, 1266, 1471, 1799,
+        2277, 2945, 3072, 3072,
+    }}, {{
+        1431, 1412, 1403, 1379, 1343, 1293, 1229, 1180, 1125, 1075,
+        1040, 1014,  996,  979,  965,  957,  951,  948,  947,  957,
+         951,  940,  924,  903,  877,  846,  815,  785,  753,  725,
+         702,  686,  681,  689,  714,  760,  847,  947, 1028, 1083,
+        1108, 1109, 1101, 1100, 1132, 1222, 1402, 1705, 2160, 2803,
+    }, {
+        1431, 1412, 1401, 1375, 1336, 1278, 1215, 1168, 1115, 1066,
+        1032, 1008,  991,  975,  962,  954,  950,  947,  947,  955,
+         948,  935,  916,  894,  866,  835,  803,  772,  742,  715,
+         695,  683,  683,  697,  729,  784,  887,  982, 1054, 1096,
+        1111, 1106, 1098, 1107, 1159, 1281, 1505, 1865, 2391, 3072,
+    }, {
+        1427, 1411, 1393, 1353, 1293, 1215, 1160, 1118, 1072, 1031,
+        1003,  984,  971,  960,  952,  948,  947,  957,  952,  941,
+         924,  902,  876,  847,  815,  781,  750,  723,  700,  685,
+         681,  691,  719,  766,  858,  958, 1039, 1089, 1109, 1108,
+        1099, 1102, 1141, 1245, 1442, 1766, 2250, 2930, 3072, 3072,
+    }}
+};
+
+static const int16_t lwc_gain_tab[11][7] = {
+    {   -21,  -197,  -271,  -466, 32767, 32767, 32767 },
+    {  -197,   -29,  -244,  -271,  -540, 32767, 32767 },
+    {  -271,  -244,   -29,  -249,  -271,  -593, 32767 },
+    {  -466,  -271,  -249,   -29,  -251,  -271,  -632 },
+    {  -540,  -271,  -251,   -29,  -251,  -271,  -664 },
+    {  -593,  -271,  -251,   -29,  -252,  -271,  -690 },
+    {  -632,  -271,  -252,   -29,  -252,  -271,  -711 },
+    {  -664,  -271,  -252,   -29,  -252,  -271,  -730 },
+    {  -690,  -271,  -252,   -29,  -252,  -271,  -745 },
+    {  -711,  -271,  -252,   -29,  -253,  -271,  -759 },
+    {  -730,  -271,  -253,   -29,  -253,  -271,  -771 },
+};
+
+static const int16_t lwc_adj_tab[7] = {
+    -192, -320, -448, -512, -448, -320, -192,
+};
+
+static const uint8_t log_add_tab[212] = {
+    64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 52, 51, 50,
+    49, 48, 47, 47, 46, 45, 44, 44, 43, 42, 41, 41, 40, 39, 38, 38,
+    37, 36, 36, 35, 35, 34, 33, 33, 32, 32, 31, 30, 30, 29, 29, 28,
+    28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 21,
+    20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15,
+    15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11,
+    10, 10, 10, 10, 10,  9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,
+     7,  7,  7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,
+     5,  5,  5,  5,  5,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+     4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,
+     2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+     2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+     1,  1,  0,  0,
+};
+
+static const uint8_t bap_tab[64] = {
+     0,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  3,  3,  3,  3,  4,
+     4,  4,  4,  5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,
+     8,  8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11, 11, 11, 11, 12,
+    12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15,
+};
+
+static float mantissa_tab1[17][4];
+static float mantissa_tab2[17][4];
+static float mantissa_tab3[17][4];
+static float exponent_tab[50];
+static float gain_tab[1024];
+
+DECLARE_ALIGNED(32, static float, window)[3712];
+
+#endif
