[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