[FFmpeg-soc] [soc]: r1538 - in aaclc: . TODO aac.h aacdec.c aactab.c aactab.h ffmpeg.patch

andoma subversion at mplayerhq.hu
Fri Dec 7 16:10:59 CET 2007


Author: andoma
Date: Fri Dec  7 16:10:55 2007
New Revision: 1538

Log:
Rebirth of the SoC AAC decoder.
This time we should focus on getting a fully working LC decoder and
then get it merged into lavc.

See 'TODO' on whats left to acomplish.




Added:
   aaclc/
   aaclc/TODO
   aaclc/aac.h
   aaclc/aacdec.c
   aaclc/aactab.c
   aaclc/aactab.h
   aaclc/ffmpeg.patch

Added: aaclc/TODO
==============================================================================
--- (empty file)
+++ aaclc/TODO	Fri Dec  7 16:10:55 2007
@@ -0,0 +1,16 @@
+Stuff that needs to be fixed (in order)
+
+* Audible clicks are present with various content.
+
+  Sample:
+
+  ftp://samples.mplayerhq.hu/MPlayer/samples/A-codecs/AAC/zodiac_audio.mov
+
+  'static' is heard in L & R channel. Good example happens exactly at 7,2 s.
+  (Convert to wav with ffmpeg and load in audacity)
+
+* Fix decent float2int conversion and downmixing
+
+* Handle more channel orders
+
+* Coupling channels are missing (copy in from soc/aac/)

Added: aaclc/aac.h
==============================================================================
--- (empty file)
+++ aaclc/aac.h	Fri Dec  7 16:10:55 2007
@@ -0,0 +1,99 @@
+/*
+ * AAC (LC) decoder
+ * This code is developed as part of Google Summer of Code 2006 Program.
+ *
+ * Copyright (c) 2005 Oded Shimon( ods15 ods15 dyndns org )
+ * Copyright (c) 2005-2006 Maxim Gavrilov ( maxim.gavrilov gmail com )
+ * Copyright (c) 2007 Andreas Öman ( andreas lonelycoder com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 FFMPEG_AAC_H
+#define FFMPEG_AAC_H
+
+/**
+ * Audio object types
+ */
+enum {
+  AOT_NULL = 0x0,
+  AOT_AAC_MAIN,
+  AOT_AAC_LC,
+  AOT_AAC_SSR,
+  AOT_AAC_LTP,
+  AOT_SBR,
+  AOT_AAC_SCALABLE,
+  AOT_TWINVQ,
+  AOT_CELP,
+  AOT_HVXC,
+  AOT_TTSI = 12,
+  AOT_MAINSYNTH,
+  AOT_WAVESYNTH,
+  AOT_MIDI,
+  AOT_SAFX,
+  AOT_ER_AAC_LC,
+  AOT_ER_AAC_LTP = 19,
+  AOT_ER_AAC_SCALABLE,
+  AOT_ER_TWINVQ,
+  AOT_ER_BSAC,
+  AOT_ER_AAC_LD,
+  AOT_ER_CELP,
+  AOT_ER_HVXC,
+  AOT_ER_HILN,
+  AOT_ER_PARAM,
+  AOT_SSC
+};
+
+/**
+ * Syntactic elements
+ * reference: Table 4.71
+ */
+enum {
+    ID_SCE = 0x0,
+    ID_CPE,
+    ID_CCE,
+    ID_LFE,
+    ID_DSE,
+    ID_PCE,
+    ID_FIL,
+    ID_END
+};
+
+/**
+ * Window sequence types
+ */
+enum {
+    ONLY_LONG_SEQUENCE = 0,
+    LONG_START_SEQUENCE,
+    EIGHT_SHORT_SEQUENCE,
+    LONG_STOP_SEQUENCE
+};
+
+/**
+ * Special codebooks
+ */
+#define ZERO_HCB 0
+#define FIRST_PAIR_HCB 5
+#define ESC_HCB 11
+#define NOISE_HCB 13
+#define INTENSITY_HCB2 14
+#define INTENSITY_HCB 15
+#define ESC_FLAG 16
+
+#define TNS_MAX_ORDER 20
+
+#endif /* FFMPEG_AACDEC_H */

Added: aaclc/aacdec.c
==============================================================================
--- (empty file)
+++ aaclc/aacdec.c	Fri Dec  7 16:10:55 2007
@@ -0,0 +1,1505 @@
+/*
+ * AAC (LC) decoder
+ * This code is developed as part of Google Summer of Code 2006 Program.
+ *
+ * Copyright (c) 2005 Oded Shimon( ods15 ods15 dyndns org )
+ * Copyright (c) 2005-2006 Maxim Gavrilov ( maxim.gavrilov gmail com )
+ * Copyright (c) 2007 Andreas Öman ( andreas lonelycoder com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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
+ */
+
+/*
+ * The 'reference:'-statements refers to the ISO/IEC 14496-3 specification
+ */
+
+#include "avcodec.h"
+#include "bitstream.h"
+#include "dsputil.h"
+#include "random.h"
+#include "aac.h"
+#include "aactab.h"
+
+#define MAX_TAGID 16
+
+/**
+ * Program config
+ */
+typedef struct {
+    int present;
+    int generated;
+
+    int num_channels;
+
+    int num_front;
+    int front_cpe;
+    int front_tag[MAX_TAGID];
+
+    int num_side;
+    int side_cpe;
+    int side_tag[MAX_TAGID];
+
+    int num_back;
+    int back_cpe;
+    int back_tag[MAX_TAGID];
+
+    int num_lfe;
+    int lfe_tag[MAX_TAGID];
+
+    int num_assoc_data;
+    int assoc_data_tag[MAX_TAGID];
+
+    int num_cc;
+    int cc_ind_sw;
+    int cc_tag[MAX_TAGID];
+
+    int mono_mixdown;
+    int stereo_mixdown;
+    int matrix_mixdown;
+    int pseudo_surround;
+} aac_program_config;
+
+/**
+ * Individual Channel Stream
+ */
+typedef struct {
+    int intensity_present;
+    int noise_present;
+
+    int max_sfb;
+    int window_sequence;
+    int window_sequence_prev;
+    int window_shape;
+    int window_shape_prev;
+    int predictor;
+    int num_window_groups;
+    uint8_t grouping;
+    uint8_t group_len[8];
+    // calculated
+    const uint16_t *swb_offset;
+    int num_swb;
+    int num_windows;
+    int tns_max_bands;
+} aac_ics;
+
+#define ICS_ESS(ics) ((ics)->window_sequence == EIGHT_SHORT_SEQUENCE)
+
+
+/**
+ * Temporal Noise Shaping
+ */
+typedef struct {
+    int present;
+    int n_filt[8];
+    int length[8][4];
+    int direction[8][4];
+    int order[8][4];
+    const float *tmp2_map[8];
+    int coef[8][4][TNS_MAX_ORDER];
+} aac_tns;
+
+
+/**
+ * M/S tool
+ */
+typedef struct {
+    int present;
+    int mask[8][64];
+} aac_ms;
+
+
+/**
+ * Pulse tool
+ */
+typedef struct {
+    int present;
+    int num_pulse;
+    int start;
+    int offset[4];
+    int amp[4];
+} aac_pulse;
+
+
+/**
+ * Coupling struct
+ */
+typedef struct {
+    int ind_sw;
+    int domain;
+
+    int num_coupled;
+    int is_cpe[9];
+    int tag_select[9];
+    int l[9];
+    int r[9];
+
+    float gain[18][8][64];
+} aac_coupling;
+
+
+/**
+ * Single Channel Element
+ */
+typedef struct {
+    int global_gain;
+    aac_ics ics;
+    aac_tns tns;
+    int cb[8][64];
+    float sf[8][64];
+    DECLARE_ALIGNED_16(float, coeffs[1024]);
+    DECLARE_ALIGNED_16(float, saved[1024]);
+    DECLARE_ALIGNED_16(float, ret[1024]);
+} aac_sce;
+
+
+/**
+ * Channel Pair Element
+ */
+typedef struct {
+    int common_window;
+    aac_ms ms;
+    aac_sce ch[2];
+} aac_cpe;
+
+
+/**
+ * Channel Coupling Element
+ */
+typedef struct {
+    aac_coupling coup;
+    aac_sce ch;
+} aac_cce;
+
+
+/**
+ * AAC context
+ */
+typedef struct {
+    AVCodecContext *avctx;
+    GetBitContext gb;
+    VLC mainvlc;
+    VLC books[11];
+
+    // main config
+    int audioObjectType;
+    int ext_audioObjectType;
+    int sbr_present;
+    int sample_rate;
+    int sample_rate_index;
+    int channels;
+    int ochannels;
+    int frame_length;
+
+    // decoder param
+    aac_program_config pcs;
+    aac_sce *che_sce[MAX_TAGID];
+    aac_cpe *che_cpe[MAX_TAGID];
+    aac_sce *che_lfe[MAX_TAGID];
+    aac_cce *che_cce[MAX_TAGID];
+
+    DECLARE_ALIGNED_16(float, buf_mdct[2048]);
+    int is_saved;
+
+    const uint16_t *swb_offset_1024;
+    const uint16_t *swb_offset_128;
+    int num_swb_1024;
+    int num_swb_128;
+    int tns_max_bands_1024;
+    int tns_max_bands_128;
+
+    DECLARE_ALIGNED_16(float, kbd_long_1024[1024]);
+    DECLARE_ALIGNED_16(float, kbd_short_128[128]);
+    DECLARE_ALIGNED_16(float, sine_long_1024[1024]);
+    DECLARE_ALIGNED_16(float, sine_short_128[128]);
+    DECLARE_ALIGNED_16(float, pow2sf_tab[256]);
+    DECLARE_ALIGNED_16(float, intensity_tab[256]);
+    DECLARE_ALIGNED_16(float, ivquant_tab[256]);
+    DECLARE_ALIGNED_16(float, revers[1024]);
+    float* iop;
+
+    MDCTContext mdct;
+    MDCTContext mdct_small;
+    DSPContext dsp;
+    int * vq[11];
+    AVRandomState random_state;
+
+    int add_bias;
+    int scale_bias;
+
+    int num_frame;
+} AACContext;
+
+
+static int is_intensity(int cb)
+{
+    if(cb == INTENSITY_HCB)
+        return 1;
+    if(cb  == INTENSITY_HCB2)
+        return -1;
+    return 0;
+}
+
+#define is_noise(cb) (cb == NOISE_HCB)
+
+static void vector_fmul_add_add_add(AACContext *ac, float *dst,
+                                    const float *src0, const float *src1,
+                                    const float *src2, const float *src3,
+                                    float src4, int len) {
+    int i;
+    ac->dsp.vector_fmul_add_add(dst, src0, src1, src2, src4, len, 1);
+    for(i = 0; i < len; i++)
+        dst[i] += src3[i];
+}
+
+
+#define TAG_MASK 0x00f
+#define FLAG_SCE 0x100
+#define FLAG_CPE 0x200
+#define FLAG_LFE 0x400
+#define FLAG_CCE 0x800
+
+/**
+ * Generate a Kaiser Window.
+ */
+static void k_window_init(int alpha, float *window, int n, int iter) {
+    int j, k;
+    float a, x;
+    a = alpha * M_PI / n;
+    a = a*a;
+    for(k=0; k<n; k++) {
+        x = k * (n - k) * a;
+        window[k] = 1.0;
+        for(j=iter; j>0; j--) {
+            window[k] = (window[k] * x / (j*j)) + 1.0;
+        }
+    }
+}
+
+/**
+ * Generate a Kaiser-Bessel Derived Window.
+ * @param alpha  determines window shape
+ * @param window array to fill with window values
+ * @param n      length of the window
+ * @param iter   number of iterations to use in BesselI0
+ */
+static void kbd_window_init(int alpha, float *window, int n, int iter) {
+    int k, n2;
+    float *kwindow;
+
+    n2 = n >> 1;
+    kwindow = &window[n2];
+    k_window_init(alpha, kwindow, n2, iter);
+    window[0] = kwindow[0];
+    for(k=1; k<n2; k++) {
+        window[k] = window[k-1] + kwindow[k];
+    }
+    for(k=0; k<n2; k++) {
+        window[k] = sqrt(window[k] / (window[n2-1]+1));
+        //window[n-1-k] = window[k];
+    }
+}
+
+/**
+ * Generate a sine Window.
+ */
+static void sine_window_init(float *window, int n) {
+    const float alpha = M_PI / n;
+    int i;
+    for(i = 0; i < n/2; i++)
+        window[i] = sin((i + 0.5) * alpha);
+}
+
+
+/**
+ * Parse audio object type
+ * reference: Table 1.14
+ */
+static int GetAudioObjectType(GetBitContext *gb)
+{
+    int result = get_bits(gb, 5);
+    if(result == 31)
+        result = 32 + get_bits(gb, 6);
+    return result;
+}
+
+/**
+ * Parse program config element
+ * reference: Table 4.2
+ *
+ * XXX: Needs fixup
+ */
+static int program_config_element(AACContext *ac, GetBitContext *gb)
+{
+    aac_program_config *pcs = &ac->pcs;
+    int id, object_type, i;
+
+    pcs->present = 1;
+    id = get_bits(gb, 4);
+    object_type = get_bits(gb, 2);
+
+    ac->sample_rate_index = get_bits(gb, 4);
+
+    pcs->num_front      = get_bits(gb, 4);
+    pcs->num_side       = get_bits(gb, 4);
+    pcs->num_back       = get_bits(gb, 4);
+    pcs->num_lfe        = get_bits(gb, 2);
+    pcs->num_assoc_data = get_bits(gb, 3);
+    pcs->num_cc         = get_bits(gb, 4);
+
+    pcs->mono_mixdown   = get_bits1(gb) ? get_bits(gb, 4) + 1 : 0;
+    pcs->stereo_mixdown = get_bits1(gb) ? get_bits(gb, 4) + 1 : 0;
+
+    if(get_bits1(gb)) {
+        pcs->matrix_mixdown = get_bits(gb, 2) + 1;
+        pcs->pseudo_surround = get_bits1(gb);
+    } else {
+        pcs->matrix_mixdown = 0;
+        pcs->pseudo_surround = 0;
+    }
+
+    pcs->front_cpe = 0;
+    ac->channels += pcs->num_front;
+    for(i = 0; i < pcs->num_front; i++) {
+        if(get_bits1(gb)) {
+            pcs->front_cpe |= (1 << i);
+            ac->channels++;
+        }
+        pcs->front_tag[i] = get_bits(gb, 4);
+    }
+    pcs->side_cpe = 0;
+    ac->channels += pcs->num_side;
+    for(i = 0; i < pcs->num_side; i++) {
+        if(get_bits1(gb)) {
+            pcs->side_cpe |= (1 << i);
+            ac->channels++;
+        }
+        pcs->side_tag[i] = get_bits(gb, 4);
+    }
+    pcs->back_cpe = 0;
+    ac->channels += pcs->num_back;
+    for(i = 0; i < pcs->num_back; i++) {
+        if(get_bits1(gb)) {
+            pcs->back_cpe |= (1 << i);
+            ac->channels++;
+        }
+        pcs->back_tag[i] = get_bits(gb, 4);
+    }
+    ac->channels += pcs->num_lfe;
+    for(i = 0; i < pcs->num_lfe; i++)
+        pcs->lfe_tag[i] = get_bits(gb, 4);
+
+    pcs->num_channels = ac->channels;
+    // not a real audio channel
+    for(i = 0; i < pcs->num_assoc_data; i++)
+        pcs->assoc_data_tag[i] = get_bits(gb, 4);
+    pcs->cc_ind_sw = 0;
+    for(i = 0; i < pcs->num_cc; i++) {
+        pcs->cc_ind_sw |= (get_bits1(gb) << i);
+        pcs->cc_tag[i] = get_bits(gb, 4);
+    }
+    align_get_bits(gb);
+    skip_bits(gb, 8 * get_bits(gb, 8));
+    return 0;
+}
+
+/**
+ * Implicit channel configuration
+ * reference: Table 1.17
+ *
+ * XXX: Needs fixup
+ */
+static int implicit_channel_config(AACContext *ac)
+{
+    switch(ac->channels) {
+    case 1:        /* C */
+        ac->che_sce[0] = av_mallocz(sizeof(aac_sce));
+        ac->ochannels = 1;
+        break;
+
+    case 2:        /* L + R */
+        ac->che_cpe[0] = av_mallocz(sizeof(aac_cpe));
+        ac->ochannels = 2;
+        break;
+
+
+    case 6:
+        ac->che_sce[0] = av_mallocz(sizeof(aac_sce));
+        ac->che_cpe[0] = av_mallocz(sizeof(aac_cpe));
+        ac->che_cpe[1] = av_mallocz(sizeof(aac_cpe));
+        ac->che_lfe[0] = av_mallocz(sizeof(aac_sce));
+        ac->ochannels = 6;
+        break;
+
+    default:
+        return -1;
+    }
+    return 0;
+}
+
+/**
+ * Parse GA specific configuration
+ * reference: Table 4.1
+ */
+static int GASpecificConfig(AACContext *ac, GetBitContext *gb)
+{
+    if(get_bits1(gb))     // frameLengthFlag
+        return -1;        // We only support 1024 / 128*8 MDCT windows
+
+    if(get_bits1(gb))
+        get_bits(gb, 14); // coreCoderDelay
+
+    if(get_bits1(gb))     // extensionFlag, should be 0 for AAC_LC
+        return -1;
+
+    if(ac->channels == 0)
+        return program_config_element(ac, gb);
+    else
+        return implicit_channel_config(ac);
+}
+
+
+/**
+ * Parse audio specific configuration
+ * reference: Table 1.13
+ */
+static int AudioSpecificConfig(AACContext *ac, void *data, int data_size)
+{
+    GetBitContext * gb = &ac->gb;
+
+    init_get_bits(gb, data, data_size * 8);
+
+    ac->audioObjectType = GetAudioObjectType(gb);
+    if(ac->audioObjectType != AOT_AAC_LC)
+        return -1;
+
+    ac->sample_rate_index = get_bits(gb, 4);
+    if(ac->sample_rate_index == 0xf)
+        ac->sample_rate = get_bits(gb, 24);
+
+    ac->channels = get_bits(gb, 4);
+
+    if(GASpecificConfig(ac, gb) < 0)
+        return -1;
+
+    if(ac->sample_rate_index == 15) {
+        /* Explicit rate configured, XXX: Use table 4.68 */
+    } else if(ac->sample_rate_index > 12) {
+        return -1; // Reserved
+    } else {
+        ac->sample_rate = aac_sample_rates[ac->sample_rate_index];
+    }
+    return 0;
+}
+
+/**
+ * Top level init
+ */
+static int aac_decode_init(AVCodecContext *avctx)
+{
+    AACContext *ac = avctx->priv_data;
+    int i;
+
+    ac->avctx = avctx;
+
+    if(AudioSpecificConfig(ac, avctx->extradata, avctx->extradata_size))
+        return -1;
+
+    avctx->sample_rate = ac->sample_rate;
+    avctx->channels = ac->ochannels;
+
+    for(i = 0; i < 11; i++) {
+        static const int mod_cb[11] = { 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17 };
+        static const int off_cb[11] = { 1, 1, 0, 0, 4, 4, 0, 0,  0,  0,  0 };
+        const aac_codebook *aco = &aac_codebooks[i];
+
+        int j, values = aco->s/sizeof(aco->a[0]);
+        int dim = (i >= 4 ? 2 : 4);
+        int mod = mod_cb[i], off = off_cb[i], index = 0;
+        int ret;
+        ret = init_vlc(&ac->books[i], 6, values,
+                       &aco->a[0][1], sizeof(aco->a[0]),
+                       sizeof(aco->a[0][1]),
+                       &aco->a[0][0], sizeof(aco->a[0]),
+                       sizeof(aco->a[0][0]),
+                       0);
+        assert(!ret);
+        ac->vq[i] = av_malloc(dim * values * sizeof(int));
+        if(dim == 2) {
+            for(j = 0; j < values * dim; j += dim) {
+                index = j/dim;
+                ac->vq[i][j  ] = (index / (mod            ) - off);
+                index %= mod;
+                ac->vq[i][j+1] = (index                     - off);
+            }
+        } else {
+            for(j = 0; j < values * dim; j += dim) {
+                index = j/dim;
+                ac->vq[i][j  ] = (index / (mod * mod * mod) - off);
+                index %= mod*mod*mod;
+                ac->vq[i][j+1] = (index / (mod * mod      ) - off);
+                index %= mod*mod;
+                ac->vq[i][j+2] = (index / (mod            ) - off);
+                index %= mod;
+                ac->vq[i][j+3] = (index                     - off);
+            }
+        }
+    }
+
+    /* Initialize RNG dither */
+    av_init_random(0x1f2e3d4c, &ac->random_state);
+
+    /* Speedup tables */
+    for(i = 0; i < 256; i++)
+        ac->intensity_tab[i] = pow(0.5, (i - 100) / 4.);
+    for(i = 0; i < sizeof(ac->ivquant_tab)/sizeof(ac->ivquant_tab[0]); i++)
+        ac->ivquant_tab[i] = pow(i, 4./3);
+
+    if(ac->dsp.float_to_int16 == ff_float_to_int16_c) {
+        ac->add_bias = 385;
+        ac->scale_bias = 32768;
+    } else {
+        ac->add_bias = 0;
+        ac->scale_bias = 1;
+    }
+    for(i = 0; i < 256; i++)
+        ac->pow2sf_tab[i] = pow(2, (i - 100)/4.) /1024./ac->scale_bias;
+
+    ac->num_frame = -1;
+
+    ac->swb_offset_1024    = aac_swb_offset_1024[ac->sample_rate_index];
+    ac->num_swb_1024       = aac_num_swb_1024[ac->sample_rate_index];
+    ac->tns_max_bands_1024 = aac_tns_max_bands_1024[ac->sample_rate_index];
+    ac->swb_offset_128     = aac_swb_offset_128[ac->sample_rate_index];
+    ac->num_swb_128        = aac_num_swb_128[ac->sample_rate_index];
+    ac->tns_max_bands_128  = aac_tns_max_bands_128[ac->sample_rate_index];
+
+    init_vlc(&ac->mainvlc, 7,
+             sizeof(aac_scalefactor_huffman_table)/
+             sizeof(aac_scalefactor_huffman_table[0]),
+             &aac_scalefactor_huffman_table[0][1],
+             sizeof(aac_scalefactor_huffman_table[0]),
+             sizeof(aac_scalefactor_huffman_table[0][1]),
+             &aac_scalefactor_huffman_table[0][0],
+             sizeof(aac_scalefactor_huffman_table[0]),
+             sizeof(aac_scalefactor_huffman_table[0][0]),
+             0);
+
+    ff_mdct_init(&ac->mdct, 11, 1);
+    ff_mdct_init(&ac->mdct_small, 8, 1);
+    kbd_window_init(4, ac->kbd_long_1024, 2048, 50);
+    kbd_window_init(6, ac->kbd_short_128, 256,  50);
+    sine_window_init(ac->sine_long_1024, 2048);
+    sine_window_init(ac->sine_short_128, 256);
+
+    for(i = 0; i < 128; i++) {
+        ac->sine_short_128[i] *= 8.;
+        ac->kbd_short_128[i] *= 8.;
+    }
+    dsputil_init(&ac->dsp, avctx);
+    return 0;
+}
+
+/**
+ * Joint coding, M/S Stereo parser
+ */
+static int ms_parser(AACContext *ac, GetBitContext *gb, aac_cpe *cpe)
+{
+    aac_ms *ms = &cpe->ms;
+    int g, i;
+
+    ms->present = get_bits(gb, 2);
+    switch(ms->present) {
+    case 1:
+    case 2:
+        for(g = 0; g < cpe->ch[0].ics.num_window_groups; g++) {
+            for(i = 0; i < cpe->ch[0].ics.max_sfb; i++) {
+                ms->mask[g][i] = ms->present == 1 ? get_bits1(gb) : 1;
+            }
+        }
+        break;
+
+    case 3:
+        return -1; /* Reserved */
+    }
+    return 0;
+}
+
+/**
+ * Joint coding, M/S Stereo
+ */
+static void ms_tool(AACContext *ac, aac_cpe *cpe) {
+    const aac_ms *ms = &cpe->ms;
+    const aac_ics *ics = &cpe->ch[0].ics;
+    aac_sce *sce0 = &cpe->ch[0];
+    aac_sce *sce1 = &cpe->ch[1];
+    float *ch0 = sce0->coeffs;
+    float *ch1 = sce1->coeffs;
+    int g, i, k, gp;
+    const uint16_t * offsets = ics->swb_offset;
+
+    if(!ms->present)
+        return;
+
+    for(g = 0; g < ics->num_window_groups; g++) {
+        for(gp = 0; gp < ics->group_len[g]; gp++) {
+            for(i = 0; i < ics->max_sfb; i++) {
+                if(ms->mask[g][i] && !is_intensity(sce1->cb[g][i]) &&
+                    !is_noise(sce1->cb[g][i])) {
+                    for(k = offsets[i]; k < offsets[i+1]; k++) {
+                        float tmp = ch0[k] - ch1[k];
+                        ch0[k] += ch1[k];
+                        ch1[k] = tmp;
+                    }
+                }
+            }
+            ch0 += 128;
+            ch1 += 128;
+        }
+    }
+}
+
+
+/**
+ * Pulse tool parser
+ */
+static void pulse_parser(AACContext *ac, GetBitContext *gb, aac_pulse *pulse)
+{
+    int i;
+
+    if(!(pulse->present = get_bits1(gb)))
+       return;
+    pulse->num_pulse = get_bits(gb, 2);
+    pulse->start = get_bits(gb, 6);
+    for(i = 0; i <= pulse->num_pulse; i++) {
+        pulse->offset[i] = get_bits(gb, 5);
+        pulse->amp[i] = get_bits(gb, 4);
+    }
+}
+
+
+/**
+ * Pulse tool
+ */
+static void pulse_tool(AACContext *ac, aac_ics * const ics,
+                       aac_pulse * const pulse, int *icoef)
+{
+    int i, off;
+    if(!pulse->present)
+        return;
+
+    off = ics->swb_offset[pulse->start];
+    for(i = 0; i <= pulse->num_pulse; i++) {
+        off += pulse->offset[i];
+        if(icoef[off] > 0)
+            icoef[off] += pulse->amp[i];
+        else
+            icoef[off] -= pulse->amp[i];
+    }
+}
+
+
+/**
+ * Intensity stereo tool
+ */
+static void intensity_tool(AACContext *ac, aac_cpe *cpe)
+{
+    const aac_ics *ics = &cpe->ch[1].ics;
+    aac_sce *sce0 = &cpe->ch[0];
+    aac_sce *sce1 = &cpe->ch[1];
+    const uint16_t *offsets = ics->swb_offset;
+    int g, gp, i, k, c;
+    float scale;
+
+    if(!ics->intensity_present)
+        return;
+
+    for(g = 0; g < ics->num_window_groups; g++) {
+        for(gp = 0; gp < ics->group_len[g]; gp++) {
+            for(i = 0; i < ics->max_sfb; i++) {
+                if((c = is_intensity(sce1->cb[g][i]))) {
+                    if(cpe->ms.present == 1)
+                        c *= (1 - 2 * cpe->ms.mask[g][i]);
+
+                    scale = c * sce1->sf[g][i];
+
+                    for(k = offsets[i] + gp * 128;
+                         k < offsets[i+1] + gp * 128; k++) {
+                        sce1->coeffs[k] = scale * sce0->coeffs[k];
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+/**
+ * Temporal Noise Shaping tool parser
+ */
+static void tns_parser(AACContext *ac, GetBitContext *gb, const aac_ics *ics,
+                       aac_tns *tns)
+{
+    int w, filt, i, coef_len, coef_res = 0, coef_compress;
+
+    if(!(tns->present = get_bits1(gb)))
+        return;
+
+    for(w = 0; w < ics->num_windows; w++) {
+        tns->n_filt[w] = get_bits(gb, ICS_ESS(ics) ? 1 : 2);
+        if(tns->n_filt[w])
+            coef_res = get_bits1(gb) + 3;
+        for(filt = 0; filt < tns->n_filt[w]; filt++) {
+            tns->length[w][filt] = get_bits(gb, ICS_ESS(ics) ? 4 : 6);
+            if((tns->order[w][filt] = get_bits(gb, ICS_ESS(ics) ? 3 : 5))) {
+                tns->direction[w][filt] = get_bits1(gb);
+                coef_compress = get_bits1(gb);
+                coef_len = coef_res - coef_compress;
+                tns->tmp2_map[w] = aac_tns_coeffs_table[(coef_compress << 1) +
+                                                        (coef_res - 3)];
+                for(i = 0; i < tns->order[w][filt]; i++)
+                    tns->coef[w][filt][i] = get_bits(gb, coef_len);
+            }
+        }
+    }
+}
+
+
+/**
+ * Temporal Noise Shaping tool
+ */
+static void tns_filter_tool(AACContext * ac, aac_sce *sce, float *coef)
+{
+    const aac_ics *ics = &sce->ics;
+    const aac_tns *tns = &sce->tns;
+    const int mmm = FFMIN(ics->tns_max_bands,  ics->max_sfb);
+    int w, filt, m, i, ib, bottom, top, order, start, end, size, inc;
+    float tmp;
+    float lpc[TNS_MAX_ORDER + 1], b[2 * TNS_MAX_ORDER];
+    if(!tns->present)
+        return;
+
+    for(w = 0; w < ics->num_windows; w++) {
+        bottom = ics->num_swb;
+        for(filt = 0; filt < tns->n_filt[w]; filt++) {
+            top = bottom;
+            bottom = FFMAX(top - tns->length[w][filt], 0);
+            order  = FFMIN(tns->order[w][filt], TNS_MAX_ORDER);
+            if(order == 0)
+                continue;
+
+            // tns_decode_coef
+            lpc[0] = 1;
+            for(m = 1; m <= order; m++) {
+                lpc[m] = tns->tmp2_map[w][tns->coef[w][filt][m - 1]];
+                for(i = 1; i < m; i++)
+                    b[i] = lpc[i] + lpc[m] * lpc[m-i];
+                for(i = 1; i < m; i++)
+                    lpc[i] = b[i];
+            }
+
+            start = ics->swb_offset[FFMIN(bottom, mmm)];
+            end = ics->swb_offset[FFMIN(top, mmm)];
+            if((size = end - start) <= 0)
+                continue;
+            if(tns->direction[w][filt]) {
+                inc = -1; start = end - 1;
+            } else {
+                inc = 1;
+            }
+            start += w * 128;
+
+            // ar filter
+            memset(b, 0, sizeof(b));
+            ib = 0;
+
+            for(m = 0; m < size; m++) {
+                tmp = coef[start];
+                for(i = 0; i < order; i++)
+                    tmp -= b[ib + i] * lpc[i + 1];
+                if(--ib < 0)
+                    ib = order - 1;
+                b[ib] = b[ib + order] = tmp;
+                coef[start] = tmp;
+                start += inc;
+            }
+        }
+    }
+}
+
+
+/**
+ * Wrapper for use together with transform_sce_tool()
+ */
+static void tns_trans(AACContext *ac, aac_sce *sce)
+{
+    tns_filter_tool(ac, sce, sce->coeffs);
+}
+
+
+/**
+ *
+ */
+static float ivquant(AACContext *ac, int a) {
+    const float sign = FFSIGN(a);
+    a = FFABS(a);
+    if(a < sizeof(ac->ivquant_tab) / sizeof(ac->ivquant_tab[0]))
+        return sign * ac->ivquant_tab[a];
+    else
+        return sign * pow(a, 4./3);
+}
+
+
+/**
+ * Quantization tool
+ */
+static void quant_to_spec_tool(AACContext *ac, aac_ics *ics, const int *icoef,
+                               int cb[][64], float sf[][64], float *coef)
+{
+    const uint16_t * offsets = ics->swb_offset;
+    int g, i, group, k;
+    int total = ICS_ESS(ics) ? 128 : 1024;
+    float energy, scale;
+    for(g = 0; g < ics->num_window_groups; g++) {
+        memset(coef + g*total + offsets[ics->max_sfb], 0,
+               sizeof(float) * (total - offsets[ics->max_sfb]));
+    }
+
+    for(g = 0; g < ics->num_window_groups; g++) {
+        for(i = 0; i < ics->max_sfb; i++) {
+            if(cb[g][i] == NOISE_HCB) {
+                for(group = 0; group < ics->group_len[g]; group++) {
+                    energy = 0;
+                    scale = 1;
+                    for(k = offsets[i]; k < offsets[i+1]; k++)
+                        energy += (float)icoef[group*128+k] *
+                            icoef[group*128+k];
+
+                    scale *= sf[g][i] / sqrt(energy);
+                    for(k = offsets[i]; k < offsets[i+1]; k++)
+                        coef[group*128+k] = icoef[group*128+k] * scale;
+                }
+            } else if(cb[g][i] != INTENSITY_HCB &&
+                      cb[g][i] != INTENSITY_HCB2) {
+
+                for(group = 0; group < ics->group_len[g]; group++) {
+                    for(k = offsets[i]; k < offsets[i+1]; k++) {
+                        coef[group*128+k] = ivquant(ac, icoef[group*128+k]) *
+                            sf[g][i];
+                    }
+                }
+            } else {
+                assert(0);
+            }
+        }
+        coef  += ics->group_len[g]*128;
+        icoef += ics->group_len[g]*128;
+    }
+}
+
+
+/**
+ * Inverse MDCT Filterbank tool
+ *
+ * The imdct transform uses 'out' as a temporary buffer
+ */
+static void window_trans(AACContext *ac, aac_sce *sce) {
+    aac_ics *ics = &sce->ics;
+    float *in = sce->coeffs;
+    float *out = sce->ret;
+    float *saved = sce->saved;
+
+    const float *lwindow = ics->window_shape ? ac->kbd_long_1024 : ac->sine_long_1024;
+    const float *swindow = ics->window_shape ? ac->kbd_short_128 : ac->sine_short_128;
+    const float *lwindow_prev = ics->window_shape_prev ? ac->kbd_long_1024 : ac->sine_long_1024;
+    const float *swindow_prev = ics->window_shape_prev ? ac->kbd_short_128 : ac->sine_short_128;
+    float * buf = ac->buf_mdct;
+    int i;
+
+    if(ics->window_sequence != EIGHT_SHORT_SEQUENCE) {
+        ff_imdct_calc(&ac->mdct, buf, in, out);
+
+        if(ac->is_saved) {
+            if(ics->window_sequence != LONG_STOP_SEQUENCE) {
+                ac->dsp.vector_fmul_add_add(out, buf, lwindow_prev, saved,
+                                            ac->add_bias, 1024, 1);
+            } else {
+                for(i = 0; i < 448; i++) out[i] = saved[i] + ac->add_bias;
+                for(i = 448; i < 576; i++) buf[i] *= 0.125; // normalize
+                ac->dsp.vector_fmul_add_add(out + 448, buf + 448, swindow_prev,
+                                            saved + 448, ac->add_bias, 128, 1);
+                for(i = 576; i < 1024; i++)   out[i] = buf[i] + ac->add_bias;
+            }
+        }
+        if(ics->window_sequence != LONG_START_SEQUENCE) {
+            ac->dsp.vector_fmul_reverse(saved, buf + 1024, lwindow, 1024);
+        } else {
+            memcpy(saved, buf + 1024, 448 * sizeof(float));
+            for(i = 448; i < 576; i++) buf[i + 1024] *= 0.125; // normalize
+            ac->dsp.vector_fmul_reverse(saved + 448, buf + 1024 + 448, swindow,
+                                        128);
+            memset(saved + 576, 0, 448 * sizeof(float));
+        }
+    } else {
+        int i;
+
+        for(i = 0; i < 2048; i += 256) {
+            ff_imdct_calc(&ac->mdct_small, buf + i, in + i/2, out);
+            ac->dsp.vector_fmul_reverse(ac->revers + i/2, buf + i + 128,
+                                        swindow, 128);
+        }
+
+        for(i = 0; i < 448; i++)   out[i] = saved[i] + ac->add_bias;
+        out += 448; saved += 448;
+        ac->dsp.vector_fmul_add_add(out + 0*128, buf + 0*128, swindow_prev, saved, ac->add_bias, 128, 1);
+        vector_fmul_add_add_add(ac, out + 1*128, buf + 2*128, swindow, saved + 1*128, ac->revers + 0*128, ac->add_bias, 128);
+        vector_fmul_add_add_add(ac, out + 2*128, buf + 4*128, swindow, saved + 2*128, ac->revers + 1*128, ac->add_bias, 128);
+        vector_fmul_add_add_add(ac, out + 3*128, buf + 6*128, swindow, saved + 3*128, ac->revers + 2*128, ac->add_bias, 128);
+        vector_fmul_add_add_add(ac, out + 4*128, buf + 8*128, swindow, saved + 4*128, ac->revers + 3*128, ac->add_bias, 64);
+
+        saved -= 448;
+        buf += 1024;
+        ac->dsp.vector_fmul_add_add(saved,       buf + 64, swindow, ac->revers + 3*128+64,  0, 64, 1);
+        ac->dsp.vector_fmul_add_add(saved + 64,  buf + 2*128, swindow, ac->revers + 4*128, 0, 128, 1);
+        ac->dsp.vector_fmul_add_add(saved + 192, buf + 4*128, swindow, ac->revers + 5*128, 0, 128, 1);
+        ac->dsp.vector_fmul_add_add(saved + 320, buf + 6*128, swindow, ac->revers + 6*128, 0, 128, 1);
+        memcpy(                     saved + 448, ac->revers + 7*128, 128 * sizeof(float));
+
+        memset(saved + 576, 0, 448 * sizeof(float));
+    }
+}
+
+
+/**
+ * Decode Individual Channel Stream info
+ * reference: table 4.6
+ */
+static int ics_info(AACContext *ac, GetBitContext *gb, int common_window,
+                     aac_ics *ics)
+{
+    int i;
+
+    if(get_bits1(gb))   // ics_reserved_bit
+        return -1;
+    ics->window_sequence = get_bits(gb, 2);
+    ics->window_shape_prev = ics->window_shape;
+    ics->window_shape = get_bits1(gb);
+    if(ics->window_shape_prev == -1)
+        ics->window_shape_prev = ics->window_shape;
+    ics->num_window_groups = 1;
+    ics->group_len[0] = 1;
+    if(ICS_ESS(ics)) {
+        ics->max_sfb = get_bits(gb, 4);
+        ics->grouping = get_bits(gb, 7);
+        for(i = 0; i < 7; i++) {
+            if(ics->grouping & (1<<(6-i))) {
+                ics->group_len[ics->num_window_groups-1]++;
+            } else {
+                ics->num_window_groups++;
+                ics->group_len[ics->num_window_groups-1] = 1;
+            }
+        }
+        ics->swb_offset = ac->swb_offset_128;
+        ics->num_swb = ac->num_swb_128;
+        ics->num_windows = 8;
+        ics->tns_max_bands = ac->tns_max_bands_128;
+    } else {
+        ics->max_sfb = get_bits(gb, 6);
+        ics->swb_offset = ac->swb_offset_1024;
+        ics->num_swb = ac->num_swb_1024;
+        ics->num_windows = 1;
+        ics->tns_max_bands = ac->tns_max_bands_1024;
+        if(get_bits1(gb)) { // predictor_data_present
+            av_log(ac->avctx, AV_LOG_ERROR, "Prediction not supported\n");
+            return -1;
+        }
+    }
+    return 0;
+}
+
+
+/**
+ * Decode scale_factor_data
+ * reference: Table 4.47
+ */
+static int scale_factor_data(AACContext *ac, GetBitContext *gb,
+                             aac_sce *sce, aac_ics *ics)
+{
+    int g, i;
+    unsigned int intensity = 100;
+    unsigned int global_gain = sce->global_gain;
+    int noise = sce->global_gain - 90;
+    int noise_flag = 1;
+    float sf;
+
+    ics->intensity_present = 0;
+    ics->noise_present = 0;
+    for(g = 0; g < ics->num_window_groups; g++) {
+        for(i = 0; i < ics->max_sfb; i++) {
+            switch(sce->cb[g][i]) {
+            case ZERO_HCB:
+                sce->sf[g][i] = 0;
+                continue;
+
+            case INTENSITY_HCB:
+            case INTENSITY_HCB2:
+                ics->intensity_present = 1;
+                intensity += get_vlc2(gb, ac->mainvlc.table, 7, 3) - 60;
+                if(intensity > 255)
+                    return -1;
+                sf = ac->intensity_tab[intensity];
+                break;
+
+            case NOISE_HCB:
+                ics->noise_present = 1;
+                if(noise_flag) {
+                    noise_flag = 0;
+                    noise += get_bits(gb, 9) - 256;
+                } else {
+                    noise += get_vlc2(gb, ac->mainvlc.table, 7, 3) - 60;
+                }
+                sf = pow(2.0, 0.25 * noise)/1024./ac->scale_bias;
+                break;
+
+            default:
+                global_gain += get_vlc2(gb, ac->mainvlc.table, 7, 3) - 60;
+                if(global_gain > 255 || global_gain < 0)
+                    return -1;
+                sf = ac->pow2sf_tab[global_gain];
+            }
+            sce->sf[g][i] = sf;
+        }
+    }
+    return 0;
+}
+
+
+/**
+ * Decode section_data payload
+ * reference: Table 4.46
+ */
+static void section_data(AACContext *ac, GetBitContext *gb, aac_ics *ics,
+                         int cb[][64]) {
+    int g, k, sect_len, sect_len_incr, sect_cb;
+    const int bits = ICS_ESS(ics) ? 3 : 5;
+    const int sect_esc_val = (1 << bits) - 1;
+
+    for(g = 0; g < ics->num_window_groups; g++) {
+        for(k = 0; k < ics->max_sfb;) {
+            sect_len = 0;
+            sect_cb = get_bits(gb, 4);
+
+            while((sect_len_incr = get_bits(gb, bits)) == sect_esc_val)
+                sect_len += sect_esc_val;
+            sect_len += sect_len_incr;
+            sect_len += k;
+            for(; k < sect_len && k < ics->max_sfb; k++)
+                cb[g][k] = sect_cb;
+        }
+    }
+}
+
+
+/**
+ * Decode spectral data for VLC codebooks
+ */
+static int spectral_data_vlc(AACContext *ac, GetBitContext *gb,
+                             const int cur_cb, const int group,
+                             const int k, int *icoef, int d)
+{
+    static const int unsigned_cb[] = { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1 };
+    int sign[4] = {1,1,1,1};
+    int j, ptr[4], index;
+
+    if((index = get_vlc2(gb, ac->books[cur_cb - 1].table, 6, 3)) < 0)
+        return -1;
+
+    memcpy(ptr, &ac->vq[cur_cb - 1][index * d], d * sizeof(int));
+
+    if(unsigned_cb[cur_cb - 1]) {
+        for(j = 0; j < d; j++)
+            if(ptr[j] && get_bits1(gb))
+                sign[j] = -1;
+    }
+    if(cur_cb == ESC_HCB) {
+        for(j = 0; j < 2; j++) {
+            if(ptr[j] == 16) {
+                int n = 4;
+                while(get_bits1(gb)) n++;
+                ptr[j] = (1<<n) + get_bits(gb, n);
+            }
+        }
+    }
+    for(j = 0; j < d; j++)
+        icoef[group*128+k+j] = sign[j] * ptr[j];
+    return 0;
+}
+
+
+/**
+ * Decode spectral data
+ * reference: Table 4.50
+ */
+static int spectral_data(AACContext *ac, GetBitContext *gb,
+                         const aac_ics *ics, int cb[8][64],
+                         int *icoef)
+{
+    int i, k, g, cur_cb, d, group;
+    const uint16_t * offsets = ics->swb_offset;
+    const int total = ICS_ESS(ics) ? 128 : 1024;
+
+    for(g = 0; g < ics->num_window_groups; g++)
+        memset(icoef + g * total + offsets[ics->max_sfb], 0,
+               sizeof(int) * (total - offsets[ics->max_sfb]));
+
+    for(g = 0; g < ics->num_window_groups; g++) {
+        for(i = 0; i < ics->max_sfb; i++) {
+            cur_cb = cb[g][i];
+            d = cur_cb >= FIRST_PAIR_HCB ? 2 : 4;
+
+
+            switch(cur_cb) {
+            case INTENSITY_HCB:
+            case INTENSITY_HCB2:
+                continue;
+
+            case NOISE_HCB:
+                for(group = 0; group < ics->group_len[g]; group++)
+                    for(k = offsets[i]; k < offsets[i+1]; k++)
+                        icoef[group*128+k] =
+                            av_random(&ac->random_state) & 0x0000FFFF;
+                continue;
+
+            case ZERO_HCB:
+                for(group = 0; group < ics->group_len[g]; group++)
+                    memset(icoef + group * 128 + offsets[i], 0,
+                           (offsets[i+1] - offsets[i])*sizeof(int));
+                continue;
+
+            default:
+                for(group = 0; group < ics->group_len[g]; group++)
+                    for(k = offsets[i]; k < offsets[i+1]; k += d)
+                        if(spectral_data_vlc(ac, gb, cur_cb, group, k, icoef, d))
+                            return -1;
+            }
+        }
+        icoef += ics->group_len[g]*128;
+    }
+    return 0;
+}
+
+
+/**
+ * Decode an individual_channel_stream payload
+ * reference: Table 4.44
+ */
+static int individual_channel_stream(AACContext *ac, GetBitContext *gb,
+                                     int common_window, int scale_flag,
+                                     aac_sce *sce)
+{
+    int icoeffs[1024];
+    aac_pulse pulse;
+    aac_tns *tns = &sce->tns;
+    aac_ics *ics = &sce->ics;
+    float *out = sce->coeffs;
+
+    memset(&pulse, 0, sizeof(pulse));
+    sce->global_gain = get_bits(gb, 8);
+
+    if(!common_window && !scale_flag)
+        ics_info(ac, gb, 0, ics);
+
+    section_data(ac, gb, ics, sce->cb);
+    if(scale_factor_data(ac, gb, sce, ics))
+        return -1;
+
+    if(!scale_flag) {
+        pulse_parser(ac, gb, &pulse);
+        tns_parser(ac, gb, ics, tns);
+
+        if(get_bits1(gb)) {
+            av_log(ac->avctx, AV_LOG_INFO, "gain control not supported\n");
+            return -1;
+        }
+    }
+    if(spectral_data(ac, gb, ics, sce->cb, icoeffs))
+        return -1;
+    pulse_tool(ac, ics, &pulse, icoeffs);
+    quant_to_spec_tool(ac, ics, icoeffs, sce->cb, sce->sf, out);
+    return 0;
+}
+
+
+/**
+ * Decode a single_channel_element
+ * reference: Table 4.4
+ */
+static int single_channel_element(AACContext *ac, GetBitContext *gb)
+{
+    aac_sce *sce;
+    int id = get_bits(gb, 4);
+    if((sce = ac->che_sce[id]) == NULL) {
+        av_log(ac->avctx, AV_LOG_ERROR,
+               "Single channel element %d not configured\n", id);
+        return -1;
+    }
+    return individual_channel_stream(ac, gb, 0, 0, sce);
+}
+
+
+/**
+ * Decode a channel_pair_element
+ * reference: Table 4.4
+ */
+static int channel_pair_element(AACContext *ac, GetBitContext *gb) {
+    int i;
+    aac_cpe *cpe;
+    int id = get_bits(gb, 4);
+    if((cpe = ac->che_cpe[id]) == NULL) {
+        av_log(ac->avctx, AV_LOG_ERROR,
+               "Channel pair element %d not configured\n", id);
+        return -1;
+    }
+
+    cpe->common_window = get_bits1(gb);
+    if(cpe->common_window) {
+        ics_info(ac, gb, 1, &cpe->ch[0].ics);
+        i = cpe->ch[1].ics.window_shape_prev;
+        cpe->ch[1].ics = cpe->ch[0].ics;
+        cpe->ch[1].ics.window_shape_prev = i;
+        if(ms_parser(ac, gb, cpe))
+            return -1;
+    } else {
+        cpe->ms.present = 0;
+    }
+
+    if(individual_channel_stream(ac, gb, cpe->common_window, 0, &cpe->ch[0]))
+        return -1;
+    if(individual_channel_stream(ac, gb, cpe->common_window, 0, &cpe->ch[1]))
+        return -1;
+
+    if(cpe->common_window)
+        ms_tool(ac, cpe);
+
+    intensity_tool(ac, cpe);
+    return 0;
+}
+
+
+/**
+ * Decode a lfe_channel_element
+ * reference: Table 4.4
+ */
+static int lfe_channel_element(AACContext *ac, GetBitContext *gb)
+{
+    aac_sce *sce;
+    int id = get_bits(gb, 4);
+    if((sce = ac->che_lfe[id]) == NULL) {
+        av_log(ac->avctx, AV_LOG_ERROR,
+               "Low frequency element %d not configured\n", id);
+        return -1;
+    }
+
+    return individual_channel_stream(ac, gb, 0, 0, sce);
+}
+
+
+/**
+ * Decode a data_stream_element
+ * reference: Table 4.10
+ */
+static int data_stream_element(AACContext *ac, GetBitContext *gb)
+{
+    int id, byte_align;
+    int count;
+    id = get_bits(gb, 4);
+    byte_align = get_bits1(gb);
+    count = get_bits(gb, 8);
+    if(count == 255)
+        count += get_bits(gb, 8);
+    if(byte_align)
+        align_get_bits(gb);
+    skip_bits(gb, 8 * count);
+    return 0;
+}
+
+
+/**
+ * Perform function \p f on all active channel elements
+ */
+static void transform_sce_tool(AACContext * ac,
+                               void (*f)(AACContext *ac, aac_sce *sce))
+{
+    int i;
+
+    for(i = 0; i < MAX_TAGID; i++) {
+        if(ac->che_sce[i] != NULL)
+            f(ac, ac->che_sce[i]);
+        if(ac->che_cpe[i] != NULL) {
+            f(ac, &ac->che_cpe[i]->ch[0]);
+            f(ac, &ac->che_cpe[i]->ch[1]);
+        }
+        if(ac->che_lfe[i] != NULL)
+            f(ac, ac->che_lfe[i]);
+        if(ac->che_cce[i] != NULL)
+            f(ac, &ac->che_cce[i]->ch);
+    }
+}
+
+
+/**
+ * Write out samples. XXX: This needs to be rewritten
+ */
+static void output_samples(AACContext *ac, AVCodecContext *avctx,
+                           void *data, int *data_size)
+{
+    int size = ac->ochannels * 1024 * sizeof(uint16_t);
+    float *mixbuf = NULL, *src = NULL;
+    int i;
+
+    *data_size = 0;
+
+    if(!ac->is_saved) {
+        ac->is_saved = 1;
+        return;
+    }
+
+    switch(ac->ochannels) {
+    case 1:
+        src = ac->che_sce[0]->ret;
+        break;
+
+    case 2:
+        src = mixbuf = av_malloc(size * 2);
+        for(i = 0; i < 1024; i++) {
+            mixbuf[i * 2 + 0] = ac->che_cpe[0]->ch[0].ret[i];
+            mixbuf[i * 2 + 1] = ac->che_cpe[0]->ch[1].ret[i];
+        }
+        break;
+
+    case 6:
+        src = mixbuf = av_malloc(size * 6);
+        for(i = 0; i < 1024; i++) {
+            mixbuf[i * 6 + 0] = ac->che_cpe[0]->ch[0].ret[i];
+            mixbuf[i * 6 + 1] = ac->che_cpe[0]->ch[1].ret[i];
+            mixbuf[i * 6 + 2] = ac->che_sce[0]->ret[i];
+            mixbuf[i * 6 + 3] = ac->che_lfe[0]->ret[i];
+            mixbuf[i * 6 + 4] = ac->che_cpe[1]->ch[0].ret[i];
+            mixbuf[i * 6 + 5] = ac->che_cpe[1]->ch[1].ret[i];
+        }
+        break;
+    }
+
+
+    ac->dsp.float_to_int16(data, src, 1024 * ac->ochannels);
+    av_free(mixbuf);
+    *data_size = size;
+}
+
+
+/**
+ * Decode an AAC frame
+ */
+static int aac_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+                            uint8_t * buf, int buf_size)
+{
+    AACContext * ac = avctx->priv_data;
+    GetBitContext * gb = &ac->gb;
+    int id, cnt, err;
+
+    init_get_bits(gb, buf, buf_size * 8);
+
+    while((id = get_bits(gb, 3)) != ID_END) {
+        err = 0;
+        switch (id) {
+        case ID_SCE:
+            err = single_channel_element(ac, gb);
+            break;
+
+        case ID_CPE:
+            err = channel_pair_element(ac, gb);
+            break;
+
+        case ID_FIL:
+            cnt = get_bits(gb, 4);
+            if(cnt == 15)
+                cnt += get_bits(gb, 8) - 1;
+            skip_bits(gb, 8 * cnt);
+            break;
+
+        case ID_DSE:
+            err = data_stream_element(ac, gb);
+            break;
+
+        case ID_LFE:
+            err = lfe_channel_element(ac, gb);
+            break;
+
+        default:
+            av_log(avctx, AV_LOG_ERROR, "Unhandled id %d\n", id);
+            err = 1;
+            break;
+        }
+        if(err)
+            return buf_size;
+    }
+
+    transform_sce_tool(ac, tns_trans);
+    transform_sce_tool(ac, window_trans);
+
+    ac->num_frame++;
+    output_samples(ac, avctx, data, data_size);
+    return buf_size;
+}
+
+
+/**
+ * Decoder close
+ */
+static int aac_decode_close(AVCodecContext *avctx)
+{
+    AACContext *ac = avctx->priv_data;
+    int i;
+
+    for(i = 0; i < MAX_TAGID; i++) {
+        av_free(ac->che_sce[i]);
+        av_free(ac->che_cpe[i]);
+        av_free(ac->che_lfe[i]);
+        av_free(ac->che_cce[i]);
+    }
+
+    for(i = 0; i < 11; i++) {
+        free_vlc(&ac->books[i]);
+        av_free(ac->vq[i]);
+    }
+    free_vlc(&ac->mainvlc);
+    ff_mdct_end(&ac->mdct);
+    ff_mdct_end(&ac->mdct_small);
+    return 0;
+}
+
+
+
+AVCodec aac_decoder = {
+    "aac",
+    CODEC_TYPE_AUDIO,
+    CODEC_ID_AAC,
+    sizeof(AACContext),
+    aac_decode_init,
+    NULL,
+    aac_decode_close,
+    aac_decode_frame,
+};

Added: aaclc/aactab.c
==============================================================================
--- (empty file)
+++ aaclc/aactab.c	Fri Dec  7 16:10:55 2007
@@ -0,0 +1,676 @@
+/*
+ * AAC (LC) decoder
+ * This code is developed as part of Google Summer of Code 2006 Program.
+ *
+ * Copyright (c) 2005 Oded Shimon( ods15 ods15 dyndns org )
+ * Copyright (c) 2005-2006 Maxim Gavrilov ( maxim.gavrilov gmail com )
+ * Copyright (c) 2007 Andreas Öman ( andreas lonelycoder com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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
+ */
+
+/*
+ * The reference: -statements refers to the ISO/IEC 14496-3 specification
+ */
+
+#include "aactab.h"
+#include "aac.h"
+
+/**
+ * samplingFrequencyIndex
+ * Reference: Table 1.16
+ */
+const int aac_sample_rates[16] = {
+    96000, 88200, 64000, 48000, 44100, 32000,
+    24000, 22050, 16000, 12000, 11025, 8000, 7350
+};
+
+// scalefactor bands
+static const uint16_t swb_offset_1024_96[] = {
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56,
+    64, 72, 80, 88, 96, 108, 120, 132, 144, 156, 172, 188, 212, 240,
+    276, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024
+};
+
+static const uint16_t swb_offset_128_96[] = {
+    0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
+};
+
+static const uint16_t swb_offset_1024_64[] = {
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56,
+    64, 72, 80, 88, 100, 112, 124, 140, 156, 172, 192, 216, 240, 268,
+    304, 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, 744, 784, 824,
+    864, 904, 944, 984, 1024
+};
+
+static const uint16_t swb_offset_128_64[] = {
+    0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
+};
+
+
+static const uint16_t swb_offset_1024_48[] = {
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72,
+    80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292,
+    320, 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, 672, 704, 736,
+    768, 800, 832, 864, 896, 928, 1024
+};
+
+static const uint16_t swb_offset_128_48[] = {
+    0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128
+};
+
+static const uint16_t swb_offset_1024_32[] = {
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72,
+    80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292,
+    320, 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, 672, 704, 736,
+    768, 800, 832, 864, 896, 928, 960, 992, 1024
+};
+
+
+static const uint16_t swb_offset_1024_24[] = {
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68,
+    76, 84, 92, 100, 108, 116, 124, 136, 148, 160, 172, 188, 204, 220,
+    240, 260, 284, 308, 336, 364, 396, 432, 468, 508, 552, 600, 652, 704,
+    768, 832, 896, 960, 1024
+};
+
+static const uint16_t swb_offset_128_24[] = {
+    0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128
+};
+
+static const uint16_t swb_offset_1024_16[] = {
+    0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 100, 112, 124,
+    136, 148, 160, 172, 184, 196, 212, 228, 244, 260, 280, 300, 320, 344,
+    368, 396, 424, 456, 492, 532, 572, 616, 664, 716, 772, 832, 896, 960, 1024
+};
+
+static const uint16_t swb_offset_128_16[] = {
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 128
+};
+
+static const uint16_t swb_offset_1024_8[] = {
+    0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 172,
+    188, 204, 220, 236, 252, 268, 288, 308, 328, 348, 372, 396, 420, 448,
+    476, 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, 1024
+};
+
+static const uint16_t swb_offset_128_8[] = {
+    0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 128
+};
+
+const uint16_t *aac_swb_offset_1024[12] = {
+    swb_offset_1024_96, swb_offset_1024_96, swb_offset_1024_64,
+    swb_offset_1024_48, swb_offset_1024_48, swb_offset_1024_32,
+    swb_offset_1024_24, swb_offset_1024_24, swb_offset_1024_16,
+    swb_offset_1024_16, swb_offset_1024_16, swb_offset_1024_8
+};
+
+const uint8_t aac_num_swb_1024[12] = {
+    41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40
+};
+
+const uint16_t *aac_swb_offset_128[12] = {
+    swb_offset_128_96, swb_offset_128_96, swb_offset_128_64,
+    swb_offset_128_48, swb_offset_128_48, swb_offset_128_48,
+    swb_offset_128_24, swb_offset_128_24, swb_offset_128_16,
+    swb_offset_128_16, swb_offset_128_16, swb_offset_128_8
+};
+
+const uint8_t aac_num_swb_128[12] = {
+    12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15
+};
+
+
+// TNS tables
+const uint8_t aac_tns_max_bands_1024[12] = {
+    31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39
+};
+
+const uint8_t aac_tns_max_bands_128[12] = {
+    9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14
+};
+
+static const float tns_coeffs_map_1_3[TNS_MAX_ORDER] = {
+    0.00000000,    0.43388373, -0.64278758, -0.34202015,
+    0.97492790, 0.78183150, -0.64278758, -0.34202015,
+    -0.43388373, -0.78183150, -0.64278758, -0.34202015,
+    -0.78183150, -0.43388373, -0.64278758, -0.34202015,
+    0.78183150, 0.97492790, -0.64278758, -0.34202015
+};
+
+static const float tns_coeffs_map_0_3[TNS_MAX_ORDER] = {
+    0.00000000, 0.43388373, 0.78183150, 0.97492790,
+    -0.98480773, -0.86602539, -0.64278758, -0.34202015,
+    -0.43388373, -0.78183150, -0.97492790, -0.97492790,
+    -0.98480773, -0.86602539, -0.64278758, -0.34202015,
+    0.78183150, 0.97492790, 0.97492790, 0.78183150
+};
+
+static const float tns_coeffs_map_1_4[TNS_MAX_ORDER] = {
+    0.00000000, 0.20791170, 0.40673664, 0.58778524,
+    -0.67369562, -0.52643216, -0.36124167, -0.18374951,
+    0.99452192, 0.95105648, 0.86602539, 0.74314481,
+    -0.67369562, -0.52643216, -0.36124167, -0.18374951,
+    -0.20791176, -0.40673670, -0.58778530, -0.74314487
+};
+
+static const float tns_coeffs_map_0_4[TNS_MAX_ORDER] = {
+    0.00000000, 0.20791170, 0.40673664, 0.58778524,
+    0.74314481, 0.86602539, 0.95105654, 0.99452192,
+    -0.99573416, -0.96182561, -0.89516330, -0.79801720,
+    -0.67369562, -0.52643216, -0.36124167, -0.18374951,
+    -0.20791176, -0.40673670, -0.58778530, -0.74314487
+};
+
+const float *aac_tns_coeffs_table[4] = {
+    tns_coeffs_map_0_3,
+    tns_coeffs_map_0_4,
+    tns_coeffs_map_1_3,
+    tns_coeffs_map_1_4
+};
+
+// Huffman tables
+const unsigned int aac_scalefactor_huffman_table[121][2] = {
+    /* codeword, code length */
+    { 0x3FFE8, 18 },
+    { 0x3FFE6, 18 },
+    { 0x3FFE7, 18 },
+    { 0x3FFE5, 18 },
+    { 0x7FFF5, 19 },
+    { 0x7FFF1, 19 },
+    { 0x7FFED, 19 },
+    { 0x7FFF6, 19 },
+    { 0x7FFEE, 19 },
+    { 0x7FFEF, 19 },
+    { 0x7FFF0, 19 },
+    { 0x7FFFC, 19 },
+    { 0x7FFFD, 19 },
+    { 0x7FFFF, 19 },
+    { 0x7FFFE, 19 },
+    { 0x7FFF7, 19 },
+    { 0x7FFF8, 19 },
+    { 0x7FFFB, 19 },
+    { 0x7FFF9, 19 },
+    { 0x3FFE4, 18 },
+    { 0x7FFFA, 19 },
+    { 0x3FFE3, 18 },
+    { 0x1FFEF, 17 },
+    { 0x1FFF0, 17 },
+    {  0xFFF5, 16 },
+    { 0x1FFEE, 17 },
+    {  0xFFF2, 16 },
+    {  0xFFF3, 16 },
+    {  0xFFF4, 16 },
+    {  0xFFF1, 16 },
+    {  0x7FF6, 15 },
+    {  0x7FF7, 15 },
+    {  0x3FF9, 14 },
+    {  0x3FF5, 14 },
+    {  0x3FF7, 14 },
+    {  0x3FF3, 14 },
+    {  0x3FF6, 14 },
+    {  0x3FF2, 14 },
+    {  0x1FF7, 13 },
+    {  0x1FF5, 13 },
+    {   0xFF9, 12 },
+    {   0xFF7, 12 },
+    {   0xFF6, 12 },
+    {   0x7F9, 11 },
+    {   0xFF4, 12 },
+    {   0x7F8, 11 },
+    {   0x3F9, 10 },
+    {   0x3F7, 10 },
+    {   0x3F5, 10 },
+    {   0x1F8,  9 },
+    {   0x1F7,  9 },
+    {    0xFA,  8 },
+    {    0xF8,  8 },
+    {    0xF6,  8 },
+    {    0x79,  7 },
+    {    0x3A,  6 },
+    {    0x38,  6 },
+    {    0x1A,  5 },
+    {     0xB,  4 },
+    {     0x4,  3 },
+    {     0x0,  1 },
+    {     0xA,  4 },
+    {     0xC,  4 },
+    {    0x1B,  5 },
+    {    0x39,  6 },
+    {    0x3B,  6 },
+    {    0x78,  7 },
+    {    0x7A,  7 },
+    {    0xF7,  8 },
+    {    0xF9,  8 },
+    {   0x1F6,  9 },
+    {   0x1F9,  9 },
+    {   0x3F4, 10 },
+    {   0x3F6, 10 },
+    {   0x3F8, 10 },
+    {   0x7F5, 11 },
+    {   0x7F4, 11 },
+    {   0x7F6, 11 },
+    {   0x7F7, 11 },
+    {   0xFF5, 12 },
+    {   0xFF8, 12 },
+    {  0x1FF4, 13 },
+    {  0x1FF6, 13 },
+    {  0x1FF8, 13 },
+    {  0x3FF8, 14 },
+    {  0x3FF4, 14 },
+    {  0xFFF0, 16 },
+    {  0x7FF4, 15 },
+    {  0xFFF6, 16 },
+    {  0x7FF5, 15 },
+    { 0x3FFE2, 18 },
+    { 0x7FFD9, 19 },
+    { 0x7FFDA, 19 },
+    { 0x7FFDB, 19 },
+    { 0x7FFDC, 19 },
+    { 0x7FFDD, 19 },
+    { 0x7FFDE, 19 },
+    { 0x7FFD8, 19 },
+    { 0x7FFD2, 19 },
+    { 0x7FFD3, 19 },
+    { 0x7FFD4, 19 },
+    { 0x7FFD5, 19 },
+    { 0x7FFD6, 19 },
+    { 0x7FFF2, 19 },
+    { 0x7FFDF, 19 },
+    { 0x7FFE7, 19 },
+    { 0x7FFE8, 19 },
+    { 0x7FFE9, 19 },
+    { 0x7FFEA, 19 },
+    { 0x7FFEB, 19 },
+    { 0x7FFE6, 19 },
+    { 0x7FFE0, 19 },
+    { 0x7FFE1, 19 },
+    { 0x7FFE2, 19 },
+    { 0x7FFE3, 19 },
+    { 0x7FFE4, 19 },
+    { 0x7FFE5, 19 },
+    { 0x7FFD7, 19 },
+    { 0x7FFEC, 19 },
+    { 0x7FFF4, 19 },
+    { 0x7FFF3, 19 },
+};
+
+static const uint16_t codebook1[][2] = {
+    {   0x7F8, 11 },
+    {   0x1F1,  9 }, {   0x7FD, 11 }, {   0x3F5, 10 }, {    0x68,  7 },
+    {   0x3F0, 10 }, {   0x7F7, 11 }, {   0x1EC,  9 }, {   0x7F5, 11 },
+    {   0x3F1, 10 }, {    0x72,  7 }, {   0x3F4, 10 }, {    0x74,  7 },
+    {    0x11,  5 }, {    0x76,  7 }, {   0x1EB,  9 }, {    0x6C,  7 },
+    {   0x3F6, 10 }, {   0x7FC, 11 }, {   0x1E1,  9 }, {   0x7F1, 11 },
+    {   0x1F0,  9 }, {    0x61,  7 }, {   0x1F6,  9 }, {   0x7F2, 11 },
+    {   0x1EA,  9 }, {   0x7FB, 11 }, {   0x1F2,  9 }, {    0x69,  7 },
+    {   0x1ED,  9 }, {    0x77,  7 }, {    0x17,  5 }, {    0x6F,  7 },
+    {   0x1E6,  9 }, {    0x64,  7 }, {   0x1E5,  9 }, {    0x67,  7 },
+    {    0x15,  5 }, {    0x62,  7 }, {    0x12,  5 }, {     0x0,  1 },
+    {    0x14,  5 }, {    0x65,  7 }, {    0x16,  5 }, {    0x6D,  7 },
+    {   0x1E9,  9 }, {    0x63,  7 }, {   0x1E4,  9 }, {    0x6B,  7 },
+    {    0x13,  5 }, {    0x71,  7 }, {   0x1E3,  9 }, {    0x70,  7 },
+    {   0x1F3,  9 }, {   0x7FE, 11 }, {   0x1E7,  9 }, {   0x7F3, 11 },
+    {   0x1EF,  9 }, {    0x60,  7 }, {   0x1EE,  9 }, {   0x7F0, 11 },
+    {   0x1E2,  9 }, {   0x7FA, 11 }, {   0x3F3, 10 }, {    0x6A,  7 },
+    {   0x1E8,  9 }, {    0x75,  7 }, {    0x10,  5 }, {    0x73,  7 },
+    {   0x1F4,  9 }, {    0x6E,  7 }, {   0x3F7, 10 }, {   0x7F6, 11 },
+    {   0x1E0,  9 }, {   0x7F9, 11 }, {   0x3F2, 10 }, {    0x66,  7 },
+    {   0x1F5,  9 }, {   0x7FF, 11 }, {   0x1F7,  9 }, {   0x7F4, 11 },
+};
+
+static const uint16_t codebook2[][2] = {
+    {   0x1F3,  9 },
+    {    0x6F,  7 }, {   0x1FD,  9 }, {    0xEB,  8 }, {    0x23,  6 },
+    {    0xEA,  8 }, {   0x1F7,  9 }, {    0xE8,  8 }, {   0x1FA,  9 },
+    {    0xF2,  8 }, {    0x2D,  6 }, {    0x70,  7 }, {    0x20,  6 },
+    {     0x6,  5 }, {    0x2B,  6 }, {    0x6E,  7 }, {    0x28,  6 },
+    {    0xE9,  8 }, {   0x1F9,  9 }, {    0x66,  7 }, {    0xF8,  8 },
+    {    0xE7,  8 }, {    0x1B,  6 }, {    0xF1,  8 }, {   0x1F4,  9 },
+    {    0x6B,  7 }, {   0x1F5,  9 }, {    0xEC,  8 }, {    0x2A,  6 },
+    {    0x6C,  7 }, {    0x2C,  6 }, {     0xA,  5 }, {    0x27,  6 },
+    {    0x67,  7 }, {    0x1A,  6 }, {    0xF5,  8 }, {    0x24,  6 },
+    {     0x8,  5 }, {    0x1F,  6 }, {     0x9,  5 }, {     0x0,  3 },
+    {     0x7,  5 }, {    0x1D,  6 }, {     0xB,  5 }, {    0x30,  6 },
+    {    0xEF,  8 }, {    0x1C,  6 }, {    0x64,  7 }, {    0x1E,  6 },
+    {     0xC,  5 }, {    0x29,  6 }, {    0xF3,  8 }, {    0x2F,  6 },
+    {    0xF0,  8 }, {   0x1FC,  9 }, {    0x71,  7 }, {   0x1F2,  9 },
+    {    0xF4,  8 }, {    0x21,  6 }, {    0xE6,  8 }, {    0xF7,  8 },
+    {    0x68,  7 }, {   0x1F8,  9 }, {    0xEE,  8 }, {    0x22,  6 },
+    {    0x65,  7 }, {    0x31,  6 }, {     0x2,  4 }, {    0x26,  6 },
+    {    0xED,  8 }, {    0x25,  6 }, {    0x6A,  7 }, {   0x1FB,  9 },
+    {    0x72,  7 }, {   0x1FE,  9 }, {    0x69,  7 }, {    0x2E,  6 },
+    {    0xF6,  8 }, {   0x1FF,  9 }, {    0x6D,  7 }, {   0x1F6,  9 },
+};
+
+static const uint16_t codebook3[][2] = {
+    {     0x0,  1 },
+    {     0x9,  4 }, {    0xEF,  8 }, {     0xB,  4 }, {    0x19,  5 },
+    {    0xF0,  8 }, {   0x1EB,  9 }, {   0x1E6,  9 }, {   0x3F2, 10 },
+    {     0xA,  4 }, {    0x35,  6 }, {   0x1EF,  9 }, {    0x34,  6 },
+    {    0x37,  6 }, {   0x1E9,  9 }, {   0x1ED,  9 }, {   0x1E7,  9 },
+    {   0x3F3, 10 }, {   0x1EE,  9 }, {   0x3ED, 10 }, {  0x1FFA, 13 },
+    {   0x1EC,  9 }, {   0x1F2,  9 }, {   0x7F9, 11 }, {   0x7F8, 11 },
+    {   0x3F8, 10 }, {   0xFF8, 12 }, {     0x8,  4 }, {    0x38,  6 },
+    {   0x3F6, 10 }, {    0x36,  6 }, {    0x75,  7 }, {   0x3F1, 10 },
+    {   0x3EB, 10 }, {   0x3EC, 10 }, {   0xFF4, 12 }, {    0x18,  5 },
+    {    0x76,  7 }, {   0x7F4, 11 }, {    0x39,  6 }, {    0x74,  7 },
+    {   0x3EF, 10 }, {   0x1F3,  9 }, {   0x1F4,  9 }, {   0x7F6, 11 },
+    {   0x1E8,  9 }, {   0x3EA, 10 }, {  0x1FFC, 13 }, {    0xF2,  8 },
+    {   0x1F1,  9 }, {   0xFFB, 12 }, {   0x3F5, 10 }, {   0x7F3, 11 },
+    {   0xFFC, 12 }, {    0xEE,  8 }, {   0x3F7, 10 }, {  0x7FFE, 15 },
+    {   0x1F0,  9 }, {   0x7F5, 11 }, {  0x7FFD, 15 }, {  0x1FFB, 13 },
+    {  0x3FFA, 14 }, {  0xFFFF, 16 }, {    0xF1,  8 }, {   0x3F0, 10 },
+    {  0x3FFC, 14 }, {   0x1EA,  9 }, {   0x3EE, 10 }, {  0x3FFB, 14 },
+    {   0xFF6, 12 }, {   0xFFA, 12 }, {  0x7FFC, 15 }, {   0x7F2, 11 },
+    {   0xFF5, 12 }, {  0xFFFE, 16 }, {   0x3F4, 10 }, {   0x7F7, 11 },
+    {  0x7FFB, 15 }, {   0xFF7, 12 }, {   0xFF9, 12 }, {  0x7FFA, 15 },
+};
+
+static const uint16_t codebook4[][2] = {
+    {     0x7,  4 },
+    {    0x16,  5 }, {    0xF6,  8 }, {    0x18,  5 }, {     0x8,  4 },
+    {    0xEF,  8 }, {   0x1EF,  9 }, {    0xF3,  8 }, {   0x7F8, 11 },
+    {    0x19,  5 }, {    0x17,  5 }, {    0xED,  8 }, {    0x15,  5 },
+    {     0x1,  4 }, {    0xE2,  8 }, {    0xF0,  8 }, {    0x70,  7 },
+    {   0x3F0, 10 }, {   0x1EE,  9 }, {    0xF1,  8 }, {   0x7FA, 11 },
+    {    0xEE,  8 }, {    0xE4,  8 }, {   0x3F2, 10 }, {   0x7F6, 11 },
+    {   0x3EF, 10 }, {   0x7FD, 11 }, {     0x5,  4 }, {    0x14,  5 },
+    {    0xF2,  8 }, {     0x9,  4 }, {     0x4,  4 }, {    0xE5,  8 },
+    {    0xF4,  8 }, {    0xE8,  8 }, {   0x3F4, 10 }, {     0x6,  4 },
+    {     0x2,  4 }, {    0xE7,  8 }, {     0x3,  4 }, {     0x0,  4 },
+    {    0x6B,  7 }, {    0xE3,  8 }, {    0x69,  7 }, {   0x1F3,  9 },
+    {    0xEB,  8 }, {    0xE6,  8 }, {   0x3F6, 10 }, {    0x6E,  7 },
+    {    0x6A,  7 }, {   0x1F4,  9 }, {   0x3EC, 10 }, {   0x1F0,  9 },
+    {   0x3F9, 10 }, {    0xF5,  8 }, {    0xEC,  8 }, {   0x7FB, 11 },
+    {    0xEA,  8 }, {    0x6F,  7 }, {   0x3F7, 10 }, {   0x7F9, 11 },
+    {   0x3F3, 10 }, {   0xFFF, 12 }, {    0xE9,  8 }, {    0x6D,  7 },
+    {   0x3F8, 10 }, {    0x6C,  7 }, {    0x68,  7 }, {   0x1F5,  9 },
+    {   0x3EE, 10 }, {   0x1F2,  9 }, {   0x7F4, 11 }, {   0x7F7, 11 },
+    {   0x3F1, 10 }, {   0xFFE, 12 }, {   0x3ED, 10 }, {   0x1F1,  9 },
+    {   0x7F5, 11 }, {   0x7FE, 11 }, {   0x3F5, 10 }, {   0x7FC, 11 },
+};
+
+static const uint16_t codebook5[][2] = {
+    {  0x1FFF, 13 },
+    {   0xFF7, 12 }, {   0x7F4, 11 }, {   0x7E8, 11 }, {   0x3F1, 10 },
+    {   0x7EE, 11 }, {   0x7F9, 11 }, {   0xFF8, 12 }, {  0x1FFD, 13 },
+    {   0xFFD, 12 }, {   0x7F1, 11 }, {   0x3E8, 10 }, {   0x1E8,  9 },
+    {    0xF0,  8 }, {   0x1EC,  9 }, {   0x3EE, 10 }, {   0x7F2, 11 },
+    {   0xFFA, 12 }, {   0xFF4, 12 }, {   0x3EF, 10 }, {   0x1F2,  9 },
+    {    0xE8,  8 }, {    0x70,  7 }, {    0xEC,  8 }, {   0x1F0,  9 },
+    {   0x3EA, 10 }, {   0x7F3, 11 }, {   0x7EB, 11 }, {   0x1EB,  9 },
+    {    0xEA,  8 }, {    0x1A,  5 }, {     0x8,  4 }, {    0x19,  5 },
+    {    0xEE,  8 }, {   0x1EF,  9 }, {   0x7ED, 11 }, {   0x3F0, 10 },
+    {    0xF2,  8 }, {    0x73,  7 }, {     0xB,  4 }, {     0x0,  1 },
+    {     0xA,  4 }, {    0x71,  7 }, {    0xF3,  8 }, {   0x7E9, 11 },
+    {   0x7EF, 11 }, {   0x1EE,  9 }, {    0xEF,  8 }, {    0x18,  5 },
+    {     0x9,  4 }, {    0x1B,  5 }, {    0xEB,  8 }, {   0x1E9,  9 },
+    {   0x7EC, 11 }, {   0x7F6, 11 }, {   0x3EB, 10 }, {   0x1F3,  9 },
+    {    0xED,  8 }, {    0x72,  7 }, {    0xE9,  8 }, {   0x1F1,  9 },
+    {   0x3ED, 10 }, {   0x7F7, 11 }, {   0xFF6, 12 }, {   0x7F0, 11 },
+    {   0x3E9, 10 }, {   0x1ED,  9 }, {    0xF1,  8 }, {   0x1EA,  9 },
+    {   0x3EC, 10 }, {   0x7F8, 11 }, {   0xFF9, 12 }, {  0x1FFC, 13 },
+    {   0xFFC, 12 }, {   0xFF5, 12 }, {   0x7EA, 11 }, {   0x3F3, 10 },
+    {   0x3F2, 10 }, {   0x7F5, 11 }, {   0xFFB, 12 }, {  0x1FFE, 13 },
+};
+
+static const uint16_t codebook6[][2] = {
+    {   0x7FE, 11 },
+    {   0x3FD, 10 }, {   0x1F1,  9 }, {   0x1EB,  9 }, {   0x1F4,  9 },
+    {   0x1EA,  9 }, {   0x1F0,  9 }, {   0x3FC, 10 }, {   0x7FD, 11 },
+    {   0x3F6, 10 }, {   0x1E5,  9 }, {    0xEA,  8 }, {    0x6C,  7 },
+    {    0x71,  7 }, {    0x68,  7 }, {    0xF0,  8 }, {   0x1E6,  9 },
+    {   0x3F7, 10 }, {   0x1F3,  9 }, {    0xEF,  8 }, {    0x32,  6 },
+    {    0x27,  6 }, {    0x28,  6 }, {    0x26,  6 }, {    0x31,  6 },
+    {    0xEB,  8 }, {   0x1F7,  9 }, {   0x1E8,  9 }, {    0x6F,  7 },
+    {    0x2E,  6 }, {     0x8,  4 }, {     0x4,  4 }, {     0x6,  4 },
+    {    0x29,  6 }, {    0x6B,  7 }, {   0x1EE,  9 }, {   0x1EF,  9 },
+    {    0x72,  7 }, {    0x2D,  6 }, {     0x2,  4 }, {     0x0,  4 },
+    {     0x3,  4 }, {    0x2F,  6 }, {    0x73,  7 }, {   0x1FA,  9 },
+    {   0x1E7,  9 }, {    0x6E,  7 }, {    0x2B,  6 }, {     0x7,  4 },
+    {     0x1,  4 }, {     0x5,  4 }, {    0x2C,  6 }, {    0x6D,  7 },
+    {   0x1EC,  9 }, {   0x1F9,  9 }, {    0xEE,  8 }, {    0x30,  6 },
+    {    0x24,  6 }, {    0x2A,  6 }, {    0x25,  6 }, {    0x33,  6 },
+    {    0xEC,  8 }, {   0x1F2,  9 }, {   0x3F8, 10 }, {   0x1E4,  9 },
+    {    0xED,  8 }, {    0x6A,  7 }, {    0x70,  7 }, {    0x69,  7 },
+    {    0x74,  7 }, {    0xF1,  8 }, {   0x3FA, 10 }, {   0x7FF, 11 },
+    {   0x3F9, 10 }, {   0x1F6,  9 }, {   0x1ED,  9 }, {   0x1F8,  9 },
+    {   0x1E9,  9 }, {   0x1F5,  9 }, {   0x3FB, 10 }, {   0x7FC, 11 },
+};
+
+static const uint16_t codebook7[][2] = {
+    {     0x0,  1 },
+    {     0x5,  3 }, {    0x37,  6 }, {    0x74,  7 }, {    0xF2,  8 },
+    {   0x1EB,  9 }, {   0x3ED, 10 }, {   0x7F7, 11 }, {     0x4,  3 },
+    {     0xC,  4 }, {    0x35,  6 }, {    0x71,  7 }, {    0xEC,  8 },
+    {    0xEE,  8 }, {   0x1EE,  9 }, {   0x1F5,  9 }, {    0x36,  6 },
+    {    0x34,  6 }, {    0x72,  7 }, {    0xEA,  8 }, {    0xF1,  8 },
+    {   0x1E9,  9 }, {   0x1F3,  9 }, {   0x3F5, 10 }, {    0x73,  7 },
+    {    0x70,  7 }, {    0xEB,  8 }, {    0xF0,  8 }, {   0x1F1,  9 },
+    {   0x1F0,  9 }, {   0x3EC, 10 }, {   0x3FA, 10 }, {    0xF3,  8 },
+    {    0xED,  8 }, {   0x1E8,  9 }, {   0x1EF,  9 }, {   0x3EF, 10 },
+    {   0x3F1, 10 }, {   0x3F9, 10 }, {   0x7FB, 11 }, {   0x1ED,  9 },
+    {    0xEF,  8 }, {   0x1EA,  9 }, {   0x1F2,  9 }, {   0x3F3, 10 },
+    {   0x3F8, 10 }, {   0x7F9, 11 }, {   0x7FC, 11 }, {   0x3EE, 10 },
+    {   0x1EC,  9 }, {   0x1F4,  9 }, {   0x3F4, 10 }, {   0x3F7, 10 },
+    {   0x7F8, 11 }, {   0xFFD, 12 }, {   0xFFE, 12 }, {   0x7F6, 11 },
+    {   0x3F0, 10 }, {   0x3F2, 10 }, {   0x3F6, 10 }, {   0x7FA, 11 },
+    {   0x7FD, 11 }, {   0xFFC, 12 }, {   0xFFF, 12 },
+};
+
+static const uint16_t codebook8[][2] = {
+    {     0xE,  5 },
+    {     0x5,  4 }, {    0x10,  5 }, {    0x30,  6 }, {    0x6F,  7 },
+    {    0xF1,  8 }, {   0x1FA,  9 }, {   0x3FE, 10 }, {     0x3,  4 },
+    {     0x0,  3 }, {     0x4,  4 }, {    0x12,  5 }, {    0x2C,  6 },
+    {    0x6A,  7 }, {    0x75,  7 }, {    0xF8,  8 }, {     0xF,  5 },
+    {     0x2,  4 }, {     0x6,  4 }, {    0x14,  5 }, {    0x2E,  6 },
+    {    0x69,  7 }, {    0x72,  7 }, {    0xF5,  8 }, {    0x2F,  6 },
+    {    0x11,  5 }, {    0x13,  5 }, {    0x2A,  6 }, {    0x32,  6 },
+    {    0x6C,  7 }, {    0xEC,  8 }, {    0xFA,  8 }, {    0x71,  7 },
+    {    0x2B,  6 }, {    0x2D,  6 }, {    0x31,  6 }, {    0x6D,  7 },
+    {    0x70,  7 }, {    0xF2,  8 }, {   0x1F9,  9 }, {    0xEF,  8 },
+    {    0x68,  7 }, {    0x33,  6 }, {    0x6B,  7 }, {    0x6E,  7 },
+    {    0xEE,  8 }, {    0xF9,  8 }, {   0x3FC, 10 }, {   0x1F8,  9 },
+    {    0x74,  7 }, {    0x73,  7 }, {    0xED,  8 }, {    0xF0,  8 },
+    {    0xF6,  8 }, {   0x1F6,  9 }, {   0x1FD,  9 }, {   0x3FD, 10 },
+    {    0xF3,  8 }, {    0xF4,  8 }, {    0xF7,  8 }, {   0x1F7,  9 },
+    {   0x1FB,  9 }, {   0x1FC,  9 }, {   0x3FF, 10 },
+};
+
+static const uint16_t codebook9[][2] = {
+    {     0x0,  1 },
+    {     0x5,  3 }, {    0x37,  6 }, {    0xE7,  8 }, {   0x1DE,  9 },
+    {   0x3CE, 10 }, {   0x3D9, 10 }, {   0x7C8, 11 }, {   0x7CD, 11 },
+    {   0xFC8, 12 }, {   0xFDD, 12 }, {  0x1FE4, 13 }, {  0x1FEC, 13 },
+    {     0x4,  3 }, {     0xC,  4 }, {    0x35,  6 }, {    0x72,  7 },
+    {    0xEA,  8 }, {    0xED,  8 }, {   0x1E2,  9 }, {   0x3D1, 10 },
+    {   0x3D3, 10 }, {   0x3E0, 10 }, {   0x7D8, 11 }, {   0xFCF, 12 },
+    {   0xFD5, 12 }, {    0x36,  6 }, {    0x34,  6 }, {    0x71,  7 },
+    {    0xE8,  8 }, {    0xEC,  8 }, {   0x1E1,  9 }, {   0x3CF, 10 },
+    {   0x3DD, 10 }, {   0x3DB, 10 }, {   0x7D0, 11 }, {   0xFC7, 12 },
+    {   0xFD4, 12 }, {   0xFE4, 12 }, {    0xE6,  8 }, {    0x70,  7 },
+    {    0xE9,  8 }, {   0x1DD,  9 }, {   0x1E3,  9 }, {   0x3D2, 10 },
+    {   0x3DC, 10 }, {   0x7CC, 11 }, {   0x7CA, 11 }, {   0x7DE, 11 },
+    {   0xFD8, 12 }, {   0xFEA, 12 }, {  0x1FDB, 13 }, {   0x1DF,  9 },
+    {    0xEB,  8 }, {   0x1DC,  9 }, {   0x1E6,  9 }, {   0x3D5, 10 },
+    {   0x3DE, 10 }, {   0x7CB, 11 }, {   0x7DD, 11 }, {   0x7DC, 11 },
+    {   0xFCD, 12 }, {   0xFE2, 12 }, {   0xFE7, 12 }, {  0x1FE1, 13 },
+    {   0x3D0, 10 }, {   0x1E0,  9 }, {   0x1E4,  9 }, {   0x3D6, 10 },
+    {   0x7C5, 11 }, {   0x7D1, 11 }, {   0x7DB, 11 }, {   0xFD2, 12 },
+    {   0x7E0, 11 }, {   0xFD9, 12 }, {   0xFEB, 12 }, {  0x1FE3, 13 },
+    {  0x1FE9, 13 }, {   0x7C4, 11 }, {   0x1E5,  9 }, {   0x3D7, 10 },
+    {   0x7C6, 11 }, {   0x7CF, 11 }, {   0x7DA, 11 }, {   0xFCB, 12 },
+    {   0xFDA, 12 }, {   0xFE3, 12 }, {   0xFE9, 12 }, {  0x1FE6, 13 },
+    {  0x1FF3, 13 }, {  0x1FF7, 13 }, {   0x7D3, 11 }, {   0x3D8, 10 },
+    {   0x3E1, 10 }, {   0x7D4, 11 }, {   0x7D9, 11 }, {   0xFD3, 12 },
+    {   0xFDE, 12 }, {  0x1FDD, 13 }, {  0x1FD9, 13 }, {  0x1FE2, 13 },
+    {  0x1FEA, 13 }, {  0x1FF1, 13 }, {  0x1FF6, 13 }, {   0x7D2, 11 },
+    {   0x3D4, 10 }, {   0x3DA, 10 }, {   0x7C7, 11 }, {   0x7D7, 11 },
+    {   0x7E2, 11 }, {   0xFCE, 12 }, {   0xFDB, 12 }, {  0x1FD8, 13 },
+    {  0x1FEE, 13 }, {  0x3FF0, 14 }, {  0x1FF4, 13 }, {  0x3FF2, 14 },
+    {   0x7E1, 11 }, {   0x3DF, 10 }, {   0x7C9, 11 }, {   0x7D6, 11 },
+    {   0xFCA, 12 }, {   0xFD0, 12 }, {   0xFE5, 12 }, {   0xFE6, 12 },
+    {  0x1FEB, 13 }, {  0x1FEF, 13 }, {  0x3FF3, 14 }, {  0x3FF4, 14 },
+    {  0x3FF5, 14 }, {   0xFE0, 12 }, {   0x7CE, 11 }, {   0x7D5, 11 },
+    {   0xFC6, 12 }, {   0xFD1, 12 }, {   0xFE1, 12 }, {  0x1FE0, 13 },
+    {  0x1FE8, 13 }, {  0x1FF0, 13 }, {  0x3FF1, 14 }, {  0x3FF8, 14 },
+    {  0x3FF6, 14 }, {  0x7FFC, 15 }, {   0xFE8, 12 }, {   0x7DF, 11 },
+    {   0xFC9, 12 }, {   0xFD7, 12 }, {   0xFDC, 12 }, {  0x1FDC, 13 },
+    {  0x1FDF, 13 }, {  0x1FED, 13 }, {  0x1FF5, 13 }, {  0x3FF9, 14 },
+    {  0x3FFB, 14 }, {  0x7FFD, 15 }, {  0x7FFE, 15 }, {  0x1FE7, 13 },
+    {   0xFCC, 12 }, {   0xFD6, 12 }, {   0xFDF, 12 }, {  0x1FDE, 13 },
+    {  0x1FDA, 13 }, {  0x1FE5, 13 }, {  0x1FF2, 13 }, {  0x3FFA, 14 },
+    {  0x3FF7, 14 }, {  0x3FFC, 14 }, {  0x3FFD, 14 }, {  0x7FFF, 15 },
+};
+
+static const uint16_t codebook10[][2] = {
+    {    0x22,  6 },
+    {     0x8,  5 }, {    0x1D,  6 }, {    0x26,  6 }, {    0x5F,  7 },
+    {    0xD3,  8 }, {   0x1CF,  9 }, {   0x3D0, 10 }, {   0x3D7, 10 },
+    {   0x3ED, 10 }, {   0x7F0, 11 }, {   0x7F6, 11 }, {   0xFFD, 12 },
+    {     0x7,  5 }, {     0x0,  4 }, {     0x1,  4 }, {     0x9,  5 },
+    {    0x20,  6 }, {    0x54,  7 }, {    0x60,  7 }, {    0xD5,  8 },
+    {    0xDC,  8 }, {   0x1D4,  9 }, {   0x3CD, 10 }, {   0x3DE, 10 },
+    {   0x7E7, 11 }, {    0x1C,  6 }, {     0x2,  4 }, {     0x6,  5 },
+    {     0xC,  5 }, {    0x1E,  6 }, {    0x28,  6 }, {    0x5B,  7 },
+    {    0xCD,  8 }, {    0xD9,  8 }, {   0x1CE,  9 }, {   0x1DC,  9 },
+    {   0x3D9, 10 }, {   0x3F1, 10 }, {    0x25,  6 }, {     0xB,  5 },
+    {     0xA,  5 }, {     0xD,  5 }, {    0x24,  6 }, {    0x57,  7 },
+    {    0x61,  7 }, {    0xCC,  8 }, {    0xDD,  8 }, {   0x1CC,  9 },
+    {   0x1DE,  9 }, {   0x3D3, 10 }, {   0x3E7, 10 }, {    0x5D,  7 },
+    {    0x21,  6 }, {    0x1F,  6 }, {    0x23,  6 }, {    0x27,  6 },
+    {    0x59,  7 }, {    0x64,  7 }, {    0xD8,  8 }, {    0xDF,  8 },
+    {   0x1D2,  9 }, {   0x1E2,  9 }, {   0x3DD, 10 }, {   0x3EE, 10 },
+    {    0xD1,  8 }, {    0x55,  7 }, {    0x29,  6 }, {    0x56,  7 },
+    {    0x58,  7 }, {    0x62,  7 }, {    0xCE,  8 }, {    0xE0,  8 },
+    {    0xE2,  8 }, {   0x1DA,  9 }, {   0x3D4, 10 }, {   0x3E3, 10 },
+    {   0x7EB, 11 }, {   0x1C9,  9 }, {    0x5E,  7 }, {    0x5A,  7 },
+    {    0x5C,  7 }, {    0x63,  7 }, {    0xCA,  8 }, {    0xDA,  8 },
+    {   0x1C7,  9 }, {   0x1CA,  9 }, {   0x1E0,  9 }, {   0x3DB, 10 },
+    {   0x3E8, 10 }, {   0x7EC, 11 }, {   0x1E3,  9 }, {    0xD2,  8 },
+    {    0xCB,  8 }, {    0xD0,  8 }, {    0xD7,  8 }, {    0xDB,  8 },
+    {   0x1C6,  9 }, {   0x1D5,  9 }, {   0x1D8,  9 }, {   0x3CA, 10 },
+    {   0x3DA, 10 }, {   0x7EA, 11 }, {   0x7F1, 11 }, {   0x1E1,  9 },
+    {    0xD4,  8 }, {    0xCF,  8 }, {    0xD6,  8 }, {    0xDE,  8 },
+    {    0xE1,  8 }, {   0x1D0,  9 }, {   0x1D6,  9 }, {   0x3D1, 10 },
+    {   0x3D5, 10 }, {   0x3F2, 10 }, {   0x7EE, 11 }, {   0x7FB, 11 },
+    {   0x3E9, 10 }, {   0x1CD,  9 }, {   0x1C8,  9 }, {   0x1CB,  9 },
+    {   0x1D1,  9 }, {   0x1D7,  9 }, {   0x1DF,  9 }, {   0x3CF, 10 },
+    {   0x3E0, 10 }, {   0x3EF, 10 }, {   0x7E6, 11 }, {   0x7F8, 11 },
+    {   0xFFA, 12 }, {   0x3EB, 10 }, {   0x1DD,  9 }, {   0x1D3,  9 },
+    {   0x1D9,  9 }, {   0x1DB,  9 }, {   0x3D2, 10 }, {   0x3CC, 10 },
+    {   0x3DC, 10 }, {   0x3EA, 10 }, {   0x7ED, 11 }, {   0x7F3, 11 },
+    {   0x7F9, 11 }, {   0xFF9, 12 }, {   0x7F2, 11 }, {   0x3CE, 10 },
+    {   0x1E4,  9 }, {   0x3CB, 10 }, {   0x3D8, 10 }, {   0x3D6, 10 },
+    {   0x3E2, 10 }, {   0x3E5, 10 }, {   0x7E8, 11 }, {   0x7F4, 11 },
+    {   0x7F5, 11 }, {   0x7F7, 11 }, {   0xFFB, 12 }, {   0x7FA, 11 },
+    {   0x3EC, 10 }, {   0x3DF, 10 }, {   0x3E1, 10 }, {   0x3E4, 10 },
+    {   0x3E6, 10 }, {   0x3F0, 10 }, {   0x7E9, 11 }, {   0x7EF, 11 },
+    {   0xFF8, 12 }, {   0xFFE, 12 }, {   0xFFC, 12 }, {   0xFFF, 12 },
+};
+
+static const uint16_t codebook11[][2] = {
+    {     0x0,  4 },
+    {     0x6,  5 }, {    0x19,  6 }, {    0x3D,  7 }, {    0x9C,  8 },
+    {    0xC6,  8 }, {   0x1A7,  9 }, {   0x390, 10 }, {   0x3C2, 10 },
+    {   0x3DF, 10 }, {   0x7E6, 11 }, {   0x7F3, 11 }, {   0xFFB, 12 },
+    {   0x7EC, 11 }, {   0xFFA, 12 }, {   0xFFE, 12 }, {   0x38E, 10 },
+    {     0x5,  5 }, {     0x1,  4 }, {     0x8,  5 }, {    0x14,  6 },
+    {    0x37,  7 }, {    0x42,  7 }, {    0x92,  8 }, {    0xAF,  8 },
+    {   0x191,  9 }, {   0x1A5,  9 }, {   0x1B5,  9 }, {   0x39E, 10 },
+    {   0x3C0, 10 }, {   0x3A2, 10 }, {   0x3CD, 10 }, {   0x7D6, 11 },
+    {    0xAE,  8 }, {    0x17,  6 }, {     0x7,  5 }, {     0x9,  5 },
+    {    0x18,  6 }, {    0x39,  7 }, {    0x40,  7 }, {    0x8E,  8 },
+    {    0xA3,  8 }, {    0xB8,  8 }, {   0x199,  9 }, {   0x1AC,  9 },
+    {   0x1C1,  9 }, {   0x3B1, 10 }, {   0x396, 10 }, {   0x3BE, 10 },
+    {   0x3CA, 10 }, {    0x9D,  8 }, {    0x3C,  7 }, {    0x15,  6 },
+    {    0x16,  6 }, {    0x1A,  6 }, {    0x3B,  7 }, {    0x44,  7 },
+    {    0x91,  8 }, {    0xA5,  8 }, {    0xBE,  8 }, {   0x196,  9 },
+    {   0x1AE,  9 }, {   0x1B9,  9 }, {   0x3A1, 10 }, {   0x391, 10 },
+    {   0x3A5, 10 }, {   0x3D5, 10 }, {    0x94,  8 }, {    0x9A,  8 },
+    {    0x36,  7 }, {    0x38,  7 }, {    0x3A,  7 }, {    0x41,  7 },
+    {    0x8C,  8 }, {    0x9B,  8 }, {    0xB0,  8 }, {    0xC3,  8 },
+    {   0x19E,  9 }, {   0x1AB,  9 }, {   0x1BC,  9 }, {   0x39F, 10 },
+    {   0x38F, 10 }, {   0x3A9, 10 }, {   0x3CF, 10 }, {    0x93,  8 },
+    {    0xBF,  8 }, {    0x3E,  7 }, {    0x3F,  7 }, {    0x43,  7 },
+    {    0x45,  7 }, {    0x9E,  8 }, {    0xA7,  8 }, {    0xB9,  8 },
+    {   0x194,  9 }, {   0x1A2,  9 }, {   0x1BA,  9 }, {   0x1C3,  9 },
+    {   0x3A6, 10 }, {   0x3A7, 10 }, {   0x3BB, 10 }, {   0x3D4, 10 },
+    {    0x9F,  8 }, {   0x1A0,  9 }, {    0x8F,  8 }, {    0x8D,  8 },
+    {    0x90,  8 }, {    0x98,  8 }, {    0xA6,  8 }, {    0xB6,  8 },
+    {    0xC4,  8 }, {   0x19F,  9 }, {   0x1AF,  9 }, {   0x1BF,  9 },
+    {   0x399, 10 }, {   0x3BF, 10 }, {   0x3B4, 10 }, {   0x3C9, 10 },
+    {   0x3E7, 10 }, {    0xA8,  8 }, {   0x1B6,  9 }, {    0xAB,  8 },
+    {    0xA4,  8 }, {    0xAA,  8 }, {    0xB2,  8 }, {    0xC2,  8 },
+    {    0xC5,  8 }, {   0x198,  9 }, {   0x1A4,  9 }, {   0x1B8,  9 },
+    {   0x38C, 10 }, {   0x3A4, 10 }, {   0x3C4, 10 }, {   0x3C6, 10 },
+    {   0x3DD, 10 }, {   0x3E8, 10 }, {    0xAD,  8 }, {   0x3AF, 10 },
+    {   0x192,  9 }, {    0xBD,  8 }, {    0xBC,  8 }, {   0x18E,  9 },
+    {   0x197,  9 }, {   0x19A,  9 }, {   0x1A3,  9 }, {   0x1B1,  9 },
+    {   0x38D, 10 }, {   0x398, 10 }, {   0x3B7, 10 }, {   0x3D3, 10 },
+    {   0x3D1, 10 }, {   0x3DB, 10 }, {   0x7DD, 11 }, {    0xB4,  8 },
+    {   0x3DE, 10 }, {   0x1A9,  9 }, {   0x19B,  9 }, {   0x19C,  9 },
+    {   0x1A1,  9 }, {   0x1AA,  9 }, {   0x1AD,  9 }, {   0x1B3,  9 },
+    {   0x38B, 10 }, {   0x3B2, 10 }, {   0x3B8, 10 }, {   0x3CE, 10 },
+    {   0x3E1, 10 }, {   0x3E0, 10 }, {   0x7D2, 11 }, {   0x7E5, 11 },
+    {    0xB7,  8 }, {   0x7E3, 11 }, {   0x1BB,  9 }, {   0x1A8,  9 },
+    {   0x1A6,  9 }, {   0x1B0,  9 }, {   0x1B2,  9 }, {   0x1B7,  9 },
+    {   0x39B, 10 }, {   0x39A, 10 }, {   0x3BA, 10 }, {   0x3B5, 10 },
+    {   0x3D6, 10 }, {   0x7D7, 11 }, {   0x3E4, 10 }, {   0x7D8, 11 },
+    {   0x7EA, 11 }, {    0xBA,  8 }, {   0x7E8, 11 }, {   0x3A0, 10 },
+    {   0x1BD,  9 }, {   0x1B4,  9 }, {   0x38A, 10 }, {   0x1C4,  9 },
+    {   0x392, 10 }, {   0x3AA, 10 }, {   0x3B0, 10 }, {   0x3BC, 10 },
+    {   0x3D7, 10 }, {   0x7D4, 11 }, {   0x7DC, 11 }, {   0x7DB, 11 },
+    {   0x7D5, 11 }, {   0x7F0, 11 }, {    0xC1,  8 }, {   0x7FB, 11 },
+    {   0x3C8, 10 }, {   0x3A3, 10 }, {   0x395, 10 }, {   0x39D, 10 },
+    {   0x3AC, 10 }, {   0x3AE, 10 }, {   0x3C5, 10 }, {   0x3D8, 10 },
+    {   0x3E2, 10 }, {   0x3E6, 10 }, {   0x7E4, 11 }, {   0x7E7, 11 },
+    {   0x7E0, 11 }, {   0x7E9, 11 }, {   0x7F7, 11 }, {   0x190,  9 },
+    {   0x7F2, 11 }, {   0x393, 10 }, {   0x1BE,  9 }, {   0x1C0,  9 },
+    {   0x394, 10 }, {   0x397, 10 }, {   0x3AD, 10 }, {   0x3C3, 10 },
+    {   0x3C1, 10 }, {   0x3D2, 10 }, {   0x7DA, 11 }, {   0x7D9, 11 },
+    {   0x7DF, 11 }, {   0x7EB, 11 }, {   0x7F4, 11 }, {   0x7FA, 11 },
+    {   0x195,  9 }, {   0x7F8, 11 }, {   0x3BD, 10 }, {   0x39C, 10 },
+    {   0x3AB, 10 }, {   0x3A8, 10 }, {   0x3B3, 10 }, {   0x3B9, 10 },
+    {   0x3D0, 10 }, {   0x3E3, 10 }, {   0x3E5, 10 }, {   0x7E2, 11 },
+    {   0x7DE, 11 }, {   0x7ED, 11 }, {   0x7F1, 11 }, {   0x7F9, 11 },
+    {   0x7FC, 11 }, {   0x193,  9 }, {   0xFFD, 12 }, {   0x3DC, 10 },
+    {   0x3B6, 10 }, {   0x3C7, 10 }, {   0x3CC, 10 }, {   0x3CB, 10 },
+    {   0x3D9, 10 }, {   0x3DA, 10 }, {   0x7D3, 11 }, {   0x7E1, 11 },
+    {   0x7EE, 11 }, {   0x7EF, 11 }, {   0x7F5, 11 }, {   0x7F6, 11 },
+    {   0xFFC, 12 }, {   0xFFF, 12 }, {   0x19D,  9 }, {   0x1C2,  9 },
+    {    0xB5,  8 }, {    0xA1,  8 }, {    0x96,  8 }, {    0x97,  8 },
+    {    0x95,  8 }, {    0x99,  8 }, {    0xA0,  8 }, {    0xA2,  8 },
+    {    0xAC,  8 }, {    0xA9,  8 }, {    0xB1,  8 }, {    0xB3,  8 },
+    {    0xBB,  8 }, {    0xC0,  8 }, {   0x18F,  9 }, {     0x4,  5 },
+};
+
+const aac_codebook aac_codebooks[12] = {
+    { codebook1 , sizeof(codebook1)  },
+    { codebook2 , sizeof(codebook2)  },
+    { codebook3 , sizeof(codebook3)  },
+    { codebook4 , sizeof(codebook4)  },
+    { codebook5 , sizeof(codebook5)  },
+    { codebook6 , sizeof(codebook6)  },
+    { codebook7 , sizeof(codebook7)  },
+    { codebook8 , sizeof(codebook8)  },
+    { codebook9 , sizeof(codebook9)  },
+    { codebook10, sizeof(codebook10) },
+    { codebook11, sizeof(codebook11) },
+};

Added: aaclc/aactab.h
==============================================================================
--- (empty file)
+++ aaclc/aactab.h	Fri Dec  7 16:10:55 2007
@@ -0,0 +1,47 @@
+/*
+ * AAC (LC) decoder
+ * This code is developed as part of Google Summer of Code 2006 Program.
+ *
+ * Copyright (c) 2005 Oded Shimon( ods15 ods15 dyndns org )
+ * Copyright (c) 2005-2006 Maxim Gavrilov ( maxim.gavrilov gmail com )
+ * Copyright (c) 2007 Andreas Öman ( andreas lonelycoder com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 FFMPEG_AACTAB_H
+#define FFMPEG_AACTAB_H
+
+#include "common.h"
+
+typedef struct {
+    const uint16_t (*a)[2];
+    const unsigned int s;
+} aac_codebook;
+
+extern const int          aac_sample_rates[16];
+extern const aac_codebook aac_codebooks[12];
+extern const unsigned int aac_scalefactor_huffman_table[121][2];
+extern const uint16_t    *aac_swb_offset_1024[12];
+extern const uint16_t    *aac_swb_offset_128[12];
+extern const uint8_t      aac_num_swb_1024[12];
+extern const uint8_t      aac_num_swb_128[12];
+extern const uint8_t      aac_tns_max_bands_1024[12];
+extern const uint8_t      aac_tns_max_bands_128[12];
+extern const float       *aac_tns_coeffs_table[4];
+
+#endif /* FFMPEG_AACTAB_H */

Added: aaclc/ffmpeg.patch
==============================================================================
--- (empty file)
+++ aaclc/ffmpeg.patch	Fri Dec  7 16:10:55 2007
@@ -0,0 +1,24 @@
+Index: libavcodec/Makefile
+===================================================================
+--- libavcodec/Makefile	(revision 11186)
++++ libavcodec/Makefile	(working copy)
+@@ -32,6 +32,7 @@
+ 
+ HEADERS = avcodec.h opt.h
+ 
++OBJS-$(CONFIG_AAC_DECODER)             += aacdec.o aactab.o mdct.o fft.o
+ OBJS-$(CONFIG_AASC_DECODER)            += aasc.o
+ OBJS-$(CONFIG_AC3_DECODER)             += ac3dec.o ac3tab.o ac3.o mdct.o fft.o
+ OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc.o ac3tab.o ac3.o
+Index: libavcodec/allcodecs.c
+===================================================================
+--- libavcodec/allcodecs.c	(revision 11186)
++++ libavcodec/allcodecs.c	(working copy)
+@@ -170,6 +170,7 @@
+     REGISTER_ENCDEC  (ZMBV, zmbv);
+ 
+     /* audio codecs */
++    REGISTER_DECODER (AAC, aac);
+     REGISTER_DECODER (MPEG4AAC, mpeg4aac);
+     REGISTER_ENCDEC  (AC3, ac3);
+     REGISTER_DECODER (ALAC, alac);



More information about the FFmpeg-soc mailing list