summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-07-14 23:43:01 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-07-14 23:43:01 +0000
commit53c5ec96b87ef2bb61c7d3188d549623495d4500 (patch)
treea1b4904418281d23a2ab750b70be88db40062aa3
parent0ee981a355115c35cc9b6aa5066d6b7271c4b28a (diff)
downloadxine-lib-53c5ec96b87ef2bb61c7d3188d549623495d4500.tar.gz
xine-lib-53c5ec96b87ef2bb61c7d3188d549623495d4500.tar.bz2
merge FAAD2 - the GPL AAC decoder library.
xine_decoder.c is working, but demux_qt must send some needed initialization data. currently it's hardcoded to play my test stream, so it's not usable yet. CVS patchset: 2267 CVS date: 2002/07/14 23:43:01
-rw-r--r--src/libfaad/Makefile.am51
-rw-r--r--src/libfaad/analysis.h43
-rw-r--r--src/libfaad/bits.c63
-rw-r--r--src/libfaad/bits.h116
-rw-r--r--src/libfaad/common.c32
-rw-r--r--src/libfaad/common.h195
-rw-r--r--src/libfaad/data.c223
-rw-r--r--src/libfaad/data.h45
-rw-r--r--src/libfaad/decoder.c855
-rw-r--r--src/libfaad/decoder.h146
-rw-r--r--src/libfaad/drc.c77
-rw-r--r--src/libfaad/drc.h38
-rw-r--r--src/libfaad/error.c38
-rw-r--r--src/libfaad/error.h34
-rw-r--r--src/libfaad/faad.h121
-rw-r--r--src/libfaad/filtbank.c442
-rw-r--r--src/libfaad/filtbank.h74
-rw-r--r--src/libfaad/huffman.h279
-rw-r--r--src/libfaad/ic_predict.c180
-rw-r--r--src/libfaad/ic_predict.h55
-rw-r--r--src/libfaad/is.c69
-rw-r--r--src/libfaad/is.h58
-rw-r--r--src/libfaad/kbd_win.h1197
-rw-r--r--src/libfaad/lt_predict.c134
-rw-r--r--src/libfaad/lt_predict.h55
-rw-r--r--src/libfaad/mdct.c188
-rw-r--r--src/libfaad/mdct.h56
-rw-r--r--src/libfaad/mp4.c174
-rw-r--r--src/libfaad/mp4.h44
-rw-r--r--src/libfaad/ms.c66
-rw-r--r--src/libfaad/ms.h35
-rw-r--r--src/libfaad/output.c107
-rw-r--r--src/libfaad/output.h40
-rw-r--r--src/libfaad/pns.c120
-rw-r--r--src/libfaad/pns.h51
-rw-r--r--src/libfaad/pulse.c41
-rw-r--r--src/libfaad/pulse.h34
-rw-r--r--src/libfaad/reordered_spectral_data.c607
-rw-r--r--src/libfaad/sbr_dec.c60
-rw-r--r--src/libfaad/sbr_dec.h38
-rw-r--r--src/libfaad/sbr_huff.c673
-rw-r--r--src/libfaad/sbr_huff.h58
-rw-r--r--src/libfaad/sbr_qmf.c289
-rw-r--r--src/libfaad/sbr_qmf.h41
-rw-r--r--src/libfaad/sbr_syntax.c609
-rw-r--r--src/libfaad/sbr_syntax.h115
-rw-r--r--src/libfaad/specrec.c344
-rw-r--r--src/libfaad/specrec.h50
-rw-r--r--src/libfaad/syntax.c1429
-rw-r--r--src/libfaad/syntax.h360
-rw-r--r--src/libfaad/tns.c315
-rw-r--r--src/libfaad/tns.h52
-rw-r--r--src/libfaad/xine_decoder.c338
53 files changed, 10954 insertions, 0 deletions
diff --git a/src/libfaad/Makefile.am b/src/libfaad/Makefile.am
new file mode 100644
index 000000000..3dcd38753
--- /dev/null
+++ b/src/libfaad/Makefile.am
@@ -0,0 +1,51 @@
+##
+## Process this file with automake to produce Makefile.in
+##
+
+SUBDIRS = fftw
+
+LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
+
+libdir = $(XINE_PLUGINDIR)
+
+
+CFLAGS = @CFLAGS@ -I$(srcdir)/fftw
+
+DEBUG_CFLAGS = @DEBUG_CFLAGS@ -I$(srcdir)/fftw
+
+#if HAVE_FAAD
+faad_module = xineplug_decode_faad.la
+#endif
+
+lib_LTLIBRARIES = $(faad_module)
+
+VPATH = @srcdir@:codebook:
+
+xineplug_decode_faad_la_SOURCES = xine_decoder.c \
+ bits.c data.c decoder.c drc.c error.c filtbank.c \
+ ic_predict.c is.c lt_predict.c mdct.c mp4.c ms.c output.c pns.c \
+ pulse.c specrec.c syntax.c tns.c reordered_spectral_data.c \
+ hcb_1.c hcb_2.c hcb_3.c hcb_4.c hcb_5.c hcb_6.c hcb_7.c hcb_8.c \
+ hcb_9.c hcb_10.c hcb_11.c hcb_sf.c
+xineplug_decode_faad_la_LDFLAGS = -avoid-version -module
+xineplug_decode_faad_la_LIBADD = $(top_builddir)/src/libfaad/fftw/libfftw.la
+
+noinst_HEADERS = analysis.h bits.h data.h decoder.h drc.h error.h \
+ filtbank.h huffman.h ic_predict.h is.h kbd_win.h \
+ lt_predict.h mdct.h mp4.h ms.h output.h pns.h pulse.h \
+ specrec.h syntax.h tns.h codebook/hcb.h faad.h
+
+
+debug:
+ @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
+
+install-debug: debug
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/libfaad/analysis.h b/src/libfaad/analysis.h
new file mode 100644
index 000000000..96ce6b200
--- /dev/null
+++ b/src/libfaad/analysis.h
@@ -0,0 +1,43 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: analysis.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __ANALYSIS_H__
+#define __ANALYSIS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef ANALYSIS
+#define DEBUGDEC ,uint8_t print,uint16_t var,uint8_t *dbg
+#define DEBUGVAR(A,B,C) ,A,B,C
+extern uint16_t dbg_count;
+#else
+#define DEBUGDEC
+#define DEBUGVAR(A,B,C)
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/bits.c b/src/libfaad/bits.c
new file mode 100644
index 000000000..894a308b5
--- /dev/null
+++ b/src/libfaad/bits.c
@@ -0,0 +1,63 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: bits.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+#include "bits.h"
+
+/* initialize buffer, call once before first getbits or showbits */
+void faad_initbits(bitfile *ld, void *buffer)
+{
+ uint32_t tmp;
+
+ ld->start = (uint32_t*)buffer;
+
+ tmp = *(uint32_t*)buffer;
+#ifndef ARCH_IS_BIG_ENDIAN
+ BSWAP(tmp);
+#endif
+ ld->bufa = tmp;
+
+ tmp = *((uint32_t*)buffer + 1);
+#ifndef ARCH_IS_BIG_ENDIAN
+ BSWAP(tmp);
+#endif
+ ld->bufb = tmp;
+
+ ld->pos = 0;
+ ld->tail = ((uint32_t*)buffer + 2);
+}
+
+uint32_t faad_get_processed_bits(bitfile *ld)
+{
+ return 8 * (4*(ld->tail - ld->start) - 4) - (32 - ld->pos);
+}
+
+uint8_t faad_byte_align(bitfile *ld)
+{
+ uint8_t remainder = (uint8_t)(ld->pos % 8);
+
+ if (remainder)
+ {
+ faad_flushbits(ld, 8 - remainder);
+ return (8 - remainder);
+ }
+ return 0;
+}
diff --git a/src/libfaad/bits.h b/src/libfaad/bits.h
new file mode 100644
index 000000000..8d7222bc4
--- /dev/null
+++ b/src/libfaad/bits.h
@@ -0,0 +1,116 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: bits.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __BITS_H__
+#define __BITS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "analysis.h"
+#ifdef ANALYSIS
+#include <stdio.h>
+#endif
+
+#define BYTE_NUMBIT 8
+#define bit2byte(a) ((a+7)/BYTE_NUMBIT)
+
+typedef struct _bitfile
+{
+ /* bit input */
+ uint32_t bufa;
+ uint32_t bufb;
+ uint32_t pos;
+ uint32_t *tail;
+ uint32_t *start;
+} bitfile;
+
+
+#if defined(_WIN32)
+#define BSWAP(a) __asm mov eax,a __asm bswap eax __asm mov a, eax
+#elif defined(LINUX) || defined(DJGPP)
+#define BSWAP(a) __asm__ ( "bswapl %0\n" : "=r" (a) : "0" (a) )
+#else
+#define BSWAP(a) \
+ ((a) = ( ((a)&0xff)<<24) | (((a)&0xff00)<<8) | (((a)>>8)&0xff00) | (((a)>>24)&0xff))
+#endif
+
+
+void faad_initbits(bitfile *ld, void *buffer);
+uint8_t faad_byte_align(bitfile *ld);
+uint32_t faad_get_processed_bits(bitfile *ld);
+
+
+static INLINE uint32_t faad_showbits(bitfile *ld, uint8_t bits)
+{
+ int32_t nbit = (bits + ld->pos) - 32;
+ if (nbit > 0)
+ {
+ return ((ld->bufa & (0xffffffff >> ld->pos)) << nbit) |
+ (ld->bufb >> (32 - nbit));
+ } else {
+ return (ld->bufa & (0xffffffff >> ld->pos)) >> (32 - ld->pos - bits);
+ }
+}
+
+static INLINE void faad_flushbits(bitfile *ld, uint8_t bits)
+{
+ ld->pos += bits;
+
+ if (ld->pos >= 32)
+ {
+ uint32_t tmp;
+
+ ld->bufa = ld->bufb;
+ tmp = *(uint32_t*)ld->tail;
+#ifndef ARCH_IS_BIG_ENDIAN
+ BSWAP(tmp);
+#endif
+ ld->bufb = tmp;
+ ld->tail++;
+ ld->pos -= 32;
+ }
+}
+
+/* return next n bits (right adjusted) */
+static INLINE uint32_t faad_getbits(bitfile *ld, uint8_t n DEBUGDEC)
+{
+ uint32_t ret = faad_showbits(ld, n);
+ faad_flushbits(ld, n);
+
+#ifdef ANALYSIS
+ if (print)
+ fprintf(stdout, "%4d %2d bits, val: %4d, variable: %d %s\n", dbg_count++, n, ret, var, dbg);
+#endif
+
+ return ret;
+}
+
+static INLINE uint8_t faad_get1bit(bitfile *ld DEBUGDEC)
+{
+ return (uint8_t)faad_getbits(ld, 1 DEBUGVAR(print,var,dbg));
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/common.c b/src/libfaad/common.c
new file mode 100644
index 000000000..394366d17
--- /dev/null
+++ b/src/libfaad/common.c
@@ -0,0 +1,32 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: common.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+/* just some common functions that could be used anywhere */
+
+#include "common.h"
+
+#define LOG2 0.30102999566398
+
+
+uint32_t int_log2(uint32_t val)
+{
+ return (uint32_t)(log((real_t)val)/LOG2 + 0.5);
+}
diff --git a/src/libfaad/common.h b/src/libfaad/common.h
new file mode 100644
index 000000000..742325ff9
--- /dev/null
+++ b/src/libfaad/common.h
@@ -0,0 +1,195 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: common.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef LINUX
+#define INLINE inline
+#else
+#ifdef _WIN32
+#define INLINE __inline
+#else
+#define INLINE
+#endif
+#endif
+
+#ifndef max
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef min
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef LN2
+#define LN2 0.6931471805599453
+#endif
+
+#ifndef LN05
+#define LN05 -LN2
+#endif
+
+/* COMPILE TIME DEFINITIONS */
+
+/* use double precision */
+/* #define USE_DOUBLE_PRECISION */
+
+//#define SBR
+#define ERROR_RESILIENCE
+
+
+/* Allow decoding of MAIN profile AAC */
+#define MAIN_DEC
+/* Allow decoding of LTP profile AAC */
+#define LTP_DEC
+/* Allow decoding of LD profile AAC */
+#define LD_DEC
+
+/* LD can't do without LTP */
+#ifdef LD_DEC
+#ifndef ERROR_RESILIENCE
+#define ERROR_RESILIENCE
+#endif
+#ifndef LTP_DEC
+#define LTP_DEC
+#endif
+#endif
+
+
+/* END COMPILE TIME DEFINITIONS */
+
+
+#if defined(_WIN32)
+
+
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int8 uint8_t;
+typedef __int32 int32_t;
+typedef __int16 int16_t;
+typedef __int8 int8_t;
+typedef float float32_t;
+
+
+#elif defined(LINUX) || defined(DJGPP)
+
+
+#if defined(LINUX)
+#include <stdint.h>
+#else
+typedef unsigned long uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+typedef long int32_t;
+typedef short int16_t;
+typedef char int8_t;
+typedef float float32_t;
+#endif
+
+
+#else /* Some other OS */
+
+
+#include <inttypes.h>
+
+#endif
+
+
+#ifndef USE_DOUBLE_PRECISION
+
+ typedef float real_t;
+
+ #define MUL(A,B) ((A)*(B))
+
+ #ifdef __ICL /* only Intel C compiler has fmath ??? */
+
+ #include <mathf.h>
+
+ #define sin sinf
+ #define cos cosf
+ #define log logf
+ #define exp expf
+ #define floor floorf
+ #define ceil ceilf
+ #define sqrt sqrtf
+
+ #else
+
+ #include <math.h>
+
+#ifdef HAVE_SINF
+# define sin sinf
+#endif
+#ifdef HAVE_COSF
+# define cos cosf
+#endif
+#ifdef HAVE_LOGF
+# define log logf
+#endif
+#ifdef HAVE_EXPF
+# define exp expf
+#endif
+#ifdef HAVE_FLOORF
+# define floor floorf
+#endif
+#ifdef HAVE_FLOORF
+# define ceil ceilf
+#endif
+#ifdef HAVE_SQRTF
+# define sqrt sqrtf
+#endif
+
+ #endif
+
+#else
+
+ typedef double real_t;
+ #include <math.h>
+
+ #define MUL(A,B) ((A)*(B))
+
+#endif
+
+typedef struct {
+ real_t re;
+ real_t im;
+} complex_t;
+
+
+/* common functions */
+uint32_t int_log2(uint32_t val);
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846f
+#endif
+#ifndef M_PI_2 /* PI/2 */
+#define M_PI_2 1.57079632679489661923
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/data.c b/src/libfaad/data.c
new file mode 100644
index 000000000..294f4e487
--- /dev/null
+++ b/src/libfaad/data.c
@@ -0,0 +1,223 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: data.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+#include "data.h"
+
+#ifdef LD_DEC
+extern uint8_t num_swb_512_window[] =
+{
+ 0, 0, 0, 35, 35, 36, 30, 30, 0, 0, 0, 0
+};
+#endif
+
+extern uint8_t num_swb_1024_window[] =
+{
+ 41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40
+};
+
+extern uint8_t num_swb_128_window[] =
+{
+ 12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15
+};
+
+static 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 uint16_t swb_offset_128_96[] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
+};
+
+static 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 uint16_t swb_offset_128_64[] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128
+};
+
+
+static 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
+};
+
+#ifdef LD_DEC
+static uint16_t swb_offset_512_48[] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 68, 76, 84,
+ 92, 100, 112, 124, 136, 148, 164, 184, 208, 236, 268, 300, 332, 364, 396,
+ 428, 460, 512
+};
+#endif
+
+static uint16_t swb_offset_128_48[] =
+{
+ 0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128
+};
+
+static 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
+};
+
+#ifdef LD_DEC
+static uint16_t swb_offset_512_32[] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80,
+ 88, 96, 108, 120, 132, 144, 160, 176, 192, 212, 236, 260, 288, 320, 352,
+ 384, 416, 448, 480, 512
+};
+#endif
+
+static 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
+};
+
+#ifdef LD_DEC
+static uint16_t swb_offset_512_24[] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, 60, 68,
+ 80, 92, 104, 120, 140, 164, 192, 224, 256, 288, 320, 352, 384, 416,
+ 448, 480, 512
+};
+#endif
+
+static uint16_t swb_offset_128_24[] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128
+};
+
+static 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 uint16_t swb_offset_128_16[] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 128
+};
+
+static 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 uint16_t swb_offset_128_8[] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 128
+};
+
+extern uint16_t *swb_offset_1024_window[] =
+{
+ swb_offset_1024_96, /* 96000 */
+ swb_offset_1024_96, /* 88200 */
+ swb_offset_1024_64, /* 64000 */
+ swb_offset_1024_48, /* 48000 */
+ swb_offset_1024_48, /* 44100 */
+ swb_offset_1024_32, /* 32000 */
+ swb_offset_1024_24, /* 24000 */
+ swb_offset_1024_24, /* 22050 */
+ swb_offset_1024_16, /* 16000 */
+ swb_offset_1024_16, /* 12000 */
+ swb_offset_1024_16, /* 11025 */
+ swb_offset_1024_8 /* 8000 */
+};
+
+#ifdef LD_DEC
+extern uint16_t *swb_offset_512_window[] =
+{
+ 0, /* 96000 */
+ 0, /* 88200 */
+ 0, /* 64000 */
+ swb_offset_512_48, /* 48000 */
+ swb_offset_512_48, /* 44100 */
+ swb_offset_512_32, /* 32000 */
+ swb_offset_512_24, /* 24000 */
+ swb_offset_512_24, /* 22050 */
+ 0, /* 16000 */
+ 0, /* 12000 */
+ 0, /* 11025 */
+ 0 /* 8000 */
+};
+#endif
+
+extern uint16_t *swb_offset_128_window[] =
+{
+ swb_offset_128_96, /* 96000 */
+ swb_offset_128_96, /* 88200 */
+ swb_offset_128_64, /* 64000 */
+ swb_offset_128_48, /* 48000 */
+ swb_offset_128_48, /* 44100 */
+ swb_offset_128_48, /* 32000 */
+ swb_offset_128_24, /* 24000 */
+ swb_offset_128_24, /* 22050 */
+ swb_offset_128_16, /* 16000 */
+ swb_offset_128_16, /* 12000 */
+ swb_offset_128_16, /* 11025 */
+ swb_offset_128_8 /* 8000 */
+};
+
+extern uint8_t pred_sfb_max[] =
+{
+ 33, /* 96000 */
+ 33, /* 88200 */
+ 38, /* 64000 */
+ 40, /* 48000 */
+ 40, /* 44100 */
+ 40, /* 32000 */
+ 41, /* 24000 */
+ 41, /* 22050 */
+ 37, /* 16000 */
+ 37, /* 12000 */
+ 37, /* 11025 */
+ 34 /* 8000 */
+};
+
+extern uint32_t sample_rates[] =
+{
+ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000,
+ 12000, 11025, 8000
+};
diff --git a/src/libfaad/data.h b/src/libfaad/data.h
new file mode 100644
index 000000000..f72a9ed9c
--- /dev/null
+++ b/src/libfaad/data.h
@@ -0,0 +1,45 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: data.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __DATA_H__
+#define __DATA_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern uint8_t num_swb_1024_window[];
+#ifdef LD_DEC
+extern uint8_t num_swb_512_window[];
+#endif
+extern uint8_t num_swb_128_window[];
+extern uint16_t *swb_offset_1024_window[];
+#ifdef LD_DEC
+extern uint16_t *swb_offset_512_window[];
+#endif
+extern uint16_t *swb_offset_128_window[];
+extern uint8_t pred_sfb_max[];
+extern uint32_t sample_rates[];
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/decoder.c b/src/libfaad/decoder.c
new file mode 100644
index 000000000..d81ba526c
--- /dev/null
+++ b/src/libfaad/decoder.c
@@ -0,0 +1,855 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: decoder.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include <stdlib.h>
+#include <memory.h>
+#include "common.h"
+#include "decoder.h"
+#include "mp4.h"
+#include "syntax.h"
+#include "specrec.h"
+#include "data.h"
+#include "tns.h"
+#include "pns.h"
+#include "is.h"
+#include "ms.h"
+#include "ic_predict.h"
+#include "lt_predict.h"
+#include "drc.h"
+#include "error.h"
+#include "output.h"
+
+#ifdef ANALYSIS
+uint16_t dbg_count;
+#endif
+
+uint8_t* FAADAPI faacDecGetErrorMessage(uint8_t errcode)
+{
+ return err_msg[errcode];
+}
+
+faacDecHandle FAADAPI faacDecOpen()
+{
+ uint8_t i;
+ faacDecHandle hDecoder = NULL;
+
+ if ((hDecoder = (faacDecHandle)malloc(sizeof(faacDecStruct))) == NULL)
+ return NULL;
+
+ memset(hDecoder, 0, sizeof(faacDecStruct));
+ memset(&hDecoder->fb, 0, sizeof(fb_info));
+
+ hDecoder->config.outputFormat = FAAD_FMT_16BIT;
+ hDecoder->config.defObjectType = MAIN;
+ hDecoder->config.defSampleRate = 44100; /* Default: 44.1kHz */
+ hDecoder->adts_header_present = 0;
+ hDecoder->adif_header_present = 0;
+ hDecoder->aacSectionDataResilienceFlag = 0;
+ hDecoder->aacScalefactorDataResilienceFlag = 0;
+ hDecoder->aacSpectralDataResilienceFlag = 0;
+ hDecoder->frameLength = 1024;
+
+ hDecoder->frame = 0;
+ hDecoder->sample_buffer = NULL;
+
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ hDecoder->window_shape_prev[i] = 0;
+ hDecoder->time_state[i] = NULL;
+ hDecoder->time_out[i] = NULL;
+#ifdef MAIN_DEC
+ hDecoder->pred_stat[i] = NULL;
+#endif
+#ifdef LTP_DEC
+ hDecoder->ltp_lag[i] = 0;
+ hDecoder->lt_pred_stat[i] = NULL;
+#endif
+ }
+
+ init_drc(&hDecoder->drc, 1.0f, 1.0f);
+#if IQ_TABLE_SIZE && POW_TABLE_SIZE
+ build_tables(hDecoder->iq_table, hDecoder->pow2_table);
+#elif !POW_TABLE_SIZE
+ build_tables(hDecoder->iq_table, NULL);
+#endif
+
+ return hDecoder;
+}
+
+faacDecConfigurationPtr FAADAPI faacDecGetCurrentConfiguration(faacDecHandle hDecoder)
+{
+ faacDecConfigurationPtr config = &(hDecoder->config);
+
+ return config;
+}
+
+uint8_t FAADAPI faacDecSetConfiguration(faacDecHandle hDecoder,
+ faacDecConfigurationPtr config)
+{
+ hDecoder->config.defObjectType = config->defObjectType;
+#ifdef DRM
+ if (config->defObjectType == DRM_ER_LC)
+ {
+ hDecoder->aacSectionDataResilienceFlag = 1; /* VCB11 */
+ hDecoder->aacScalefactorDataResilienceFlag = 0; /* no RVLC */
+ hDecoder->aacSpectralDataResilienceFlag = 1; /* HCR */
+ hDecoder->frameLength = 960;
+ }
+#endif
+ hDecoder->config.defSampleRate = config->defSampleRate;
+ hDecoder->config.outputFormat = config->outputFormat;
+
+ /* OK */
+ return 1;
+}
+
+/* Returns the sample rate index */
+static uint8_t get_sr_index(uint32_t samplerate)
+{
+ if (92017 <= samplerate) return 0;
+ if (75132 <= samplerate) return 1;
+ if (55426 <= samplerate) return 2;
+ if (46009 <= samplerate) return 3;
+ if (37566 <= samplerate) return 4;
+ if (27713 <= samplerate) return 5;
+ if (23004 <= samplerate) return 6;
+ if (18783 <= samplerate) return 7;
+ if (13856 <= samplerate) return 8;
+ if (11502 <= samplerate) return 9;
+ if (9391 <= samplerate) return 10;
+
+ return 11;
+}
+
+/* Returns 0 if an object type is decodable, otherwise returns -1 */
+static int8_t can_decode_ot(uint8_t object_type)
+{
+ switch (object_type)
+ {
+ case LC:
+ return 0;
+ case MAIN:
+#ifdef MAIN_DEC
+ return 0;
+#else
+ return -1;
+#endif
+ case SSR:
+ return -1;
+ case LTP:
+#ifdef LTP_DEC
+ return 0;
+#else
+ return -1;
+#endif
+
+ /* ER object types */
+#ifdef ERROR_RESILIENCE
+ case ER_LC:
+#ifdef DRM
+ case DRM_ER_LC:
+#endif
+ return 0;
+ case ER_LTP:
+#ifdef LTP_DEC
+ return 0;
+#else
+ return -1;
+#endif
+ case LD:
+#ifdef LD_DEC
+ return 0;
+#else
+ return -1;
+#endif
+#endif
+ }
+
+ return -1;
+}
+
+int32_t FAADAPI faacDecInit(faacDecHandle hDecoder, uint8_t *buffer,
+ uint32_t *samplerate, uint8_t *channels)
+{
+ uint32_t bits = 0;
+ bitfile ld;
+ adif_header adif;
+ adts_header adts;
+
+ hDecoder->sf_index = get_sr_index(hDecoder->config.defSampleRate);
+ hDecoder->object_type = hDecoder->config.defObjectType;
+ *samplerate = sample_rates[hDecoder->sf_index];
+ *channels = 1;
+
+ if (buffer != NULL)
+ {
+ faad_initbits(&ld, buffer);
+
+#ifdef DRM
+ if (hDecoder->object_type != DRM_ER_LC)
+#endif
+ /* Check if an ADIF header is present */
+ if ((buffer[0] == 'A') && (buffer[1] == 'D') &&
+ (buffer[2] == 'I') && (buffer[3] == 'F'))
+ {
+ hDecoder->adif_header_present = 1;
+
+ get_adif_header(&adif, &ld);
+
+ hDecoder->sf_index = adif.pce.sf_index;
+ hDecoder->object_type = adif.pce.object_type;
+
+ *samplerate = sample_rates[hDecoder->sf_index];
+ *channels = adif.pce.channels;
+
+ bits = bit2byte(faad_get_processed_bits(&ld));
+
+ /* Check if an ADTS header is present */
+ } else if (faad_showbits(&ld, 12) == 0xfff) {
+ hDecoder->adts_header_present = 1;
+
+ adts_frame(&adts, &ld);
+
+ hDecoder->sf_index = adts.sf_index;
+ hDecoder->object_type = adts.profile;
+
+ *samplerate = sample_rates[hDecoder->sf_index];
+ *channels = (adts.channel_configuration > 6) ?
+ 2 : adts.channel_configuration;
+ }
+ }
+ hDecoder->channelConfiguration = *channels;
+
+ /* must be done before frameLength is divided by 2 for LD */
+ filter_bank_init(&hDecoder->fb, hDecoder->frameLength);
+
+#ifdef LD_DEC
+ if (hDecoder->object_type == LD)
+ hDecoder->frameLength >>= 1;
+#endif
+
+ if (can_decode_ot(hDecoder->object_type) < 0)
+ return -1;
+
+ return bits;
+}
+
+/* Init the library using a DecoderSpecificInfo */
+int8_t FAADAPI faacDecInit2(faacDecHandle hDecoder, uint8_t *pBuffer,
+ uint32_t SizeOfDecoderSpecificInfo,
+ uint32_t *samplerate, uint8_t *channels)
+{
+ int8_t rc;
+ uint8_t frameLengthFlag;
+
+ hDecoder->adif_header_present = 0;
+ hDecoder->adts_header_present = 0;
+
+ if((hDecoder == NULL)
+ || (pBuffer == NULL)
+ || (SizeOfDecoderSpecificInfo < 2)
+ || (samplerate == NULL)
+ || (channels == NULL))
+ {
+ return -1;
+ }
+
+ rc = AudioSpecificConfig(pBuffer, samplerate, channels,
+ &hDecoder->sf_index, &hDecoder->object_type,
+ &hDecoder->aacSectionDataResilienceFlag,
+ &hDecoder->aacScalefactorDataResilienceFlag,
+ &hDecoder->aacSpectralDataResilienceFlag,
+ &frameLengthFlag);
+ if (hDecoder->object_type < 4)
+ hDecoder->object_type--; /* For AAC differs from MPEG-4 */
+ if (rc != 0)
+ {
+ return rc;
+ }
+ hDecoder->channelConfiguration = *channels;
+ if (frameLengthFlag)
+ hDecoder->frameLength = 960;
+
+ /* must be done before frameLength is divided by 2 for LD */
+ filter_bank_init(&hDecoder->fb, hDecoder->frameLength);
+
+#ifdef LD_DEC
+ if (hDecoder->object_type == LD)
+ hDecoder->frameLength >>= 1;
+#endif
+
+ return 0;
+}
+
+void FAADAPI faacDecClose(faacDecHandle hDecoder)
+{
+ uint8_t i;
+
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ if (hDecoder->time_state[i]) free(hDecoder->time_state[i]);
+ if (hDecoder->time_out[i]) free(hDecoder->time_out[i]);
+#ifdef MAIN_DEC
+ if (hDecoder->pred_stat[i]) free(hDecoder->pred_stat[i]);
+#endif
+#ifdef LTP_DEC
+ if (hDecoder->lt_pred_stat[i]) free(hDecoder->lt_pred_stat[i]);
+#endif
+ }
+
+ filter_bank_end(&hDecoder->fb);
+
+ if (hDecoder->sample_buffer) free(hDecoder->sample_buffer);
+
+ if (hDecoder) free(hDecoder);
+}
+
+#ifdef ERROR_RESILIENCE
+#define decode_sce_lfe() \
+ spec_data[channels] = (int16_t*)malloc(frame_len*sizeof(int16_t)); \
+ spec_coef[channels] = (real_t*)malloc(frame_len*sizeof(real_t)); \
+ \
+ syntax_elements[ch_ele] = (element*)malloc(sizeof(element)); \
+ memset(syntax_elements[ch_ele], 0, sizeof(element)); \
+ syntax_elements[ch_ele]->ele_id = id_syn_ele; \
+ syntax_elements[ch_ele]->channel = channels; \
+ \
+ if ((hInfo->error = single_lfe_channel_element(syntax_elements[ch_ele], \
+ ld, spec_data[channels], sf_index, object_type, frame_len, \
+ aacSectionDataResilienceFlag, aacScalefactorDataResilienceFlag, \
+ aacSpectralDataResilienceFlag)) > 0) \
+ { \
+ /* to make sure everything gets deallocated */ \
+ channels++; ch_ele++; \
+ goto error; \
+ } \
+ \
+ channels++; \
+ ch_ele++;
+#else
+#define decode_sce_lfe() \
+ spec_data[channels] = (int16_t*)malloc(frame_len*sizeof(int16_t)); \
+ spec_coef[channels] = (real_t*)malloc(frame_len*sizeof(real_t)); \
+ \
+ syntax_elements[ch_ele] = (element*)malloc(sizeof(element)); \
+ memset(syntax_elements[ch_ele], 0, sizeof(element)); \
+ syntax_elements[ch_ele]->ele_id = id_syn_ele; \
+ syntax_elements[ch_ele]->channel = channels; \
+ \
+ if ((hInfo->error = single_lfe_channel_element(syntax_elements[ch_ele], \
+ ld, spec_data[channels], sf_index, object_type, frame_len)) > 0) \
+ { \
+ /* to make sure everything gets deallocated */ \
+ channels++; ch_ele++; \
+ goto error; \
+ } \
+ \
+ channels++; \
+ ch_ele++;
+#endif
+
+#ifdef ERROR_RESILIENCE
+#define decode_cpe() \
+ spec_data[channels] = (int16_t*)malloc(frame_len*sizeof(int16_t)); \
+ spec_data[channels+1] = (int16_t*)malloc(frame_len*sizeof(int16_t)); \
+ spec_coef[channels] = (real_t*)malloc(frame_len*sizeof(real_t)); \
+ spec_coef[channels+1] = (real_t*)malloc(frame_len*sizeof(real_t)); \
+ \
+ syntax_elements[ch_ele] = (element*)malloc(sizeof(element)); \
+ memset(syntax_elements[ch_ele], 0, sizeof(element)); \
+ syntax_elements[ch_ele]->ele_id = id_syn_ele; \
+ syntax_elements[ch_ele]->channel = channels; \
+ syntax_elements[ch_ele]->paired_channel = channels+1; \
+ \
+ if ((hInfo->error = channel_pair_element(syntax_elements[ch_ele], \
+ ld, spec_data[channels], spec_data[channels+1], \
+ sf_index, object_type, frame_len, \
+ aacSectionDataResilienceFlag, aacScalefactorDataResilienceFlag, \
+ aacSpectralDataResilienceFlag)) > 0) \
+ { \
+ /* to make sure everything gets deallocated */ \
+ channels+=2; ch_ele++; \
+ goto error; \
+ } \
+ \
+ channels += 2; \
+ ch_ele++;
+#else
+#define decode_cpe() \
+ spec_data[channels] = (int16_t*)malloc(frame_len*sizeof(int16_t)); \
+ spec_data[channels+1] = (int16_t*)malloc(frame_len*sizeof(int16_t)); \
+ spec_coef[channels] = (real_t*)malloc(frame_len*sizeof(real_t)); \
+ spec_coef[channels+1] = (real_t*)malloc(frame_len*sizeof(real_t)); \
+ \
+ syntax_elements[ch_ele] = (element*)malloc(sizeof(element)); \
+ memset(syntax_elements[ch_ele], 0, sizeof(element)); \
+ syntax_elements[ch_ele]->ele_id = id_syn_ele; \
+ syntax_elements[ch_ele]->channel = channels; \
+ syntax_elements[ch_ele]->paired_channel = channels+1; \
+ \
+ if ((hInfo->error = channel_pair_element(syntax_elements[ch_ele], \
+ ld, spec_data[channels], spec_data[channels+1], \
+ sf_index, object_type, frame_len)) > 0) \
+ { \
+ /* to make sure everything gets deallocated */ \
+ channels+=2; ch_ele++; \
+ goto error; \
+ } \
+ \
+ channels += 2; \
+ ch_ele++;
+#endif
+
+void* FAADAPI faacDecDecode(faacDecHandle hDecoder,
+ faacDecFrameInfo *hInfo,
+ uint8_t *buffer)
+{
+ int32_t i;
+ uint8_t id_syn_ele, ele, ch;
+ adts_header adts;
+ uint8_t channels, ch_ele;
+ bitfile *ld = malloc(sizeof(bitfile));
+
+ /* local copys of globals */
+ uint8_t sf_index = hDecoder->sf_index;
+ uint8_t object_type = hDecoder->object_type;
+ uint8_t channelConfiguration = hDecoder->channelConfiguration;
+#ifdef MAIN_DEC
+ pred_state **pred_stat = hDecoder->pred_stat;
+#endif
+#ifdef LTP_DEC
+ real_t **lt_pred_stat = hDecoder->lt_pred_stat;
+#endif
+ real_t *iq_table = hDecoder->iq_table;
+#if POW_TABLE_SIZE
+ real_t *pow2_table = hDecoder->pow2_table;
+#else
+ real_t *pow2_table = NULL;
+#endif
+ uint8_t *window_shape_prev = hDecoder->window_shape_prev;
+ real_t **time_state = hDecoder->time_state;
+ real_t **time_out = hDecoder->time_out;
+ fb_info *fb = &hDecoder->fb;
+ drc_info *drc = &hDecoder->drc;
+ uint8_t outputFormat = hDecoder->config.outputFormat;
+#ifdef LTP_DEC
+ uint16_t *ltp_lag = hDecoder->ltp_lag;
+#endif
+#ifdef ERROR_RESILIENCE
+ uint8_t aacSectionDataResilienceFlag = hDecoder->aacSectionDataResilienceFlag;
+ uint8_t aacScalefactorDataResilienceFlag = hDecoder->aacScalefactorDataResilienceFlag;
+ uint8_t aacSpectralDataResilienceFlag = hDecoder->aacSpectralDataResilienceFlag;
+#endif
+
+ program_config pce;
+ element *syntax_elements[MAX_SYNTAX_ELEMENTS];
+ int16_t *spec_data[MAX_CHANNELS];
+ real_t *spec_coef[MAX_CHANNELS];
+
+ /* frame length is different for Low Delay AAC */
+ uint16_t frame_len = hDecoder->frameLength;
+
+ void *sample_buffer;
+
+ ele = 0;
+ channels = 0;
+ ch_ele = 0;
+
+ memset(hInfo, 0, sizeof(faacDecFrameInfo));
+
+ /* initialize the bitstream */
+ faad_initbits(ld, buffer);
+
+ if (hDecoder->adts_header_present)
+ {
+ if ((hInfo->error = adts_frame(&adts, ld)) > 0)
+ goto error;
+
+ /* MPEG2 does byte_alignment() here,
+ * but ADTS header is always multiple of 8 bits in MPEG2
+ * so not needed to actually do it.
+ */
+ }
+
+#ifdef ANALYSIS
+ dbg_count = 0;
+#endif
+
+#ifdef ERROR_RESILIENCE
+ if (object_type < ER_OBJECT_START)
+ {
+#endif
+ /* Table 4.4.3: raw_data_block() */
+ while ((id_syn_ele = (uint8_t)faad_getbits(ld, LEN_SE_ID
+ DEBUGVAR(1,4,"faacDecDecode(): id_syn_ele"))) != ID_END)
+ {
+ switch (id_syn_ele) {
+ case ID_SCE:
+ case ID_LFE:
+ decode_sce_lfe();
+ break;
+ case ID_CPE:
+ decode_cpe();
+ break;
+ case ID_CCE: /* not implemented yet */
+ hInfo->error = 6;
+ goto error;
+ break;
+ case ID_DSE:
+ data_stream_element(ld);
+ break;
+ case ID_PCE:
+ if ((hInfo->error = program_config_element(&pce, ld)) > 0)
+ goto error;
+ break;
+ case ID_FIL:
+ if ((hInfo->error = fill_element(ld, drc)) > 0)
+ goto error;
+ break;
+ }
+ ele++;
+ }
+#ifdef ERROR_RESILIENCE
+ } else {
+ /* Table 262: er_raw_data_block() */
+ switch (channelConfiguration)
+ {
+ case 1:
+ id_syn_ele = ID_SCE;
+ decode_sce_lfe();
+ break;
+ case 2:
+ id_syn_ele = ID_CPE;
+ decode_cpe();
+ break;
+ case 3:
+ id_syn_ele = ID_SCE;
+ decode_sce_lfe();
+ id_syn_ele = ID_CPE;
+ decode_cpe();
+ break;
+ case 4:
+ id_syn_ele = ID_SCE;
+ decode_sce_lfe();
+ id_syn_ele = ID_CPE;
+ decode_cpe();
+ id_syn_ele = ID_SCE;
+ decode_sce_lfe();
+ break;
+ case 5:
+ id_syn_ele = ID_SCE;
+ decode_sce_lfe();
+ id_syn_ele = ID_CPE;
+ decode_cpe();
+ id_syn_ele = ID_CPE;
+ decode_cpe();
+ break;
+ case 6:
+ id_syn_ele = ID_SCE;
+ decode_sce_lfe();
+ id_syn_ele = ID_CPE;
+ decode_cpe();
+ id_syn_ele = ID_CPE;
+ decode_cpe();
+ id_syn_ele = ID_LFE;
+ decode_sce_lfe();
+ break;
+ case 7:
+ id_syn_ele = ID_SCE;
+ decode_sce_lfe();
+ id_syn_ele = ID_CPE;
+ decode_cpe();
+ id_syn_ele = ID_CPE;
+ decode_cpe();
+ id_syn_ele = ID_CPE;
+ decode_cpe();
+ id_syn_ele = ID_LFE;
+ decode_sce_lfe();
+ break;
+ default:
+ hInfo->error = 7;
+ goto error;
+ }
+#if 0
+ cnt = bits_to_decode() / 8;
+ while (cnt >= 1)
+ {
+ cnt -= extension_payload(cnt);
+ }
+#endif
+ }
+#endif
+
+ /* no more bit reading after this */
+ faad_byte_align(ld);
+ hInfo->bytesconsumed = bit2byte(faad_get_processed_bits(ld));
+ if (ld) free(ld);
+ ld = NULL;
+
+ /* number of samples in this frame */
+ hInfo->samples = frame_len*channels;
+ /* number of samples in this frame */
+ hInfo->channels = channels;
+
+ if (hDecoder->sample_buffer == NULL)
+ hDecoder->sample_buffer = malloc(frame_len*channels*sizeof(float32_t));
+
+ sample_buffer = hDecoder->sample_buffer;
+
+ /* noiseless coding is done, the rest of the tools come now */
+ for (ch = 0; ch < channels; ch++)
+ {
+ ic_stream *ics;
+
+ /* find the syntax element to which this channel belongs */
+ for (i = 0; i < ch_ele; i++)
+ {
+ if (syntax_elements[i]->channel == ch)
+ {
+ ics = &(syntax_elements[i]->ics1);
+ break;
+ } else if (syntax_elements[i]->paired_channel == ch) {
+ ics = &(syntax_elements[i]->ics2);
+ break;
+ }
+ }
+
+ /* inverse quantization */
+ inverse_quantization(spec_coef[ch], spec_data[ch], iq_table,
+ frame_len);
+
+ /* apply scalefactors */
+ apply_scalefactors(ics, spec_coef[ch], pow2_table, frame_len);
+
+ /* deinterleave short block grouping */
+ if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+ quant_to_spec(ics, spec_coef[ch], frame_len);
+ }
+
+ /* Because for ms and is both channels spectral coefficients are needed
+ we have to restart running through all channels here.
+ */
+ for (ch = 0; ch < channels; ch++)
+ {
+ uint8_t pch = 0;
+ uint8_t right_channel;
+ ic_stream *ics, *icsr;
+ ltp_info *ltp;
+
+ /* find the syntax element to which this channel belongs */
+ for (i = 0; i < ch_ele; i++)
+ {
+ if (syntax_elements[i]->channel == ch)
+ {
+ ics = &(syntax_elements[i]->ics1);
+ icsr = &(syntax_elements[i]->ics2);
+ ltp = &(ics->ltp);
+ pch = syntax_elements[i]->paired_channel;
+ right_channel = 0;
+ break;
+ } else if (syntax_elements[i]->paired_channel == ch) {
+ ics = &(syntax_elements[i]->ics2);
+ ltp = &(ics->ltp2);
+ right_channel = 1;
+ break;
+ }
+ }
+
+ /* mid/side decoding */
+ if (!right_channel)
+ ms_decode(ics, icsr, spec_coef[ch], spec_coef[pch], frame_len);
+
+ /* pns decoding */
+ pns_decode(ics, spec_coef[ch], frame_len);
+
+ /* intensity stereo decoding */
+ if (!right_channel)
+ is_decode(ics, icsr, spec_coef[ch], spec_coef[pch], frame_len);
+
+#ifdef MAIN_DEC
+ /* MAIN object type prediction */
+ if (object_type == MAIN)
+ {
+ /* allocate the state only when needed */
+ if (pred_stat[ch] == NULL)
+ {
+ pred_stat[ch] = malloc(frame_len * sizeof(pred_state));
+ reset_all_predictors(pred_stat[ch], frame_len);
+ }
+
+ /* intra channel prediction */
+ ic_prediction(ics, spec_coef[ch], pred_stat[ch], frame_len);
+
+ /* In addition, for scalefactor bands coded by perceptual
+ noise substitution the predictors belonging to the
+ corresponding spectral coefficients are reset.
+ */
+ pns_reset_pred_state(ics, pred_stat[ch]);
+ }
+#endif
+#ifdef LTP_DEC
+ else if ((object_type == LTP)
+#ifdef ERROR_RESILIENCE
+ || (object_type == ER_LTP)
+#endif
+#ifdef LD_DEC
+ || (object_type == LD)
+#endif
+ )
+ {
+#ifdef LD_DEC
+ if (object_type == LD)
+ {
+ if (ltp->data_present)
+ {
+ if (!ltp->lag_update)
+ ltp->lag = ltp_lag[ch];
+ else
+ ltp_lag[ch] = ltp->lag;
+ }
+ }
+#endif
+
+ /* allocate the state only when needed */
+ if (lt_pred_stat[ch] == NULL)
+ {
+ lt_pred_stat[ch] = malloc(frame_len*4 * sizeof(real_t));
+ memset(lt_pred_stat[ch], 0, frame_len*4 * sizeof(real_t));
+ }
+
+ /* long term prediction */
+ lt_prediction(ics, ltp, spec_coef[ch], lt_pred_stat[ch], fb,
+ ics->window_shape, window_shape_prev[ch],
+ sf_index, object_type, frame_len);
+ }
+#endif
+
+ /* tns decoding */
+ tns_decode_frame(ics, &(ics->tns), sf_index, object_type,
+ spec_coef[ch], frame_len);
+
+ /* drc decoding */
+ if (drc->present)
+ {
+ if (!drc->exclude_mask[ch] || !drc->excluded_chns_present)
+ drc_decode(drc, spec_coef[ch]);
+ }
+
+ if (time_state[ch] == NULL)
+ {
+ real_t *tp;
+
+ time_state[ch] = malloc(frame_len*sizeof(real_t));
+ tp = time_state[ch];
+ for (i = frame_len/16-1; i >= 0; --i)
+ {
+ *tp++ = 0; *tp++ = 0; *tp++ = 0; *tp++ = 0;
+ *tp++ = 0; *tp++ = 0; *tp++ = 0; *tp++ = 0;
+ *tp++ = 0; *tp++ = 0; *tp++ = 0; *tp++ = 0;
+ *tp++ = 0; *tp++ = 0; *tp++ = 0; *tp++ = 0;
+ }
+ }
+ if (time_out[ch] == NULL)
+ {
+ time_out[ch] = malloc(frame_len*2*sizeof(real_t));
+ }
+
+ /* filter bank */
+ ifilter_bank(fb, ics->window_sequence, ics->window_shape,
+ window_shape_prev[ch], spec_coef[ch], time_state[ch],
+ time_out[ch], object_type, frame_len);
+ /* save window shape for next frame */
+ window_shape_prev[ch] = ics->window_shape;
+
+#ifdef LTP_DEC
+ if ((object_type == LTP)
+#ifdef ERROR_RESILIENCE
+ || (object_type == ER_LTP)
+#endif
+#ifdef LD_DEC
+ || (object_type == LD)
+#endif
+ )
+ {
+ lt_update_state(lt_pred_stat[ch], time_out[ch], time_state[ch],
+ frame_len, object_type);
+ }
+#endif
+ }
+
+ sample_buffer = output_to_PCM(time_out, sample_buffer, channels,
+ frame_len, outputFormat);
+
+ hDecoder->frame++;
+#ifdef LD_DEC
+ if (object_type != LD)
+ {
+#endif
+ if (hDecoder->frame <= 1)
+ hInfo->samples = 0;
+#ifdef LD_DEC
+ } else {
+ /* LD encoders will give lower delay */
+ if (hDecoder->frame <= 0)
+ hInfo->samples = 0;
+ }
+#endif
+
+ /* cleanup */
+ for (ch = 0; ch < channels; ch++)
+ {
+ free(spec_coef[ch]);
+ free(spec_data[ch]);
+ }
+
+ for (i = 0; i < ch_ele; i++)
+ {
+ free(syntax_elements[i]);
+ }
+
+#ifdef ANALYSIS
+ fflush(stdout);
+#endif
+
+ return sample_buffer;
+
+error:
+ /* free all memory that could have been allocated */
+ if (ld) free(ld);
+
+ /* cleanup */
+ for (ch = 0; ch < channels; ch++)
+ {
+ free(spec_coef[ch]);
+ free(spec_data[ch]);
+ }
+
+ for (i = 0; i < ch_ele; i++)
+ {
+ free(syntax_elements[i]);
+ }
+
+#ifdef ANALYSIS
+ fflush(stdout);
+#endif
+
+ return NULL;
+}
diff --git a/src/libfaad/decoder.h b/src/libfaad/decoder.h
new file mode 100644
index 000000000..fb9f8c8c4
--- /dev/null
+++ b/src/libfaad/decoder.h
@@ -0,0 +1,146 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: decoder.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __DECODER_H__
+#define __DECODER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN32
+ #pragma pack(push, 8)
+ #ifndef FAADAPI
+ #define FAADAPI __cdecl
+ #endif
+#else
+ #ifndef FAADAPI
+ #define FAADAPI
+ #endif
+#endif
+
+#include "bits.h"
+#include "syntax.h"
+#include "specrec.h"
+#include "filtbank.h"
+#include "ic_predict.h"
+
+
+#define FAAD_FMT_16BIT 1
+#define FAAD_FMT_24BIT 2
+#define FAAD_FMT_32BIT 3
+#define FAAD_FMT_FLOAT 4
+
+typedef struct faacDecConfiguration
+{
+ uint8_t defObjectType;
+ uint32_t defSampleRate;
+ uint8_t outputFormat;
+} faacDecConfiguration, *faacDecConfigurationPtr;
+
+typedef struct faacDecFrameInfo
+{
+ uint32_t bytesconsumed;
+ uint32_t samples;
+ uint8_t channels;
+ uint8_t error;
+} faacDecFrameInfo;
+
+typedef struct
+{
+ uint8_t adts_header_present;
+ uint8_t adif_header_present;
+ uint8_t sf_index;
+ uint8_t object_type;
+ uint8_t channelConfiguration;
+ uint8_t aacSectionDataResilienceFlag;
+ uint8_t aacScalefactorDataResilienceFlag;
+ uint8_t aacSpectralDataResilienceFlag;
+ uint16_t frameLength;
+
+ uint32_t frame;
+
+ void *sample_buffer;
+
+ uint8_t window_shape_prev[MAX_CHANNELS];
+#ifdef LTP_DEC
+ uint16_t ltp_lag[MAX_CHANNELS];
+#endif
+ fb_info fb;
+ drc_info drc;
+
+ real_t *time_state[MAX_CHANNELS];
+ real_t *time_out[MAX_CHANNELS];
+
+#ifdef MAIN_DEC
+ pred_state *pred_stat[MAX_CHANNELS];
+#endif
+#ifdef LTP_DEC
+ real_t *lt_pred_stat[MAX_CHANNELS];
+#endif
+
+ real_t exp_table[256];
+ real_t mnt_table[128];
+
+ real_t iq_table[IQ_TABLE_SIZE];
+#if POW_TABLE_SIZE
+ real_t pow2_table[POW_TABLE_SIZE];
+#endif
+
+ /* Configuration data */
+ faacDecConfiguration config;
+} faacDecStruct, *faacDecHandle;
+
+
+uint8_t* FAADAPI faacDecGetErrorMessage(uint8_t errcode);
+
+faacDecHandle FAADAPI faacDecOpen();
+
+faacDecConfigurationPtr FAADAPI faacDecGetCurrentConfiguration(faacDecHandle hDecoder);
+
+uint8_t FAADAPI faacDecSetConfiguration(faacDecHandle hDecoder,
+ faacDecConfigurationPtr config);
+
+/* Init the library based on info from the AAC file (ADTS/ADIF) */
+int32_t FAADAPI faacDecInit(faacDecHandle hDecoder,
+ uint8_t *buffer,
+ uint32_t *samplerate,
+ uint8_t *channels);
+
+/* Init the library using a DecoderSpecificInfo */
+int8_t FAADAPI faacDecInit2(faacDecHandle hDecoder, uint8_t *pBuffer,
+ uint32_t SizeOfDecoderSpecificInfo,
+ uint32_t *samplerate, uint8_t *channels);
+
+void FAADAPI faacDecClose(faacDecHandle hDecoder);
+
+void* FAADAPI faacDecDecode(faacDecHandle hDecoder,
+ faacDecFrameInfo *hInfo,
+ uint8_t *buffer);
+
+#ifdef _WIN32
+ #pragma pack(pop)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/drc.c b/src/libfaad/drc.c
new file mode 100644
index 000000000..0da3ed110
--- /dev/null
+++ b/src/libfaad/drc.c
@@ -0,0 +1,77 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: drc.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+
+#include <memory.h>
+#include "syntax.h"
+#include "drc.h"
+
+void init_drc(drc_info *drc, real_t cut, real_t boost)
+{
+ memset(drc, 0, sizeof(drc_info));
+
+ drc->ctrl1 = cut;
+ drc->ctrl2 = boost;
+
+ drc->num_bands = 1;
+ drc->band_top[0] = 1024/4 - 1;
+ drc->dyn_rng_sgn[0] = 1;
+ drc->dyn_rng_ctl[0] = 0;
+}
+
+void drc_decode(drc_info *drc, real_t *spec)
+{
+ uint16_t i, bd, top;
+ real_t factor;
+ uint16_t bottom = 0;
+
+ if (drc->num_bands == 1)
+ drc->band_top[0] = 1024/4 - 1;
+
+ for (bd = 0; bd < drc->num_bands; bd++)
+ {
+ top = 4 * (drc->band_top[bd] + 1);
+
+ /* Decode DRC gain factor */
+ if (drc->dyn_rng_sgn[bd]) /* compress */
+ factor = (real_t)exp(LN2 * (-drc->ctrl1 * drc->dyn_rng_ctl[bd]/24.0));
+ else /* boost */
+ factor = (real_t)exp(LN2 * (drc->ctrl2 * drc->dyn_rng_ctl[bd]/24.0));
+
+ /* Level alignment between different programs (if desired) */
+ /* If program reference normalization is done in the digital domain,
+ modify factor to perform normalization.
+ prog_ref_level can alternatively be passed to the system for
+ modification of the level in the analog domain. Analog level
+ modification avoids problems with reduced DAC SNR (if signal is
+ attenuated) or clipping (if signal is boosted)
+ */
+ factor = MUL(factor,
+ (real_t)exp(LN05 * ((DRC_REF_LEVEL - drc->prog_ref_level)/24.0)));
+
+ /* Apply gain factor */
+ for (i = bottom; i < top; i++)
+ spec[i] = MUL(spec[i], factor);
+
+ bottom = top;
+ }
+}
diff --git a/src/libfaad/drc.h b/src/libfaad/drc.h
new file mode 100644
index 000000000..d81e8f717
--- /dev/null
+++ b/src/libfaad/drc.h
@@ -0,0 +1,38 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: drc.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __DRC_H__
+#define __DRC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DRC_REF_LEVEL 20*4 /* -20 dB */
+
+void init_drc(drc_info *drc, real_t cut, real_t boost);
+void drc_decode(drc_info *drc, real_t *spec);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/error.c b/src/libfaad/error.c
new file mode 100644
index 000000000..8b31c01fc
--- /dev/null
+++ b/src/libfaad/error.c
@@ -0,0 +1,38 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: error.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+#include "error.h"
+
+extern uint8_t *err_msg[] = {
+ "No error",
+ "Gain control not yet implemented",
+ "Pulse coding not allowed in short blocks",
+ "Invalid huffman codebook",
+ "Negative scalefactor found, should be impossible",
+ "Unable to find ADTS syncword",
+ "Channel coupling not yet implemented",
+ "Channel configuration not allowed in error resilient frame",
+ "Bit error in error resilient scalefactor decoding",
+ "Error decoding huffman scalefactor (bitstream error)",
+ "Error decoding huffman codeword (bitstream error)",
+ "Non existent huffman codebook number found"
+}; \ No newline at end of file
diff --git a/src/libfaad/error.h b/src/libfaad/error.h
new file mode 100644
index 000000000..5a9f38b09
--- /dev/null
+++ b/src/libfaad/error.h
@@ -0,0 +1,34 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: error.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __ERROR_H__
+#define __ERROR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern uint8_t *err_msg[];
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/faad.h b/src/libfaad/faad.h
new file mode 100644
index 000000000..68e5bf3a6
--- /dev/null
+++ b/src/libfaad/faad.h
@@ -0,0 +1,121 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: faad.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __AACDEC_H__
+#define __AACDEC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef _WIN32
+ #pragma pack(push, 8)
+ #ifndef FAADAPI
+ #define FAADAPI __cdecl
+ #endif
+#else
+ #ifndef FAADAPI
+ #define FAADAPI
+ #endif
+#endif
+
+
+#define MAIN 0
+#define LC 1
+#define SSR 2
+#define LTP 3
+#define ER_LC 17
+#define LD 23
+#define DRM_ER_LC 27 /* special object type for DRM */
+
+#define FAAD_FMT_16BIT 1
+#define FAAD_FMT_24BIT 2
+#define FAAD_FMT_32BIT 3
+#define FAAD_FMT_FLOAT 4
+
+/* A decode call can eat up to FAAD_MIN_STREAMSIZE octets per decoded channel,
+ so at least so much octets per channel should be available in this stream */
+#define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */
+
+
+typedef void *faacDecHandle;
+
+
+typedef struct faacDecConfiguration
+{
+ unsigned char defObjectType;
+ unsigned long defSampleRate;
+ unsigned char outputFormat;
+} faacDecConfiguration, *faacDecConfigurationPtr;
+
+typedef struct faacDecFrameInfo
+{
+ unsigned long bytesconsumed;
+ unsigned long samples;
+ unsigned char channels;
+ unsigned char error;
+} faacDecFrameInfo;
+
+unsigned char* FAADAPI faacDecGetErrorMessage(unsigned char errcode);
+
+faacDecHandle FAADAPI faacDecOpen();
+
+faacDecConfigurationPtr FAADAPI faacDecGetCurrentConfiguration(faacDecHandle hDecoder);
+
+unsigned char FAADAPI faacDecSetConfiguration(faacDecHandle hDecoder,
+ faacDecConfigurationPtr config);
+
+/* Init the library based on info from the AAC file (ADTS/ADIF) */
+long FAADAPI faacDecInit(faacDecHandle hDecoder,
+ unsigned char *buffer,
+ unsigned long *samplerate,
+ unsigned char *channels);
+
+/* Init the library using a DecoderSpecificInfo */
+char FAADAPI faacDecInit2(faacDecHandle hDecoder, unsigned char *pBuffer,
+ unsigned long SizeOfDecoderSpecificInfo,
+ unsigned long *samplerate, unsigned char *channels);
+
+void FAADAPI faacDecClose(faacDecHandle hDecoder);
+
+void* FAADAPI faacDecDecode(faacDecHandle hDecoder,
+ faacDecFrameInfo *hInfo,
+ unsigned char *buffer);
+
+char FAADAPI AudioSpecificConfig(unsigned char *pBuffer,
+ unsigned long *samplerate,
+ unsigned char *channels,
+ unsigned char *sf_index,
+ unsigned char *object_type,
+ unsigned char *aacSectionDataResilienceFlag,
+ unsigned char *aacScalefactorDataResilienceFlag,
+ unsigned char *aacSpectralDataResilienceFlag,
+ unsigned char *frameLengthFlag);
+
+#ifdef _WIN32
+ #pragma pack(pop)
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/src/libfaad/filtbank.c b/src/libfaad/filtbank.c
new file mode 100644
index 000000000..092c17600
--- /dev/null
+++ b/src/libfaad/filtbank.c
@@ -0,0 +1,442 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: filtbank.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include "filtbank.h"
+#include "syntax.h"
+#include "kbd_win.h"
+#include "mdct.h"
+
+
+void filter_bank_init(fb_info *fb, uint16_t frame_len)
+{
+ uint16_t i;
+ uint16_t nshort = frame_len/8;
+#ifdef LD_DEC
+ uint16_t frame_len_ld = frame_len/2;
+#endif
+
+ /* normal */
+ faad_mdct_init(&(fb->mdct256), 2*nshort);
+ faad_mdct_init(&(fb->mdct2048), 2*frame_len);
+
+ fb->long_window[0] = malloc(frame_len*sizeof(real_t));
+ fb->short_window[0] = malloc(nshort*sizeof(real_t));
+ fb->long_window[1] = kbd_long;
+ fb->short_window[1] = kbd_short;
+
+ /* calculate the sine windows */
+ for (i = 0; i < frame_len; i++)
+ fb->long_window[0][i] = (real_t)sin(M_PI / (2.0 * frame_len) * (i + 0.5));
+ for (i = 0; i < nshort; i++)
+ fb->short_window[0][i] = (real_t)sin(M_PI / (2.0 * nshort) * (i + 0.5));
+
+#ifdef LD_DEC
+ /* LD */
+ faad_mdct_init(&(fb->mdct1024), frame_len_ld);
+
+ fb->ld_window[0] = malloc(frame_len_ld*sizeof(real_t));
+ fb->ld_window[1] = malloc(frame_len_ld*sizeof(real_t));
+
+ /* calculate the sine windows */
+ for (i = 0; i < frame_len_ld; i++)
+ fb->ld_window[0][i] = (real_t)sin(M_PI / (2.0 * frame_len_ld) * (i + 0.5));
+
+ /* low overlap window */
+ for (i = 0; i < 3*(frame_len_ld>>3); i++)
+ fb->ld_window[1][i] = 0.0;
+ for (; i < 5*(frame_len_ld>>3); i++)
+ fb->ld_window[1][i] = (real_t)sin((i-3*(frame_len_ld>>3)+0.5) * M_PI / (frame_len_ld>>1));
+ for (; i < frame_len_ld; i++)
+ fb->ld_window[1][i] = 1.0;
+#endif
+}
+
+void filter_bank_end(fb_info *fb)
+{
+ faad_mdct_end(&(fb->mdct256));
+ faad_mdct_end(&(fb->mdct2048));
+
+ if (fb->long_window[0]) free(fb->long_window[0]);
+ if (fb->short_window[0]) free(fb->short_window[0]);
+
+#ifdef LD_DEC
+ faad_mdct_end(&(fb->mdct1024));
+
+ if (fb->ld_window[0]) free(fb->ld_window[0]);
+ if (fb->ld_window[1]) free(fb->ld_window[1]);
+#endif
+}
+
+static INLINE void vcopy(real_t *src, real_t *dest, uint16_t vlen)
+{
+ int16_t i;
+
+ assert(vlen % 4 == 0);
+
+ for (i = vlen/4-1; i >= 0; --i)
+ {
+ *dest++ = *src++; *dest++ = *src++; *dest++ = *src++; *dest++ = *src++;
+ }
+}
+
+static INLINE void vzero(real_t *dest, uint16_t vlen)
+{
+ int16_t i;
+
+ assert(vlen % 4 == 0);
+
+ for (i = vlen/4-1; i >= 0; --i)
+ {
+ *dest-- = 0; *dest-- = 0; *dest-- = 0; *dest-- = 0;
+ }
+}
+
+static INLINE void vmult1(real_t *src1, real_t *src2, real_t *dest, uint16_t vlen)
+{
+ int16_t i;
+
+ assert(vlen % 4 == 0);
+
+ for (i = vlen/4-1; i >= 0 ; --i)
+ {
+ *dest++ = MUL(*src1++, *src2++); *dest++ = MUL(*src1++, *src2++);
+ *dest++ = MUL(*src1++, *src2++); *dest++ = MUL(*src1++, *src2++);
+ }
+}
+
+static INLINE void vmult2(real_t *src1, real_t *src2, real_t *dest, uint16_t vlen)
+{
+ int16_t i;
+
+ assert(vlen % 4 == 0);
+
+ for (i = vlen/4-1; i >= 0 ; --i)
+ {
+ *dest++ = MUL(*src1++, *src2--); *dest++ = MUL(*src1++, *src2--);
+ *dest++ = MUL(*src1++, *src2--); *dest++ = MUL(*src1++, *src2--);
+ }
+}
+
+static INLINE void vadd(real_t *src1, real_t *src2, real_t *dest, uint16_t vlen)
+{
+ int16_t i;
+
+ assert(vlen % 4 == 0);
+
+ for (i = vlen/4-1; i >= 0; --i)
+ {
+ *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++;
+ *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++;
+/*
+ *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++;
+ *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++;
+ *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++;
+ *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++;
+ *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++;
+ *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++;
+*/
+ }
+}
+
+static INLINE void imdct(fb_info *fb, real_t *in_data, real_t *out_data, uint16_t len)
+{
+ mdct_info *mdct;
+
+ switch (len)
+ {
+ case 2048:
+ case 1920:
+ mdct = &(fb->mdct2048);
+ break;
+ case 256:
+ case 240:
+ mdct = &(fb->mdct256);
+ break;
+#ifdef LD_DEC
+ case 1024:
+ case 960:
+ mdct = &(fb->mdct1024);
+ break;
+#endif
+ }
+
+ faad_imdct(mdct, in_data, out_data);
+}
+
+#ifdef LTP_DEC
+static INLINE void mdct(fb_info *fb, real_t *in_data, real_t *out_data, uint16_t len)
+{
+ mdct_info *mdct;
+
+ switch (len)
+ {
+ case 2048:
+ case 1920:
+ mdct = &(fb->mdct2048);
+ break;
+ case 256:
+ case 120:
+ mdct = &(fb->mdct256);
+ break;
+#ifdef LD_DEC
+ case 1024:
+ case 960:
+ mdct = &(fb->mdct1024);
+ break;
+#endif
+ }
+
+ faad_mdct(mdct, in_data, out_data);
+}
+#endif
+
+void ifilter_bank(fb_info *fb, uint8_t window_sequence, uint8_t window_shape,
+ uint8_t window_shape_prev, real_t *freq_in, real_t *time_buff,
+ real_t *time_out, uint8_t object_type, uint16_t frame_len)
+{
+ real_t *o_buf, *transf_buf;
+ real_t *obuf_temp;
+
+ real_t *window_long;
+ real_t *window_long_prev;
+ real_t *window_short;
+ real_t *window_short_prev;
+ real_t *window_short_prev_ptr;
+
+ real_t *fp;
+ int8_t win;
+ uint16_t nlong = frame_len;
+ uint16_t nshort = frame_len/8;
+
+ uint16_t nflat_ls = (nlong-nshort)/2;
+
+ transf_buf = malloc(2*nlong*sizeof(real_t));
+
+#ifdef LD_DEC
+ if (object_type == LD)
+ {
+ window_long = fb->ld_window[window_shape];
+ window_long_prev = fb->ld_window[window_shape_prev];
+ } else {
+#endif
+ window_long = fb->long_window[window_shape];
+ window_long_prev = fb->long_window[window_shape_prev];
+ window_short = fb->short_window[window_shape];
+ window_short_prev = fb->short_window[window_shape_prev];
+#ifdef LD_DEC
+ }
+#endif
+
+ /* pointer to previous window function */
+ window_short_prev_ptr = window_short_prev;
+
+ vcopy(time_buff, time_out, nlong);
+ o_buf = time_out;
+
+ switch (window_sequence)
+ {
+ case ONLY_LONG_SEQUENCE:
+ /* inverse transform */
+ imdct(fb, freq_in, transf_buf, 2*nlong);
+
+ /* window function (previous) on first half of the new data */
+ vmult1(transf_buf, window_long_prev, transf_buf, nlong);
+
+ /* overlap and add second half of the old data with first half
+ of the new data */
+ vadd(transf_buf, o_buf, o_buf, nlong);
+
+ /* reversed window function on second half of the new data */
+ vmult2(transf_buf+nlong, window_long+nlong-1, o_buf+nlong, nlong);
+ break;
+
+ case LONG_START_SEQUENCE:
+ /* inverse transform */
+ imdct(fb, freq_in, transf_buf, 2*nlong);
+
+ /* window function (previous) on first half of the new data */
+ vmult1(transf_buf, window_long_prev, transf_buf, nlong);
+
+ /* overlap and add second half of the old data with first half
+ of the new data */
+ vadd(transf_buf, o_buf, o_buf, nlong);
+
+ /* copy data from nlong upto (3*nlong-nshort)/4; (window function = 1.0) */
+ vcopy(transf_buf+nlong, o_buf+nlong, nflat_ls);
+
+ /* reversed window function on part of second half of the new data */
+ vmult2(transf_buf+nlong+nflat_ls, window_short+nshort-1,
+ o_buf+nlong+nflat_ls, nshort);
+
+ /* zero rest of the data; (window function = 0.0) */
+ vzero(o_buf+2*nlong-1, nflat_ls);
+ break;
+
+ case EIGHT_SHORT_SEQUENCE:
+ obuf_temp = malloc(2*nlong*sizeof(real_t));
+ vzero(obuf_temp+2*nlong-1, 2*nlong);
+
+ fp = obuf_temp;
+ vcopy(time_buff+nflat_ls, fp, nshort);
+
+ for (win = 8-1; win >= 0; --win)
+ {
+ /* inverse transform */
+ imdct(fb, freq_in, transf_buf, 2*nshort);
+
+ /* window function (previous) on first half of the new data */
+ vmult1(transf_buf, window_short_prev_ptr, transf_buf, nshort);
+
+ /* overlap and add second half of the old data with first half
+ of the new data */
+ vadd(transf_buf, fp, fp, nshort);
+
+ /* reversed window function on second half of the new data */
+ vmult2(transf_buf+nshort, window_short+nshort-1, fp+nshort, nshort);
+
+ /* shift to next short block */
+ freq_in += nshort;
+ fp += nshort;
+ window_short_prev_ptr = window_short;
+ }
+
+ vcopy(obuf_temp, o_buf + 448, nlong*2-nflat_ls);
+ vzero(o_buf+2*nlong-1, nflat_ls);
+
+ free(obuf_temp);
+ break;
+
+ case LONG_STOP_SEQUENCE:
+ /* inverse transform */
+ imdct(fb, freq_in, transf_buf, 2*nlong);
+
+ /* zero first part of first half of the data (window function = 0.0) */
+ vzero(transf_buf+nflat_ls-1, nflat_ls);
+
+ /* window function (previous) on part of the first half of
+ the new data */
+ vmult1(transf_buf+nflat_ls, window_short_prev_ptr,
+ transf_buf+nflat_ls, nshort);
+
+ /* third part of the stop sequence window is window function = 1,
+ so no need to actually apply that */
+
+ /* overlap and add second half of the old data with first half
+ of the new data */
+ vadd(transf_buf, o_buf, o_buf, nlong);
+
+ /* reversed window function on second half of the new data */
+ vmult2(transf_buf+nlong, window_long+nlong-1, o_buf+nlong, nlong);
+ break;
+ }
+
+ /* save second half of data */
+ vcopy(o_buf+nlong, time_buff, nlong);
+
+ free(transf_buf);
+}
+
+#ifdef LTP_DEC
+/* only works for LTP -> no overlapping */
+void filter_bank_ltp(fb_info *fb, uint8_t window_sequence, uint8_t window_shape,
+ uint8_t window_shape_prev, real_t *in_data, real_t *out_mdct,
+ uint8_t object_type, uint16_t frame_len)
+{
+ int8_t win;
+ real_t *windowed_buf;
+ real_t *p_o_buf;
+
+ real_t *window_long;
+ real_t *window_long_prev;
+ real_t *window_short;
+ real_t *window_short_prev;
+ real_t *window_short_prev_ptr;
+
+ uint16_t nlong = frame_len;
+ uint16_t nshort = frame_len/8;
+ uint16_t nflat_ls = (nlong-nshort)/2;
+
+ windowed_buf = malloc(nlong*2*sizeof(real_t));
+
+#ifdef LD_DEC
+ if (object_type == LD)
+ {
+ window_long = fb->ld_window[window_shape];
+ window_long_prev = fb->ld_window[window_shape_prev];
+ } else {
+#endif
+ window_long = fb->long_window[window_shape];
+ window_long_prev = fb->long_window[window_shape_prev];
+ window_short = fb->short_window[window_shape];
+ window_short_prev = fb->short_window[window_shape_prev];
+#ifdef LD_DEC
+ }
+#endif
+
+ window_short_prev_ptr = window_short_prev;
+
+ p_o_buf = in_data;
+
+ switch(window_sequence)
+ {
+ case ONLY_LONG_SEQUENCE:
+ vmult1(p_o_buf, window_long_prev, windowed_buf, nlong);
+ vmult2(p_o_buf+nlong, window_long+nlong-1, windowed_buf+nlong, nlong);
+ mdct(fb, windowed_buf, out_mdct, 2*nlong);
+ break;
+
+ case LONG_START_SEQUENCE:
+ vmult1(p_o_buf, window_long_prev, windowed_buf, nlong);
+ vcopy(p_o_buf+nlong, windowed_buf+nlong, nflat_ls);
+ vmult2(p_o_buf+nlong+nflat_ls, window_short+nshort-1, windowed_buf+nlong+nflat_ls, nshort);
+ vzero(windowed_buf+2*nlong-1, nflat_ls);
+ mdct(fb, windowed_buf, out_mdct, 2*nlong);
+ break;
+
+ case EIGHT_SHORT_SEQUENCE:
+ for (win = 8-1; win >= 0; --win)
+ {
+ vmult1(p_o_buf, window_short_prev_ptr, windowed_buf, nshort);
+ vmult2(p_o_buf+nshort, window_short+nshort-1, windowed_buf+nshort, nshort);
+ mdct(fb, windowed_buf, out_mdct, 2*nshort);
+
+ out_mdct += nshort;
+ p_o_buf += 2*nshort;
+ window_short_prev_ptr = window_short;
+ }
+ break;
+
+ case LONG_STOP_SEQUENCE:
+ vzero(windowed_buf+nflat_ls-1, nflat_ls);
+ vmult1(p_o_buf+nflat_ls, window_short_prev_ptr, windowed_buf+nflat_ls, nshort);
+ vcopy(p_o_buf+nflat_ls+nshort, windowed_buf+nflat_ls+nshort, nflat_ls);
+ vmult2(p_o_buf+nlong, window_long+nlong-1, windowed_buf+nlong, nlong);
+ mdct(fb, windowed_buf, out_mdct, 2*nlong);
+ break;
+ }
+
+ free(windowed_buf);
+}
+#endif
diff --git a/src/libfaad/filtbank.h b/src/libfaad/filtbank.h
new file mode 100644
index 000000000..e84e729e0
--- /dev/null
+++ b/src/libfaad/filtbank.h
@@ -0,0 +1,74 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: filtbank.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __FILTBANK_H__
+#define __FILTBANK_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mdct.h"
+
+
+typedef struct
+{
+ real_t *long_window[2];
+ real_t *short_window[2];
+#ifdef LD_DEC
+ real_t *ld_window[2];
+#endif
+
+ mdct_info mdct256;
+#ifdef LD_DEC
+ mdct_info mdct1024;
+#endif
+ mdct_info mdct2048;
+} fb_info;
+
+void filter_bank_init(fb_info *fb, uint16_t frame_len);
+void filter_bank_end(fb_info *fb);
+
+#ifdef LTP_DEC
+void filter_bank_ltp(fb_info *fb,
+ uint8_t window_sequence,
+ uint8_t window_shape,
+ uint8_t window_shape_prev,
+ real_t *in_data,
+ real_t *out_mdct,
+ uint8_t object_type,
+ uint16_t frame_len);
+#endif
+
+void ifilter_bank(fb_info *fb,
+ uint8_t window_sequence,
+ uint8_t window_shape,
+ uint8_t window_shape_prev,
+ real_t *freq_in,
+ real_t *time_buff,
+ real_t *time_out,
+ uint8_t object_type,
+ uint16_t frame_len);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/huffman.h b/src/libfaad/huffman.h
new file mode 100644
index 000000000..b67e1eab0
--- /dev/null
+++ b/src/libfaad/huffman.h
@@ -0,0 +1,279 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: huffman.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __HUFFMAN_H__
+#define __HUFFMAN_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#ifdef ANALYSIS
+#include <stdio.h>
+#endif
+#include "bits.h"
+#include "codebook/hcb.h"
+
+
+static INLINE int8_t huffman_scale_factor(bitfile *ld)
+{
+ uint16_t offset = 0;
+
+ while (hcb_sf[offset][1])
+ {
+ uint8_t b = faad_get1bit(ld
+ DEBUGVAR(1,255,"huffman_scale_factor()"));
+ offset += hcb_sf[offset][b];
+
+ if (offset > 240)
+ {
+ /* printf("ERROR: offset into hcb_sf = %d >240!\n", offset); */
+ return -1;
+ }
+ }
+
+ return hcb_sf[offset][0];
+}
+
+
+static hcb *hcb_table[] = {
+ 0, hcb1_1, hcb2_1, 0, hcb4_1, 0, hcb6_1, 0, hcb8_1, 0, hcb10_1, hcb11_1
+};
+
+static hcb_2_quad *hcb_2_quad_table[] = {
+ 0, hcb1_2, hcb2_2, 0, hcb4_2, 0, 0, 0, 0, 0, 0, 0
+};
+
+static hcb_2_pair *hcb_2_pair_table[] = {
+ 0, 0, 0, 0, 0, 0, hcb6_2, 0, hcb8_2, 0, hcb10_2, hcb11_2
+};
+
+static hcb_bin_pair *hcb_bin_table[] = {
+ 0, 0, 0, 0, 0, hcb5, 0, hcb7, 0, hcb9, 0, 0
+};
+
+static uint8_t hcbN[] = { 0, 5, 5, 0, 5, 0, 5, 0, 5, 0, 6, 5 };
+
+static int hcb_2_quad_table_size[] = { 0, 114, 86, 0, 185, 0, 0, 0, 0, 0, 0, 0 };
+static int hcb_2_pair_table_size[] = { 0, 0, 0, 0, 0, 0, 126, 0, 83, 0, 210, 373 };
+static int hcb_bin_table_size[] = { 0, 0, 0, 161, 0, 161, 0, 127, 0, 337, 0, 0 };
+
+static INLINE uint8_t huffman_spectral_data(uint8_t cb, bitfile *ld, int16_t *sp)
+{
+ uint32_t cw;
+ uint16_t offset = 0;
+ uint8_t extra_bits;
+
+ switch (cb)
+ {
+ case 1: /* 2-step method for data quadruples */
+ case 2:
+ case 4:
+
+ cw = faad_showbits(ld, hcbN[cb]);
+ offset = hcb_table[cb][cw].offset;
+ extra_bits = hcb_table[cb][cw].extra_bits;
+
+ if (extra_bits)
+ {
+ /* we know for sure it's more than hcbN[cb] bits long */
+ faad_flushbits(ld, hcbN[cb]);
+ offset += (uint16_t)faad_showbits(ld, extra_bits);
+ faad_flushbits(ld, hcb_2_quad_table[cb][offset].bits - hcbN[cb]);
+ } else {
+ faad_flushbits(ld, hcb_2_quad_table[cb][offset].bits);
+ }
+
+ if (offset > hcb_2_quad_table_size[cb])
+ {
+ /* printf("ERROR: offset into hcb_2_quad_table = %d >%d!\n", offset,
+ hcb_2_quad_table_size[cb]); */
+ return 10;
+ }
+
+ sp[0] = hcb_2_quad_table[cb][offset].x;
+ sp[1] = hcb_2_quad_table[cb][offset].y;
+ sp[2] = hcb_2_quad_table[cb][offset].v;
+ sp[3] = hcb_2_quad_table[cb][offset].w;
+
+ return 0;
+
+ case 6: /* 2-step method for data pairs */
+ case 8:
+ case 10:
+ case 11:
+#ifdef ERROR_RESILIENCE
+ /* VCB11 uses codebook 11 */
+ case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
+ case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31:
+
+ /* TODO: If ER is used, some extra error checking should be done */
+ if (cb >= 16)
+ cb = 11;
+#endif
+ cw = faad_showbits(ld, hcbN[cb]);
+ offset = hcb_table[cb][cw].offset;
+ extra_bits = hcb_table[cb][cw].extra_bits;
+
+ if (extra_bits)
+ {
+ /* we know for sure it's more than hcbN[cb] bits long */
+ faad_flushbits(ld, hcbN[cb]);
+ offset += (uint16_t)faad_showbits(ld, extra_bits);
+ faad_flushbits(ld, hcb_2_pair_table[cb][offset].bits - hcbN[cb]);
+ } else {
+ faad_flushbits(ld, hcb_2_pair_table[cb][offset].bits);
+ }
+
+ if (offset > hcb_2_pair_table_size[cb])
+ {
+ /* printf("ERROR: offset into hcb_2_pair_table = %d >%d!\n", offset,
+ hcb_2_pair_table_size[cb]); */
+ return 10;
+ }
+
+ sp[0] = hcb_2_pair_table[cb][offset].x;
+ sp[1] = hcb_2_pair_table[cb][offset].y;
+
+ return 0;
+
+ case 3: /* binary search for data quadruples */
+
+ while (!hcb3[offset].is_leaf)
+ {
+ uint8_t b = faad_get1bit(ld
+ DEBUGVAR(1,255,"huffman_spectral_data():3"));
+ offset += hcb3[offset].data[b];
+ }
+
+ if (offset > hcb_bin_table_size[cb])
+ {
+ /* printf("ERROR: offset into hcb_bin_table = %d >%d!\n", offset,
+ hcb_bin_table_size[cb]); */
+ return 10;
+ }
+
+ sp[0] = hcb3[offset].data[0];
+ sp[1] = hcb3[offset].data[1];
+ sp[2] = hcb3[offset].data[2];
+ sp[3] = hcb3[offset].data[3];
+
+ return 0;
+
+ case 5: /* binary search for data pairs */
+ case 7:
+ case 9:
+
+ while (!hcb_bin_table[cb][offset].is_leaf)
+ {
+ uint8_t b = faad_get1bit(ld
+ DEBUGVAR(1,255,"huffman_spectral_data():9"));
+ offset += hcb_bin_table[cb][offset].data[b];
+ }
+
+ if (offset > hcb_bin_table_size[cb])
+ {
+ /* printf("ERROR: offset into hcb_bin_table = %d >%d!\n", offset,
+ hcb_bin_table_size[cb]); */
+ return 10;
+ }
+
+ sp[0] = hcb_bin_table[cb][offset].data[0];
+ sp[1] = hcb_bin_table[cb][offset].data[1];
+
+ return 0;
+
+ default:
+ /* Non existent codebook number, something went wrong */
+ return 11;
+ }
+
+ return 0;
+}
+
+static INLINE void huffman_sign_bits(bitfile *ld, int16_t *sp, uint8_t len)
+{
+ uint8_t i;
+
+ for(i = 0; i < len; i++)
+ {
+ if(sp[i])
+ {
+ if(faad_get1bit(ld
+ DEBUGVAR(1,5,"huffman_sign_bits(): sign bit")) & 1)
+ {
+ sp[i] = -sp[i];
+ }
+ }
+ }
+}
+
+static INLINE int32_t huffman_getescape(bitfile *ld, int16_t sp)
+{
+ uint8_t neg, i;
+ int32_t j, off;
+
+ if (sp < 0) {
+ if(sp != -16)
+ return sp;
+ neg = 1;
+ } else {
+ if(sp != 16)
+ return sp;
+ neg = 0;
+ }
+
+ for (i = 4; ; i++)
+ {
+ if (faad_get1bit(ld
+ DEBUGVAR(1,6,"huffman_getescape(): escape size")) == 0)
+ {
+ break;
+ }
+ }
+
+#if 0
+ if (i > 16)
+ {
+ off = faad_getbits(ld, i-16
+ DEBUGVAR(1,7,"huffman_getescape(): escape, first part")) << 16;
+ off |= faad_getbits(ld, 16
+ DEBUGVAR(1,8,"huffman_getescape(): escape, second part"));
+ } else {
+#endif
+ off = faad_getbits(ld, i
+ DEBUGVAR(1,9,"huffman_getescape(): escape"));
+#if 0
+ }
+#endif
+
+ j = off + (1<<i);
+ if (neg)
+ j = -j;
+
+ return j;
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/ic_predict.c b/src/libfaad/ic_predict.c
new file mode 100644
index 000000000..28f5a2d0a
--- /dev/null
+++ b/src/libfaad/ic_predict.c
@@ -0,0 +1,180 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: ic_predict.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+
+#ifdef MAIN_DEC
+
+#include "syntax.h"
+#include "ic_predict.h"
+#include "pns.h"
+
+static void flt_round_inf(real_t *pf)
+{
+ int32_t flg;
+ uint32_t tmp;
+ real_t *pt = (real_t *)&tmp;
+
+ *pt = *pf;
+ flg = tmp & (uint32_t)0x00008000;
+ tmp &= (uint32_t)0xffff0000;
+ *pf = *pt;
+
+ /* round 1/2 lsb toward infinity */
+ if (flg)
+ {
+ tmp &= (uint32_t)0xff800000; /* extract exponent and sign */
+ tmp |= (uint32_t)0x00010000; /* insert 1 lsb */
+ *pf += *pt; /* add 1 lsb and elided one */
+ tmp &= (uint32_t)0xff800000; /* extract exponent and sign */
+ *pf -= *pt; /* subtract elided one */
+ }
+}
+
+static void ic_predict(pred_state *state, real_t input, real_t *output, uint8_t pred)
+{
+ real_t dr1, predictedvalue;
+ real_t e0, e1;
+ real_t k1, k2;
+
+ real_t *r;
+ real_t *KOR;
+ real_t *VAR;
+
+ r = state->r; /* delay elements */
+ KOR = state->KOR; /* correlations */
+ VAR = state->VAR; /* variances */
+
+ k1 = KOR[0]/VAR[0]*B;
+
+ if (pred)
+ {
+ /* only needed for the actual predicted value, k1 is always needed */
+ k2 = KOR[1]/VAR[1]*B;
+
+ predictedvalue = MUL(k1, r[0]) + MUL(k2, r[1]);
+ flt_round_inf(&predictedvalue);
+
+ *output = input + predictedvalue;
+ } else {
+ *output = input;
+ }
+
+ /* calculate new state data */
+ e0 = *output;
+ e1 = e0 - MUL(k1, r[0]);
+
+ dr1 = k1 * e0;
+
+ VAR[0] = MUL(ALPHA, VAR[0]) + (0.5f) * (MUL(r[0], r[0]) + MUL(e0, e0));
+ KOR[0] = MUL(ALPHA, KOR[0]) + MUL(r[0], e0);
+ VAR[1] = MUL(ALPHA, VAR[1]) + (0.5f) * (MUL(r[1], r[1]) + MUL(e1, e1));
+ KOR[1] = MUL(ALPHA, KOR[1]) + MUL(r[1], e1);
+
+ r[1] = MUL(A, (r[0]-dr1));
+ r[0] = MUL(A, e0);
+}
+
+static void reset_pred_state(pred_state *state)
+{
+ state->r[0] = 0.0f;
+ state->r[1] = 0.0f;
+ state->KOR[0] = 0.0f;
+ state->KOR[1] = 0.0f;
+ state->VAR[0] = 1.0f;
+ state->VAR[1] = 1.0f;
+}
+
+void pns_reset_pred_state(ic_stream *ics, pred_state *state)
+{
+ uint8_t sfb, g, b;
+ uint16_t i, offs, offs2;
+
+ /* prediction only for long blocks */
+ if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+ return;
+
+ for (g = 0; g < ics->num_window_groups; g++)
+ {
+ for (b = 0; b < ics->window_group_length[g]; b++)
+ {
+ for (sfb = 0; sfb < ics->max_sfb; sfb++)
+ {
+ if (is_noise(ics, g, sfb))
+ {
+ offs = ics->swb_offset[sfb];
+ offs2 = ics->swb_offset[sfb+1];
+
+ for (i = offs; i < offs2; i++)
+ reset_pred_state(&state[i]);
+ }
+ }
+ }
+ }
+}
+
+void reset_all_predictors(pred_state *state, uint16_t frame_len)
+{
+ uint16_t i;
+
+ for (i = 0; i < frame_len; i++)
+ reset_pred_state(&state[i]);
+}
+
+/* intra channel prediction */
+void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state,
+ uint16_t frame_len)
+{
+ uint8_t sfb;
+ uint16_t bin;
+
+ if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+ {
+ reset_all_predictors(state, frame_len);
+ } else {
+ for (sfb = 0; sfb < ics->pred.limit; sfb++)
+ {
+ uint16_t low = ics->swb_offset[sfb];
+ uint16_t high = ics->swb_offset[sfb+1];
+
+ for (bin = low; bin < high; bin++)
+ {
+ ic_predict(&state[bin], spec[bin], &spec[bin],
+ (ics->predictor_data_present &&
+ ics->pred.prediction_used[sfb]));
+ }
+ }
+
+ if (ics->predictor_data_present)
+ {
+ if (ics->pred.predictor_reset)
+ {
+ for (bin = ics->pred.predictor_reset_group_number - 1;
+ bin < frame_len; bin += 30)
+ {
+ reset_pred_state(&state[bin]);
+ }
+ }
+ }
+ }
+}
+
+#endif
diff --git a/src/libfaad/ic_predict.h b/src/libfaad/ic_predict.h
new file mode 100644
index 000000000..054615329
--- /dev/null
+++ b/src/libfaad/ic_predict.h
@@ -0,0 +1,55 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: ic_predict.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifdef MAIN_DEC
+
+#ifndef __IC_PREDICT_H__
+#define __IC_PREDICT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ALPHA 0.90625f
+#define A 0.953125f
+#define B 0.953125f
+
+
+/* used to save the state */
+typedef struct {
+ real_t r[2];
+ real_t KOR[2];
+ real_t VAR[2];
+} pred_state;
+
+
+void pns_reset_pred_state(ic_stream *ics, pred_state *state);
+void reset_all_predictors(pred_state *state, uint16_t frame_len);
+void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state,
+ uint16_t frame_len);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif
diff --git a/src/libfaad/is.c b/src/libfaad/is.c
new file mode 100644
index 000000000..f64c41859
--- /dev/null
+++ b/src/libfaad/is.c
@@ -0,0 +1,69 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: is.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+
+#include "syntax.h"
+#include "is.h"
+
+void is_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec,
+ uint16_t frame_len)
+{
+ uint8_t g, sfb, b;
+ uint16_t i, k;
+ real_t scale;
+
+ uint16_t nshort = frame_len/8;
+ uint8_t group = 0;
+
+ for (g = 0; g < icsr->num_window_groups; g++)
+ {
+ /* Do intensity stereo decoding */
+ for (b = 0; b < icsr->window_group_length[g]; b++)
+ {
+ for (sfb = 0; sfb < icsr->max_sfb; sfb++)
+ {
+ if (is_intensity(icsr, g, sfb))
+ {
+ /* For scalefactor bands coded in intensity stereo the
+ corresponding predictors in the right channel are
+ switched to "off".
+ */
+ ics->pred.prediction_used[sfb] = 0;
+ icsr->pred.prediction_used[sfb] = 0;
+
+ scale = MUL(is_intensity(icsr, g, sfb),
+ MUL(invert_intensity(ics, g, sfb),
+ (real_t)exp(LN05 * (0.25*icsr->scale_factors[g][sfb]))));
+
+ /* Scale from left to right channel,
+ do not touch left channel */
+ for (i = icsr->swb_offset[sfb]; i < icsr->swb_offset[sfb+1]; i++)
+ {
+ k = (group*nshort)+i;
+ r_spec[k] = MUL(l_spec[k], scale);
+ }
+ }
+ }
+ group++;
+ }
+ }
+}
diff --git a/src/libfaad/is.h b/src/libfaad/is.h
new file mode 100644
index 000000000..3b311b8d8
--- /dev/null
+++ b/src/libfaad/is.h
@@ -0,0 +1,58 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: is.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __IS_H__
+#define __IS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "syntax.h"
+
+void is_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec,
+ uint16_t frame_len);
+
+static INLINE int8_t is_intensity(ic_stream *ics, uint8_t group, uint8_t sfb)
+{
+ switch (ics->sfb_cb[group][sfb])
+ {
+ case INTENSITY_HCB:
+ return 1;
+ case INTENSITY_HCB2:
+ return -1;
+ default:
+ return 0;
+ }
+}
+
+static INLINE int8_t invert_intensity(ic_stream *ics, uint8_t group, uint8_t sfb)
+{
+ if (ics->ms_mask_present == 1)
+ return (1-2*ics->ms_used[group][sfb]);
+ return 1;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/kbd_win.h b/src/libfaad/kbd_win.h
new file mode 100644
index 000000000..b28e085de
--- /dev/null
+++ b/src/libfaad/kbd_win.h
@@ -0,0 +1,1197 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: kbd_win.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __KBD_WIN_H__
+#define __KBD_WIN_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable:4305)
+#endif
+
+real_t kbd_long[] =
+{
+ 0.00029256153896361,
+ 0.00042998567353047,
+ 0.00054674074589540,
+ 0.00065482304299792,
+ 0.00075870195068747,
+ 0.00086059331713336,
+ 0.00096177541439010,
+ 0.0010630609410878,
+ 0.0011650036308132,
+ 0.0012680012194148,
+ 0.0013723517232956,
+ 0.0014782864109136,
+ 0.0015859901976719,
+ 0.0016956148252373,
+ 0.0018072876903517,
+ 0.0019211179405514,
+ 0.0020372007924215,
+ 0.0021556206591754,
+ 0.0022764534599614,
+ 0.0023997683540995,
+ 0.0025256290631156,
+ 0.0026540948920831,
+ 0.0027852215281403,
+ 0.0029190616715331,
+ 0.0030556655443223,
+ 0.0031950812943391,
+ 0.0033373553240392,
+ 0.0034825325586930,
+ 0.0036306566699199,
+ 0.0037817702604646,
+ 0.0039359150179719,
+ 0.0040931318437260,
+ 0.0042534609610026,
+ 0.0044169420066964,
+ 0.0045836141091341,
+ 0.0047535159544086,
+ 0.0049266858431214,
+ 0.0051031617390698,
+ 0.0052829813111335,
+ 0.0054661819693975,
+ 0.0056528008963682,
+ 0.0058428750739943,
+ 0.0060364413070882,
+ 0.0062335362436492,
+ 0.0064341963925079,
+ 0.0066384581386503,
+ 0.0068463577565218,
+ 0.0070579314215715,
+ 0.0072732152202559,
+ 0.0074922451586909,
+ 0.0077150571701162,
+ 0.0079416871213115,
+ 0.0081721708180857,
+ 0.0084065440099458,
+ 0.0086448423940363,
+ 0.0088871016184291,
+ 0.0091333572848345,
+ 0.0093836449507939,
+ 0.0096380001314086,
+ 0.0098964583006517,
+ 0.010159054892306,
+ 0.010425825300561,
+ 0.010696804880310,
+ 0.010972028947167,
+ 0.011251532777236,
+ 0.011535351606646,
+ 0.011823520630897,
+ 0.012116075003993,
+ 0.012413049837429,
+ 0.012714480198999,
+ 0.013020401111478,
+ 0.013330847551161,
+ 0.013645854446288,
+ 0.013965456675352,
+ 0.014289689065314,
+ 0.014618586389712,
+ 0.014952183366697,
+ 0.015290514656976,
+ 0.015633614861688,
+ 0.015981518520214,
+ 0.016334260107915,
+ 0.016691874033817,
+ 0.017054394638241,
+ 0.017421856190380,
+ 0.017794292885832,
+ 0.018171738844085,
+ 0.018554228105962,
+ 0.018941794631032,
+ 0.019334472294980,
+ 0.019732294886947,
+ 0.020135296106839,
+ 0.020543509562604,
+ 0.020956968767488,
+ 0.021375707137257,
+ 0.021799757987407,
+ 0.022229154530343,
+ 0.022663929872540,
+ 0.023104117011689,
+ 0.023549748833816,
+ 0.024000858110398,
+ 0.024457477495451,
+ 0.024919639522613,
+ 0.025387376602207,
+ 0.025860721018295,
+ 0.026339704925726,
+ 0.026824360347160,
+ 0.027314719170100,
+ 0.027810813143900,
+ 0.028312673876775,
+ 0.028820332832801,
+ 0.029333821328905,
+ 0.029853170531859,
+ 0.030378411455255,
+ 0.030909574956490,
+ 0.031446691733739,
+ 0.031989792322926,
+ 0.032538907094693,
+ 0.033094066251369,
+ 0.033655299823935,
+ 0.034222637668991,
+ 0.034796109465717,
+ 0.035375744712844,
+ 0.035961572725616,
+ 0.036553622632758,
+ 0.037151923373446,
+ 0.037756503694277,
+ 0.038367392146243,
+ 0.038984617081711,
+ 0.039608206651398,
+ 0.040238188801359,
+ 0.040874591269976,
+ 0.041517441584950,
+ 0.042166767060301,
+ 0.042822594793376,
+ 0.043484951661852,
+ 0.044153864320760,
+ 0.044829359199509,
+ 0.045511462498913,
+ 0.046200200188234,
+ 0.046895598002228,
+ 0.047597681438201,
+ 0.048306475753074,
+ 0.049022005960455,
+ 0.049744296827725,
+ 0.050473372873129,
+ 0.051209258362879,
+ 0.051951977308273,
+ 0.052701553462813,
+ 0.053458010319350,
+ 0.054221371107223,
+ 0.054991658789428,
+ 0.055768896059787,
+ 0.056553105340134,
+ 0.057344308777513,
+ 0.058142528241393,
+ 0.058947785320893,
+ 0.059760101322019,
+ 0.060579497264926,
+ 0.061405993881180,
+ 0.062239611611049,
+ 0.063080370600799,
+ 0.063928290700012,
+ 0.064783391458919,
+ 0.065645692125747,
+ 0.066515211644086,
+ 0.067391968650269,
+ 0.068275981470777,
+ 0.069167268119652,
+ 0.070065846295935,
+ 0.070971733381121,
+ 0.071884946436630,
+ 0.072805502201299,
+ 0.073733417088896,
+ 0.074668707185649,
+ 0.075611388247794,
+ 0.076561475699152,
+ 0.077518984628715,
+ 0.078483929788261,
+ 0.079456325589986,
+ 0.080436186104162,
+ 0.081423525056808,
+ 0.082418355827392,
+ 0.083420691446553,
+ 0.084430544593841,
+ 0.085447927595483,
+ 0.086472852422178,
+ 0.087505330686900,
+ 0.088545373642744,
+ 0.089592992180780,
+ 0.090648196827937,
+ 0.091710997744919,
+ 0.092781404724131,
+ 0.093859427187640,
+ 0.094945074185163,
+ 0.096038354392069,
+ 0.097139276107423,
+ 0.098247847252041,
+ 0.099364075366580,
+ 0.10048796760965,
+ 0.10161953075597,
+ 0.10275877119451,
+ 0.10390569492671,
+ 0.10506030756469,
+ 0.10622261432949,
+ 0.10739262004941,
+ 0.10857032915821,
+ 0.10975574569357,
+ 0.11094887329534,
+ 0.11214971520402,
+ 0.11335827425914,
+ 0.11457455289772,
+ 0.11579855315274,
+ 0.11703027665170,
+ 0.11826972461510,
+ 0.11951689785504,
+ 0.12077179677383,
+ 0.12203442136263,
+ 0.12330477120008,
+ 0.12458284545102,
+ 0.12586864286523,
+ 0.12716216177615,
+ 0.12846340009971,
+ 0.12977235533312,
+ 0.13108902455375,
+ 0.13241340441801,
+ 0.13374549116025,
+ 0.13508528059173,
+ 0.13643276809961,
+ 0.13778794864595,
+ 0.13915081676677,
+ 0.14052136657114,
+ 0.14189959174027,
+ 0.14328548552671,
+ 0.14467904075349,
+ 0.14608024981336,
+ 0.14748910466804,
+ 0.14890559684750,
+ 0.15032971744929,
+ 0.15176145713790,
+ 0.15320080614414,
+ 0.15464775426459,
+ 0.15610229086100,
+ 0.15756440485987,
+ 0.15903408475193,
+ 0.16051131859170,
+ 0.16199609399712,
+ 0.16348839814917,
+ 0.16498821779156,
+ 0.16649553923042,
+ 0.16801034833404,
+ 0.16953263053270,
+ 0.17106237081842,
+ 0.17259955374484,
+ 0.17414416342714,
+ 0.17569618354193,
+ 0.17725559732720,
+ 0.17882238758238,
+ 0.18039653666830,
+ 0.18197802650733,
+ 0.18356683858343,
+ 0.18516295394233,
+ 0.18676635319174,
+ 0.18837701650148,
+ 0.18999492360384,
+ 0.19162005379380,
+ 0.19325238592940,
+ 0.19489189843209,
+ 0.19653856928714,
+ 0.19819237604409,
+ 0.19985329581721,
+ 0.20152130528605,
+ 0.20319638069594,
+ 0.20487849785865,
+ 0.20656763215298,
+ 0.20826375852540,
+ 0.20996685149083,
+ 0.21167688513330,
+ 0.21339383310678,
+ 0.21511766863598,
+ 0.21684836451719,
+ 0.21858589311922,
+ 0.22033022638425,
+ 0.22208133582887,
+ 0.22383919254503,
+ 0.22560376720111,
+ 0.22737503004300,
+ 0.22915295089517,
+ 0.23093749916189,
+ 0.23272864382838,
+ 0.23452635346201,
+ 0.23633059621364,
+ 0.23814133981883,
+ 0.23995855159925,
+ 0.24178219846403,
+ 0.24361224691114,
+ 0.24544866302890,
+ 0.24729141249740,
+ 0.24914046059007,
+ 0.25099577217522,
+ 0.25285731171763,
+ 0.25472504328019,
+ 0.25659893052556,
+ 0.25847893671788,
+ 0.26036502472451,
+ 0.26225715701781,
+ 0.26415529567692,
+ 0.26605940238966,
+ 0.26796943845439,
+ 0.26988536478190,
+ 0.27180714189742,
+ 0.27373472994256,
+ 0.27566808867736,
+ 0.27760717748238,
+ 0.27955195536071,
+ 0.28150238094021,
+ 0.28345841247557,
+ 0.28542000785059,
+ 0.28738712458038,
+ 0.28935971981364,
+ 0.29133775033492,
+ 0.29332117256704,
+ 0.29530994257338,
+ 0.29730401606034,
+ 0.29930334837974,
+ 0.30130789453132,
+ 0.30331760916521,
+ 0.30533244658452,
+ 0.30735236074785,
+ 0.30937730527195,
+ 0.31140723343430,
+ 0.31344209817583,
+ 0.31548185210356,
+ 0.31752644749341,
+ 0.31957583629288,
+ 0.32162997012390,
+ 0.32368880028565,
+ 0.32575227775738,
+ 0.32782035320134,
+ 0.32989297696566,
+ 0.33197009908736,
+ 0.33405166929523,
+ 0.33613763701295,
+ 0.33822795136203,
+ 0.34032256116495,
+ 0.34242141494820,
+ 0.34452446094547,
+ 0.34663164710072,
+ 0.34874292107143,
+ 0.35085823023181,
+ 0.35297752167598,
+ 0.35510074222129,
+ 0.35722783841160,
+ 0.35935875652060,
+ 0.36149344255514,
+ 0.36363184225864,
+ 0.36577390111444,
+ 0.36791956434930,
+ 0.37006877693676,
+ 0.37222148360070,
+ 0.37437762881878,
+ 0.37653715682603,
+ 0.37870001161834,
+ 0.38086613695607,
+ 0.38303547636766,
+ 0.38520797315322,
+ 0.38738357038821,
+ 0.38956221092708,
+ 0.39174383740701,
+ 0.39392839225157,
+ 0.39611581767449,
+ 0.39830605568342,
+ 0.40049904808370,
+ 0.40269473648218,
+ 0.40489306229101,
+ 0.40709396673153,
+ 0.40929739083810,
+ 0.41150327546197,
+ 0.41371156127524,
+ 0.41592218877472,
+ 0.41813509828594,
+ 0.42035022996702,
+ 0.42256752381274,
+ 0.42478691965848,
+ 0.42700835718423,
+ 0.42923177591866,
+ 0.43145711524314,
+ 0.43368431439580,
+ 0.43591331247564,
+ 0.43814404844658,
+ 0.44037646114161,
+ 0.44261048926688,
+ 0.44484607140589,
+ 0.44708314602359,
+ 0.44932165147057,
+ 0.45156152598727,
+ 0.45380270770813,
+ 0.45604513466581,
+ 0.45828874479543,
+ 0.46053347593880,
+ 0.46277926584861,
+ 0.46502605219277,
+ 0.46727377255861,
+ 0.46952236445718,
+ 0.47177176532752,
+ 0.47402191254100,
+ 0.47627274340557,
+ 0.47852419517009,
+ 0.48077620502869,
+ 0.48302871012505,
+ 0.48528164755674,
+ 0.48753495437962,
+ 0.48978856761212,
+ 0.49204242423966,
+ 0.49429646121898,
+ 0.49655061548250,
+ 0.49880482394273,
+ 0.50105902349665,
+ 0.50331315103004,
+ 0.50556714342194,
+ 0.50782093754901,
+ 0.51007447028990,
+ 0.51232767852971,
+ 0.51458049916433,
+ 0.51683286910489,
+ 0.51908472528213,
+ 0.52133600465083,
+ 0.52358664419420,
+ 0.52583658092832,
+ 0.52808575190648,
+ 0.53033409422367,
+ 0.53258154502092,
+ 0.53482804148974,
+ 0.53707352087652,
+ 0.53931792048690,
+ 0.54156117769021,
+ 0.54380322992385,
+ 0.54604401469766,
+ 0.54828346959835,
+ 0.55052153229384,
+ 0.55275814053768,
+ 0.55499323217338,
+ 0.55722674513883,
+ 0.55945861747062,
+ 0.56168878730842,
+ 0.56391719289930,
+ 0.56614377260214,
+ 0.56836846489188,
+ 0.57059120836390,
+ 0.57281194173835,
+ 0.57503060386439,
+ 0.57724713372458,
+ 0.57946147043912,
+ 0.58167355327012,
+ 0.58388332162591,
+ 0.58609071506528,
+ 0.58829567330173,
+ 0.59049813620770,
+ 0.59269804381879,
+ 0.59489533633802,
+ 0.59708995413996,
+ 0.59928183777495,
+ 0.60147092797329,
+ 0.60365716564937,
+ 0.60584049190582,
+ 0.60802084803764,
+ 0.61019817553632,
+ 0.61237241609393,
+ 0.61454351160718,
+ 0.61671140418155,
+ 0.61887603613527,
+ 0.62103735000336,
+ 0.62319528854167,
+ 0.62534979473088,
+ 0.62750081178042,
+ 0.62964828313250,
+ 0.63179215246597,
+ 0.63393236370030,
+ 0.63606886099946,
+ 0.63820158877577,
+ 0.64033049169379,
+ 0.64245551467413,
+ 0.64457660289729,
+ 0.64669370180740,
+ 0.64880675711607,
+ 0.65091571480603,
+ 0.65302052113494,
+ 0.65512112263906,
+ 0.65721746613689,
+ 0.65930949873289,
+ 0.66139716782102,
+ 0.66348042108842,
+ 0.66555920651892,
+ 0.66763347239664,
+ 0.66970316730947,
+ 0.67176824015260,
+ 0.67382864013196,
+ 0.67588431676768,
+ 0.67793521989751,
+ 0.67998129968017,
+ 0.68202250659876,
+ 0.68405879146403,
+ 0.68609010541774,
+ 0.68811639993588,
+ 0.69013762683195,
+ 0.69215373826012,
+ 0.69416468671849,
+ 0.69617042505214,
+ 0.69817090645634,
+ 0.70016608447958,
+ 0.70215591302664,
+ 0.70414034636163,
+ 0.70611933911096,
+ 0.70809284626630,
+ 0.71006082318751,
+ 0.71202322560554,
+ 0.71398000962530,
+ 0.71593113172842,
+ 0.71787654877613,
+ 0.71981621801195,
+ 0.72175009706445,
+ 0.72367814394990,
+ 0.72560031707496,
+ 0.72751657523927,
+ 0.72942687763803,
+ 0.73133118386457,
+ 0.73322945391280,
+ 0.73512164817975,
+ 0.73700772746796,
+ 0.73888765298787,
+ 0.74076138636020,
+ 0.74262888961827,
+ 0.74449012521027,
+ 0.74634505600152,
+ 0.74819364527663,
+ 0.75003585674175,
+ 0.75187165452661,
+ 0.75370100318668,
+ 0.75552386770515,
+ 0.75734021349500,
+ 0.75915000640095,
+ 0.76095321270137,
+ 0.76274979911019,
+ 0.76453973277875,
+ 0.76632298129757,
+ 0.76809951269819,
+ 0.76986929545481,
+ 0.77163229848604,
+ 0.77338849115651,
+ 0.77513784327849,
+ 0.77688032511340,
+ 0.77861590737340,
+ 0.78034456122283,
+ 0.78206625827961,
+ 0.78378097061667,
+ 0.78548867076330,
+ 0.78718933170643,
+ 0.78888292689189,
+ 0.79056943022564,
+ 0.79224881607494,
+ 0.79392105926949,
+ 0.79558613510249,
+ 0.79724401933170,
+ 0.79889468818046,
+ 0.80053811833858,
+ 0.80217428696334,
+ 0.80380317168028,
+ 0.80542475058405,
+ 0.80703900223920,
+ 0.80864590568089,
+ 0.81024544041560,
+ 0.81183758642175,
+ 0.81342232415032,
+ 0.81499963452540,
+ 0.81656949894467,
+ 0.81813189927991,
+ 0.81968681787738,
+ 0.82123423755821,
+ 0.82277414161874,
+ 0.82430651383076,
+ 0.82583133844180,
+ 0.82734860017528,
+ 0.82885828423070,
+ 0.83036037628369,
+ 0.83185486248609,
+ 0.83334172946597,
+ 0.83482096432759,
+ 0.83629255465130,
+ 0.83775648849344,
+ 0.83921275438615,
+ 0.84066134133716,
+ 0.84210223882952,
+ 0.84353543682130,
+ 0.84496092574524,
+ 0.84637869650833,
+ 0.84778874049138,
+ 0.84919104954855,
+ 0.85058561600677,
+ 0.85197243266520,
+ 0.85335149279457,
+ 0.85472279013653,
+ 0.85608631890295,
+ 0.85744207377513,
+ 0.85879004990298,
+ 0.86013024290422,
+ 0.86146264886346,
+ 0.86278726433124,
+ 0.86410408632306,
+ 0.86541311231838,
+ 0.86671434025950,
+ 0.86800776855046,
+ 0.86929339605590,
+ 0.87057122209981,
+ 0.87184124646433,
+ 0.87310346938840,
+ 0.87435789156650,
+ 0.87560451414719,
+ 0.87684333873173,
+ 0.87807436737261,
+ 0.87929760257204,
+ 0.88051304728038,
+ 0.88172070489456,
+ 0.88292057925645,
+ 0.88411267465117,
+ 0.88529699580537,
+ 0.88647354788545,
+ 0.88764233649580,
+ 0.88880336767692,
+ 0.88995664790351,
+ 0.89110218408260,
+ 0.89223998355154,
+ 0.89337005407600,
+ 0.89449240384793,
+ 0.89560704148345,
+ 0.89671397602074,
+ 0.89781321691786,
+ 0.89890477405053,
+ 0.89998865770993,
+ 0.90106487860034,
+ 0.90213344783689,
+ 0.90319437694315,
+ 0.90424767784873,
+ 0.90529336288690,
+ 0.90633144479201,
+ 0.90736193669708,
+ 0.90838485213119,
+ 0.90940020501694,
+ 0.91040800966776,
+ 0.91140828078533,
+ 0.91240103345685,
+ 0.91338628315231,
+ 0.91436404572173,
+ 0.91533433739238,
+ 0.91629717476594,
+ 0.91725257481564,
+ 0.91820055488334,
+ 0.91914113267664,
+ 0.92007432626589,
+ 0.92100015408120,
+ 0.92191863490944,
+ 0.92282978789113,
+ 0.92373363251740,
+ 0.92463018862687,
+ 0.92551947640245,
+ 0.92640151636824,
+ 0.92727632938624,
+ 0.92814393665320,
+ 0.92900435969727,
+ 0.92985762037477,
+ 0.93070374086684,
+ 0.93154274367610,
+ 0.93237465162328,
+ 0.93319948784382,
+ 0.93401727578443,
+ 0.93482803919967,
+ 0.93563180214841,
+ 0.93642858899043,
+ 0.93721842438279,
+ 0.93800133327637,
+ 0.93877734091223,
+ 0.93954647281807,
+ 0.94030875480458,
+ 0.94106421296182,
+ 0.94181287365556,
+ 0.94255476352362,
+ 0.94328990947213,
+ 0.94401833867184,
+ 0.94474007855439,
+ 0.94545515680855,
+ 0.94616360137644,
+ 0.94686544044975,
+ 0.94756070246592,
+ 0.94824941610434,
+ 0.94893161028248,
+ 0.94960731415209,
+ 0.95027655709525,
+ 0.95093936872056,
+ 0.95159577885924,
+ 0.95224581756115,
+ 0.95288951509097,
+ 0.95352690192417,
+ 0.95415800874314,
+ 0.95478286643320,
+ 0.95540150607863,
+ 0.95601395895871,
+ 0.95662025654373,
+ 0.95722043049100,
+ 0.95781451264084,
+ 0.95840253501260,
+ 0.95898452980058,
+ 0.95956052937008,
+ 0.96013056625336,
+ 0.96069467314557,
+ 0.96125288290073,
+ 0.96180522852773,
+ 0.96235174318622,
+ 0.96289246018262,
+ 0.96342741296604,
+ 0.96395663512424,
+ 0.96448016037959,
+ 0.96499802258499,
+ 0.96551025571985,
+ 0.96601689388602,
+ 0.96651797130376,
+ 0.96701352230768,
+ 0.96750358134269,
+ 0.96798818295998,
+ 0.96846736181297,
+ 0.96894115265327,
+ 0.96940959032667,
+ 0.96987270976912,
+ 0.97033054600270,
+ 0.97078313413161,
+ 0.97123050933818,
+ 0.97167270687887,
+ 0.97210976208030,
+ 0.97254171033525,
+ 0.97296858709871,
+ 0.97339042788392,
+ 0.97380726825843,
+ 0.97421914384017,
+ 0.97462609029350,
+ 0.97502814332534,
+ 0.97542533868127,
+ 0.97581771214160,
+ 0.97620529951759,
+ 0.97658813664749,
+ 0.97696625939282,
+ 0.97733970363445,
+ 0.97770850526884,
+ 0.97807270020427,
+ 0.97843232435704,
+ 0.97878741364771,
+ 0.97913800399743,
+ 0.97948413132414,
+ 0.97982583153895,
+ 0.98016314054243,
+ 0.98049609422096,
+ 0.98082472844313,
+ 0.98114907905608,
+ 0.98146918188197,
+ 0.98178507271438,
+ 0.98209678731477,
+ 0.98240436140902,
+ 0.98270783068385,
+ 0.98300723078342,
+ 0.98330259730589,
+ 0.98359396579995,
+ 0.98388137176152,
+ 0.98416485063031,
+ 0.98444443778651,
+ 0.98472016854752,
+ 0.98499207816463,
+ 0.98526020181980,
+ 0.98552457462240,
+ 0.98578523160609,
+ 0.98604220772560,
+ 0.98629553785362,
+ 0.98654525677772,
+ 0.98679139919726,
+ 0.98703399972035,
+ 0.98727309286089,
+ 0.98750871303556,
+ 0.98774089456089,
+ 0.98796967165036,
+ 0.98819507841154,
+ 0.98841714884323,
+ 0.98863591683269,
+ 0.98885141615285,
+ 0.98906368045957,
+ 0.98927274328896,
+ 0.98947863805473,
+ 0.98968139804554,
+ 0.98988105642241,
+ 0.99007764621618,
+ 0.99027120032501,
+ 0.99046175151186,
+ 0.99064933240208,
+ 0.99083397548099,
+ 0.99101571309153,
+ 0.99119457743191,
+ 0.99137060055337,
+ 0.99154381435784,
+ 0.99171425059582,
+ 0.99188194086414,
+ 0.99204691660388,
+ 0.99220920909823,
+ 0.99236884947045,
+ 0.99252586868186,
+ 0.99268029752989,
+ 0.99283216664606,
+ 0.99298150649419,
+ 0.99312834736847,
+ 0.99327271939167,
+ 0.99341465251338,
+ 0.99355417650825,
+ 0.99369132097430,
+ 0.99382611533130,
+ 0.99395858881910,
+ 0.99408877049612,
+ 0.99421668923778,
+ 0.99434237373503,
+ 0.99446585249289,
+ 0.99458715382906,
+ 0.99470630587254,
+ 0.99482333656229,
+ 0.99493827364600,
+ 0.99505114467878,
+ 0.99516197702200,
+ 0.99527079784214,
+ 0.99537763410962,
+ 0.99548251259777,
+ 0.99558545988178,
+ 0.99568650233767,
+ 0.99578566614138,
+ 0.99588297726783,
+ 0.99597846149005,
+ 0.99607214437834,
+ 0.99616405129947,
+ 0.99625420741595,
+ 0.99634263768527,
+ 0.99642936685928,
+ 0.99651441948352,
+ 0.99659781989663,
+ 0.99667959222978,
+ 0.99675976040620,
+ 0.99683834814063,
+ 0.99691537893895,
+ 0.99699087609774,
+ 0.99706486270391,
+ 0.99713736163442,
+ 0.99720839555593,
+ 0.99727798692461,
+ 0.99734615798589,
+ 0.99741293077431,
+ 0.99747832711337,
+ 0.99754236861541,
+ 0.99760507668158,
+ 0.99766647250181,
+ 0.99772657705478,
+ 0.99778541110799,
+ 0.99784299521785,
+ 0.99789934972976,
+ 0.99795449477828,
+ 0.99800845028730,
+ 0.99806123597027,
+ 0.99811287133042,
+ 0.99816337566108,
+ 0.99821276804596,
+ 0.99826106735952,
+ 0.99830829226732,
+ 0.99835446122649,
+ 0.99839959248609,
+ 0.99844370408765,
+ 0.99848681386566,
+ 0.99852893944805,
+ 0.99857009825685,
+ 0.99861030750869,
+ 0.99864958421549,
+ 0.99868794518504,
+ 0.99872540702178,
+ 0.99876198612738,
+ 0.99879769870160,
+ 0.99883256074295,
+ 0.99886658804953,
+ 0.99889979621983,
+ 0.99893220065356,
+ 0.99896381655254,
+ 0.99899465892154,
+ 0.99902474256924,
+ 0.99905408210916,
+ 0.99908269196056,
+ 0.99911058634952,
+ 0.99913777930986,
+ 0.99916428468421,
+ 0.99919011612505,
+ 0.99921528709576,
+ 0.99923981087174,
+ 0.99926370054150,
+ 0.99928696900779,
+ 0.99930962898876,
+ 0.99933169301910,
+ 0.99935317345126,
+ 0.99937408245662,
+ 0.99939443202674,
+ 0.99941423397457,
+ 0.99943349993572,
+ 0.99945224136972,
+ 0.99947046956130,
+ 0.99948819562171,
+ 0.99950543049000,
+ 0.99952218493439,
+ 0.99953846955355,
+ 0.99955429477803,
+ 0.99956967087154,
+ 0.99958460793242,
+ 0.99959911589494,
+ 0.99961320453077,
+ 0.99962688345035,
+ 0.99964016210433,
+ 0.99965304978499,
+ 0.99966555562769,
+ 0.99967768861231,
+ 0.99968945756473,
+ 0.99970087115825,
+ 0.99971193791510,
+ 0.99972266620792,
+ 0.99973306426121,
+ 0.99974314015288,
+ 0.99975290181568,
+ 0.99976235703876,
+ 0.99977151346914,
+ 0.99978037861326,
+ 0.99978895983845,
+ 0.99979726437448,
+ 0.99980529931507,
+ 0.99981307161943,
+ 0.99982058811377,
+ 0.99982785549283,
+ 0.99983488032144,
+ 0.99984166903600,
+ 0.99984822794606,
+ 0.99985456323584,
+ 0.99986068096572,
+ 0.99986658707386,
+ 0.99987228737764,
+ 0.99987778757524,
+ 0.99988309324717,
+ 0.99988820985777,
+ 0.99989314275675,
+ 0.99989789718072,
+ 0.99990247825468,
+ 0.99990689099357,
+ 0.99991114030376,
+ 0.99991523098456,
+ 0.99991916772971,
+ 0.99992295512891,
+ 0.99992659766930,
+ 0.99993009973692,
+ 0.99993346561824,
+ 0.99993669950161,
+ 0.99993980547870,
+ 0.99994278754604,
+ 0.99994564960642,
+ 0.99994839547033,
+ 0.99995102885747,
+ 0.99995355339809,
+ 0.99995597263451,
+ 0.99995829002249,
+ 0.99996050893264,
+ 0.99996263265183,
+ 0.99996466438460,
+ 0.99996660725452,
+ 0.99996846430558,
+ 0.99997023850356,
+ 0.99997193273736,
+ 0.99997354982037,
+ 0.99997509249183,
+ 0.99997656341810,
+ 0.99997796519400,
+ 0.99997930034415,
+ 0.99998057132421,
+ 0.99998178052220,
+ 0.99998293025975,
+ 0.99998402279338,
+ 0.99998506031574,
+ 0.99998604495686,
+ 0.99998697878536,
+ 0.99998786380966,
+ 0.99998870197921,
+ 0.99998949518567,
+ 0.99999024526408,
+ 0.99999095399401,
+ 0.99999162310077,
+ 0.99999225425649,
+ 0.99999284908128,
+ 0.99999340914435,
+ 0.99999393596510,
+ 0.99999443101421,
+ 0.99999489571473,
+ 0.99999533144314,
+ 0.99999573953040,
+ 0.99999612126300,
+ 0.99999647788395,
+ 0.99999681059383,
+ 0.99999712055178,
+ 0.99999740887647,
+ 0.99999767664709,
+ 0.99999792490431,
+ 0.99999815465123,
+ 0.99999836685427,
+ 0.99999856244415,
+ 0.99999874231676,
+ 0.99999890733405,
+ 0.99999905832493,
+ 0.99999919608613,
+ 0.99999932138304,
+ 0.99999943495056,
+ 0.99999953749392,
+ 0.99999962968950,
+ 0.99999971218563,
+ 0.99999978560337,
+ 0.99999985053727,
+ 0.99999990755616,
+ 0.99999995720387
+};
+
+
+real_t kbd_short[] =
+{
+ 4.3795702929468881e-005,
+ 0.00011867384265436617,
+ 0.0002307165763996192,
+ 0.00038947282760568383,
+ 0.00060581272288302553,
+ 0.00089199695169487453,
+ 0.0012617254423430522,
+ 0.0017301724373162003,
+ 0.0023140071937421476,
+ 0.0030313989666022221,
+ 0.0039020049735530842,
+ 0.0049469401815512024,
+ 0.0061887279335368318,
+ 0.0076512306364647726,
+ 0.0093595599562652423,
+ 0.011339966208377799,
+ 0.013619706891715299,
+ 0.016226894586323766,
+ 0.019190324717288168,
+ 0.022539283975960878,
+ 0.026303340480472455,
+ 0.030512117046644357,
+ 0.03519504922365594,
+ 0.040381130021856941,
+ 0.046098643518702249,
+ 0.052374889768730587,
+ 0.059235903660769147,
+ 0.066706170556282418,
+ 0.074808341703430481,
+ 0.083562952548726227,
+ 0.092988147159339674,
+ 0.1030994120216919,
+ 0.11390932249409955,
+ 0.12542730516149531,
+ 0.13765941926783826,
+ 0.15060816028651081,
+ 0.16427228853114245,
+ 0.17864668550988483,
+ 0.19372224048676889,
+ 0.20948576943658073,
+ 0.22591996826744942,
+ 0.24300340184133981,
+ 0.26071052995068139,
+ 0.27901177101369551,
+ 0.29787360383626599,
+ 0.3172587073594233,
+ 0.33712613787396362,
+ 0.35743154274286698,
+ 0.37812740923363009,
+ 0.39916334663203618,
+ 0.42048639939189658,
+ 0.4420413886774246,
+ 0.4637712792815169,
+ 0.4856175685594023,
+ 0.50752069370766872,
+ 0.52942045344797806,
+ 0.55125643994680196,
+ 0.57296847662071559,
+ 0.59449705734411495,
+ 0.61578378249506627,
+ 0.63677178724712891,
+ 0.65740615754163356,
+ 0.67763432925662526,
+ 0.69740646622548552,
+ 0.71667581294953808,
+ 0.73539901809352737,
+ 0.75353642514900732,
+ 0.77105232699609816,
+ 0.78791518148597028,
+ 0.80409778560147072,
+ 0.81957740622770781,
+ 0.83433586607383625,
+ 0.84835958382689225,
+ 0.86163956818294229,
+ 0.87417136598406997,
+ 0.88595496528524853,
+ 0.89699465477567619,
+ 0.90729884157670959,
+ 0.91687983002436779,
+ 0.92575356460899649,
+ 0.93393934077779084,
+ 0.94145948779657318,
+ 0.94833902830402828,
+ 0.95460531956280026,
+ 0.96028768170574896,
+ 0.96541701848104766,
+ 0.97002543610646474,
+ 0.97414586584250062,
+ 0.97781169577969584,
+ 0.98105641710392333,
+ 0.98391328975491177,
+ 0.98641503193166202,
+ 0.98859353733226141,
+ 0.99047962335771556,
+ 0.9921028127769449,
+ 0.99349115056397752,
+ 0.99467105680259038,
+ 0.9956672157341897,
+ 0.99650250022834352,
+ 0.99719793020823266,
+ 0.99777266288955657,
+ 0.99824401211201486,
+ 0.99862749357391212,
+ 0.99893689243401962,
+ 0.99918434952623147,
+ 0.99938046234161726,
+ 0.99953439696357238,
+ 0.99965400728430465,
+ 0.99974595807027455,
+ 0.99981584876278362,
+ 0.99986833527824281,
+ 0.99990724749057802,
+ 0.99993570051598468,
+ 0.99995619835942084,
+ 0.99997072890647543,
+ 0.9999808496399144,
+ 0.99998776381655818,
+ 0.99999238714961569,
+ 0.99999540529959718,
+ 0.99999732268176988,
+ 0.99999850325054862,
+ 0.99999920402413744,
+ 0.9999996021706401,
+ 0.99999981649545566,
+ 0.99999992415545547,
+ 0.99999997338493041,
+ 0.99999999295825959,
+ 0.99999999904096815
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/lt_predict.c b/src/libfaad/lt_predict.c
new file mode 100644
index 000000000..ff5c33f10
--- /dev/null
+++ b/src/libfaad/lt_predict.c
@@ -0,0 +1,134 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: lt_predict.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+
+#include "common.h"
+
+#ifdef LTP_DEC
+
+#include <stdlib.h>
+#include "syntax.h"
+#include "lt_predict.h"
+#include "filtbank.h"
+#include "tns.h"
+
+static real_t codebook[8] =
+{
+ 0.570829f, 0.696616f, 0.813004f, 0.911304f, 0.984900f, 1.067894f,
+ 1.194601f, 1.369533f
+};
+
+void lt_prediction(ic_stream *ics, ltp_info *ltp, real_t *spec,
+ real_t *lt_pred_stat, fb_info *fb, uint8_t win_shape,
+ uint8_t win_shape_prev, uint8_t sr_index,
+ uint8_t object_type, uint16_t frame_len)
+{
+ uint8_t sfb;
+ uint16_t bin, i, num_samples;
+ real_t *x_est;
+ real_t *X_est;
+
+ if (ics->window_sequence != EIGHT_SHORT_SEQUENCE)
+ {
+ if (ltp->data_present)
+ {
+ num_samples = frame_len << 1;
+
+ x_est = malloc(num_samples*sizeof(real_t));
+ X_est = malloc(num_samples*sizeof(real_t));
+
+ for(i = 0; i < num_samples; i++)
+ {
+ /* The extra lookback M (N/2 for LD, 0 for LTP) is handled
+ in the buffer updating */
+ x_est[i] = MUL(codebook[ltp->coef],
+ lt_pred_stat[num_samples + i - ltp->lag]);
+ }
+
+ filter_bank_ltp(fb, ics->window_sequence, win_shape, win_shape_prev,
+ x_est, X_est, object_type, frame_len);
+
+ tns_encode_frame(ics, &(ics->tns), sr_index, object_type, X_est,
+ frame_len);
+
+ for (sfb = 0; sfb < ltp->last_band; sfb++)
+ {
+ if (ltp->long_used[sfb])
+ {
+ uint16_t low = ics->swb_offset[sfb];
+ uint16_t high = ics->swb_offset[sfb+1];
+
+ for (bin = low; bin < high; bin++)
+ {
+ spec[bin] += X_est[bin];
+ }
+ }
+ }
+
+ free(x_est);
+ free(X_est);
+ }
+ }
+}
+
+void lt_update_state(real_t *lt_pred_stat, real_t *time, real_t *overlap,
+ uint16_t frame_len, uint8_t object_type)
+{
+ uint16_t i;
+
+ /*
+ * The reference point for index i and the content of the buffer
+ * lt_pred_stat are arranged so that lt_pred_stat(0 ... N/2 - 1) contains the
+ * last aliased half window from the IMDCT, and lt_pred_stat(N/2 ... N-1)
+ * is always all zeros. The rest of lt_pred_stat (i<0) contains the previous
+ * fully reconstructed time domain samples, i.e., output of the decoder.
+ *
+ * These values are shifted up by N*2 to avoid (i<0)
+ *
+ * For the LD object type an extra 512 samples lookback is accomodated here.
+ */
+#ifdef LD_DEC
+ if (object_type == LD)
+ {
+ for (i = 0; i < frame_len; i++)
+ {
+ lt_pred_stat[i] /* extra 512 */ = lt_pred_stat[i + frame_len];
+ lt_pred_stat[frame_len + i] = lt_pred_stat[i + (frame_len * 2)];
+ lt_pred_stat[(frame_len * 2) + i] = time[i];
+ lt_pred_stat[(frame_len * 3) + i] = overlap[i];
+ }
+ } else {
+#endif
+ for (i = 0; i < frame_len; i++)
+ {
+ lt_pred_stat[i] = lt_pred_stat[i + frame_len];
+ lt_pred_stat[frame_len + i] = time[i];
+ lt_pred_stat[(frame_len * 2) + i] = overlap[i];
+#if 0 /* set to zero once upon initialisation */
+ lt_pred_stat[(frame_len * 3) + i] = 0;
+#endif
+ }
+#ifdef LD_DEC
+ }
+#endif
+}
+
+#endif
diff --git a/src/libfaad/lt_predict.h b/src/libfaad/lt_predict.h
new file mode 100644
index 000000000..42049b8d0
--- /dev/null
+++ b/src/libfaad/lt_predict.h
@@ -0,0 +1,55 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: lt_predict.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifdef LTP_DEC
+
+#ifndef __LT_PREDICT_H__
+#define __LT_PREDICT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "filtbank.h"
+
+void lt_prediction(ic_stream *ics,
+ ltp_info *ltp,
+ real_t *spec,
+ real_t *lt_pred_stat,
+ fb_info *fb,
+ uint8_t win_shape,
+ uint8_t win_shape_prev,
+ uint8_t sr_index,
+ uint8_t object_type,
+ uint16_t frame_len);
+
+void lt_update_state(real_t *lt_pred_stat,
+ real_t *time,
+ real_t *overlap,
+ uint16_t frame_len,
+ uint8_t object_type);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif
diff --git a/src/libfaad/mdct.c b/src/libfaad/mdct.c
new file mode 100644
index 000000000..4d6d05997
--- /dev/null
+++ b/src/libfaad/mdct.c
@@ -0,0 +1,188 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: mdct.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+/*
+ * Fast (I)MDCT Implementation using (I)FFT ((Inverse) Fast Fourier Transform)
+ * and consists of three steps: pre-(I)FFT complex multiplication, complex
+ * (I)FFT, post-(I)FFT complex multiplication,
+ *
+ * As described in:
+ * P. Duhamel, Y. Mahieux, and J.P. Petit, "A Fast Algorithm for the
+ * Implementation of Filter Banks Based on 'Time Domain Aliasing
+ * Cancellation’," IEEE Proc. on ICASSP‘91, 1991, pp. 2209-2212.
+ *
+ *
+ * As of April 6th 2002 completely rewritten.
+ * Thanks to the FFTW library this (I)MDCT can now be used for any data
+ * size n, where n is divisible by 8.
+ *
+ */
+
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <assert.h>
+
+/* uses fftw (http://www.fftw.org) for very fast arbitrary-n FFT and IFFT */
+#include <fftw.h>
+
+
+#include "mdct.h"
+
+
+void faad_mdct_init(mdct_info *mdct, uint16_t N)
+{
+ uint16_t k;
+
+ assert(N % 8 == 0);
+
+ mdct->N = N;
+ mdct->sincos = (faad_sincos*)malloc(N/4*sizeof(faad_sincos));
+ mdct->Z1 = (fftw_complex*)malloc(N/4*sizeof(fftw_complex));
+ mdct->Z2 = (fftw_complex*)malloc(N/4*sizeof(fftw_complex));
+
+ for (k = 0; k < N/4; k++)
+ {
+ real_t angle = 2.0 * M_PI * (k + 1.0/8.0)/(real_t)N;
+ mdct->sincos[k].sin = -sin(angle);
+ mdct->sincos[k].cos = -cos(angle);
+ }
+
+ mdct->plan_backward = fftw_create_plan(N/4, FFTW_BACKWARD, FFTW_ESTIMATE);
+#ifdef LTP_DEC
+ mdct->plan_forward = fftw_create_plan(N/4, FFTW_FORWARD, FFTW_ESTIMATE);
+#endif
+}
+
+void faad_mdct_end(mdct_info *mdct)
+{
+ fftw_destroy_plan(mdct->plan_backward);
+#ifdef LTP_DEC
+ fftw_destroy_plan(mdct->plan_forward);
+#endif
+
+ if (mdct->Z2) free(mdct->Z2);
+ if (mdct->Z1) free(mdct->Z1);
+ if (mdct->sincos) free(mdct->sincos);
+}
+
+void faad_imdct(mdct_info *mdct, real_t *X_in, real_t *X_out)
+{
+ uint16_t k;
+
+ fftw_complex *Z1 = mdct->Z1;
+ fftw_complex *Z2 = mdct->Z2;
+ faad_sincos *sincos = mdct->sincos;
+
+ uint16_t N = mdct->N;
+ uint16_t N2 = N >> 1;
+ uint16_t N4 = N >> 2;
+ uint16_t N8 = N >> 3;
+
+ real_t fac = 2.0/(real_t)N;
+
+ /* pre-IFFT complex multiplication */
+ for (k = 0; k < N4; k++)
+ {
+ uint16_t n = k << 1;
+ real_t x0 = X_in[ n];
+ real_t x1 = X_in[N2 - 1 - n];
+ Z1[k].re = MUL(fac, MUL(x1, sincos[k].cos) - MUL(x0, sincos[k].sin));
+ Z1[k].im = MUL(fac, MUL(x0, sincos[k].cos) + MUL(x1, sincos[k].sin));
+ }
+
+ /* complex IFFT */
+ fftw_one(mdct->plan_backward, Z1, Z2);
+
+ /* post-IFFT complex multiplication */
+ for (k = 0; k < N4; k++)
+ {
+ real_t zr = Z2[k].re;
+ real_t zi = Z2[k].im;
+ Z2[k].re = MUL(zr, sincos[k].cos) - MUL(zi, sincos[k].sin);
+ Z2[k].im = MUL(zi, sincos[k].cos) + MUL(zr, sincos[k].sin);
+ }
+
+ /* reordering */
+ for (k = 0; k < N8; k++)
+ {
+ uint16_t n = k << 1;
+ X_out[ n] = -Z2[N8 + k].im;
+ X_out[ 1 + n] = Z2[N8 - 1 - k].re;
+ X_out[N4 + n] = -Z2[ k].re;
+ X_out[N4 + 1 + n] = Z2[N4 - 1 - k].im;
+ X_out[N2 + n] = -Z2[N8 + k].re;
+ X_out[N2 + 1 + n] = Z2[N8 - 1 - k].im;
+ X_out[N2 + N4 + n] = Z2[ k].im;
+ X_out[N2 + N4 + 1 + n] = -Z2[N4 - 1 - k].re;
+ }
+}
+
+#ifdef LTP_DEC
+void faad_mdct(mdct_info *mdct, real_t *X_in, real_t *X_out)
+{
+ uint16_t k;
+
+ fftw_complex *Z1 = mdct->Z1;
+ fftw_complex *Z2 = mdct->Z2;
+ faad_sincos *sincos = mdct->sincos;
+
+ uint16_t N = mdct->N;
+ uint16_t N2 = N >> 1;
+ uint16_t N4 = N >> 2;
+ uint16_t N8 = N >> 3;
+
+
+ /* pre-FFT complex multiplication */
+ for (k = 0; k < N8; k++)
+ {
+ uint16_t n = k << 1;
+ real_t zr = X_in[N - N4 - 1 - n] + X_in[N - N4 + n];
+ real_t zi = X_in[ N4 + n] - X_in[ N4 - 1 - n];
+
+ Z1[k ].re = -MUL(zr, sincos[k ].cos) - MUL(zi, sincos[k ].sin);
+ Z1[k ].im = -MUL(zi, sincos[k ].cos) + MUL(zr, sincos[k ].sin);
+
+ zr = X_in[ N2 - 1 - n] - X_in[ n];
+ zi = X_in[ N2 + n] + X_in[N - 1 - n];
+
+ Z1[k + N8].re = -MUL(zr, sincos[k + N8].cos) - MUL(zi, sincos[k + N8].sin);
+ Z1[k + N8].im = -MUL(zi, sincos[k + N8].cos) + MUL(zr, sincos[k + N8].sin);
+ }
+
+ /* complex FFT */
+ fftw_one(mdct->plan_forward, Z1, Z2);
+
+ /* post-FFT complex multiplication */
+ for (k = 0; k < N4; k++)
+ {
+ uint16_t n = k << 1;
+ real_t zr = MUL(2.0, MUL(Z2[k].re, sincos[k].cos) + MUL(Z2[k].im, sincos[k].sin));
+ real_t zi = MUL(2.0, MUL(Z2[k].im, sincos[k].cos) - MUL(Z2[k].re, sincos[k].sin));
+
+ X_out[ n] = -zr;
+ X_out[N2 - 1 - n] = zi;
+ X_out[N2 + n] = -zi;
+ X_out[N - 1 - n] = zr;
+ }
+}
+#endif
diff --git a/src/libfaad/mdct.h b/src/libfaad/mdct.h
new file mode 100644
index 000000000..42b80eced
--- /dev/null
+++ b/src/libfaad/mdct.h
@@ -0,0 +1,56 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: mdct.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __MDCT_H__
+#define __MDCT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fftw.h>
+
+typedef struct {
+ real_t sin;
+ real_t cos;
+} faad_sincos;
+
+typedef struct {
+ fftw_complex *Z1;
+ fftw_complex *Z2;
+ faad_sincos *sincos;
+ fftw_plan plan_backward;
+#ifdef LTP_DEC
+ fftw_plan plan_forward;
+#endif
+ uint16_t N;
+} mdct_info;
+
+void faad_mdct_init(mdct_info *mdct, uint16_t N);
+void faad_mdct_end(mdct_info *mdct);
+void faad_imdct(mdct_info *mdct, real_t *X_in, real_t *X_out);
+void faad_mdct(mdct_info *mdct, real_t *X_in, real_t *X_out);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/mp4.c b/src/libfaad/mp4.c
new file mode 100644
index 000000000..d9037d7a9
--- /dev/null
+++ b/src/libfaad/mp4.c
@@ -0,0 +1,174 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: mp4.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+#include "bits.h"
+#include "mp4.h"
+#include "data.h"
+#include "syntax.h"
+
+/* defines if an object type can be decoded by this library or not */
+static uint8_t ObjectTypesTable[32] = {
+ 0, /* NULL */
+#ifdef MAIN_DEC
+ 1, /* AAC Main */
+#else
+ 0, /* AAC Main */
+#endif
+ 1, /* AAC LC */
+ 0, /* AAC SSR */
+#ifdef LTP_DEC
+ 1, /* AAC LTP */
+#else
+ 0, /* AAC LTP */
+#endif
+ 0, /* Reserved */
+ 0, /* AAC Scalable */
+ 0, /* TwinVQ */
+ 0, /* CELP */
+ 0, /* HVXC */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* TTSI */
+ 0, /* Main synthetic */
+ 0, /* Wavetable synthesis */
+ 0, /* General MIDI */
+ 0, /* Algorithmic Synthesis and Audio FX */
+
+ /* MPEG-4 Version 2 */
+#ifdef ERROR_RESILIENCE
+ 1, /* ER AAC LC */
+ 0, /* (Reserved) */
+#ifdef LTP_DEC
+ 1, /* ER AAC LTP */
+#else
+ 0, /* ER AAC LTP */
+#endif
+ 0, /* ER AAC scalable */
+ 0, /* ER TwinVQ */
+ 0, /* ER BSAC */
+#ifdef LD_DEC
+ 1, /* ER AAC LD */
+#else
+ 0, /* ER AAC LD */
+#endif
+ 0, /* ER CELP */
+ 0, /* ER HVXC */
+ 0, /* ER HILN */
+ 0, /* ER Parametric */
+#else /* No ER defined */
+ 0, /* ER AAC LC */
+ 0, /* (Reserved) */
+ 0, /* ER AAC LTP */
+ 0, /* ER AAC scalable */
+ 0, /* ER TwinVQ */
+ 0, /* ER BSAC */
+ 0, /* ER AAC LD */
+ 0, /* ER CELP */
+ 0, /* ER HVXC */
+ 0, /* ER HILN */
+ 0, /* ER Parametric */
+#endif
+ 0, /* (Reserved) */
+ 0, /* (Reserved) */
+ 0, /* (Reserved) */
+ 0 /* (Reserved) */
+};
+
+/* Table 1.6.1 */
+int8_t FAADAPI AudioSpecificConfig(uint8_t *pBuffer,
+ uint32_t *samplerate,
+ uint8_t *channels,
+ uint8_t *sf_index,
+ uint8_t *object_type,
+ uint8_t *aacSectionDataResilienceFlag,
+ uint8_t *aacScalefactorDataResilienceFlag,
+ uint8_t *aacSpectralDataResilienceFlag,
+ uint8_t *frameLengthFlag)
+{
+ bitfile ld;
+ uint8_t ObjectTypeIndex, SamplingFrequencyIndex, ChannelsConfiguration;
+
+ faad_initbits(&ld, pBuffer);
+ faad_byte_align(&ld);
+
+ ObjectTypeIndex = (uint8_t)faad_getbits(&ld, 5
+ DEBUGVAR(1,1,"parse_audio_decoder_specific_info(): ObjectTypeIndex"));
+
+ SamplingFrequencyIndex = (uint8_t)faad_getbits(&ld, 4
+ DEBUGVAR(1,2,"parse_audio_decoder_specific_info(): SamplingFrequencyIndex"));
+
+ ChannelsConfiguration = (uint8_t)faad_getbits(&ld, 4
+ DEBUGVAR(1,3,"parse_audio_decoder_specific_info(): ChannelsConfiguration"));
+
+ *samplerate = sample_rates[SamplingFrequencyIndex];
+
+ *channels = ChannelsConfiguration;
+
+ *sf_index = SamplingFrequencyIndex;
+ *object_type = ObjectTypeIndex;
+
+
+ if (ObjectTypesTable[ObjectTypeIndex] != 1)
+ {
+ return -1;
+ }
+
+ if (*samplerate == 0)
+ {
+ return -2;
+ }
+
+ if(ChannelsConfiguration > 7)
+ {
+ return -3;
+ }
+
+ /* get GASpecificConfig */
+ if (ObjectTypeIndex == 1 || ObjectTypeIndex == 2 ||
+ ObjectTypeIndex == 3 || ObjectTypeIndex == 4 ||
+ ObjectTypeIndex == 6 || ObjectTypeIndex == 7)
+ {
+ return GASpecificConfig(&ld, channels, ObjectTypeIndex,
+ aacSectionDataResilienceFlag,
+ aacScalefactorDataResilienceFlag,
+ aacSpectralDataResilienceFlag,
+ frameLengthFlag);
+#ifdef ERROR_RESILIENCE
+ } else if (ObjectTypeIndex >= ER_OBJECT_START) { /* ER */
+ uint8_t result = GASpecificConfig(&ld, channels, ObjectTypeIndex,
+ aacSectionDataResilienceFlag,
+ aacScalefactorDataResilienceFlag,
+ aacSpectralDataResilienceFlag,
+ frameLengthFlag);
+ uint8_t ep_config = (uint8_t)faad_getbits(&ld, 2
+ DEBUGVAR(1,143,"parse_audio_decoder_specific_info(): epConfig"));
+ if (ep_config != 0)
+ return -5;
+
+ return result;
+#endif
+ } else {
+ return -4;
+ }
+
+ return 0;
+}
diff --git a/src/libfaad/mp4.h b/src/libfaad/mp4.h
new file mode 100644
index 000000000..a0c5d6052
--- /dev/null
+++ b/src/libfaad/mp4.h
@@ -0,0 +1,44 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: mp4.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __MP4_H__
+#define __MP4_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "decoder.h"
+
+int8_t FAADAPI AudioSpecificConfig(uint8_t *pBuffer,
+ uint32_t *samplerate,
+ uint8_t *channels,
+ uint8_t *sf_index,
+ uint8_t *object_type,
+ uint8_t *aacSectionDataResilienceFlag,
+ uint8_t *aacScalefactorDataResilienceFlag,
+ uint8_t *aacSpectralDataResilienceFlag,
+ uint8_t *frameLengthFlag);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/ms.c b/src/libfaad/ms.c
new file mode 100644
index 000000000..fcf2c8774
--- /dev/null
+++ b/src/libfaad/ms.c
@@ -0,0 +1,66 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: ms.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+#include "syntax.h"
+#include "ms.h"
+#include "is.h"
+#include "pns.h"
+
+void ms_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec,
+ uint16_t frame_len)
+{
+ uint8_t g, b, sfb;
+ uint8_t group = 0;
+ uint16_t nshort = frame_len/8;
+
+ uint16_t i, k;
+ real_t tmp;
+
+ if (ics->ms_mask_present >= 1)
+ {
+ for (g = 0; g < ics->num_window_groups; g++)
+ {
+ for (b = 0; b < ics->window_group_length[g]; b++)
+ {
+ for(sfb = 0; sfb < ics->max_sfb; sfb++)
+ {
+ /* If intensity stereo coding or noise substitution is on
+ for a particular scalefactor band, no M/S stereo decoding
+ is carried out.
+ */
+ if ((ics->ms_used[g][sfb] || ics->ms_mask_present == 2) &&
+ !is_intensity(icsr, g, sfb) && !is_noise(ics, g, sfb))
+ {
+ for (i = ics->swb_offset[sfb]; i < ics->swb_offset[sfb+1]; i++)
+ {
+ k = (group*nshort) + i;
+ tmp = l_spec[k] - r_spec[k];
+ l_spec[k] = l_spec[k] + r_spec[k];
+ r_spec[k] = tmp;
+ }
+ }
+ }
+ group++;
+ }
+ }
+ }
+}
diff --git a/src/libfaad/ms.h b/src/libfaad/ms.h
new file mode 100644
index 000000000..cc79498f3
--- /dev/null
+++ b/src/libfaad/ms.h
@@ -0,0 +1,35 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: ms.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __MS_H__
+#define __MS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void ms_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec,
+ uint16_t frame_len);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/output.c b/src/libfaad/output.c
new file mode 100644
index 000000000..f6e8c1382
--- /dev/null
+++ b/src/libfaad/output.c
@@ -0,0 +1,107 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: output.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+
+#include "output.h"
+#include "decoder.h"
+
+
+#define ftol(A,B) {tmp = *(int32_t*) & A - 0x4B7F8000; \
+ B = (int16_t)((tmp==(int16_t)tmp) ? tmp : (tmp>>31)^0x7FFF);}
+
+#define ROUND(x) ((x >= 0) ? (int32_t)floor((x) + 0.5) : (int32_t)ceil((x) + 0.5))
+
+#define ROUND32(x) ROUND(x)
+
+#define FLOAT_SCALE (1.0f/(1<<15))
+
+
+void* output_to_PCM(real_t **input, void *sample_buffer, uint8_t channels,
+ uint16_t frame_len, uint8_t format)
+{
+ uint8_t ch;
+ uint16_t i;
+
+ uint8_t *p = (uint8_t*)sample_buffer;
+ int16_t *short_sample_buffer = (int16_t*)sample_buffer;
+ int32_t *int_sample_buffer = (int32_t*)sample_buffer;
+ float32_t *float_sample_buffer = (float32_t*)sample_buffer;
+
+ /* Copy output to a standard PCM buffer */
+ switch (format)
+ {
+ case FAAD_FMT_16BIT:
+ for (ch = 0; ch < channels; ch++)
+ {
+ for(i = 0; i < frame_len; i++)
+ {
+ int32_t tmp;
+ real_t ftemp;
+
+ ftemp = input[ch][i] + 0xff8000;
+ ftol(ftemp, short_sample_buffer[(i*channels)+ch]);
+ }
+ }
+ break;
+ case FAAD_FMT_24BIT:
+ for (ch = 0; ch < channels; ch++)
+ {
+ for(i = 0; i < frame_len; i++)
+ {
+ if (input[ch][i] > (1<<15)-1)
+ input[ch][i] = (1<<15)-1;
+ else if (input[ch][i] < -(1<<15))
+ input[ch][i] = -(1<<15);
+ int_sample_buffer[(i*channels)+ch] = ROUND(input[ch][i]*(1<<8));
+ }
+ }
+ break;
+ case FAAD_FMT_32BIT:
+ for (ch = 0; ch < channels; ch++)
+ {
+ for(i = 0; i < frame_len; i++)
+ {
+ if (input[ch][i] > (1<<15)-1)
+ input[ch][i] = (1<<15)-1;
+ else if (input[ch][i] < -(1<<15))
+ input[ch][i] = -(1<<15);
+ int_sample_buffer[(i*channels)+ch] = ROUND32(input[ch][i]*(1<<16));
+ }
+ }
+ break;
+ case FAAD_FMT_FLOAT:
+ for (ch = 0; ch < channels; ch++)
+ {
+ for(i = 0; i < frame_len; i++)
+ {
+ if (input[ch][i] > (1<<15)-1)
+ input[ch][i] = (1<<15)-1;
+ else if (input[ch][i] < -(1<<15))
+ input[ch][i] = -(1<<15);
+ float_sample_buffer[(i*channels)+ch] = input[ch][i]*FLOAT_SCALE;
+ }
+ }
+ break;
+ }
+
+ return sample_buffer;
+} \ No newline at end of file
diff --git a/src/libfaad/output.h b/src/libfaad/output.h
new file mode 100644
index 000000000..144a20f35
--- /dev/null
+++ b/src/libfaad/output.h
@@ -0,0 +1,40 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: output.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __OUTPUT_H__
+#define __OUTPUT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void* output_to_PCM(real_t **input,
+ void *samplebuffer,
+ uint8_t channels,
+ uint16_t frame_len,
+ uint8_t format);
+
+typedef float float32_t;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/pns.c b/src/libfaad/pns.c
new file mode 100644
index 000000000..8df56cb9c
--- /dev/null
+++ b/src/libfaad/pns.c
@@ -0,0 +1,120 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: pns.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+
+#include "pns.h"
+
+
+/* Needs some more work */
+/* From the spec:
+ If the same scalefactor band and group is coded by perceptual noise
+ substitution in both channels of a channel pair, the correlation of
+ the noise signal can be controlled by means of the ms_used field: While
+ the default noise generation process works independently for each channel
+ (separate generation of random vectors), the same random vector is used
+ for both channels if ms_used[] is set for a particular scalefactor band
+ and group. In this case, no M/S stereo coding is carried out (because M/S
+ stereo coding and noise substitution coding are mutually exclusive).
+ If the same scalefactor band and group is coded by perceptual noise
+ substitution in only one channel of a channel pair the setting of ms_used[]
+ is not evaluated.
+*/
+
+
+
+static INLINE int32_t random2()
+{
+ static int32_t state = 1;
+
+ state = (1664525L * state) + 1013904223L; /* Numerical recipes */
+
+ return state;
+}
+
+/* The function gen_rand_vector(addr, size) generates a vector of length
+ <size> with signed random values of average energy MEAN_NRG per random
+ value. A suitable random number generator can be realized using one
+ multiplication/accumulation per random value.
+*/
+static INLINE void gen_rand_vector(real_t *spec, uint16_t scale_factor, uint16_t size)
+{
+ uint16_t i;
+ real_t scale;
+
+ for (i = 0; i < size; i++)
+ {
+ spec[i] = (real_t)random2();
+ }
+
+ /* 14496-3 says:
+ scale = 1.0f/(size * (real_t)sqrt(MEAN_NRG));
+ */
+ scale = 1.0f/(real_t)sqrt(size * MEAN_NRG);
+ scale = MUL(scale, (real_t)exp(LN2 * 0.25 * scale_factor));
+
+ /* Scale random vector to desired target energy */
+ for (i = 0; i < size; i++)
+ spec[i] = MUL(spec[i], scale);
+}
+
+void pns_decode(ic_stream *ics, real_t *spec, uint16_t frame_len)
+{
+ uint8_t g, sfb, b;
+ uint16_t size, offs;
+
+ uint8_t group = 0;
+ uint16_t nshort = frame_len/8;
+
+ for (g = 0; g < ics->num_window_groups; g++)
+ {
+ /* Do perceptual noise substitution decoding */
+ for (b = 0; b < ics->window_group_length[g]; b++)
+ {
+ for (sfb = 0; sfb < ics->max_sfb; sfb++)
+ {
+ if (is_noise(ics, g, sfb))
+ {
+ /* Simultaneous use of LTP and PNS is not prevented in the
+ syntax. If both LTP, and PNS are enabled on the same
+ scalefactor band, PNS takes precedence, and no prediction
+ is applied to this band.
+ */
+ ics->ltp.long_used[sfb] = 0;
+ ics->ltp2.long_used[sfb] = 0;
+
+ /* For scalefactor bands coded using PNS the corresponding
+ predictors are switched to "off".
+ */
+ ics->pred.prediction_used[sfb] = 0;
+
+ offs = ics->swb_offset[sfb];
+ size = ics->swb_offset[sfb+1] - offs;
+
+ /* Generate random vector */
+ gen_rand_vector(&spec[(group*nshort)+offs],
+ ics->scale_factors[g][sfb], size);
+ }
+ }
+ group++;
+ }
+ }
+}
diff --git a/src/libfaad/pns.h b/src/libfaad/pns.h
new file mode 100644
index 000000000..6cbcf00b8
--- /dev/null
+++ b/src/libfaad/pns.h
@@ -0,0 +1,51 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: pns.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __PNS_H__
+#define __PNS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "syntax.h"
+#include "common.h"
+
+#define NOISE_OFFSET 90
+#define MEAN_NRG 1.537228e+18 /* (2^31)^2 / 3 */
+
+
+void pns_decode(ic_stream *ics, real_t *spec, uint16_t frame_len);
+
+static INLINE int32_t random2();
+static void gen_rand_vector(real_t *spec, uint16_t scale_factor, uint16_t size);
+
+static INLINE uint8_t is_noise(ic_stream *ics, uint8_t group, uint8_t sfb)
+{
+ if (ics->sfb_cb[group][sfb] == NOISE_HCB)
+ return 1;
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/pulse.c b/src/libfaad/pulse.c
new file mode 100644
index 000000000..f3f149a71
--- /dev/null
+++ b/src/libfaad/pulse.c
@@ -0,0 +1,41 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: pulse.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+#include "syntax.h"
+#include "pulse.h"
+
+void pulse_decode(ic_stream *ics, int16_t *spec_data)
+{
+ uint8_t i;
+ uint16_t k;
+ pulse_info *pul = &(ics->pul);
+
+ k = ics->swb_offset[pul->pulse_start_sfb];
+
+ for(i = 0; i <= pul->number_pulse; i++) {
+ k += pul->pulse_offset[i];
+ if (spec_data[k] > 0)
+ spec_data[k] += pul->pulse_amp[i];
+ else
+ spec_data[k] -= pul->pulse_amp[i];
+ }
+}
diff --git a/src/libfaad/pulse.h b/src/libfaad/pulse.h
new file mode 100644
index 000000000..13283acfa
--- /dev/null
+++ b/src/libfaad/pulse.h
@@ -0,0 +1,34 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: pulse.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __PULSE_H__
+#define __PULSE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void pulse_decode(ic_stream *ics, int16_t *spec_coef);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/reordered_spectral_data.c b/src/libfaad/reordered_spectral_data.c
new file mode 100644
index 000000000..3ebf51e41
--- /dev/null
+++ b/src/libfaad/reordered_spectral_data.c
@@ -0,0 +1,607 @@
+#include <stdlib.h>
+#include <memory.h>
+#include "common.h"
+#include "syntax.h"
+#include "specrec.h"
+#include "bits.h"
+#include "data.h"
+#include "pulse.h"
+#include "analysis.h"
+#include "bits.h"
+#include "codebook/hcb.h"
+
+/* Implements the HCR11 tool as described in ISO/IEC 14496-3/Amd.1, 8.5.3.3 */
+
+#ifdef ERROR_RESILIENCE
+
+//FIXME these tables are not needed twice actually
+
+static hcb *hcb_table[] = {
+ 0, hcb1_1, hcb2_1, 0, hcb4_1, 0, hcb6_1, 0, hcb8_1, 0, hcb10_1, hcb11_1
+};
+
+static hcb_2_quad *hcb_2_quad_table[] = {
+ 0, hcb1_2, hcb2_2, 0, hcb4_2, 0, 0, 0, 0, 0, 0, 0
+};
+
+static hcb_2_pair *hcb_2_pair_table[] = {
+ 0, 0, 0, 0, 0, 0, hcb6_2, 0, hcb8_2, 0, hcb10_2, hcb11_2
+};
+
+static hcb_bin_pair *hcb_bin_table[] = {
+ 0, 0, 0, 0, 0, hcb5, 0, hcb7, 0, hcb9, 0, 0
+};
+
+static uint8_t hcbN[] = { 0, 5, 5, 0, 5, 0, 5, 0, 5, 0, 6, 5 };
+
+
+/* defines whether a huffman codebook is unsigned or not */
+/* Table 4.6.2 */
+static uint8_t unsigned_cb[] = { 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ /* codebook 16 to 31 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+typedef struct
+{
+ /* bit input */
+ uint32_t bufa;
+ uint32_t bufb;
+ int16_t len;
+} bits_t;
+
+
+static INLINE uint32_t showbits(bits_t *ld, uint8_t bits) {
+
+ if (bits == 0) return 0;
+ if (ld->len <= 32){
+ /* huffman_spectral_data_2 needs to read more than may be available, bits maybe
+ > ld->len, deliver 0 than */
+ if (ld->len >= bits)
+ return ((ld->bufa >> (ld->len - bits)) & (0xFFFFFFFF >> (32 - bits)));
+ else
+ return ((ld->bufa << (bits - ld->len)) & (0xFFFFFFFF >> (32 - bits)));
+ } else {
+ if ((ld->len - bits) < 32) {
+
+ return ( (ld->bufb & (0xFFFFFFFF >> (64 - ld->len))) << (bits - ld->len + 32)) |
+ (ld->bufa >> (ld->len - bits));
+ } else {
+ return ((ld->bufb >> (ld->len - bits - 32)) & (0xFFFFFFFF >> (32 - bits)));
+ }
+ }
+}
+
+/* return 1 if position is outside of buffer, 0 otherwise */
+static INLINE int8_t flushbits( bits_t *ld, uint8_t bits)
+{
+ ld->len -= bits;
+
+ if (ld->len <0) {
+ ld->len = 0;
+ return 1;
+ } else
+ return 0;
+}
+
+
+static INLINE int8_t getbits(bits_t *ld, uint8_t n, uint32_t *result)
+{
+ *result = showbits(ld, n);
+ return flushbits(ld, n);
+}
+
+static INLINE int8_t get1bit(bits_t *ld, uint8_t *result)
+{
+ uint32_t res;
+ int8_t ret;
+
+ ret = getbits(ld, 1, &res);
+ *result = res & 1;
+ return ret;
+}
+
+/* Special version of huffman_spectral_data adapted from huffman.h
+ Will not read from a bitfile but a bits_t structure.
+ Will keep track of the bits decoded and return the number of bits remaining.
+ Do not read more than ld->len, return -1 if codeword would be longer */
+
+static int8_t huffman_spectral_data_2(uint8_t cb, bits_t *ld, int16_t *sp )
+{
+ uint32_t cw;
+ uint16_t offset = 0;
+ uint8_t extra_bits;
+ uint8_t i;
+ uint8_t save_cb = cb;
+
+
+ switch (cb)
+ {
+ case 1: /* 2-step method for data quadruples */
+ case 2:
+ case 4:
+
+ cw = showbits(ld, hcbN[cb]);
+ offset = hcb_table[cb][cw].offset;
+ extra_bits = hcb_table[cb][cw].extra_bits;
+
+ if (extra_bits)
+ {
+ /* we know for sure it's more than hcbN[cb] bits long */
+ if ( flushbits(ld, hcbN[cb]) ) return -1;
+ offset += (uint16_t)showbits(ld, extra_bits);
+ if ( flushbits(ld, hcb_2_quad_table[cb][offset].bits - hcbN[cb]) ) return -1;
+ } else {
+ if ( flushbits(ld, hcb_2_quad_table[cb][offset].bits) ) return -1;
+ }
+
+ sp[0] = hcb_2_quad_table[cb][offset].x;
+ sp[1] = hcb_2_quad_table[cb][offset].y;
+ sp[2] = hcb_2_quad_table[cb][offset].v;
+ sp[3] = hcb_2_quad_table[cb][offset].w;
+ break;
+
+ case 6: /* 2-step method for data pairs */
+ case 8:
+ case 10:
+ case 11:
+ /* VCB11 uses codebook 11 */
+ case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
+ case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31:
+
+ /* TODO: If ER is used, some extra error checking should be done */
+ if (cb >= 16)
+ cb = 11;
+
+ cw = showbits(ld, hcbN[cb]);
+ offset = hcb_table[cb][cw].offset;
+ extra_bits = hcb_table[cb][cw].extra_bits;
+
+ if (extra_bits)
+ {
+ /* we know for sure it's more than hcbN[cb] bits long */
+ if ( flushbits(ld, hcbN[cb]) ) return -1;
+ offset += (uint16_t)showbits(ld, extra_bits);
+ if ( flushbits(ld, hcb_2_pair_table[cb][offset].bits - hcbN[cb]) ) return -1;
+ } else {
+ if ( flushbits(ld, hcb_2_pair_table[cb][offset].bits) ) return -1;
+ }
+ sp[0] = hcb_2_pair_table[cb][offset].x;
+ sp[1] = hcb_2_pair_table[cb][offset].y;
+ break;
+
+ case 3: /* binary search for data quadruples */
+
+ while (!hcb3[offset].is_leaf)
+ {
+ uint8_t b;
+
+ if ( get1bit(ld, &b) ) return -1;
+ offset += hcb3[offset].data[b];
+ }
+
+ sp[0] = hcb3[offset].data[0];
+ sp[1] = hcb3[offset].data[1];
+ sp[2] = hcb3[offset].data[2];
+ sp[3] = hcb3[offset].data[3];
+
+ break;
+
+ case 5: /* binary search for data pairs */
+ case 7:
+ case 9:
+
+ while (!hcb_bin_table[cb][offset].is_leaf)
+ {
+ uint8_t b;
+
+ if (get1bit(ld, &b) ) return -1;
+ offset += hcb_bin_table[cb][offset].data[b];
+ }
+
+ sp[0] = hcb_bin_table[cb][offset].data[0];
+ sp[1] = hcb_bin_table[cb][offset].data[1];
+
+ break;
+ }
+
+ /* decode sign bits */
+ if (unsigned_cb[cb]) {
+
+ for(i = 0; i < ((cb < FIRST_PAIR_HCB) ? QUAD_LEN : PAIR_LEN); i++)
+ {
+ if(sp[i])
+ {
+ uint8_t b;
+ if ( get1bit(ld, &b) ) return -1;
+ if (b != 0) {
+ sp[i] = -sp[i];
+ }
+ }
+ }
+ }
+
+ /* decode huffman escape bits */
+ if ((cb == ESC_HCB) || (cb >= 16))
+ {
+ uint8_t k;
+ for (k=0; k<2; k++){
+
+ if ((sp[k] == 16) || (sp[k] == -16)) {
+
+ uint8_t neg, i;
+ int32_t j, off;
+
+ neg = (sp[k] < 0) ? 1 : 0;
+
+ for (i = 4; ; i++)
+ {
+ uint8_t b;
+ if ( get1bit(ld, &b) ) return -1;
+ if (b == 0)
+ {
+ break;
+ }
+ }
+// TODO: here we would need to test "off" if VCB11 is used!
+ if ( getbits(ld, i, &off) ) return -1;
+ j = off + (1<<i);
+ sp[k] = neg ? -j : j;
+ }
+ }
+ }
+ return ld->len;
+}
+
+/* rewind len (max. 32) bits so that the MSB becomes LSB */
+
+static uint32_t rewind_word( uint32_t W, uint8_t len){
+
+ uint8_t i;
+ uint32_t tmp_W=0;
+
+ for ( i=0; i<len; i++ ) {
+ tmp_W<<=1;
+ if (W & (1<<i)) tmp_W |= 1;
+ }
+ return tmp_W;
+}
+
+static void rewind_lword( uint32_t *highW, uint32_t *lowW, uint8_t len){
+
+ uint32_t tmp_lW=0;
+
+ if (len > 32) {
+ tmp_lW = rewind_word( (*highW << (64-len)) | (*lowW >> (len-32)), 32);
+ *highW = rewind_word( *lowW << (64-len) , 32);
+ *lowW = tmp_lW;
+ } else {
+ *highW =0;
+ *lowW = rewind_word( *lowW, len);
+ }
+}
+
+/* Takes a codeword as stored in r, rewinds the remaining bits and stores it back */
+
+static void rewind_bits(bits_t * r){
+
+ uint32_t hw, lw;
+
+ if (r->len == 0) return;
+
+ if (r->len >32) {
+ lw = r->bufa;
+ hw = r->bufb & (0xFFFFFFFF >> (64 - r->len));
+ rewind_lword( &hw, &lw, r->len );
+ r->bufa = lw;
+ r->bufb = hw;
+
+ } else {
+ lw = showbits(r, r->len );
+ r->bufa = rewind_word( lw, r->len);
+ r->bufb = 0;
+ }
+}
+
+/* takes codewords from a and b, concatenate them and store them in b */
+
+static void concat_bits( bits_t * a, bits_t * b) {
+
+ uint32_t hwa, lwa, hwb, lwb;
+
+ if (a->len == 0) return;
+
+ if (a->len >32) {
+ lwa = a->bufa;
+ hwa = a->bufb & (0xFFFFFFFF >> (64 - a->len));
+ } else {
+ lwa = showbits(a, a->len );
+ hwa = 0;
+ }
+ if (b->len >=32) {
+ lwb = b->bufa;
+ hwb = (b->bufb & (0xFFFFFFFF >> (64 - b->len)) ) | ( lwa << (b->len - 32));
+ } else {
+ lwb = showbits(b, b->len ) | (lwa << (b->len));
+ hwb = (lwa >> (32 - b->len)) | (hwa << (b->len));
+ }
+
+ b->bufa = lwb;
+ b->bufb = hwb;
+ b->len += a->len;
+}
+
+/* 8.5.3.3.1 */
+
+static const uint8_t PresortedCodebook_VCB11[] = { 11, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 9, 7, 5, 3, 1};
+static const uint8_t PresortedCodebook[] = { 11, 9, 7, 5, 3, 1};
+
+static const uint8_t maxCwLen[32] = {0, 11, 9, 20, 16, 13, 11, 14, 12, 17, 14, 49,
+ 0, 0, 0, 0, 14, 17, 21, 21, 25, 25, 29, 29, 29, 29, 33, 33, 33, 37, 37, 41};
+
+typedef struct {
+
+ bits_t bits;
+ uint8_t decoded;
+ uint16_t sp_offset;
+ uint8_t cb;
+} codeword_state;
+
+
+#define segmentWidth( codebook ) min( maxCwLen[codebook], ics->length_of_longest_codeword )
+
+uint8_t reordered_spectral_data(ic_stream *ics, bitfile *ld, int16_t *spectral_data,
+ uint16_t frame_len, uint8_t aacSectionDataResilienceFlag)
+{
+ uint16_t sp_offset[8];
+ uint16_t g,i, presort;
+ uint16_t NrCodeWords=0, numberOfSegments=0, BitsRead=0;
+ uint8_t numberOfSets, set;
+ codeword_state Codewords[ 1024 ]; // FIXME max length? PCWs are not stored, so index is Codewordnr - numberOfSegments!, maybe malloc()?
+ bits_t Segment[ 512 ];
+
+ uint8_t PCW_decoded=0;
+ uint16_t segment_index=0, codeword_index=0;
+ uint16_t nshort = frame_len/8;
+
+
+ memset (spectral_data, 0, frame_len*sizeof(uint16_t));
+
+ if (ics->length_of_reordered_spectral_data == 0)
+ return 0; /* nothing to do */
+
+ /* if we have a corrupted bitstream this can happen... */
+ if ((ics->length_of_longest_codeword == 0) ||
+ (ics->length_of_reordered_spectral_data <
+ ics->length_of_longest_codeword))
+ {
+ return 10; /* this is not good... */
+ }
+
+ /* store the offset into the spectral data for all the window groups because we can't do it later */
+
+ sp_offset[0] = 0;
+ for (g=1; g < ics->num_window_groups; g++) {
+ sp_offset[g] = sp_offset[g-1] + nshort*ics->window_group_length[g-1];
+ }
+
+ /* All data is sorted according to the codebook used */
+ for (presort = 0; presort < (aacSectionDataResilienceFlag ? 22 : 6); presort++) {
+
+ uint8_t sfb;
+ /* next codebook that has to be processed according to presorting */
+ uint8_t nextCB = aacSectionDataResilienceFlag ? PresortedCodebook_VCB11[ presort ] : PresortedCodebook[ presort ];
+
+ /* Data belonging to the same spectral unit and having the same codebook comes in consecutive codewords.
+ This is done by scanning all sfbs for possible codewords. For sfbs with more than 4 elements this has to be
+ repeated */
+
+ for (sfb=0; sfb<ics->max_sfb; sfb ++) {
+
+ uint8_t sect_cb, w;
+
+ for (w=0; w< (ics->swb_offset[sfb+1] - ics->swb_offset[sfb]); w+=4){
+ for(g = 0; g < ics->num_window_groups; g++)
+ {
+ for (i = 0; i < ics->num_sec[g]; i++)
+ {
+
+
+ sect_cb = ics->sect_cb[g][i];
+
+ if (
+ /* process only sections that are due now */
+ (( sect_cb == nextCB ) || (( nextCB < ESC_HCB ) && ( sect_cb == nextCB+1)) ) &&
+
+ /* process only sfb's that are due now */
+ ((ics->sect_start[g][i] <= sfb) && (ics->sect_end[g][i] > sfb))
+ ) {
+
+
+ if ((sect_cb != ZERO_HCB) &&
+ (sect_cb != NOISE_HCB) &&
+ (sect_cb != INTENSITY_HCB) &&
+ (sect_cb != INTENSITY_HCB2))
+ {
+ uint8_t inc = (sect_cb < FIRST_PAIR_HCB) ? QUAD_LEN : PAIR_LEN;
+ uint16_t k;
+
+ uint32_t hw, lw;
+
+
+ for (k=0; (k < (4/inc)*ics->window_group_length[g]) &&
+ ( (k+w*ics->window_group_length[g]/inc) < (ics->sect_sfb_offset[g][sfb+1] - ics->sect_sfb_offset[g][sfb])); k++) {
+
+ uint16_t sp = sp_offset[g] + ics->sect_sfb_offset[g][sfb] + inc*(k+w*ics->window_group_length[g]/inc);
+
+ if (!PCW_decoded) {
+
+ /* if we haven't yet read until the end of the buffer, we can directly decode the so-called PCWs */
+ if ((BitsRead + segmentWidth( sect_cb ))<= ics->length_of_reordered_spectral_data) {
+
+ Segment[ numberOfSegments ].len = segmentWidth( sect_cb );
+
+ if (segmentWidth( sect_cb ) > 32) {
+ Segment[ numberOfSegments ].bufb = faad_showbits(ld, segmentWidth( sect_cb ) - 32);
+ faad_flushbits(ld, segmentWidth( sect_cb) - 32);
+ Segment[ numberOfSegments ].bufa = faad_showbits(ld, 32),
+ faad_flushbits(ld, 32 );
+
+ } else {
+ Segment[ numberOfSegments ].bufa = faad_showbits(ld, segmentWidth( sect_cb ));
+ Segment[ numberOfSegments ].bufb = 0;
+ faad_flushbits(ld, segmentWidth( sect_cb) );
+ }
+
+ huffman_spectral_data_2(sect_cb, &Segment[ numberOfSegments ], &spectral_data[sp]);
+
+ BitsRead += segmentWidth( sect_cb );
+
+ /* skip to next segment, but store left bits in new buffer */
+ rewind_bits( &Segment[ numberOfSegments ]);
+
+ numberOfSegments++;
+ } else {
+
+ /* the last segment is extended until length_of_reordered_spectral_data */
+
+ if (BitsRead < ics->length_of_reordered_spectral_data) {
+
+ uint8_t additional_bits = (ics->length_of_reordered_spectral_data - BitsRead);
+
+ if ( additional_bits > 32) {
+ hw = faad_showbits(ld, additional_bits - 32);
+ faad_flushbits(ld, additional_bits - 32);
+ lw = faad_showbits(ld, 32);
+ faad_flushbits(ld, 32 );
+ } else {
+ lw = faad_showbits(ld, additional_bits);
+ hw = 0;
+ faad_flushbits(ld, additional_bits );
+ }
+ rewind_lword( &hw, &lw, additional_bits + Segment[ numberOfSegments-1 ].len );
+ if (Segment[ numberOfSegments-1 ].len > 32) {
+
+ Segment[ numberOfSegments-1 ].bufb = hw +
+ showbits(&Segment[ numberOfSegments-1 ], Segment[ numberOfSegments-1 ].len - 32);
+ Segment[ numberOfSegments-1 ].bufa = lw +
+ showbits(&Segment[ numberOfSegments-1 ], 32);
+ } else {
+ Segment[ numberOfSegments-1 ].bufa = lw +
+ showbits(&Segment[ numberOfSegments-1 ], Segment[ numberOfSegments-1 ].len);
+ Segment[ numberOfSegments-1 ].bufb = hw;
+ }
+ Segment[ numberOfSegments-1 ].len += additional_bits;
+
+
+ }
+ BitsRead = ics->length_of_reordered_spectral_data;
+ PCW_decoded = 1;
+
+ Codewords[ 0 ].sp_offset = sp;
+ Codewords[ 0 ].cb = sect_cb;
+ Codewords[ 0 ].decoded = 0;
+ Codewords[ 0 ].bits.len = 0;
+ }
+ } else {
+ Codewords[ NrCodeWords - numberOfSegments ].sp_offset = sp;
+ Codewords[ NrCodeWords - numberOfSegments ].cb = sect_cb;
+ Codewords[ NrCodeWords - numberOfSegments ].decoded = 0;
+ Codewords[ NrCodeWords - numberOfSegments ].bits.len = 0;
+
+ } /* PCW decoded */
+ NrCodeWords++;
+ } /* of k */
+ }
+ }
+ } /* of i */
+ } /* of g */
+ } /* of w */
+ } /* of sfb */
+ } /* of presort */
+
+ numberOfSets = NrCodeWords / numberOfSegments;
+
+ /* second step: decode nonPCWs */
+
+ for (set = 1; set <= numberOfSets; set++) {
+
+ uint16_t trial;
+ for (trial = 0; trial < numberOfSegments; trial++) {
+
+ uint16_t codewordBase;
+ uint16_t codeword_index;
+ uint16_t set_decoded=numberOfSegments;
+
+ if (set == numberOfSets)
+ set_decoded = NrCodeWords - set*numberOfSegments; /* last set is shorter than the rest */
+
+ for (codewordBase = 0; codewordBase < numberOfSegments; codewordBase++) {
+
+ uint16_t segment_index = (trial + codewordBase) % numberOfSegments;
+ uint16_t codeword_index = codewordBase + set*numberOfSegments - numberOfSegments;
+
+ if ((codeword_index + numberOfSegments) >= NrCodeWords)
+ break;
+ if (!Codewords[ codeword_index ].decoded) {
+ if ( Segment[ segment_index ].len > 0) {
+
+ uint16_t tmplen;
+ if (Codewords[ codeword_index ].bits.len != 0) {
+ /* on the first trial the data is only stored in Segment[], not in Codewords[].
+ On next trials first collect the data stored for this codeword and
+ concatenate the new data from Segment[] */
+
+ concat_bits( &Codewords[ codeword_index ].bits, &Segment[ segment_index ]);
+ /* Now everthing is stored in Segment[] */
+ }
+ tmplen = Segment[ segment_index ].len;
+ if ( huffman_spectral_data_2(Codewords[ codeword_index ].cb, &Segment[ segment_index ],
+ &spectral_data[ Codewords[ codeword_index ].sp_offset ]) >=0) {
+
+ /* CW did fit into segment */
+
+ Codewords[ codeword_index ].decoded = 1;
+ set_decoded--;
+ } else {
+
+ /* CW did not fit, so store for later use */
+
+ Codewords[ codeword_index ].bits.len = tmplen;
+ Codewords[ codeword_index ].bits.bufa = Segment[ segment_index ].bufa;
+ Codewords[ codeword_index ].bits.bufb = Segment[ segment_index ].bufb;
+ }
+ }
+ }
+ } /* of codewordBase */
+
+ if (set_decoded == 0) break; /* no undecoded codewords left in this set */
+
+ } /* of trial */
+
+ /* rewind all bits in remaining segments with len>0 */
+ for (i=0; i < numberOfSegments; i++)
+ rewind_bits( &Segment[ i ] );
+ }
+
+#if 0
+ {
+ int i, r=0, c=0;
+ for (i=0; i< numberOfSegments; i++)
+ r += Segment[ i ].len;
+ if (r != 0) {
+printf("reordered_spectral_data: %d bits remaining!\n", r);
+ }
+ for (i=0; i< NrCodeWords - numberOfSegments; i++) {
+ if (Codewords[ i ].decoded == 0) {
+ c++;
+ }
+ }
+ if (c != 0) {
+printf("reordered_spectral_data: %d Undecoded Codewords remaining!\n",c );
+ }
+ if ((r !=0) || (c!=0)) return 10;
+ }
+#endif
+
+ return 0;
+}
+#endif
diff --git a/src/libfaad/sbr_dec.c b/src/libfaad/sbr_dec.c
new file mode 100644
index 000000000..b4f51b726
--- /dev/null
+++ b/src/libfaad/sbr_dec.c
@@ -0,0 +1,60 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: sbr_dec.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+/*
+ SBR Decoder overview:
+
+ To achieve a synchronized output signal, the following steps have to be
+ acknowledged in the decoder:
+ - The bitstream parser divides the bitstream into two parts; the AAC
+ core coder part and the SBR part.
+ - The SBR bitstream part is fed to the bitstream de-multiplexer followed
+ by de-quantization The raw data is Huffman decoded.
+ - The AAC bitstream part is fed to the AAC core decoder, where the
+ bitstream data of the current frame is decoded, yielding a time domain
+ audio signal block of 1024 samples. The block length could easily be
+ adapted to other sizes e.g. 960.
+ - The core coder audio block is fed to the analysis QMF bank using a
+ delay of 1312 samples.
+ - The analysis QMF bank performs the filtering of the delayed core coder
+ audio signal. The output from the filtering is stored in the matrix
+ Xlow. The output from the analysis QMF bank is delayed tHFGen subband
+ samples, before being fed to the synthesis QMF bank. To achieve
+ synchronization tHFGen = 32, i.e. the value must equal the number of
+ subband samples corresponding to one frame.
+ - The HF generator calculates XHigh given the matrix XLow. The process
+ is guided by the SBR data contained in the current frame.
+ - The envelope adjuster calculates the matrix Y given the matrix XHigh
+ and the SBR envelope data, extracted from the SBR bitstream. To
+ achieve synchronization, tHFAdj has to be set to tHFAdj = 0, i.e. the
+ envelope adjuster operates on data delayed tHFGen subband samples.
+ - The synthesis QMF bank operates on the delayed output from the analysis
+ QMF bank and the output from the envelope adjuster.
+ */
+
+#include "common.h"
+
+#ifdef SBR
+
+#include "sbr_syntax.h"
+#include "sbr_qmf.h"
+
+#endif
diff --git a/src/libfaad/sbr_dec.h b/src/libfaad/sbr_dec.h
new file mode 100644
index 000000000..c08ae3578
--- /dev/null
+++ b/src/libfaad/sbr_dec.h
@@ -0,0 +1,38 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: sbr_dec.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifdef SBR
+
+#ifndef __SBR_DEC_H__
+#define __SBR_DEC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* SBR */ \ No newline at end of file
diff --git a/src/libfaad/sbr_huff.c b/src/libfaad/sbr_huff.c
new file mode 100644
index 000000000..62413d708
--- /dev/null
+++ b/src/libfaad/sbr_huff.c
@@ -0,0 +1,673 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: sbr_huff.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+
+#ifdef SBR
+
+#include "bits.h"
+#include "sbr_huff.h"
+
+
+/* huffman tables all have some offset LAV */
+uint16_t sbr_huff_dec(bitfile *ld, sbr_huff_tab *t_huff)
+{
+}
+
+
+sbr_huff_tab t_huffman_env_1_5dB[] = {
+{ /* */ 0, 60},
+{ /* */ 1, 59},
+{ /* */ 4, 61},
+{ /* */ 5, 58},
+{ /* */ 12, 62},
+{ /* */ 13, 57},
+{ /* */ 28, 63},
+{ /* */ 29, 56},
+{ /* */ 60, 64},
+{ /* */ 61, 55},
+{ /* */ 124, 65},
+{ /* */ 125, 54},
+{ /* */ 252, 66},
+{ /* */ 253, 53},
+{ /* */ 508, 67},
+{ /* */ 509, 52},
+{ /* */ 1020, 51},
+{ /* */ 1021, 68},
+{ /* */ 2044, 50},
+{ /* */ 4090, 69},
+{ /* */ 4091, 49},
+{ /* */ 8184, 70},
+{ /* */ 8185, 48},
+{ /* */ 8186, 47},
+{ /* */ 16374, 71},
+{ /* */ 16375, 46},
+{ /* */ 16376, 72},
+{ /* */ 16377, 45},
+{ /* */ 32756, 44},
+{ /* */ 32757, 73},
+{ /* */ 65516, 41},
+{ /* */ 65517, 42},
+{ /* */ 65518, 43},
+{ /* */ 65519, 74},
+{ /* */ 65520, 36},
+{ /* */ 65521, 40},
+{ /* */ 65522, 76},
+{ /* */ 131046, 34},
+{ /* */ 131047, 39},
+{ /* */ 131048, 75},
+{ /* */ 131049, 37},
+{ /* */ 262100, 35},
+{ /* */ 262101, 38},
+{ /* */ 262102, 0},
+{ /* */ 262103, 1},
+{ /* */ 262104, 2},
+{ /* */ 262105, 3},
+{ /* */ 262106, 4},
+{ /* */ 262107, 5},
+{ /* */ 524216, 6},
+{ /* */ 524217, 7},
+{ /* */ 524218, 8},
+{ /* */ 524219, 9},
+{ /* */ 524220, 10},
+{ /* */ 524221, 11},
+{ /* */ 524222, 12},
+{ /* */ 524223, 13},
+{ /* */ 524224, 14},
+{ /* */ 524225, 15},
+{ /* */ 524226, 16},
+{ /* */ 524227, 17},
+{ /* */ 524228, 18},
+{ /* */ 524229, 19},
+{ /* */ 524230, 20},
+{ /* */ 524231, 21},
+{ /* */ 524232, 22},
+{ /* */ 524233, 23},
+{ /* */ 524234, 24},
+{ /* */ 524235, 25},
+{ /* */ 524236, 26},
+{ /* */ 524237, 27},
+{ /* */ 524238, 28},
+{ /* */ 524239, 29},
+{ /* */ 524240, 30},
+{ /* */ 524241, 31},
+{ /* */ 524242, 32},
+{ /* */ 524243, 33},
+{ /* */ 524244, 77},
+{ /* */ 524245, 78},
+{ /* */ 524246, 79},
+{ /* */ 524247, 80},
+{ /* */ 524248, 81},
+{ /* */ 524249, 82},
+{ /* */ 524250, 83},
+{ /* */ 524251, 84},
+{ /* */ 524252, 85},
+{ /* */ 524253, 86},
+{ /* */ 524254, 87},
+{ /* */ 524255, 88},
+{ /* */ 524256, 89},
+{ /* */ 524257, 90},
+{ /* */ 524258, 91},
+{ /* */ 524259, 92},
+{ /* */ 524260, 93},
+{ /* */ 524261, 94},
+{ /* */ 524262, 95},
+{ /* */ 524263, 96},
+{ /* */ 524264, 97},
+{ /* */ 524265, 98},
+{ /* */ 524266, 99},
+{ /* */ 524267, 100},
+{ /* */ 524268, 101},
+{ /* */ 524269, 102},
+{ /* */ 524270, 103},
+{ /* */ 524271, 104},
+{ /* */ 524272, 105},
+{ /* */ 524273, 106},
+{ /* */ 524274, 107},
+{ /* */ 524275, 108},
+{ /* */ 524276, 109},
+{ /* */ 524277, 110},
+{ /* */ 524278, 111},
+{ /* */ 524279, 112},
+{ /* */ 524280, 113},
+{ /* */ 524281, 114},
+{ /* */ 524282, 115},
+{ /* */ 524283, 116},
+{ /* */ 524284, 117},
+{ /* */ 524285, 118},
+{ /* */ 524286, 119},
+{ /* */ 524287, 120}
+};
+
+sbr_huff_tab f_huffman_env_1_5dB[] = {
+{ /* */ 0, 60},
+{ /* */ 1, 59},
+{ /* */ 4, 61},
+{ /* */ 5, 58},
+{ /* */ 12, 57},
+{ /* */ 13, 62},
+{ /* */ 28, 56},
+{ /* */ 29, 63},
+{ /* */ 60, 55},
+{ /* */ 61, 64},
+{ /* */ 124, 54},
+{ /* */ 250, 65},
+{ /* */ 251, 53},
+{ /* */ 252, 66},
+{ /* */ 506, 52},
+{ /* */ 507, 67},
+{ /* */ 508, 51},
+{ /* */ 1018, 68},
+{ /* */ 1019, 50},
+{ /* */ 2040, 69},
+{ /* */ 2041, 49},
+{ /* */ 2042, 70},
+{ /* */ 2043, 71},
+{ /* */ 4088, 48},
+{ /* */ 4089, 72},
+{ /* */ 4090, 47},
+{ /* */ 4091, 73},
+{ /* */ 8184, 74},
+{ /* */ 8185, 46},
+{ /* */ 8186, 45},
+{ /* */ 8187, 75},
+{ /* */ 16376, 76},
+{ /* */ 16377, 77},
+{ /* */ 16378, 44},
+{ /* */ 32758, 43},
+{ /* */ 32759, 42},
+{ /* */ 65520, 41},
+{ /* */ 65521, 78},
+{ /* */ 65522, 79},
+{ /* */ 65523, 40},
+{ /* */ 65524, 39},
+{ /* */ 131050, 80},
+{ /* */ 131051, 81},
+{ /* */ 131052, 36},
+{ /* */ 131053, 37},
+{ /* */ 131054, 38},
+{ /* */ 131055, 34},
+{ /* */ 262112, 32},
+{ /* */ 262113, 82},
+{ /* */ 262114, 83},
+{ /* */ 262115, 85},
+{ /* */ 262116, 19},
+{ /* */ 262117, 35},
+{ /* */ 262118, 86},
+{ /* */ 262119, 87},
+{ /* */ 262120, 30},
+{ /* */ 262121, 33},
+{ /* */ 262122, 84},
+{ /* */ 262123, 88},
+{ /* */ 262124, 104},
+{ /* */ 524250, 9},
+{ /* */ 524251, 14},
+{ /* */ 524252, 16},
+{ /* */ 524253, 17},
+{ /* */ 524254, 23},
+{ /* */ 524255, 27},
+{ /* */ 524256, 29},
+{ /* */ 524257, 31},
+{ /* */ 524258, 90},
+{ /* */ 524259, 97},
+{ /* */ 524260, 102},
+{ /* */ 524261, 107},
+{ /* */ 524262, 108},
+{ /* */ 524263, 0},
+{ /* */ 524264, 1},
+{ /* */ 1048530, 2},
+{ /* */ 1048531, 3},
+{ /* */ 1048532, 4},
+{ /* */ 1048533, 5},
+{ /* */ 1048534, 6},
+{ /* */ 1048535, 7},
+{ /* */ 1048536, 8},
+{ /* */ 1048537, 10},
+{ /* */ 1048538, 11},
+{ /* */ 1048539, 12},
+{ /* */ 1048540, 13},
+{ /* */ 1048541, 15},
+{ /* */ 1048542, 18},
+{ /* */ 1048543, 20},
+{ /* */ 1048544, 21},
+{ /* */ 1048545, 22},
+{ /* */ 1048546, 24},
+{ /* */ 1048547, 25},
+{ /* */ 1048548, 26},
+{ /* */ 1048549, 28},
+{ /* */ 1048550, 89},
+{ /* */ 1048551, 91},
+{ /* */ 1048552, 92},
+{ /* */ 1048553, 93},
+{ /* */ 1048554, 94},
+{ /* */ 1048555, 95},
+{ /* */ 1048556, 96},
+{ /* */ 1048557, 98},
+{ /* */ 1048558, 99},
+{ /* */ 1048559, 100},
+{ /* */ 1048560, 101},
+{ /* */ 1048561, 103},
+{ /* */ 1048562, 105},
+{ /* */ 1048563, 106},
+{ /* */ 1048564, 109},
+{ /* */ 1048565, 110},
+{ /* */ 1048566, 111},
+{ /* */ 1048567, 112},
+{ /* */ 1048568, 113},
+{ /* */ 1048569, 114},
+{ /* */ 1048570, 115},
+{ /* */ 1048571, 116},
+{ /* */ 1048572, 117},
+{ /* */ 1048573, 118},
+{ /* */ 1048574, 119},
+{ /* */ 1048575, 120}
+};
+
+sbr_huff_tab t_huffman_env_bal_1_5dB[] = {
+{ /* */ 0, 24},
+{ /* */ 2, 25},
+{ /* */ 6, 23},
+{ /* */ 14, 26},
+{ /* */ 30, 22},
+{ /* */ 62, 27},
+{ /* */ 126, 21},
+{ /* */ 254, 28},
+{ /* */ 510, 20},
+{ /* */ 2044, 19},
+{ /* */ 2045, 29},
+{ /* */ 4092, 18},
+{ /* */ 4093, 30},
+{ /* */ 32752, 31},
+{ /* */ 65506, 17},
+{ /* */ 65507, 32},
+{ /* */ 65508, 0},
+{ /* */ 65509, 1},
+{ /* */ 65510, 2},
+{ /* */ 65511, 3},
+{ /* */ 65512, 4},
+{ /* */ 65513, 5},
+{ /* */ 65514, 6},
+{ /* */ 65515, 7},
+{ /* */ 65516, 8},
+{ /* */ 65517, 9},
+{ /* */ 65518, 10},
+{ /* */ 65519, 11},
+{ /* */ 65520, 12},
+{ /* */ 65521, 13},
+{ /* */ 65522, 14},
+{ /* */ 65523, 15},
+{ /* */ 65524, 16},
+{ /* */ 65525, 33},
+{ /* */ 65526, 34},
+{ /* */ 65527, 35},
+{ /* */ 65528, 36},
+{ /* */ 65529, 37},
+{ /* */ 65530, 38},
+{ /* */ 131062, 39},
+{ /* */ 131063, 40},
+{ /* */ 131064, 41},
+{ /* */ 131065, 42},
+{ /* */ 131066, 43},
+{ /* */ 131067, 44},
+{ /* */ 131068, 45},
+{ /* */ 131069, 46},
+{ /* */ 131070, 47},
+{ /* */ 131071, 48}
+};
+
+sbr_huff_tab f_huffman_env_bal_1_5dB[] = {
+{ /* */ 0, 24},
+{ /* */ 2, 23},
+{ /* */ 6, 25},
+{ /* */ 14, 22},
+{ /* */ 30, 26},
+{ /* */ 62, 27},
+{ /* */ 115, 21},
+{ /* */ 243, 20},
+{ /* */ 510, 28},
+{ /* */ 2044, 19},
+{ /* */ 2045, 29},
+{ /* */ 2046, 18},
+{ /* */ 4094, 30},
+{ /* */ 16380, 17},
+{ /* */ 32762, 31},
+{ /* */ 65526, 32},
+{ /* */ 65527, 15},
+{ /* */ 131056, 16},
+{ /* */ 262114, 0},
+{ /* */ 262115, 1},
+{ /* */ 262116, 2},
+{ /* */ 262117, 3},
+{ /* */ 262118, 4},
+{ /* */ 262119, 5},
+{ /* */ 262120, 6},
+{ /* */ 262121, 7},
+{ /* */ 262122, 8},
+{ /* */ 262123, 9},
+{ /* */ 262124, 10},
+{ /* */ 262125, 11},
+{ /* */ 262126, 12},
+{ /* */ 262127, 13},
+{ /* */ 262128, 14},
+{ /* */ 262129, 33},
+{ /* */ 262130, 34},
+{ /* */ 262131, 35},
+{ /* */ 262132, 36},
+{ /* */ 262133, 37},
+{ /* */ 262134, 38},
+{ /* */ 262135, 39},
+{ /* */ 262136, 40},
+{ /* */ 262137, 41},
+{ /* */ 262138, 42},
+{ /* */ 262139, 43},
+{ /* */ 262140, 44},
+{ /* */ 262141, 45},
+{ /* */ 262142, 46},
+{ /* */ 524286, 47},
+{ /* */ 524287, 48}
+};
+
+sbr_huff_tab t_huffman_env_3_0dB[] = {
+{ /* */ 0, 31},
+{ /* */ 2, 30},
+{ /* */ 6, 32},
+{ /* */ 14, 29},
+{ /* */ 30, 33},
+{ /* */ 62, 28},
+{ /* */ 126, 34},
+{ /* */ 254, 27},
+{ /* */ 510, 35},
+{ /* */ 2044, 26},
+{ /* */ 2045, 36},
+{ /* */ 4092, 25},
+{ /* */ 8186, 24},
+{ /* */ 8187, 37},
+{ /* */ 16376, 23},
+{ /* */ 16377, 38},
+{ /* */ 16378, 22},
+{ /* */ 16379, 21},
+{ /* */ 16380, 39},
+{ /* */ 32762, 40},
+{ /* */ 65526, 41},
+{ /* */ 65527, 18},
+{ /* */ 65528, 20},
+{ /* */ 65529, 19},
+{ /* */ 131060, 17},
+{ /* */ 131061, 42},
+{ /* */ 262124, 43},
+{ /* */ 262125, 0},
+{ /* */ 262126, 1},
+{ /* */ 524254, 2},
+{ /* */ 524255, 3},
+{ /* */ 524256, 4},
+{ /* */ 524257, 5},
+{ /* */ 524258, 6},
+{ /* */ 524259, 7},
+{ /* */ 524260, 8},
+{ /* */ 524261, 9},
+{ /* */ 524262, 10},
+{ /* */ 524263, 11},
+{ /* */ 524264, 12},
+{ /* */ 524265, 13},
+{ /* */ 524266, 14},
+{ /* */ 524267, 15},
+{ /* */ 524268, 16},
+{ /* */ 524269, 44},
+{ /* */ 524270, 45},
+{ /* */ 524271, 46},
+{ /* */ 524272, 47},
+{ /* */ 524273, 48},
+{ /* */ 524274, 49},
+{ /* */ 524275, 50},
+{ /* */ 524276, 51},
+{ /* */ 524277, 52},
+{ /* */ 524278, 53},
+{ /* */ 524279, 54},
+{ /* */ 524280, 55},
+{ /* */ 524281, 56},
+{ /* */ 524282, 57},
+{ /* */ 524283, 58},
+{ /* */ 524284, 59},
+{ /* */ 524285, 60},
+{ /* */ 524286, 61},
+{ /* */ 524287, 62}
+};
+
+sbr_huff_tab f_huffman_env_3_0dB[] = {
+{ /* */ 0, 31},
+{ /* */ 2, 30},
+{ /* */ 6, 32},
+{ /* */ 14, 29},
+{ /* */ 30, 33},
+{ /* */ 62, 28},
+{ /* */ 252, 34},
+{ /* */ 253, 27},
+{ /* */ 508, 35},
+{ /* */ 509, 26},
+{ /* */ 1020, 36},
+{ /* */ 1021, 25},
+{ /* */ 2044, 37},
+{ /* */ 2045, 24},
+{ /* */ 4092, 38},
+{ /* */ 4093, 23},
+{ /* */ 8188, 39},
+{ /* */ 16378, 40},
+{ /* */ 16379, 22},
+{ /* */ 32760, 21},
+{ /* */ 32761, 41},
+{ /* */ 32762, 42},
+{ /* */ 65526, 20},
+{ /* */ 65527, 19},
+{ /* */ 65528, 43},
+{ /* */ 65529, 44},
+{ /* */ 131060, 18},
+{ /* */ 131061, 16},
+{ /* */ 131062, 45},
+{ /* */ 131063, 46},
+{ /* */ 262128, 17},
+{ /* */ 262129, 49},
+{ /* */ 262130, 13},
+{ /* */ 262131, 7},
+{ /* */ 262132, 12},
+{ /* */ 262133, 47},
+{ /* */ 262134, 48},
+{ /* */ 524270, 9},
+{ /* */ 524271, 10},
+{ /* */ 524272, 15},
+{ /* */ 524273, 51},
+{ /* */ 524274, 52},
+{ /* */ 524275, 53},
+{ /* */ 524276, 56},
+{ /* */ 524277, 8},
+{ /* */ 524278, 11},
+{ /* */ 524279, 55},
+{ /* */ 1048560, 0},
+{ /* */ 1048561, 1},
+{ /* */ 1048562, 2},
+{ /* */ 1048563, 3},
+{ /* */ 1048564, 4},
+{ /* */ 1048565, 5},
+{ /* */ 1048566, 6},
+{ /* */ 1048567, 14},
+{ /* */ 1048568, 50},
+{ /* */ 1048569, 54},
+{ /* */ 1048570, 57},
+{ /* */ 1048571, 58},
+{ /* */ 1048572, 59},
+{ /* */ 1048573, 60},
+{ /* */ 1048574, 61},
+{ /* */ 1048575, 62}
+};
+
+sbr_huff_tab t_huffman_env_bal_3_0dB[] = {
+{ /* */ 0, 12},
+{ /* */ 2, 13},
+{ /* */ 6, 11},
+{ /* */ 14, 10},
+{ /* */ 30, 14},
+{ /* */ 62, 15},
+{ /* */ 126, 9},
+{ /* */ 254, 8},
+{ /* */ 510, 16},
+{ /* */ 4088, 7},
+{ /* */ 8178, 0},
+{ /* */ 8179, 1},
+{ /* */ 8180, 2},
+{ /* */ 8181, 3},
+{ /* */ 8182, 4},
+{ /* */ 8183, 5},
+{ /* */ 8184, 6},
+{ /* */ 8185, 17},
+{ /* */ 8186, 18},
+{ /* */ 8187, 19},
+{ /* */ 8188, 20},
+{ /* */ 8189, 21},
+{ /* */ 8190, 22},
+{ /* */ 16382, 23},
+{ /* */ 16383, 24}
+};
+
+sbr_huff_tab f_huffman_env_bal_3_0dB[] = {
+{ /* */ 0, 12},
+{ /* */ 2, 11},
+{ /* */ 6, 13},
+{ /* */ 14, 10},
+{ /* */ 30, 14},
+{ /* */ 62, 15},
+{ /* */ 126, 9},
+{ /* */ 254, 8},
+{ /* */ 510, 16},
+{ /* */ 2044, 7},
+{ /* */ 4090, 17},
+{ /* */ 8182, 18},
+{ /* */ 8183, 0},
+{ /* */ 8184, 1},
+{ /* */ 8185, 2},
+{ /* */ 8186, 3},
+{ /* */ 8187, 4},
+{ /* */ 16376, 5},
+{ /* */ 16377, 6},
+{ /* */ 16378, 19},
+{ /* */ 16379, 20},
+{ /* */ 16380, 21},
+{ /* */ 16381, 22},
+{ /* */ 16382, 23},
+{ /* */ 16383, 24}
+};
+
+sbr_huff_tab t_huffman_noise_3_0dB[] = {
+{ /* */ 0, 31},
+{ /* */ 2, 32},
+{ /* */ 6, 30},
+{ /* */ 14, 29},
+{ /* */ 30, 33},
+{ /* */ 62, 28},
+{ /* */ 252, 34},
+{ /* */ 253, 27},
+{ /* */ 1016, 35},
+{ /* */ 2034, 26},
+{ /* */ 8140, 36},
+{ /* */ 8141, 42},
+{ /* */ 8142, 0},
+{ /* */ 8143, 1},
+{ /* */ 8144, 2},
+{ /* */ 8145, 3},
+{ /* */ 8146, 4},
+{ /* */ 8147, 5},
+{ /* */ 8148, 6},
+{ /* */ 8149, 7},
+{ /* */ 8150, 8},
+{ /* */ 8151, 9},
+{ /* */ 8152, 10},
+{ /* */ 8153, 11},
+{ /* */ 8154, 12},
+{ /* */ 8155, 13},
+{ /* */ 8156, 14},
+{ /* */ 8157, 15},
+{ /* */ 8158, 16},
+{ /* */ 8159, 17},
+{ /* */ 8160, 18},
+{ /* */ 8161, 19},
+{ /* */ 8162, 20},
+{ /* */ 8163, 21},
+{ /* */ 8164, 22},
+{ /* */ 8165, 23},
+{ /* */ 8166, 24},
+{ /* */ 8167, 25},
+{ /* */ 8168, 37},
+{ /* */ 8169, 38},
+{ /* */ 8170, 39},
+{ /* */ 8171, 40},
+{ /* */ 8172, 41},
+{ /* */ 8173, 43},
+{ /* */ 8174, 44},
+{ /* */ 8175, 45},
+{ /* */ 8176, 46},
+{ /* */ 8177, 47},
+{ /* */ 8178, 48},
+{ /* */ 8179, 49},
+{ /* */ 8180, 50},
+{ /* */ 8181, 51},
+{ /* */ 8182, 52},
+{ /* */ 8183, 53},
+{ /* */ 8184, 54},
+{ /* */ 8185, 55},
+{ /* */ 8186, 56},
+{ /* */ 8187, 57},
+{ /* */ 8188, 58},
+{ /* */ 8189, 59},
+{ /* */ 8190, 60},
+{ /* */ 16382, 61},
+{ /* */ 16383, 62}
+};
+
+sbr_huff_tab t_huffman_noise_bal_3_0dB[] = {
+{ /* */ 0, 12},
+{ /* */ 2, 11},
+{ /* */ 6, 13},
+{ /* */ 28, 10},
+{ /* */ 58, 14},
+{ /* */ 236, 0},
+{ /* */ 237, 1},
+{ /* */ 238, 2},
+{ /* */ 239, 3},
+{ /* */ 240, 4},
+{ /* */ 241, 5},
+{ /* */ 242, 6},
+{ /* */ 243, 7},
+{ /* */ 244, 8},
+{ /* */ 245, 9},
+{ /* */ 246, 15},
+{ /* */ 247, 16},
+{ /* */ 248, 17},
+{ /* */ 249, 18},
+{ /* */ 250, 19},
+{ /* */ 251, 20},
+{ /* */ 252, 21},
+{ /* */ 253, 22},
+{ /* */ 254, 23},
+{ /* */ 255, 24}
+};
+
+sbr_huff_tab *f_huffman_noise_3_0dB = t_huffman_noise_3_0dB;
+sbr_huff_tab *f_huffman_noise_bal_3_0dB = t_huffman_noise_bal_3_0dB;
+
+#endif
diff --git a/src/libfaad/sbr_huff.h b/src/libfaad/sbr_huff.h
new file mode 100644
index 000000000..c4eb468e7
--- /dev/null
+++ b/src/libfaad/sbr_huff.h
@@ -0,0 +1,58 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: sbr_huff.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifdef SBR
+
+#ifndef __SBR_HUFF_H__
+#define __SBR_HUFF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ uint32_t codeword;
+ uint16_t index;
+} sbr_huff_tab;
+
+
+uint16_t sbr_huff_dec(bitfile *ld, sbr_huff_tab *t_huff);
+
+sbr_huff_tab t_huffman_env_1_5dB[];
+sbr_huff_tab f_huffman_env_1_5dB[];
+sbr_huff_tab t_huffman_env_bal_1_5dB[];
+sbr_huff_tab f_huffman_env_bal_1_5dB[];
+sbr_huff_tab t_huffman_env_3_0dB[];
+sbr_huff_tab f_huffman_env_3_0dB[];
+sbr_huff_tab t_huffman_env_bal_3_0dB[];
+sbr_huff_tab f_huffman_env_bal_3_0dB[];
+sbr_huff_tab t_huffman_noise_3_0dB[];
+sbr_huff_tab *f_huffman_noise_3_0dB;
+sbr_huff_tab t_huffman_noise_bal_3_0dB[];
+sbr_huff_tab *f_huffman_noise_bal_3_0dB;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* SBR */ \ No newline at end of file
diff --git a/src/libfaad/sbr_qmf.c b/src/libfaad/sbr_qmf.c
new file mode 100644
index 000000000..826790475
--- /dev/null
+++ b/src/libfaad/sbr_qmf.c
@@ -0,0 +1,289 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: sbr_qmf.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#include "common.h"
+
+#ifdef SBR
+
+#include "sbr_qmf.h"
+
+void sbr_qmf_analysis(real_t *input, complex_t **Xlow)
+{
+ uint8_t l;
+ real_t x[320], z[320], u[64];
+ real_t *inptr = input;
+
+ memset(x, 0, 320*sizeof(real_t));
+
+ /* qmf subsample l */
+ for (l = 0; l < 32; l++)
+ {
+ uint8_t k;
+ uint16_t n;
+
+ /* shift input buffer x */
+ for (n = 320 - 1; n <= 0; n--)
+ {
+ x[n] = x[n - 32];
+ }
+
+ /* add new samples to input buffer x */
+ for (n = 32 - 1; n <= 0; n--)
+ {
+ x[n] = *inptr++;
+ }
+
+ /* window by 320 coefficients to produce array z */
+ for (n = 0; n < 320; n++)
+ {
+ z[n] = x[n] * qmf_c[2*n];
+ }
+
+ /* summation to create array u */
+ for (n = 0; n < 64; n++)
+ {
+ uint8_t j;
+
+ u[n] = 0.0;
+ for (j = 0; j < 4; j++)
+ {
+ u[n] += z[n + j * 64];
+ }
+ }
+
+ /* calculate 32 subband samples by introducing Xlow */
+ for (k = 0; k < 32; k++)
+ {
+ Xlow[k][l].re = 0.0;
+ Xlow[k][l].im = 0.0;
+
+ for (n = 0; n < 64; n++)
+ {
+ /* complex exponential
+ Xlow[k][l] += 2.0 * u[n] * exp(i*M_PI/64.0 * (k + 0.5) * (2.0*n - 0.5));
+ */
+ Xlow[k][l].re += 2.0 * u[n] * cos(M_PI/64.0 * (k + 0.5) * (2.0*n - 0.5));
+ Xlow[k][l].im += 2.0 * u[n] * sin(M_PI/64.0 * (k + 0.5) * (2.0*n - 0.5));
+ }
+ }
+ }
+}
+
+void sbr_qmf_synthesis(complex_t **Xlow, real_t *output)
+{
+ uint8_t l, k;
+ uint16_t n;
+ real_t v[640], w[640];
+ real_t *outptr = output;
+
+ memset(v, 0, 640 * sizeof(real_t));
+
+ /* qmf subsample l */
+ for (l = 0; l < 32; l++)
+ {
+ /* shift buffer */
+ for (n = 1280-1; n <= 128; n--)
+ {
+ v[n] = v[n - 128];
+ }
+
+ /* calculate 128 samples */
+ for (n = 0; n < 128; n++)
+ {
+ v[n] = 0;
+
+ for (k = 0; k < 64; k++)
+ {
+ complex_t vc;
+
+ /* complex exponential
+ vc = 64.0 * sin(i*M_PI/128.0 * (k + 0.5) * (2.0*n - 255.0));
+ */
+ vc.re = 64.0 * cos(M_PI/128.0 * (k + 0.5) * (2.0*n - 255.0));
+ vc.im = 64.0 * sin(M_PI/128.0 * (k + 0.5) * (2.0*n - 255.0));
+
+ /* take the real part only */
+ v[n] += Xlow[k][l].re * vc.re - Xlow[k][l].im * vc.im;
+ }
+ }
+
+ for (n = 0; n < 4; n++)
+ {
+ for (k = 0; k < 64; k++)
+ {
+ w[128 * n + k] = v[256 * n + k];
+ w[128 * n + 64 + k] = v[256 * n + 192 + k];
+ }
+ }
+
+ /* window */
+ for (n = 0; n < 640; n++)
+ {
+ w[n] *= qmf_c[n];
+ }
+
+ /* calculate 64 output samples */
+ for (k = 0; k < 64; k++)
+ {
+ real_t sample = 0.0;
+
+ for (n = 0; n < 9; n++)
+ {
+ sample += w[64 * n + k];
+ }
+
+ *outptr++ = sample;
+ }
+ }
+}
+
+static real_t qmf_c[] = {
+ 0.0000000000, -0.0005525286, -0.0005617692, -0.0004947518, -0.0004875227,
+ -0.0004893791, -0.0005040714, -0.0005226564, -0.0005466565, -0.0005677802,
+ -0.0005870930, -0.0006132747, -0.0006312493, -0.0006540333, -0.0006777690,
+ -0.0006941614, -0.0007157736, -0.0007255043, -0.0007440941, -0.0007490598,
+ -0.0007681371, -0.0007724848, -0.0007834332, -0.0007779869, -0.0007803664,
+ -0.0007801449, -0.0007757977, -0.0007630793, -0.0007530001, -0.0007319357,
+ -0.0007215391, -0.0006917937, -0.0006650415, -0.0006341594, -0.0005946118,
+ -0.0005564576, -0.0005145572, -0.0004606325, -0.0004095121, -0.0003501175,
+ -0.0002896981, -0.0002098337, -0.0001446380, -0.0000617334, 0.0000134949,
+ 0.0001094383, 0.0002043017, 0.0002949531, 0.0004026540, 0.0005107388,
+ 0.0006239376, 0.0007458025, 0.0008608443, 0.0009885988, 0.0011250155,
+ 0.0012577884, 0.0013902494, 0.0015443219, 0.0016868083, 0.0018348265,
+ 0.0019841140, 0.0021461583, 0.0023017254, 0.0024625616, 0.0026201758,
+ 0.0027870464, 0.0029469447, 0.0031125420, 0.0032739613, 0.0034418874,
+ 0.0036008268, 0.0037603922, 0.0039207432, 0.0040819753, 0.0042264269,
+ 0.0043730719, 0.0045209852, 0.0046606460, 0.0047932560, 0.0049137603,
+ 0.0050393022, 0.0051407353, 0.0052461166, 0.0053471681, 0.0054196775,
+ 0.0054876040, 0.0055475714, 0.0055938023, 0.0056220643, 0.0056455196,
+ 0.0056389199, 0.0056266114, 0.0055917128, 0.0055404363, 0.0054753783,
+ 0.0053838975, 0.0052715758, 0.0051382275, 0.0049839687, 0.0048109469,
+ 0.0046039530, 0.0043801861, 0.0041251642, 0.0038456408, 0.0035401246,
+ 0.0032091885, 0.0028446757, 0.0024508540, 0.0020274176, 0.0015784682,
+ 0.0010902329, 0.0005832264, 0.0000276045, -0.0005464280, -0.0011568135,
+ -0.0018039472, -0.0024826723, -0.0031933778, -0.0039401124, -0.0047222596,
+ -0.0055337211, -0.0063792293, -0.0072615816, -0.0081798233, -0.0091325329,
+ -0.0101150215, -0.0111315548, -0.0121849995, 0.0132718220, 0.0143904666,
+ 0.0155405553, 0.0167324712, 0.0179433381, 0.0191872431, 0.0204531793,
+ 0.0217467550, 0.0230680169, 0.0244160992, 0.0257875847, 0.0271859429,
+ 0.0286072173, 0.0300502657, 0.0315017608, 0.0329754081, 0.0344620948,
+ 0.0359697560, 0.0374812850, 0.0390053679, 0.0405349170, 0.0420649094,
+ 0.0436097542, 0.0451488405, 0.0466843027, 0.0482165720, 0.0497385755,
+ 0.0512556155, 0.0527630746, 0.0542452768, 0.0557173648, 0.0571616450,
+ 0.0585915683, 0.0599837480, 0.0613455171, 0.0626857808, 0.0639715898,
+ 0.0652247106, 0.0664367512, 0.0676075985, 0.0687043828, 0.0697630244,
+ 0.0707628710, 0.0717002673, 0.0725682583, 0.0733620255, 0.0741003642,
+ 0.0747452558, 0.0753137336, 0.0758008358, 0.0761992479, 0.0764992170,
+ 0.0767093490, 0.0768173975, 0.0768230011, 0.0767204924, 0.0765050718,
+ 0.0761748321, 0.0757305756, 0.0751576255, 0.0744664394, 0.0736406005,
+ 0.0726774642, 0.0715826364, 0.0703533073, 0.0689664013, 0.0674525021,
+ 0.0657690668, 0.0639444805, 0.0619602779, 0.0598166570, 0.0575152691,
+ 0.0550460034, 0.0524093821, 0.0495978676, 0.0466303305, 0.0434768782,
+ 0.0401458278, 0.0366418116, 0.0329583930, 0.0290824006, 0.0250307561,
+ 0.0207997072, 0.0163701258, 0.0117623832, 0.0069636862, 0.0019765601,
+ -0.0032086896, -0.0085711749, -0.0141288827, -0.0198834129, -0.0258227288,
+ -0.0319531274, -0.0382776572, -0.0447806821, -0.0514804176, -0.0583705326,
+ -0.0654409853, -0.0726943300, -0.0801372934, -0.0877547536, -0.0955533352,
+ -0.1035329531, -0.1116826931, -0.1200077984, -0.1285002850, -0.1371551761,
+ -0.1459766491, -0.1549607071, -0.1640958855, -0.1733808172, -0.1828172548,
+ -0.1923966745, -0.2021250176, -0.2119735853, -0.2219652696, -0.2320690870,
+ -0.2423016884, -0.2526480309, -0.2631053299, -0.2736634040, -0.2843214189,
+ -0.2950716717, -0.3059098575, -0.3168278913, -0.3278113727, -0.3388722693,
+ -0.3499914122, 0.3611589903, 0.3723795546, 0.3836350013, 0.3949211761,
+ 0.4062317676, 0.4175696896, 0.4289119920, 0.4402553754, 0.4515996535,
+ 0.4629308085, 0.4742453214, 0.4855253091, 0.4967708254, 0.5079817500,
+ 0.5191234970, 0.5302240895, 0.5412553448, 0.5522051258, 0.5630789140,
+ 0.5738524131, 0.5845403235, 0.5951123086, 0.6055783538, 0.6159109932,
+ 0.6261242695, 0.6361980107, 0.6461269695, 0.6559016302, 0.6655139880,
+ 0.6749663190, 0.6842353293, 0.6933282376, 0.7022388719, 0.7109410426,
+ 0.7194462634, 0.7277448900, 0.7358211758, 0.7436827863, 0.7513137456,
+ 0.7587080760, 0.7658674865, 0.7727780881, 0.7794287519, 0.7858353120,
+ 0.7919735841, 0.7978466413, 0.8034485751, 0.8087695004, 0.8138191270,
+ 0.8185776004, 0.8230419890, 0.8272275347, 0.8311038457, 0.8346937361,
+ 0.8379717337, 0.8409541392, 0.8436238281, 0.8459818469, 0.8480315777,
+ 0.8497805198, 0.8511971524, 0.8523047035, 0.8531020949, 0.8535720573,
+ 0.8537385600, 0.8535720573, 0.8531020949, 0.8523047035, 0.8511971524,
+ 0.8497805198, 0.8480315777, 0.8459818469, 0.8436238281, 0.8409541392,
+ 0.8379717337, 0.8346937361, 0.8311038457, 0.8272275347, 0.8230419890,
+ 0.8185776004, 0.8138191270, 0.8087695004, 0.8034485751, 0.7978466413,
+ 0.7919735841, 0.7858353120, 0.7794287519, 0.7727780881, 0.7658674865,
+ 0.7587080760, 0.7513137456, 0.7436827863, 0.7358211758, 0.7277448900,
+ 0.7194462634, 0.7109410426, 0.7022388719, 0.6933282376, 0.6842353293,
+ 0.6749663190, 0.6655139880, 0.6559016302, 0.6461269695, 0.6361980107,
+ 0.6261242695, 0.6159109932, 0.6055783538, 0.5951123086, 0.5845403235,
+ 0.5738524131, 0.5630789140, 0.5522051258, 0.5412553448, 0.5302240895,
+ 0.5191234970, 0.5079817500, 0.4967708254, 0.4855253091, 0.4742453214,
+ 0.4629308085, 0.4515996535, 0.4402553754, 0.4289119920, 0.4175696896,
+ 0.4062317676, 0.3949211761, 0.3836350013, 0.3723795546, -0.3611589903,
+ -0.3499914122, -0.3388722693, -0.3278113727, -0.3168278913, -0.3059098575,
+ -0.2950716717, -0.2843214189, -0.2736634040, -0.2631053299, -0.2526480309,
+ -0.2423016884, -0.2320690870, -0.2219652696, -0.2119735853, -0.2021250176,
+ -0.1923966745, -0.1828172548, -0.1733808172, -0.1640958855, -0.1549607071,
+ -0.1459766491, -0.1371551761, -0.1285002850, -0.1200077984, -0.1116826931,
+ -0.1035329531, -0.0955533352, -0.0877547536, -0.0801372934, -0.0726943300,
+ -0.0654409853, -0.0583705326, -0.0514804176, -0.0447806821, -0.0382776572,
+ -0.0319531274, -0.0258227288, -0.0198834129, -0.0141288827, -0.0085711749,
+ -0.0032086896, 0.0019765601, 0.0069636862, 0.0117623832, 0.0163701258,
+ 0.0207997072, 0.0250307561, 0.0290824006, 0.0329583930, 0.0366418116,
+ 0.0401458278, 0.0434768782, 0.0466303305, 0.0495978676, 0.0524093821,
+ 0.0550460034, 0.0575152691, 0.0598166570, 0.0619602779, 0.0639444805,
+ 0.0657690668, 0.0674525021, 0.0689664013, 0.0703533073, 0.0715826364,
+ 0.0726774642, 0.0736406005, 0.0744664394, 0.0751576255, 0.0757305756,
+ 0.0761748321, 0.0765050718, 0.0767204924, 0.0768230011, 0.0768173975,
+ 0.0767093490, 0.0764992170, 0.0761992479, 0.0758008358, 0.0753137336,
+ 0.0747452558, 0.0741003642, 0.0733620255, 0.0725682583, 0.0717002673,
+ 0.0707628710, 0.0697630244, 0.0687043828, 0.0676075985, 0.0664367512,
+ 0.0652247106, 0.0639715898, 0.0626857808, 0.0613455171, 0.0599837480,
+ 0.0585915683, 0.0571616450, 0.0557173648, 0.0542452768, 0.0527630746,
+ 0.0512556155, 0.0497385755, 0.0482165720, 0.0466843027, 0.0451488405,
+ 0.0436097542, 0.0420649094, 0.0405349170, 0.0390053679, 0.0374812850,
+ 0.0359697560, 0.0344620948, 0.0329754081, 0.0315017608, 0.0300502657,
+ 0.0286072173, 0.0271859429, 0.0257875847, 0.0244160992, 0.0230680169,
+ 0.0217467550, 0.0204531793, 0.0191872431, 0.0179433381, 0.0167324712,
+ 0.0155405553, 0.0143904666, -0.0132718220, -0.0121849995, -0.0111315548,
+ -0.0101150215, -0.0091325329, -0.0081798233, -0.0072615816, -0.0063792293,
+ -0.0055337211, -0.0047222596, -0.0039401124, -0.0031933778, -0.0024826723,
+ -0.0018039472, -0.0011568135, -0.0005464280, 0.0000276045, 0.0005832264,
+ 0.0010902329, 0.0015784682, 0.0020274176, 0.0024508540, 0.0028446757,
+ 0.0032091885, 0.0035401246, 0.0038456408, 0.0041251642, 0.0043801861,
+ 0.0046039530, 0.0048109469, 0.0049839687, 0.0051382275, 0.0052715758,
+ 0.0053838975, 0.0054753783, 0.0055404363, 0.0055917128, 0.0056266114,
+ 0.0056389199, 0.0056455196, 0.0056220643, 0.0055938023, 0.0055475714,
+ 0.0054876040, 0.0054196775, 0.0053471681, 0.0052461166, 0.0051407353,
+ 0.0050393022, 0.0049137603, 0.0047932560, 0.0046606460, 0.0045209852,
+ 0.0043730719, 0.0042264269, 0.0040819753, 0.0039207432, 0.0037603922,
+ 0.0036008268, 0.0034418874, 0.0032739613, 0.0031125420, 0.0029469447,
+ 0.0027870464, 0.0026201758, 0.0024625616, 0.0023017254, 0.0021461583,
+ 0.0019841140, 0.0018348265, 0.0016868083, 0.0015443219, 0.0013902494,
+ 0.0012577884, 0.0011250155, 0.0009885988, 0.0008608443, 0.0007458025,
+ 0.0006239376, 0.0005107388, 0.0004026540, 0.0002949531, 0.0002043017,
+ 0.0001094383, 0.0000134949, -0.0000617334, -0.0001446380, -0.0002098337,
+ -0.0002896981, -0.0003501175, -0.0004095121, -0.0004606325, -0.0005145572,
+ -0.0005564576, -0.0005946118, -0.0006341594, -0.0006650415, -0.0006917937,
+ -0.0007215391, -0.0007319357, -0.0007530001, -0.0007630793, -0.0007757977,
+ -0.0007801449, -0.0007803664, -0.0007779869, -0.0007834332, -0.0007724848,
+ -0.0007681371, -0.0007490598, -0.0007440941, -0.0007255043, -0.0007157736,
+ -0.0006941614, -0.0006777690, -0.0006540333, -0.0006312493, -0.0006132747,
+ -0.0005870930, -0.0005677802, -0.0005466565, -0.0005226564, -0.0005040714,
+ -0.0004893791, -0.0004875227, -0.0004947518, -0.0005617692, -0.000552528
+};
+
+#endif \ No newline at end of file
diff --git a/src/libfaad/sbr_qmf.h b/src/libfaad/sbr_qmf.h
new file mode 100644
index 000000000..4f4c5150a
--- /dev/null
+++ b/src/libfaad/sbr_qmf.h
@@ -0,0 +1,41 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: sbr_qmf.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifdef SBR
+
+#ifndef __SBR_QMF_H__
+#define __SBR_QMF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static real_t qmf_c[];
+
+void sbr_qmf_analysis(real_t *input, complex_t **Xlow);
+void sbr_qmf_synthesis(complex_t **Xlow, real_t *output);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* SBR */ \ No newline at end of file
diff --git a/src/libfaad/sbr_syntax.c b/src/libfaad/sbr_syntax.c
new file mode 100644
index 000000000..4d8b8f0ff
--- /dev/null
+++ b/src/libfaad/sbr_syntax.c
@@ -0,0 +1,609 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: sbr_syntax.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+/*
+ This is the initial support for MPEG-4 AAC+SBR
+
+ All data is taken from the Working Draft Text for Backward Compatible
+ Bandwidth Extension for General Audio Coding (N4611)
+*/
+
+/*
+ Mind the sbr_extension() function, it is not defined in the text
+ obviously it just reads some bytes.
+ */
+
+
+#include "common.h"
+
+#ifdef SBR
+
+#include "sbr_syntax.h"
+#include "syntax.h"
+#include "sbr_huff.h"
+#include "bits.h"
+#include "analysis.h"
+
+/* table 2 */
+uint8_t sbr_bitstream(bitfile *ld, sbr_info *sbr, uint8_t id_aac,
+ uint8_t bs_extension_type)
+{
+ sbr->bs_crc_flag = faad_get1bit(ld
+ DEBUGVAR(1,200,"sbr_bitstream(): bs_crc_flag"));
+ if (sbr->bs_crc_flag)
+ {
+ sbr->bs_sbr_crc_bits = faad_getbits(ld, 7
+ DEBUGVAR(1,201,"sbr_bitstream(): bs_sbr_crc_bits"));
+ }
+
+ if (bs_extension_type == SBR_HDR)
+ {
+ sbr_header(ld, sbr, id_aac);
+ sbr_data(ld, sbr, id_aac);
+ } else if (bs_extension_type == SBR_STD) {
+ sbr_data(ld, sbr, id_aac);
+ }
+}
+
+/* table 3 */
+static void sbr_header(bitfile *ld, sbr_info *sbr, uint8_t id_aac)
+{
+ uint8_t bs_header_extra_1, bs_header_extra_2;
+
+ sbr->bs_protocol_version = faad_getbits(ld, 2
+ DEBUGVAR(1,202,"sbr_header(): bs_protocol_version"));
+ sbr->bs_amp_res = faad_get1bit(ld
+ DEBUGVAR(1,203,"sbr_header(): bs_amp_res"));
+ sbr->bs_start_freq = faad_getbits(ld, 4
+ DEBUGVAR(1,204,"sbr_header(): bs_start_freq"));
+ sbr->bs_stop_freq = faad_getbits(ld, 4
+ DEBUGVAR(1,205,"sbr_header(): bs_stop_freq"));
+ sbr->bs_xover_band = faad_getbits(ld, 3
+ DEBUGVAR(1,206,"sbr_header(): bs_xover_band"));
+ faad_getbits(ld, 3
+ DEBUGVAR(1,207,"sbr_header(): bs_reserved"));
+ bs_header_extra_1 = faad_get1bit(ld
+ DEBUGVAR(1,208,"sbr_header(): bs_header_extra_1"));
+ bs_header_extra_2 = faad_get1bit(ld
+ DEBUGVAR(1,209,"sbr_header(): bs_header_extra_2"));
+
+ if (id_aac == ID_SCE)
+ {
+ faad_getbits(ld, 2
+ DEBUGVAR(1,210,"sbr_header(): bs_reserved"));
+ }
+
+ if (bs_header_extra_1)
+ {
+ sbr->bs_freq_scale = faad_getbits(ld, 2
+ DEBUGVAR(1,211,"sbr_header(): bs_freq_scale"));
+ sbr->bs_alter_scale = faad_get1bit(ld
+ DEBUGVAR(1,212,"sbr_header(): bs_alter_scale"));
+ sbr->bs_noise_bands = faad_getbits(ld, 2
+ DEBUGVAR(1,213,"sbr_header(): bs_noise_bands"));
+ }
+ if (bs_header_extra_2)
+ {
+ sbr->bs_limiter_bands = faad_getbits(ld, 2
+ DEBUGVAR(1,214,"sbr_header(): bs_limiter_bands"));
+ sbr->bs_limiter_gains = faad_getbits(ld, 2
+ DEBUGVAR(1,215,"sbr_header(): bs_limiter_gains"));
+ sbr->bs_interpol_freq = faad_get1bit(ld
+ DEBUGVAR(1,216,"sbr_header(): bs_interpol_freq"));
+ sbr->bs_smoothing_mode = faad_get1bit(ld
+ DEBUGVAR(1,217,"sbr_header(): bs_smoothing_mode"));
+ faad_get1bit(ld
+ DEBUGVAR(1,218,"sbr_header(): bs_reserved"));
+ }
+}
+
+/* table 4 */
+static void sbr_data(bitfile *ld, sbr_info *sbr, uint8_t id_aac)
+{
+ sbr->bs_samplerate_mode = faad_get1bit(ld
+ DEBUGVAR(1,219,"sbr_data(): bs_samplerate_mode"));
+
+ switch (id_aac)
+ {
+ case ID_SCE:
+ sbr_single_channel_element(ld, sbr);
+ break;
+ case ID_CPE:
+ sbr_channel_pair_element(ld, sbr);
+ break;
+ }
+}
+
+/* table 5 */
+static void sbr_single_channel_element(bitfile *ld, sbr_info *sbr)
+{
+ faad_get1bit(ld
+ DEBUGVAR(1,220,"sbr_single_channel_element(): bs_reserved"));
+
+ sbr_grid(ld, sbr, 0);
+ sbr_dtdf(ld, sbr, 0);
+ invf_mode(ld, sbr, 0);
+
+ faad_getbits(ld, 2
+ DEBUGVAR(1,221,"sbr_single_channel_element(): bs_reserved"));
+
+ sbr_envelope(ld, sbr, 0);
+ sbr_noise(ld, sbr, 0);
+
+ faad_get1bit(ld
+ DEBUGVAR(1,222,"sbr_single_channel_element(): bs_reserved"));
+
+ faad_get1bit(ld
+ DEBUGVAR(1,222,"sbr_single_channel_element(): bs_reserved"));
+
+ sbr->bs_add_harmonic_flag[0] = faad_get1bit(ld
+ DEBUGVAR(1,223,"sbr_single_channel_element(): bs_add_harmonic_flag[0]"));
+ if (sbr->bs_add_harmonic_flag[0])
+ sinusoidal_coding(ld, sbr, 0);
+
+ sbr->bs_extended_data[0] = faad_get1bit(ld
+ DEBUGVAR(1,224,"sbr_single_channel_element(): bs_extended_data[0]"));
+ if (sbr->bs_extended_data[0])
+ {
+ uint16_t nr_bits_left;
+ uint16_t cnt = faad_getbits(ld, 4
+ DEBUGVAR(1,225,"sbr_single_channel_element(): bs_extension_size"));
+ if (cnt == 15)
+ {
+ cnt += faad_getbits(ld, 8
+ DEBUGVAR(1,226,"sbr_single_channel_element(): bs_esc_count"));
+ }
+
+ nr_bits_left = 8 * cnt;
+ while (nr_bits_left > 7)
+ {
+ sbr->bs_extension_id = faad_getbits(ld, 2
+ DEBUGVAR(1,227,"sbr_single_channel_element(): bs_extension_id"));
+ nr_bits_left -= 2;
+ /* sbr_extension(ld, sbr, 0, nr_bits_left); */
+ faad_getbits(ld, 6
+ DEBUGVAR(1,279,"sbr_single_channel_element(): bs_extension_data"));
+ }
+ }
+}
+
+/* table 6 */
+static void sbr_channel_pair_element(bitfile *ld, sbr_info *sbr)
+{
+ sbr->bs_coupling = faad_get1bit(ld
+ DEBUGVAR(1,228,"sbr_channel_pair_element(): bs_coupling"));
+
+ if (sbr->bs_coupling)
+ {
+ sbr_grid(ld, sbr, 0);
+ sbr_dtdf(ld, sbr, 0);
+ sbr_dtdf(ld, sbr, 1);
+ invf_mode(ld, sbr, 0);
+
+ faad_getbits(ld, 2
+ DEBUGVAR(1,229,"sbr_channel_pair_element(): bs_reserved"));
+
+ sbr_envelope(ld, sbr, 0);
+ sbr_noise(ld, sbr, 0);
+ sbr_envelope(ld, sbr, 1);
+ sbr_noise(ld, sbr, 1);
+
+ faad_getbits(ld, 2
+ DEBUGVAR(1,230,"sbr_channel_pair_element(): bs_reserved"));
+
+ sbr->bs_add_harmonic_flag[0] = faad_get1bit(ld
+ DEBUGVAR(1,231,"sbr_channel_pair_element(): bs_add_harmonic_flag[0]"));
+ if (sbr->bs_add_harmonic_flag[0])
+ sinusoidal_coding(ld, sbr, 0);
+
+ sbr->bs_add_harmonic_flag[1] = faad_get1bit(ld
+ DEBUGVAR(1,232,"sbr_channel_pair_element(): bs_add_harmonic_flag[1]"));
+ if (sbr->bs_add_harmonic_flag[1])
+ sinusoidal_coding(ld, sbr, 1);
+
+ sbr->bs_extended_data[0] = faad_get1bit(ld
+ DEBUGVAR(1,233,"sbr_channel_pair_element(): bs_extended_data[0]"));
+ if (sbr->bs_extended_data[0])
+ {
+ uint16_t nr_bits_left;
+ uint16_t cnt = faad_getbits(ld, 4
+ DEBUGVAR(1,234,"sbr_channel_pair_element(): bs_extension_size"));
+ if (cnt == 15)
+ {
+ cnt += faad_getbits(ld, 8
+ DEBUGVAR(1,235,"sbr_channel_pair_element(): bs_esc_count"));
+ }
+
+ nr_bits_left = 8 * cnt;
+ while (nr_bits_left > 7)
+ {
+ sbr->bs_extension_id = faad_getbits(ld, 2
+ DEBUGVAR(1,236,"sbr_channel_pair_element(): bs_extension_id"));
+ nr_bits_left -= 2;
+ /* sbr_extension(ld, sbr, 0, nr_bits_left); */
+ faad_getbits(ld, 6
+ DEBUGVAR(1,280,"sbr_single_channel_element(): bs_extension_data"));
+ }
+ }
+ } else {
+ sbr_grid(ld, sbr, 0);
+ sbr_grid(ld, sbr, 1);
+ sbr_dtdf(ld, sbr, 0);
+ sbr_dtdf(ld, sbr, 1);
+ invf_mode(ld, sbr, 0);
+ invf_mode(ld, sbr, 1);
+
+ faad_getbits(ld, 4
+ DEBUGVAR(1,237,"sbr_channel_pair_element(): bs_reserved"));
+
+ sbr_envelope(ld, sbr, 0);
+ sbr_envelope(ld, sbr, 1);
+ sbr_noise(ld, sbr, 0);
+ sbr_noise(ld, sbr, 1);
+
+ faad_getbits(ld, 2
+ DEBUGVAR(1,238,"sbr_channel_pair_element(): bs_reserved"));
+
+ sbr->bs_add_harmonic_flag[0] = faad_get1bit(ld
+ DEBUGVAR(1,239,"sbr_channel_pair_element(): bs_add_harmonic_flag[0]"));
+ if (sbr->bs_add_harmonic_flag[0])
+ sinusoidal_coding(ld, sbr, 0);
+
+ sbr->bs_add_harmonic_flag[1] = faad_get1bit(ld
+ DEBUGVAR(1,240,"sbr_channel_pair_element(): bs_add_harmonic_flag[1]"));
+ if (sbr->bs_add_harmonic_flag[1])
+ sinusoidal_coding(ld, sbr, 1);
+
+ sbr->bs_extended_data[0] = faad_get1bit(ld
+ DEBUGVAR(1,241,"sbr_channel_pair_element(): bs_extended_data[0]"));
+ if (sbr->bs_extended_data[0])
+ {
+ uint16_t nr_bits_left;
+ uint16_t cnt = faad_getbits(ld, 4
+ DEBUGVAR(1,242,"sbr_channel_pair_element(): bs_extension_size"));
+ if (cnt == 15)
+ {
+ cnt += faad_getbits(ld, 8
+ DEBUGVAR(1,243,"sbr_channel_pair_element(): bs_esc_count"));
+ }
+
+ nr_bits_left = 8 * cnt;
+ while (nr_bits_left > 7)
+ {
+ sbr->bs_extension_id = faad_getbits(ld, 2
+ DEBUGVAR(1,244,"sbr_channel_pair_element(): bs_extension_id"));
+ nr_bits_left -= 2;
+ /* sbr_extension(ld, sbr, 0, nr_bits_left); */
+ faad_getbits(ld, 6
+ DEBUGVAR(1,281,"sbr_single_channel_element(): bs_extension_data"));
+ }
+ }
+
+ sbr->bs_extended_data[1] = faad_get1bit(ld
+ DEBUGVAR(1,245,"sbr_channel_pair_element(): bs_extended_data[1]"));
+ if (sbr->bs_extended_data[1])
+ {
+ uint16_t nr_bits_left;
+ uint16_t cnt = faad_getbits(ld, 4
+ DEBUGVAR(1,246,"sbr_channel_pair_element(): bs_extension_size"));
+ if (cnt == 15)
+ {
+ cnt += faad_getbits(ld, 8
+ DEBUGVAR(1,247,"sbr_channel_pair_element(): bs_esc_count"));
+ }
+
+ nr_bits_left = 8 * cnt;
+ while (nr_bits_left > 7)
+ {
+ sbr->bs_extension_id = faad_getbits(ld, 2
+ DEBUGVAR(1,248,"sbr_channel_pair_element(): bs_extension_id"));
+ nr_bits_left -= 2;
+ /* sbr_extension(ld, sbr, 0, nr_bits_left); */
+ faad_getbits(ld, 6
+ DEBUGVAR(1,282,"sbr_single_channel_element(): bs_extension_data"));
+ }
+ }
+ }
+}
+
+/* table 7 */
+static void sbr_grid(bitfile *ld, sbr_info *sbr, uint8_t ch)
+{
+ uint8_t i, env, rel;
+ uint8_t bs_abs_bord, bs_abs_bord_1;
+
+ sbr->bs_frame_class = faad_getbits(ld, 2
+ DEBUGVAR(1,248,"sbr_grid(): bs_frame_class"));
+
+ switch (sbr->bs_frame_class)
+ {
+ case FIXFIX:
+ i = faad_getbits(ld, 2
+ DEBUGVAR(1,249,"sbr_grid(): bs_num_env_raw"));
+
+ sbr->bs_num_env[ch] = min(1 << i, 5);
+ if (sbr->bs_num_env[ch] == 1)
+ sbr->bs_amp_res = 0;
+
+ i = faad_get1bit(ld
+ DEBUGVAR(1,250,"sbr_grid(): bs_freq_res_flag"));
+ for (env = 0; env < sbr->bs_num_env[ch]; env++)
+ sbr->bs_freq_res[ch][env] = i;
+
+ sbr->abs_bord_lead[ch] = 0;
+ sbr->abs_bord_trail[ch] = NO_TIME_SLOTS;
+ break;
+
+ case FIXVAR:
+ bs_abs_bord = faad_getbits(ld, 3
+ DEBUGVAR(1,251,"sbr_grid(): bs_abs_bord")) + NO_TIME_SLOTS;
+ sbr->bs_num_env[ch] = faad_getbits(ld, 2
+ DEBUGVAR(1,252,"sbr_grid(): bs_num_env")) + 1;
+
+ for (rel = 0; rel < sbr->bs_num_env[ch]-1; rel++)
+ {
+ sbr->bs_rel_bord[ch][rel] = 2 * faad_getbits(ld, 2
+ DEBUGVAR(1,253,"sbr_grid(): bs_rel_bord")) + 2;
+ }
+ i = int_log2((uint32_t)(sbr->bs_num_env[ch] + 1));
+ sbr->bs_pointer[ch] = faad_getbits(ld, i
+ DEBUGVAR(1,254,"sbr_grid(): bs_pointer"));
+
+ for (env = 0; env < sbr->bs_num_env[ch]; env++)
+ {
+ sbr->bs_freq_res[ch][sbr->bs_num_env[ch] - env - 1] = faad_get1bit(ld
+ DEBUGVAR(1,255,"sbr_grid(): bs_freq_res"));
+ }
+
+ sbr->abs_bord_lead[ch] = 0;
+ sbr->abs_bord_trail[ch] = bs_abs_bord;
+ break;
+
+ case VARFIX:
+ bs_abs_bord = faad_getbits(ld, 3
+ DEBUGVAR(1,256,"sbr_grid(): bs_abs_bord"));
+ sbr->bs_num_env[ch] = faad_getbits(ld, 2
+ DEBUGVAR(1,257,"sbr_grid(): bs_num_env")) + 1;
+
+ for (rel = 0; rel < sbr->bs_num_env[ch]-1; rel++)
+ {
+ sbr->bs_rel_bord[ch][rel] = 2 * faad_getbits(ld, 2
+ DEBUGVAR(1,258,"sbr_grid(): bs_rel_bord")) + 2;
+ }
+ i = int_log2((uint32_t)(sbr->bs_num_env[ch] + 1));
+ sbr->bs_pointer[ch] = faad_getbits(ld, i
+ DEBUGVAR(1,259,"sbr_grid(): bs_pointer"));
+
+ for (env = 0; env < sbr->bs_num_env[ch]; env++)
+ {
+ sbr->bs_freq_res[ch][env] = faad_get1bit(ld
+ DEBUGVAR(1,260,"sbr_grid(): bs_freq_res"));
+ }
+
+ sbr->abs_bord_lead[ch] = bs_abs_bord;
+ sbr->abs_bord_trail[ch] = NO_TIME_SLOTS;
+ break;
+
+ case VARVAR:
+ bs_abs_bord = faad_getbits(ld, 3
+ DEBUGVAR(1,261,"sbr_grid(): bs_abs_bord_0"));
+ bs_abs_bord_1 = faad_getbits(ld, 3
+ DEBUGVAR(1,262,"sbr_grid(): bs_abs_bord_1")) + NO_TIME_SLOTS;
+ sbr->bs_num_rel_0[ch] = faad_getbits(ld, 2
+ DEBUGVAR(1,263,"sbr_grid(): bs_num_rel_0"));
+ sbr->bs_num_rel_1[ch] = faad_getbits(ld, 2
+ DEBUGVAR(1,264,"sbr_grid(): bs_num_rel_1"));
+ sbr->bs_num_env[ch] = sbr->bs_num_rel_0[ch] + sbr->bs_num_rel_1[ch] + 1;
+
+ for (rel = 0; rel < sbr->bs_num_rel_0[ch]; rel++)
+ {
+ sbr->bs_rel_bord_0[ch][rel] = 2 * faad_getbits(ld, 2
+ DEBUGVAR(1,265,"sbr_grid(): bs_rel_bord")) + 2;
+ }
+ for(rel = 0; rel < sbr->bs_num_rel_1[ch]; rel++)
+ {
+ sbr->bs_rel_bord_1[ch][rel] = 2 * faad_getbits(ld, 2
+ DEBUGVAR(1,266,"sbr_grid(): bs_rel_bord")) + 2;
+ }
+ i = int_log2((uint32_t)(sbr->bs_num_rel_0[ch] + sbr->bs_num_rel_1[ch] + 2));
+ sbr->bs_pointer[ch] = faad_getbits(ld, i
+ DEBUGVAR(1,267,"sbr_grid(): bs_pointer"));
+
+ for (env = 0; env < sbr->bs_num_env[ch]; env++)
+ {
+ sbr->bs_freq_res[ch][env] = faad_get1bit(ld
+ DEBUGVAR(1,268,"sbr_grid(): bs_freq_res"));
+ }
+
+ sbr->abs_bord_lead[ch] = bs_abs_bord;
+ sbr->abs_bord_trail[ch] = bs_abs_bord_1;
+ break;
+ }
+
+ if (sbr->bs_num_env[ch] > 1)
+ sbr->bs_num_noise[ch] = 2;
+ else
+ sbr->bs_num_noise[ch] = 1;
+}
+
+/* table 8 */
+static void sbr_dtdf(bitfile *ld, sbr_info *sbr, uint8_t ch)
+{
+ uint8_t i;
+
+ for (i = 0; i < sbr->bs_num_env[ch]; i++)
+ {
+ sbr->bs_df_env[ch][i] = faad_get1bit(ld
+ DEBUGVAR(1,269,"sbr_dtdf(): bs_df_env"));
+ }
+
+ for (i = 0; i < sbr->bs_num_noise[ch]; i++)
+ {
+ sbr->bs_df_noise[ch][i] = faad_get1bit(ld
+ DEBUGVAR(1,270,"sbr_dtdf(): bs_df_noise"));
+ }
+}
+
+/* table 9 */
+static void invf_mode(bitfile *ld, sbr_info *sbr, uint8_t ch)
+{
+ uint8_t n;
+
+ for (n = 0; n < sbr->num_noise_bands[ch]; n++)
+ {
+ sbr->bs_invf_mode_vec[ch][n] = faad_getbits(ld, 2
+ DEBUGVAR(1,271,"invf_mode(): bs_invf_mode_vec"));
+ }
+}
+
+/* table 10 */
+static void sbr_envelope(bitfile *ld, sbr_info *sbr, uint8_t ch)
+{
+ uint8_t env, band;
+ sbr_huff_tab *t_huff, *f_huff;
+
+ if (sbr->bs_coupling)
+ {
+ if (ch)
+ {
+ if (sbr->bs_amp_res)
+ {
+ t_huff = t_huffman_env_bal_3_0dB;
+ f_huff = f_huffman_env_bal_3_0dB;
+ } else {
+ t_huff = t_huffman_env_bal_1_5dB;
+ f_huff = f_huffman_env_bal_1_5dB;
+ }
+ } else {
+ if (sbr->bs_amp_res)
+ {
+ t_huff = t_huffman_env_3_0dB;
+ f_huff = f_huffman_env_3_0dB;
+ } else {
+ t_huff = t_huffman_env_1_5dB;
+ f_huff = f_huffman_env_1_5dB;
+ }
+ }
+ } else {
+ if (sbr->bs_amp_res)
+ {
+ t_huff = t_huffman_env_3_0dB;
+ f_huff = f_huffman_env_3_0dB;
+ } else {
+ t_huff = t_huffman_env_1_5dB;
+ f_huff = f_huffman_env_1_5dB;
+ }
+ }
+
+ for (env = 0; env < sbr->bs_num_env[ch]; env++)
+ {
+ if (sbr->bs_df_env[ch][env] == 0)
+ {
+ if (sbr->bs_coupling && ch)
+ {
+ if (sbr->bs_amp_res)
+ {
+ sbr->bs_data_env[ch][env][0] = faad_getbits(ld, 5
+ DEBUGVAR(1,272,"sbr_envelope(): bs_data_env"));
+ } else {
+ sbr->bs_data_env[ch][env][0] = faad_getbits(ld, 6
+ DEBUGVAR(1,273,"sbr_envelope(): bs_data_env"));
+ }
+ } else {
+ if (sbr->bs_amp_res)
+ {
+ sbr->bs_data_env[ch][env][0] = faad_getbits(ld, 6
+ DEBUGVAR(1,274,"sbr_envelope(): bs_data_env"));
+ } else {
+ sbr->bs_data_env[ch][env][0] = faad_getbits(ld, 7
+ DEBUGVAR(1,275,"sbr_envelope(): bs_data_env"));
+ }
+ for (band = 1; band < sbr->num_env_bands[sbr->bs_freq_res[ch][env]]; band++)
+ {
+ sbr->bs_data_env[ch][env][band] = sbr_huff_dec(ld, f_huff);
+ }
+ }
+ } else {
+ for (band = 0; band < sbr->num_env_bands[sbr->bs_freq_res[ch][env]]; band++)
+ sbr->bs_data_env[ch][env][band] = sbr_huff_dec(ld, t_huff);
+ }
+ }
+}
+
+/* table 11 */
+static void sbr_noise(bitfile *ld, sbr_info *sbr, uint8_t ch)
+{
+ uint8_t noise, band;
+ sbr_huff_tab *t_huff, *f_huff;
+
+ if (sbr->bs_coupling)
+ {
+ if (ch) {
+ t_huff = t_huffman_noise_bal_3_0dB;
+ f_huff = f_huffman_noise_bal_3_0dB;
+ } else {
+ t_huff = t_huffman_noise_3_0dB;
+ f_huff = f_huffman_noise_3_0dB;
+ }
+ } else {
+ t_huff = t_huffman_noise_3_0dB;
+ f_huff = f_huffman_noise_3_0dB;
+ }
+
+ for(noise = 0; noise < sbr->bs_num_noise[ch]; noise++)
+ {
+ if(sbr->bs_df_noise[ch][noise] == 0)
+ {
+ if (sbr->bs_coupling && ch)
+ {
+ sbr->bs_data_noise[ch][noise][0] = faad_getbits(ld, 5
+ DEBUGVAR(1,276,"sbr_noise(): bs_data_noise"));
+ } else {
+ sbr->bs_data_noise[ch][noise][0] = faad_getbits(ld, 5
+ DEBUGVAR(1,277,"sbr_noise(): bs_data_noise"));
+ }
+ for (band = 1; band < sbr->num_noise_bands[ch]; band++)
+ {
+ sbr->bs_data_noise[ch][noise][band] = sbr_huff_dec(ld, f_huff);
+ }
+ } else {
+ for (band = 0; band < sbr->num_noise_bands[ch]; band++)
+ {
+ sbr->bs_data_noise[ch][noise][band] = sbr_huff_dec(ld, t_huff);
+ }
+ }
+ }
+}
+
+/* table 12 */
+static void sinusoidal_coding(bitfile *ld, sbr_info *sbr, uint8_t ch)
+{
+ uint8_t n;
+
+ for (n = 0; n < sbr->num_high_res[ch]; n++)
+ {
+ sbr->bs_add_harmonic[ch][n] = faad_get1bit(ld
+ DEBUGVAR(1,278,"sinusoidal_coding(): bs_add_harmonic"));
+ }
+}
+
+
+#endif /* SBR */ \ No newline at end of file
diff --git a/src/libfaad/sbr_syntax.h b/src/libfaad/sbr_syntax.h
new file mode 100644
index 000000000..5d094d7d1
--- /dev/null
+++ b/src/libfaad/sbr_syntax.h
@@ -0,0 +1,115 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: sbr_syntax.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifdef SBR
+
+#ifndef __SBR_SYNTAX_H__
+#define __SBR_SYNTAX_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "bits.h"
+
+
+#define SBR_STD 12
+#define SBR_HDR 13
+
+#define FIXFIX 0
+#define FIXVAR 1
+#define VARFIX 2
+#define VARVAR 3
+
+#define NO_TIME_SLOTS 16
+
+typedef struct
+{
+ /* really used */
+ uint8_t abs_bord_lead[2];
+ uint8_t abs_bord_trail[2];
+
+
+ /* to get it compiling */
+ /* we'll see during the coding of all the tools, whether
+ these are all used or not.
+ */
+ uint8_t bs_crc_flag;
+ uint8_t bs_sbr_crc_bits;
+ uint8_t bs_protocol_version;
+ uint8_t bs_amp_res;
+ uint8_t bs_start_freq;
+ uint8_t bs_stop_freq;
+ uint8_t bs_xover_band;
+ uint8_t bs_freq_scale;
+ uint8_t bs_alter_scale;
+ uint8_t bs_noise_bands;
+ uint8_t bs_limiter_bands;
+ uint8_t bs_limiter_gains;
+ uint8_t bs_interpol_freq;
+ uint8_t bs_smoothing_mode;
+ uint8_t bs_samplerate_mode;
+ uint8_t bs_add_harmonic_flag[2];
+ uint8_t bs_extended_data[2];
+ uint8_t bs_extension_id;
+ uint8_t bs_coupling;
+ uint8_t bs_frame_class;
+ uint8_t bs_num_env[2];
+ uint8_t bs_freq_res[2][6];
+ uint8_t bs_rel_bord[2][9];
+ uint8_t bs_rel_bord_0[2][9];
+ uint8_t bs_rel_bord_1[2][9];
+ uint8_t bs_pointer[2];
+ uint8_t bs_abs_bord_0[2];
+ uint8_t bs_abs_bord_1[2];
+ uint8_t bs_num_rel_0[2];
+ uint8_t bs_num_rel_1[2];
+ uint8_t bs_num_noise[2];
+ uint8_t bs_df_env[2][9];
+ uint8_t bs_df_noise[2][3];
+ uint8_t num_noise_bands[2];
+ uint8_t bs_invf_mode_vec[2][/*??*/10];
+ uint8_t num_high_res[2];
+ uint8_t bs_add_harmonic[2][/*??*/10];
+ uint16_t bs_data_env[2][/*??*/10][/*??*/10];
+ uint16_t bs_data_noise[2][/*??*/10][/*??*/10];
+ uint8_t num_env_bands[2];
+} sbr_info;
+
+uint8_t sbr_bitstream(bitfile *ld, sbr_info *sbr, uint8_t id_aac,
+ uint8_t bs_extension_type);
+static void sbr_header(bitfile *ld, sbr_info *sbr, uint8_t id_aac);
+static void sbr_data(bitfile *ld, sbr_info *sbr, uint8_t id_aac);
+static void sbr_single_channel_element(bitfile *ld, sbr_info *sbr);
+static void sbr_channel_pair_element(bitfile *ld, sbr_info *sbr);
+static void sbr_grid(bitfile *ld, sbr_info *sbr, uint8_t ch);
+static void sbr_dtdf(bitfile *ld, sbr_info *sbr, uint8_t ch);
+static void invf_mode(bitfile *ld, sbr_info *sbr, uint8_t ch);
+static void sbr_envelope(bitfile *ld, sbr_info *sbr, uint8_t ch);
+static void sbr_noise(bitfile *ld, sbr_info *sbr, uint8_t ch);
+static void sinusoidal_coding(bitfile *ld, sbr_info *sbr, uint8_t ch);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __SBR_SYNTAX_H__ */
+
+#endif /* SBR */ \ No newline at end of file
diff --git a/src/libfaad/specrec.c b/src/libfaad/specrec.c
new file mode 100644
index 000000000..7d97e2a76
--- /dev/null
+++ b/src/libfaad/specrec.c
@@ -0,0 +1,344 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: specrec.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+/*
+ Spectral reconstruction:
+ - grouping/sectioning
+ - inverse quantization
+ - applying scalefactors
+*/
+
+#include "common.h"
+
+#include "specrec.h"
+#include "syntax.h"
+#include "data.h"
+
+
+#define bit_set(A, B) ((A) & (1<<(B)))
+
+/* 4.5.2.3.4 */
+/*
+ - determine the number of windows in a window_sequence named num_windows
+ - determine the number of window_groups named num_window_groups
+ - determine the number of windows in each group named window_group_length[g]
+ - determine the total number of scalefactor window bands named num_swb for
+ the actual window type
+ - determine swb_offset[swb], the offset of the first coefficient in
+ scalefactor window band named swb of the window actually used
+ - determine sect_sfb_offset[g][section],the offset of the first coefficient
+ in section named section. This offset depends on window_sequence and
+ scale_factor_grouping and is needed to decode the spectral_data().
+*/
+uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index,
+ uint8_t object_type, uint16_t frame_len)
+{
+ uint8_t i, g;
+
+ switch (ics->window_sequence) {
+ case ONLY_LONG_SEQUENCE:
+ case LONG_START_SEQUENCE:
+ case LONG_STOP_SEQUENCE:
+ ics->num_windows = 1;
+ ics->num_window_groups = 1;
+ ics->window_group_length[ics->num_window_groups-1] = 1;
+#ifdef LD_DEC
+ if (object_type == LD)
+ {
+ ics->num_swb = num_swb_512_window[fs_index];
+ } else {
+#endif
+ ics->num_swb = num_swb_1024_window[fs_index];
+#ifdef LD_DEC
+ }
+#endif
+
+ /* preparation of sect_sfb_offset for long blocks */
+ /* also copy the last value! */
+#ifdef LD_DEC
+ if (object_type == LD)
+ {
+ for (i = 0; i < ics->num_swb; i++)
+ {
+ ics->sect_sfb_offset[0][i] = swb_offset_512_window[fs_index][i];
+ ics->swb_offset[i] = swb_offset_512_window[fs_index][i];
+ }
+ ics->sect_sfb_offset[0][ics->num_swb] = frame_len;
+ ics->swb_offset[ics->num_swb] = frame_len;
+ } else {
+#endif
+ for (i = 0; i < ics->num_swb; i++)
+ {
+ ics->sect_sfb_offset[0][i] = swb_offset_1024_window[fs_index][i];
+ ics->swb_offset[i] = swb_offset_1024_window[fs_index][i];
+ }
+ ics->sect_sfb_offset[0][ics->num_swb] = frame_len;
+ ics->swb_offset[ics->num_swb] = frame_len;
+#ifdef LD_DEC
+ }
+#endif
+ return 0;
+ case EIGHT_SHORT_SEQUENCE:
+ ics->num_windows = 8;
+ ics->num_window_groups = 1;
+ ics->window_group_length[ics->num_window_groups-1] = 1;
+ ics->num_swb = num_swb_128_window[fs_index];
+
+ for (i = 0; i < ics->num_swb; i++)
+ ics->swb_offset[i] = swb_offset_128_window[fs_index][i];
+ ics->swb_offset[ics->num_swb] = frame_len/8;
+
+ for (i = 0; i < ics->num_windows-1; i++) {
+ if (bit_set(ics->scale_factor_grouping, 6-i) == 0)
+ {
+ ics->num_window_groups += 1;
+ ics->window_group_length[ics->num_window_groups-1] = 1;
+ } else {
+ ics->window_group_length[ics->num_window_groups-1] += 1;
+ }
+ }
+
+ /* preparation of sect_sfb_offset for short blocks */
+ for (g = 0; g < ics->num_window_groups; g++)
+ {
+ uint16_t width;
+ uint8_t sect_sfb = 0;
+ uint16_t offset = 0;
+
+ for (i = 0; i < ics->num_swb; i++)
+ {
+ if (i+1 == ics->num_swb)
+ {
+ width = (frame_len/8) - swb_offset_128_window[fs_index][i];
+ } else {
+ width = swb_offset_128_window[fs_index][i+1] -
+ swb_offset_128_window[fs_index][i];
+ }
+ width *= ics->window_group_length[g];
+ ics->sect_sfb_offset[g][sect_sfb++] = offset;
+ offset += width;
+ }
+ ics->sect_sfb_offset[g][sect_sfb] = offset;
+ }
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+/*
+ For ONLY_LONG_SEQUENCE windows (num_window_groups = 1,
+ window_group_length[0] = 1) the spectral data is in ascending spectral
+ order.
+ For the EIGHT_SHORT_SEQUENCE window, the spectral order depends on the
+ grouping in the following manner:
+ - Groups are ordered sequentially
+ - Within a group, a scalefactor band consists of the spectral data of all
+ grouped SHORT_WINDOWs for the associated scalefactor window band. To
+ clarify via example, the length of a group is in the range of one to eight
+ SHORT_WINDOWs.
+ - If there are eight groups each with length one (num_window_groups = 8,
+ window_group_length[0..7] = 1), the result is a sequence of eight spectra,
+ each in ascending spectral order.
+ - If there is only one group with length eight (num_window_groups = 1,
+ window_group_length[0] = 8), the result is that spectral data of all eight
+ SHORT_WINDOWs is interleaved by scalefactor window bands.
+ - Within a scalefactor window band, the coefficients are in ascending
+ spectral order.
+*/
+void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len)
+{
+ int8_t i;
+ uint8_t g, sfb, win;
+ uint16_t width, bin;
+ real_t *start_inptr, *start_win_ptr, *win_ptr;
+
+ real_t tmp_spec[1024];
+ real_t *tmp_spec_ptr, *spec_ptr;
+
+ tmp_spec_ptr = tmp_spec;
+ for (i = frame_len/16-1; i >= 0; --i)
+ {
+ *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0;
+ *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0;
+ *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0;
+ *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0;
+ *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0;
+ *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0;
+ *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0;
+ *tmp_spec_ptr++ = 0; *tmp_spec_ptr++ = 0;
+ }
+
+ spec_ptr = spec_data;
+ tmp_spec_ptr = tmp_spec;
+ start_win_ptr = tmp_spec_ptr;
+
+ for (g = 0; g < ics->num_window_groups; g++)
+ {
+ uint16_t j = 0;
+ uint16_t win_inc = 0;
+
+ start_inptr = spec_ptr;
+
+ win_inc = ics->swb_offset[ics->num_swb];
+
+ for (sfb = 0; sfb < ics->num_swb; sfb++)
+ {
+ width = ics->swb_offset[sfb+1] - ics->swb_offset[sfb];
+
+ win_ptr = start_win_ptr;
+
+ for (win = 0; win < ics->window_group_length[g]; win++)
+ {
+ tmp_spec_ptr = win_ptr + j;
+
+ for (bin = 0; bin < width; bin += 4)
+ {
+ *tmp_spec_ptr++ = *spec_ptr++;
+ *tmp_spec_ptr++ = *spec_ptr++;
+ *tmp_spec_ptr++ = *spec_ptr++;
+ *tmp_spec_ptr++ = *spec_ptr++;
+ }
+
+ win_ptr += win_inc;
+ }
+ j += width;
+ }
+ start_win_ptr += (spec_ptr - start_inptr);
+ }
+
+ spec_ptr = spec_data;
+ tmp_spec_ptr = tmp_spec;
+
+ for (i = frame_len/16 - 1; i >= 0; --i)
+ {
+ *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++;
+ *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++;
+ *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++;
+ *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++;
+ *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++;
+ *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++;
+ *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++;
+ *spec_ptr++ = *tmp_spec_ptr++; *spec_ptr++ = *tmp_spec_ptr++;
+ }
+}
+
+void build_tables(real_t *iq_table, real_t *pow2_table)
+{
+ uint16_t i;
+
+ /* build pow(x, 4/3) table for inverse quantization */
+ for(i = 0; i < IQ_TABLE_SIZE; i++)
+ {
+ iq_table[i] = (real_t)exp(log(i) * 4.0/3.0);
+ }
+
+ /* build pow(2, 0.25*x) table for scalefactors */
+ for(i = 0; i < POW_TABLE_SIZE; i++)
+ {
+ pow2_table[i] = (real_t)exp(LN2 * 0.25 * (i-100));
+ }
+}
+
+static INLINE real_t iquant(int16_t q, real_t *iq_table)
+{
+ if (q > 0)
+ {
+ if (q < IQ_TABLE_SIZE)
+ return iq_table[q];
+ else
+ return MUL(iq_table[q>>3], 16);
+ } else if (q < 0) {
+ q = -q;
+ if (q < IQ_TABLE_SIZE)
+ return -iq_table[q];
+ else
+ return -MUL(iq_table[q>>3], 16);
+ } else {
+ return 0.0f;
+ }
+}
+
+void inverse_quantization(real_t *x_invquant, int16_t *x_quant, real_t *iq_table,
+ uint16_t frame_len)
+{
+ int8_t i;
+ int16_t *in_ptr = x_quant;
+ real_t *out_ptr = x_invquant;
+
+ for(i = frame_len/8-1; i >= 0; --i)
+ {
+ *out_ptr++ = iquant(*in_ptr++, iq_table);
+ *out_ptr++ = iquant(*in_ptr++, iq_table);
+ *out_ptr++ = iquant(*in_ptr++, iq_table);
+ *out_ptr++ = iquant(*in_ptr++, iq_table);
+ *out_ptr++ = iquant(*in_ptr++, iq_table);
+ *out_ptr++ = iquant(*in_ptr++, iq_table);
+ *out_ptr++ = iquant(*in_ptr++, iq_table);
+ *out_ptr++ = iquant(*in_ptr++, iq_table);
+ }
+}
+
+static INLINE real_t get_scale_factor_gain(uint16_t scale_factor, real_t *pow2_table)
+{
+ if (scale_factor < POW_TABLE_SIZE)
+ return pow2_table[scale_factor];
+ else
+ return (real_t)exp(LN2 * 0.25 * (scale_factor - 100));
+}
+
+void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table,
+ uint16_t frame_len)
+{
+ uint8_t g, sfb;
+ uint16_t top;
+ real_t *fp, scale;
+ uint8_t groups = 0;
+ uint16_t nshort = frame_len/8;
+
+ for (g = 0; g < ics->num_window_groups; g++)
+ {
+ uint16_t k = 0;
+
+ /* using this 128*groups doesn't hurt long blocks, because
+ long blocks only have 1 group, so that means 'groups' is
+ always 0 for long blocks
+ */
+ fp = x_invquant + (groups*nshort);
+
+ for (sfb = 0; sfb < ics->max_sfb; sfb++)
+ {
+ top = ics->sect_sfb_offset[g][sfb+1];
+
+ scale = get_scale_factor_gain(ics->scale_factors[g][sfb], pow2_table);
+
+ /* minimum size of a sf band is 4 and always a multiple of 4 */
+ for ( ; k < top; k+=4)
+ {
+ *fp = MUL(*fp, scale); fp++;
+ *fp = MUL(*fp, scale); fp++;
+ *fp = MUL(*fp, scale); fp++;
+ *fp = MUL(*fp, scale); fp++;
+ }
+ }
+ groups += ics->window_group_length[g];
+ }
+}
diff --git a/src/libfaad/specrec.h b/src/libfaad/specrec.h
new file mode 100644
index 000000000..ffe229c40
--- /dev/null
+++ b/src/libfaad/specrec.h
@@ -0,0 +1,50 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: specrec.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __SPECREC_H__
+#define __SPECREC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "syntax.h"
+
+/* !!!DON'T CHANGE IQ_TABLE_SIZE!!! */
+#define IQ_TABLE_SIZE 1026
+
+#define POW_TABLE_SIZE 200
+
+
+uint8_t window_grouping_info(ic_stream *ics, uint8_t fs_index,
+ uint8_t object_type, uint16_t frame_len);
+void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len);
+void build_tables(real_t *iq_table, real_t *pow2_table);
+void inverse_quantization(real_t *x_invquant, int16_t *x_quant, real_t *iq_table,
+ uint16_t frame_len);
+void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table,
+ uint16_t frame_len);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/syntax.c b/src/libfaad/syntax.c
new file mode 100644
index 000000000..66c61dcd0
--- /dev/null
+++ b/src/libfaad/syntax.c
@@ -0,0 +1,1429 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: syntax.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+/*
+ Reads the AAC bitstream as defined in 14496-3 (MPEG-4 Audio)
+
+ (Note that there are some differences with 13818-7 (MPEG2), these
+ are also read correctly when the MPEG ID is known (can be found in
+ an ADTS header)).
+*/
+
+#include <stdlib.h>
+#include <memory.h>
+#include "common.h"
+#include "syntax.h"
+#include "specrec.h"
+#include "huffman.h"
+#include "bits.h"
+#include "data.h"
+#include "pulse.h"
+#include "analysis.h"
+#ifdef SBR
+#include "sbr_syntax.h"
+#endif
+
+
+/* Table 4.4.1 */
+uint8_t GASpecificConfig(bitfile *ld, uint8_t *channelConfiguration,
+ uint8_t object_type,
+ uint8_t *aacSectionDataResilienceFlag,
+ uint8_t *aacScalefactorDataResilienceFlag,
+ uint8_t *aacSpectralDataResilienceFlag,
+ uint8_t *frameLengthFlag)
+{
+ uint8_t dependsOnCoreCoder, extensionFlag;
+ uint16_t coreCoderDelay;
+ program_config pce;
+
+ /* 1024 or 960 */
+ *frameLengthFlag = faad_get1bit(ld
+ DEBUGVAR(1,138,"GASpecificConfig(): FrameLengthFlag"));
+
+ dependsOnCoreCoder = faad_get1bit(ld
+ DEBUGVAR(1,139,"GASpecificConfig(): DependsOnCoreCoder"));
+ if (dependsOnCoreCoder == 1)
+ {
+ coreCoderDelay = (uint16_t)faad_getbits(ld, 14
+ DEBUGVAR(1,140,"GASpecificConfig(): CoreCoderDelay"));
+ }
+
+ extensionFlag = faad_get1bit(ld DEBUGVAR(1,141,"GASpecificConfig(): ExtensionFlag"));
+ if (*channelConfiguration == 0)
+ {
+ program_config_element(&pce, ld);
+ *channelConfiguration = pce.channels;
+
+ if (pce.num_valid_cc_elements)
+ return -3;
+ }
+
+ if (extensionFlag == 1)
+ {
+ /* Error resilience not supported yet */
+ if (object_type >= ER_OBJECT_START)
+ {
+ *aacSectionDataResilienceFlag = faad_get1bit(ld
+ DEBUGVAR(1,144,"GASpecificConfig(): aacSectionDataResilienceFlag"));
+ *aacScalefactorDataResilienceFlag = faad_get1bit(ld
+ DEBUGVAR(1,145,"GASpecificConfig(): aacScalefactorDataResilienceFlag"));
+ *aacSpectralDataResilienceFlag = faad_get1bit(ld
+ DEBUGVAR(1,146,"GASpecificConfig(): aacSpectralDataResilienceFlag"));
+
+ /* 1 bit: extensionFlag3 */
+ }
+ }
+
+ return 0;
+}
+
+/* Table 4.4.2 */
+/* An MPEG-4 Audio decoder is only required to follow the Program
+ Configuration Element in GASpecificConfig(). The decoder shall ignore
+ any Program Configuration Elements that may occur in raw data blocks.
+ PCEs transmitted in raw data blocks cannot be used to convey decoder
+ configuration information.
+*/
+uint8_t program_config_element(program_config *pce, bitfile *ld)
+{
+ uint8_t i;
+
+ pce->channels = 0;
+
+ pce->element_instance_tag = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,10,"program_config_element(): element_instance_tag"));
+
+ pce->object_type = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,11,"program_config_element(): object_type"));
+ pce->sf_index = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,12,"program_config_element(): sf_index"));
+ pce->num_front_channel_elements = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,13,"program_config_element(): num_front_channel_elements"));
+ pce->num_side_channel_elements = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,14,"program_config_element(): num_side_channel_elements"));
+ pce->num_back_channel_elements = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,15,"program_config_element(): num_back_channel_elements"));
+ pce->num_lfe_channel_elements = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,16,"program_config_element(): num_lfe_channel_elements"));
+ pce->num_assoc_data_elements = (uint8_t)faad_getbits(ld, 3
+ DEBUGVAR(1,17,"program_config_element(): num_assoc_data_elements"));
+ pce->num_valid_cc_elements = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,18,"program_config_element(): num_valid_cc_elements"));
+
+ pce->mono_mixdown_present = faad_get1bit(ld
+ DEBUGVAR(1,19,"program_config_element(): mono_mixdown_present"));
+ if (pce->mono_mixdown_present == 1)
+ {
+ pce->mono_mixdown_element_number = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,20,"program_config_element(): mono_mixdown_element_number"));
+ }
+
+ pce->stereo_mixdown_present = faad_get1bit(ld
+ DEBUGVAR(1,21,"program_config_element(): stereo_mixdown_present"));
+ if (pce->stereo_mixdown_present == 1)
+ {
+ pce->stereo_mixdown_element_number = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,22,"program_config_element(): stereo_mixdown_element_number"));
+ }
+
+ pce->matrix_mixdown_idx_present = faad_get1bit(ld
+ DEBUGVAR(1,23,"program_config_element(): matrix_mixdown_idx_present"));
+ if (pce->matrix_mixdown_idx_present == 1)
+ {
+ pce->matrix_mixdown_idx = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,24,"program_config_element(): matrix_mixdown_idx"));
+ pce->pseudo_surround_enable = faad_get1bit(ld
+ DEBUGVAR(1,25,"program_config_element(): pseudo_surround_enable"));
+ }
+
+ for (i = 0; i < pce->num_front_channel_elements; i++)
+ {
+ if ((pce->front_element_is_cpe[i] = faad_get1bit(ld
+ DEBUGVAR(1,26,"program_config_element(): front_element_is_cpe"))) & 1)
+ {
+ pce->channels += 2;
+ } else {
+ pce->channels++;
+ }
+ pce->front_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,27,"program_config_element(): front_element_tag_select"));
+ }
+
+ for (i = 0; i < pce->num_side_channel_elements; i++)
+ {
+ if ((pce->side_element_is_cpe[i] = faad_get1bit(ld
+ DEBUGVAR(1,28,"program_config_element(): side_element_is_cpe"))) & 1)
+ {
+ pce->channels += 2;
+ } else {
+ pce->channels++;
+ }
+ pce->side_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,29,"program_config_element(): side_element_tag_select"));
+ }
+
+ for (i = 0; i < pce->num_back_channel_elements; i++)
+ {
+ if ((pce->back_element_is_cpe[i] = faad_get1bit(ld
+ DEBUGVAR(1,30,"program_config_element(): back_element_is_cpe"))) & 1)
+ {
+ pce->channels += 2;
+ } else {
+ pce->channels++;
+ }
+ pce->back_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,31,"program_config_element(): back_element_tag_select"));
+ }
+
+ for (i = 0; i < pce->num_lfe_channel_elements; i++)
+ {
+ pce->channels++;
+ pce->lfe_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,32,"program_config_element(): lfe_element_tag_select"));
+ }
+
+ for (i = 0; i < pce->num_assoc_data_elements; i++)
+ pce->assoc_data_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,33,"program_config_element(): assoc_data_element_tag_select"));
+
+ for (i = 0; i < pce->num_valid_cc_elements; i++)
+ {
+ /* have to count these as channels too?? (1 or 2) */
+ pce->channels += 2;
+
+ pce->cc_element_is_ind_sw[i] = faad_get1bit(ld
+ DEBUGVAR(1,34,"program_config_element(): cc_element_is_ind_sw"));
+ pce->valid_cc_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,35,"program_config_element(): valid_cc_element_tag_select"));
+ }
+
+ faad_byte_align(ld);
+
+ pce->comment_field_bytes = (uint8_t)faad_getbits(ld, 8
+ DEBUGVAR(1,36,"program_config_element(): comment_field_bytes"));
+
+ for (i = 0; i < pce->comment_field_bytes; i++)
+ {
+ pce->comment_field_data[i] = (uint8_t)faad_getbits(ld, 8
+ DEBUGVAR(1,37,"program_config_element(): comment_field_data"));
+ }
+ pce->comment_field_data[i] = 0;
+
+ return 0;
+}
+
+/* Table 4.4.4 and */
+/* Table 4.4.9 */
+uint8_t single_lfe_channel_element(element *sce, bitfile *ld, int16_t *spec_data,
+ uint8_t sf_index, uint8_t object_type,
+ uint16_t frame_len
+#ifdef ERROR_RESILIENCE
+ ,uint8_t aacSectionDataResilienceFlag,
+ uint8_t aacScalefactorDataResilienceFlag,
+ uint8_t aacSpectralDataResilienceFlag
+#endif
+ )
+{
+ ic_stream *ics = &(sce->ics1);
+
+#ifdef DRM
+ if (object_type != DRM_ER_LC)
+#endif
+ sce->element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG
+ DEBUGVAR(1,38,"single_lfe_channel_element(): element_instance_tag"));
+
+ return individual_channel_stream(sce, ld, ics, 0, spec_data, sf_index,
+ object_type, frame_len
+#ifdef ERROR_RESILIENCE
+ ,aacSectionDataResilienceFlag,
+ aacScalefactorDataResilienceFlag,
+ aacSpectralDataResilienceFlag
+#endif
+ );
+}
+
+/* Table 4.4.5 */
+uint8_t channel_pair_element(element *cpe, bitfile *ld, int16_t *spec_data1,
+ int16_t *spec_data2, uint8_t sf_index, uint8_t object_type,
+ uint16_t frame_len
+#ifdef ERROR_RESILIENCE
+ ,uint8_t aacSectionDataResilienceFlag,
+ uint8_t aacScalefactorDataResilienceFlag,
+ uint8_t aacSpectralDataResilienceFlag
+#endif
+ )
+{
+ uint8_t result;
+ ic_stream *ics1 = &(cpe->ics1);
+ ic_stream *ics2 = &(cpe->ics2);
+
+#ifdef DRM
+ if (object_type != DRM_ER_LC)
+#endif
+ cpe->element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG
+ DEBUGVAR(1,39,"channel_pair_element(): element_instance_tag"));
+
+ if ((cpe->common_window = faad_get1bit(ld
+ DEBUGVAR(1,40,"channel_pair_element(): common_window"))) & 1)
+ {
+ /* both channels have common ics information */
+ if ((result = ics_info(ics1, ld, cpe->common_window, sf_index,
+ object_type, frame_len)) > 0)
+ return result;
+
+ ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,41,"channel_pair_element(): ms_mask_present"));
+ if (ics1->ms_mask_present == 1)
+ {
+ uint8_t g, sfb;
+ for (g = 0; g < ics1->num_window_groups; g++)
+ {
+ for (sfb = 0; sfb < ics1->max_sfb; sfb++)
+ {
+ ics1->ms_used[g][sfb] = faad_get1bit(ld
+ DEBUGVAR(1,42,"channel_pair_element(): faad_get1bit"));
+ }
+ }
+ }
+
+ memcpy(ics2, ics1, sizeof(ic_stream));
+ } else {
+ ics1->ms_mask_present = 0;
+ }
+
+ if ((result = individual_channel_stream(cpe, ld, ics1, 0, spec_data1,
+ sf_index, object_type, frame_len
+#ifdef ERROR_RESILIENCE
+ ,aacSectionDataResilienceFlag,
+ aacScalefactorDataResilienceFlag,
+ aacSpectralDataResilienceFlag
+#endif
+ )) > 0)
+ return result;
+ if ((result = individual_channel_stream(cpe, ld, ics2, 0, spec_data2,
+ sf_index, object_type, frame_len
+#ifdef ERROR_RESILIENCE
+ ,aacSectionDataResilienceFlag,
+ aacScalefactorDataResilienceFlag,
+ aacSpectralDataResilienceFlag
+#endif
+ )) > 0)
+ return result;
+
+ return 0;
+}
+
+/* Table 4.4.6 */
+static uint8_t ics_info(ic_stream *ics, bitfile *ld, uint8_t common_window,
+ uint8_t sf_index, uint8_t object_type, uint16_t frame_len)
+{
+ /* ics->ics_reserved_bit = */ faad_get1bit(ld
+ DEBUGVAR(1,43,"ics_info(): ics_reserved_bit"));
+ ics->window_sequence = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,44,"ics_info(): window_sequence"));
+ ics->window_shape = faad_get1bit(ld
+ DEBUGVAR(1,45,"ics_info(): window_shape"));
+
+ if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+ {
+ ics->max_sfb = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,46,"ics_info(): max_sfb (short)"));
+ ics->scale_factor_grouping = (uint8_t)faad_getbits(ld, 7
+ DEBUGVAR(1,47,"ics_info(): scale_factor_grouping"));
+ } else {
+ ics->max_sfb = (uint8_t)faad_getbits(ld, 6
+ DEBUGVAR(1,48,"ics_info(): max_sfb (long)"));
+
+ if ((ics->predictor_data_present = faad_get1bit(ld
+ DEBUGVAR(1,49,"ics_info(): predictor_data_present"))) & 1)
+ {
+ if (object_type == MAIN) /* MPEG2 style AAC predictor */
+ {
+ uint8_t sfb;
+
+ ics->pred.limit = min(ics->max_sfb, pred_sfb_max[sf_index]);
+
+ if ((ics->pred.predictor_reset = faad_get1bit(ld
+ DEBUGVAR(1,53,"ics_info(): pred.predictor_reset"))) & 1)
+ {
+ ics->pred.predictor_reset_group_number = (uint8_t)faad_getbits(ld, 5
+ DEBUGVAR(1,54,"ics_info(): pred.predictor_reset_group_number"));
+ }
+
+ for (sfb = 0; sfb < ics->pred.limit; sfb++)
+ {
+ ics->pred.prediction_used[sfb] = faad_get1bit(ld
+ DEBUGVAR(1,55,"ics_info(): pred.prediction_used"));
+ }
+ }
+#ifdef LTP_DEC
+ else { /* Long Term Prediction */
+ if ((ics->ltp.data_present = faad_get1bit(ld
+ DEBUGVAR(1,50,"ics_info(): ltp.data_present"))) & 1)
+ {
+ ltp_data(ics, &(ics->ltp), ld, object_type);
+ }
+ if (common_window)
+ {
+ if ((ics->ltp2.data_present = faad_get1bit(ld
+ DEBUGVAR(1,51,"ics_info(): ltp2.data_present"))) & 1)
+ {
+ ltp_data(ics, &(ics->ltp2), ld, object_type);
+ }
+ }
+ }
+#endif
+ }
+ }
+
+ /* get the grouping information */
+ return window_grouping_info(ics, sf_index, object_type, frame_len);
+}
+
+/* Table 4.4.7 */
+static void pulse_data(pulse_info *pul, bitfile *ld)
+{
+ uint8_t i;
+
+ pul->number_pulse = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,56,"pulse_data(): number_pulse"));
+ pul->pulse_start_sfb = (uint8_t)faad_getbits(ld, 6
+ DEBUGVAR(1,57,"pulse_data(): pulse_start_sfb"));
+
+ for (i = 0; i < pul->number_pulse+1; i++) {
+ pul->pulse_offset[i] = (uint8_t)faad_getbits(ld, 5
+ DEBUGVAR(1,58,"pulse_data(): pulse_offset"));
+ pul->pulse_amp[i] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,59,"pulse_data(): pulse_amp"));
+ }
+}
+
+/* Table 4.4.10 */
+uint16_t data_stream_element(bitfile *ld)
+{
+ uint8_t byte_aligned;
+ uint16_t i, count;
+
+ /* element_instance_tag = */ faad_getbits(ld, LEN_TAG
+ DEBUGVAR(1,60,"data_stream_element(): element_instance_tag"));
+ byte_aligned = faad_get1bit(ld
+ DEBUGVAR(1,61,"data_stream_element(): byte_aligned"));
+ count = faad_getbits(ld, 8
+ DEBUGVAR(1,62,"data_stream_element(): count"));
+ if (count == 255)
+ {
+ count += faad_getbits(ld, 8
+ DEBUGVAR(1,63,"data_stream_element(): extra count"));
+ }
+ if (byte_aligned)
+ faad_byte_align(ld);
+
+ for (i = 0; i < count; i++)
+ {
+ faad_getbits(ld, LEN_BYTE
+ DEBUGVAR(1,64,"data_stream_element(): data_stream_byte"));
+ }
+
+ return count;
+}
+
+/* Table 4.4.11 */
+uint8_t fill_element(bitfile *ld, drc_info *drc
+#ifdef SBR
+ ,uint8_t next_ele_id
+#endif
+ )
+{
+ uint16_t count;
+#ifdef SBR
+ uint8_t bs_extension_type;
+ uint32_t btot;
+#endif
+
+ count = (uint16_t)faad_getbits(ld, 4
+ DEBUGVAR(1,65,"fill_element(): count"));
+ if (count == 15)
+ {
+ count += (uint16_t)faad_getbits(ld, 8
+ DEBUGVAR(1,66,"fill_element(): extra count")) - 1;
+ }
+
+#ifdef SBR
+ bs_extension_type = (uint8_t)faad_showbits(ld, 4);
+
+ if (bs_extension_type == SBR_HDR || bs_extension_type == SBR_STD)
+ {
+ uint16_t i;
+ uint16_t bytes, bits;
+
+ /* flush the extension type and the fill nibble */
+ faad_flushbits(ld, 8);
+
+ btot = faad_get_processed_bits(ld);
+
+ /* SBR bitstream reading function */
+ sbr_bitstream(next_ele_id, bs_extension_type);
+
+ btot = faad_get_processed_bits(ld) - btot;
+
+ /* there might still be some fill bits left to read */
+ bits = (8*(count-1) - btot) % 8;
+ bytes = ((8*(count-1) - btot) - bits) / 8;
+
+ if (bits > 0)
+ faad_flushbits(ld, bits);
+ for (i = 0; i < bytes; i++)
+ {
+ faad_flushbits(ld, 8);
+ }
+ } else {
+#endif
+ while (count > 0)
+ {
+ count -= extension_payload(ld, drc, count);
+ }
+#ifdef SBR
+ }
+#endif
+
+ return 0;
+}
+
+/* Table 4.4.12 */
+static void gain_control_data(bitfile *ld, ic_stream *ics)
+{
+ uint8_t bd, wd, ad;
+ uint8_t adjust_num[4][8];
+ uint8_t alevcode[4][8][8];
+ uint8_t aloccode[4][8][8];
+
+ uint8_t max_band = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,1000,"gain_control_data(): max_band"));
+
+ if (ics->window_sequence == ONLY_LONG_SEQUENCE)
+ {
+ for (bd = 1; bd <= max_band; bd++)
+ {
+ for (wd=0; wd<1; wd++)
+ {
+ adjust_num[bd][wd] = (uint8_t)faad_getbits(ld, 3
+ DEBUGVAR(1,1001,"gain_control_data(): adjust_num"));
+
+ for (ad = 0; ad < adjust_num[bd][wd]; ad++)
+ {
+ alevcode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,1002,"gain_control_data(): alevcode"));
+ aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 5
+ DEBUGVAR(1,1003,"gain_control_data(): aloccode"));
+ }
+ }
+ }
+ } else if (ics->window_sequence == LONG_START_SEQUENCE) {
+ for (bd = 1; bd <= max_band; bd++)
+ {
+ for (wd = 0; wd < 2; wd++)
+ {
+ adjust_num[bd][wd] = (uint8_t)faad_getbits(ld, 3
+ DEBUGVAR(1,1001,"gain_control_data(): adjust_num"));
+
+ for (ad = 0; ad < adjust_num[bd][wd]; ad++)
+ {
+ alevcode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,1002,"gain_control_data(): alevcode"));
+ if (wd == 0)
+ {
+ aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,1003,"gain_control_data(): aloccode"));
+ } else {
+ aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,1003,"gain_control_data(): aloccode"));
+ }
+ }
+ }
+ }
+ } else if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) {
+ for (bd = 1; bd <= max_band; bd++)
+ {
+ for(wd=0; wd<8; wd++)
+ {
+ adjust_num[bd][wd] = (uint8_t)faad_getbits(ld, 3
+ DEBUGVAR(1,1001,"gain_control_data(): adjust_num"));
+
+ for (ad = 0; ad < adjust_num[bd][wd]; ad++)
+ {
+ alevcode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,1002,"gain_control_data(): alevcode"));
+ aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,1003,"gain_control_data(): aloccode"));
+ }
+ }
+ }
+ } else if (ics->window_sequence == LONG_STOP_SEQUENCE) {
+ for (bd = 1; bd <= max_band; bd++)
+ {
+ for (wd = 0; wd < 2; wd++)
+ {
+ adjust_num[bd][wd] = (uint8_t)faad_getbits(ld, 3
+ DEBUGVAR(1,1001,"gain_control_data(): adjust_num"));
+
+ for (ad = 0; ad < adjust_num[bd][wd]; ad++)
+ {
+ alevcode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,1002,"gain_control_data(): alevcode"));
+
+ if (wd == 0)
+ {
+ aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,1003,"gain_control_data(): aloccode"));
+ } else {
+ aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 5
+ DEBUGVAR(1,1003,"gain_control_data(): aloccode"));
+ }
+ }
+ }
+ }
+ }
+}
+
+/* Table 4.4.24 */
+static uint8_t individual_channel_stream(element *ele, bitfile *ld,
+ ic_stream *ics, uint8_t scal_flag,
+ int16_t *spec_data, uint8_t sf_index,
+ uint8_t object_type, uint16_t frame_len
+#ifdef ERROR_RESILIENCE
+ ,uint8_t aacSectionDataResilienceFlag,
+ uint8_t aacScalefactorDataResilienceFlag,
+ uint8_t aacSpectralDataResilienceFlag
+#endif
+ )
+{
+ uint8_t result;
+
+ ics->global_gain = (uint8_t)faad_getbits(ld, 8
+ DEBUGVAR(1,67,"individual_channel_stream(): global_gain"));
+
+ if (!ele->common_window && !scal_flag)
+ {
+ if ((result = ics_info(ics, ld, ele->common_window, sf_index,
+ object_type, frame_len)) > 0)
+ return result;
+ }
+ section_data(ics, ld
+#ifdef ERROR_RESILIENCE
+ ,aacSectionDataResilienceFlag
+#endif
+ );
+ if ((result = scale_factor_data(ics, ld
+#ifdef ERROR_RESILIENCE
+ ,aacScalefactorDataResilienceFlag
+#endif
+ )) > 0)
+ return result;
+
+ if (!scal_flag)
+ {
+ /**
+ ** NOTE: It could be that pulse data is available in scalable AAC too,
+ ** as said in Amendment 1, this could be only the case for ER AAC,
+ ** though. (have to check this out later)
+ **/
+ /* get pulse data */
+ if ((ics->pulse_data_present = faad_get1bit(ld
+ DEBUGVAR(1,68,"individual_channel_stream(): pulse_data_present"))) & 1)
+ {
+ pulse_data(&(ics->pul), ld);
+ }
+
+ /* get tns data */
+ if ((ics->tns_data_present = faad_get1bit(ld
+ DEBUGVAR(1,69,"individual_channel_stream(): tns_data_present"))) & 1)
+ {
+#ifdef ERROR_RESILIENCE
+ /* TODO I don't understand this, but the "rewrite" software moves tns_data away */
+ if ((object_type != ER_LC) && (object_type != ER_LTP)
+#ifdef DRM
+ && (object_type != DRM_ER_LC)
+#endif
+ )
+#endif
+ tns_data(ics, &(ics->tns), ld);
+ }
+
+ /* get gain control data */
+ if ((ics->gain_control_data_present = faad_get1bit(ld
+ DEBUGVAR(1,70,"individual_channel_stream(): gain_control_data_present"))) & 1)
+ {
+#if 0
+ return 1;
+#else
+ gain_control_data(ld, ics);
+#endif
+ }
+ }
+
+#ifdef ERROR_RESILIENCE
+ if (!aacSpectralDataResilienceFlag)
+ {
+ /* TODO I don't understand this, but the "rewrite" software
+ moves tns_data before spectral_data */
+ if ( (object_type == ER_LC) || (object_type == ER_LTP)
+#ifdef DRM
+ && (object_type != DRM_ER_LC)
+#endif
+ )
+ {
+ if (ics->tns_data_present)
+ tns_data(ics, &(ics->tns), ld);
+ }
+#endif
+
+ /* decode the spectral data */
+ if ((result = spectral_data(ics, ld, spec_data, frame_len)) > 0)
+ return result;
+#ifdef ERROR_RESILIENCE
+ } else {
+ ics->length_of_reordered_spectral_data = (uint16_t)faad_getbits(ld, 14
+ DEBUGVAR(1,147,"individual_channel_stream(): length_of_reordered_spectral_data"));
+ /* TODO: test for >6144/12288, see page 143 */
+ ics->length_of_longest_codeword = (uint8_t)faad_getbits(ld, 6
+ DEBUGVAR(1,148,"individual_channel_stream(): length_of_longest_codeword"));
+ if (ics->length_of_longest_codeword >= 49)
+ ics->length_of_longest_codeword = 49;
+
+ /* TODO I don't understand this, but the "rewrite" software
+ moves tns_data before spectral_data */
+
+ if (ics->tns_data_present)
+ tns_data(ics, &(ics->tns), ld);
+
+ /* error resilient spectral data decoding */
+ if ((result = reordered_spectral_data(ics, ld, spec_data, frame_len,
+ aacSectionDataResilienceFlag)) > 0)
+ {
+ return result;
+ }
+ }
+#endif
+
+ /* pulse coding reconstruction */
+ if (ics->pulse_data_present)
+ {
+ if (ics->window_sequence != EIGHT_SHORT_SEQUENCE)
+ pulse_decode(ics, spec_data);
+ else
+ return 2; /* pulse coding not allowed for long blocks */
+ }
+
+ return 0;
+}
+
+/* Table 4.4.25 */
+static void section_data(ic_stream *ics, bitfile *ld
+#ifdef ERROR_RESILIENCE
+ ,uint8_t aacSectionDataResilienceFlag
+#endif
+ )
+{
+ uint8_t g;
+ uint8_t sect_esc_val, sect_bits;
+
+ if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+ sect_bits = 3;
+ else
+ sect_bits = 5;
+ sect_esc_val = (1<<sect_bits) - 1;
+
+ for (g = 0; g < ics->num_window_groups; g++)
+ {
+ uint16_t k = 0;
+ uint8_t i = 0;
+
+ while (k < ics->max_sfb)
+ {
+ uint8_t sfb;
+ uint8_t sect_len_incr;
+ uint16_t sect_len = 0;
+ uint8_t sect_cb_bits = 4;
+
+#ifdef ERROR_RESILIENCE
+ if (aacSectionDataResilienceFlag)
+ sect_cb_bits = 5;
+#endif
+
+ ics->sect_cb[g][i] = (uint8_t)faad_getbits(ld, sect_cb_bits
+ DEBUGVAR(1,71,"section_data(): sect_cb"));
+
+#ifdef ERROR_RESILIENCE
+ if (!aacSectionDataResilienceFlag ||
+ (ics->sect_cb[g][i] < 11) ||
+ (ics->sect_cb[g][i] > 11 && ics->sect_cb[g][i] < 16))
+ {
+#endif
+ while ((sect_len_incr = (uint8_t)faad_getbits(ld, sect_bits
+ DEBUGVAR(1,72,"section_data(): sect_len_incr"))) == sect_esc_val)
+ {
+ sect_len += sect_esc_val;
+ }
+#ifdef ERROR_RESILIENCE
+ } else {
+ sect_len_incr = 1;
+ }
+#endif
+
+ sect_len += sect_len_incr;
+
+ ics->sect_start[g][i] = k;
+ ics->sect_end[g][i] = k + sect_len;
+
+ for (sfb = k; sfb < k + sect_len; sfb++)
+ ics->sfb_cb[g][sfb] = ics->sect_cb[g][i];
+
+ k += sect_len;
+ i++;
+ }
+ ics->num_sec[g] = i;
+ }
+}
+
+/*
+ * decode_scale_factors()
+ * decodes the scalefactors from the bitstream
+ */
+/*
+ * All scalefactors (and also the stereo positions and pns energies) are
+ * transmitted using Huffman coded DPCM relative to the previous active
+ * scalefactor (respectively previous stereo position or previous pns energy,
+ * see subclause 4.6.2 and 4.6.3). The first active scalefactor is
+ * differentially coded relative to the global gain.
+ */
+static uint8_t decode_scale_factors(ic_stream *ics, bitfile *ld)
+{
+ uint8_t g, sfb;
+ int8_t t;
+ int8_t noise_pcm_flag = 1;
+
+ int16_t scale_factor = ics->global_gain;
+ int16_t is_position = 0;
+ int16_t noise_energy = ics->global_gain - 90;
+
+ for (g = 0; g < ics->num_window_groups; g++)
+ {
+ for (sfb = 0; sfb < ics->max_sfb; sfb++)
+ {
+ switch (ics->sfb_cb[g][sfb])
+ {
+ case ZERO_HCB: /* zero book */
+ ics->scale_factors[g][sfb] = 0;
+ break;
+ case INTENSITY_HCB: /* intensity books */
+ case INTENSITY_HCB2:
+
+ /* decode intensity position */
+ t = huffman_scale_factor(ld);
+ if (t < 0)
+ return 9;
+ is_position += (t - 60);
+ ics->scale_factors[g][sfb] = is_position;
+
+ break;
+ case NOISE_HCB: /* noise books */
+
+ /* decode noise energy */
+ if (noise_pcm_flag)
+ {
+ noise_pcm_flag = 0;
+ t = faad_getbits(ld, 9
+ DEBUGVAR(1,73,"scale_factor_data(): first noise")) - 256;
+ } else {
+ t = huffman_scale_factor(ld);
+ if (t < 0)
+ return 9;
+ t -= 60;
+ }
+ noise_energy += t;
+ ics->scale_factors[g][sfb] = noise_energy;
+
+ break;
+ case BOOKSCL: /* invalid books */
+ return 3;
+ default: /* spectral books */
+
+ /* decode scale factor */
+ t = huffman_scale_factor(ld);
+ if (t < 0)
+ return 9;
+ scale_factor += (t - 60);
+ if (scale_factor < 0)
+ return 4;
+ ics->scale_factors[g][sfb] = scale_factor;
+
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Table 4.4.26 */
+static uint8_t scale_factor_data(ic_stream *ics, bitfile *ld
+#ifdef ERROR_RESILIENCE
+ ,uint8_t aacScalefactorDataResilienceFlag
+#endif
+ )
+{
+#ifdef ERROR_RESILIENCE
+ if (!aacScalefactorDataResilienceFlag)
+ {
+#endif
+ return decode_scale_factors(ics, ld);
+#ifdef ERROR_RESILIENCE
+ } else {
+#if 0
+ uint32_t bits_used, length_of_rvlc_sf;
+ uint8_t bits = 11;
+
+ sf_concealment = faad_get1bit(ld
+ DEBUGVAR(1,149,"scale_factor_data(): sf_concealment"));
+ rev_global_gain = faad_getbits(ld, 8
+ DEBUGVAR(1,150,"scale_factor_data(): rev_global_gain"));
+
+ if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+ bits = 9;
+
+ /* the number of bits used for the huffman codewords */
+ length_of_rvlc_sf = faad_getbits(ld, bits
+ DEBUGVAR(1,151,"scale_factor_data(): length_of_rvlc_sf"));
+
+ /* check how many bits are used in decoding the scalefactors
+ A better solution would be to read length_of_rvlc_sf ahead
+ in a buffer and use that to decode the scale factors
+ */
+ bits_used = faad_get_processed_bits(ld);
+ decode_scale_factors(ics, ld);
+ bits_used = faad_get_processed_bits(ld) - bits_used;
+
+ /* return an error if the number of decoded bits is not correct
+ FAAD should be able to recover from this, for example by
+ setting all scalefactors to 0 (e.g. muting the frame)
+ */
+ if (bits_used != length_of_rvlc_sf)
+ return 8;
+
+ sf_escapes_present; 1 uimsbf
+
+ if (sf_escapes_present)
+ {
+ length_of_rvlc_escapes; 8 uimsbf
+
+ for (g = 0; g < num_window_groups; g++)
+ {
+ for (sfb = 0; sfb < max_sfb; sfb++)
+ {
+ if (sect_cb[g][sfb] != ZERO_HCB)
+ {
+ if (is_intensity(g, sfb) &&
+ dpcm_is_position[g][sfb] == ESC_FLAG)
+ {
+ rvlc_esc_sf[dpcm_is_position[g][sfb]]; 2..20 vlclbf
+ } else {
+ if (is_noise(g, sfb) &&
+ dpcm_noise_nrg[g][sfb] == ESC_FLAG)
+ {
+ rvlc_esc_sf[dpcm_noise_nrg[g][sfb]]; 2..20 vlclbf
+ } else {
+ if (dpcm_sf[g][sfb] == ESC_FLAG)
+ {
+ rvlc_esc_sf[dpcm_sf[g][sfb]]; 2..20 vlclbf
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (intensity_used &&
+ dpcm_is_position[g][sfb] == ESC_FLAG)
+ {
+ rvlc_esc_sf[dpcm_is_last_position]; 2..20 vlclbf
+ }
+ }
+
+ if (noise_used)
+ {
+ dpcm_noise_last_position; 9 uimsbf
+ }
+#endif
+ }
+#endif
+}
+
+/* Table 4.4.27 */
+static void tns_data(ic_stream *ics, tns_info *tns, bitfile *ld)
+{
+ uint8_t w, filt, i, start_coef_bits, coef_bits;
+ uint8_t n_filt_bits = 2;
+ uint8_t length_bits = 6;
+ uint8_t order_bits = 5;
+
+ if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+ {
+ n_filt_bits = 1;
+ length_bits = 4;
+ order_bits = 3;
+ }
+
+ for (w = 0; w < ics->num_windows; w++)
+ {
+ tns->n_filt[w] = (uint8_t)faad_getbits(ld, n_filt_bits
+ DEBUGVAR(1,74,"tns_data(): n_filt"));
+
+ if (tns->n_filt[w])
+ {
+ if ((tns->coef_res[w] = faad_get1bit(ld
+ DEBUGVAR(1,75,"tns_data(): coef_res"))) & 1)
+ {
+ start_coef_bits = 4;
+ } else {
+ start_coef_bits = 3;
+ }
+ }
+
+ for (filt = 0; filt < tns->n_filt[w]; filt++)
+ {
+ tns->length[w][filt] = (uint8_t)faad_getbits(ld, length_bits
+ DEBUGVAR(1,76,"tns_data(): length"));
+ tns->order[w][filt] = (uint8_t)faad_getbits(ld, order_bits
+ DEBUGVAR(1,77,"tns_data(): order"));
+ if (tns->order[w][filt])
+ {
+ tns->direction[w][filt] = faad_get1bit(ld
+ DEBUGVAR(1,78,"tns_data(): direction"));
+ tns->coef_compress[w][filt] = faad_get1bit(ld
+ DEBUGVAR(1,79,"tns_data(): coef_compress"));
+
+ coef_bits = start_coef_bits - tns->coef_compress[w][filt];
+ for (i = 0; i < tns->order[w][filt]; i++)
+ {
+ tns->coef[w][filt][i] = (uint8_t)faad_getbits(ld, coef_bits
+ DEBUGVAR(1,80,"tns_data(): coef"));
+ }
+ }
+ }
+ }
+}
+
+#ifdef LTP_DEC
+/* Table 4.4.28 */
+/*
+ The limit MAX_LTP_SFB is not defined in 14496-3, this is a bug in the document
+ and will be corrected in one of the corrigenda.
+*/
+static void ltp_data(ic_stream *ics, ltp_info *ltp, bitfile *ld,
+ uint8_t object_type)
+{
+ uint8_t sfb, w;
+
+#ifdef LD_DEC
+ if (object_type == LD)
+ {
+ ltp->lag_update = (uint8_t)faad_getbits(ld, 1
+ DEBUGVAR(1,142,"ltp_data(): lag_update"));
+
+ if (ltp->lag_update)
+ {
+ ltp->lag = (uint16_t)faad_getbits(ld, 10
+ DEBUGVAR(1,81,"ltp_data(): lag"));
+ }
+ } else {
+#endif
+ ltp->lag = (uint16_t)faad_getbits(ld, 11
+ DEBUGVAR(1,81,"ltp_data(): lag"));
+#ifdef LD_DEC
+ }
+#endif
+ ltp->coef = (uint8_t)faad_getbits(ld, 3
+ DEBUGVAR(1,82,"ltp_data(): coef"));
+
+ if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+ {
+ for (w = 0; w < ics->num_windows; w++)
+ {
+ if ((ltp->short_used[w] = faad_get1bit(ld
+ DEBUGVAR(1,83,"ltp_data(): short_used"))) & 1)
+ {
+ ltp->short_lag_present[w] = faad_get1bit(ld
+ DEBUGVAR(1,84,"ltp_data(): short_lag_present"));
+ if (ltp->short_lag_present[w])
+ {
+ ltp->short_lag[w] = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,85,"ltp_data(): short_lag"));
+ }
+ }
+ }
+ } else {
+ ltp->last_band = (ics->max_sfb < MAX_LTP_SFB ? ics->max_sfb : MAX_LTP_SFB);
+
+ for (sfb = 0; sfb < ltp->last_band; sfb++)
+ {
+ ltp->long_used[sfb] = faad_get1bit(ld
+ DEBUGVAR(1,86,"ltp_data(): long_used"));
+ }
+ }
+}
+#endif
+
+/* defines whether a huffman codebook is unsigned or not */
+/* Table 4.6.2 */
+static uint8_t unsigned_cb[] = { 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ /* codebook 16 to 31 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+/* Table 4.4.29 */
+static uint8_t spectral_data(ic_stream *ics, bitfile *ld, int16_t *spectral_data,
+ uint16_t frame_len)
+{
+ int8_t i;
+ uint8_t g, inc;
+ int16_t *sp;
+ uint16_t k, p = 0;
+ uint8_t groups = 0;
+ uint8_t sect_cb;
+ uint8_t result;
+ uint16_t nshort = frame_len/8;
+
+ sp = spectral_data;
+ for (i = frame_len/16-1; i >= 0; --i)
+ {
+ *sp++ = 0; *sp++ = 0; *sp++ = 0; *sp++ = 0;
+ *sp++ = 0; *sp++ = 0; *sp++ = 0; *sp++ = 0;
+ *sp++ = 0; *sp++ = 0; *sp++ = 0; *sp++ = 0;
+ *sp++ = 0; *sp++ = 0; *sp++ = 0; *sp++ = 0;
+ }
+
+ for(g = 0; g < ics->num_window_groups; g++)
+ {
+ p = groups*nshort;
+
+ for (i = 0; i < ics->num_sec[g]; i++)
+ {
+ sect_cb = ics->sect_cb[g][i];
+
+ if ((sect_cb == ZERO_HCB) ||
+ (sect_cb == NOISE_HCB) ||
+ (sect_cb == INTENSITY_HCB) ||
+ (sect_cb == INTENSITY_HCB2))
+ {
+ p += (ics->sect_sfb_offset[g][ics->sect_end[g][i]] -
+ ics->sect_sfb_offset[g][ics->sect_start[g][i]]);
+ } else {
+ for (k = ics->sect_sfb_offset[g][ics->sect_start[g][i]];
+ k < ics->sect_sfb_offset[g][ics->sect_end[g][i]]; )
+ {
+ sp = spectral_data + p;
+
+ inc = (sect_cb < FIRST_PAIR_HCB) ? QUAD_LEN : PAIR_LEN;
+
+ if ((result = huffman_spectral_data(sect_cb, ld, sp)) > 0)
+ return result;
+ if (unsigned_cb[sect_cb])
+ huffman_sign_bits(ld, sp, inc);
+ k += inc;
+ p += inc;
+ if ((sect_cb == ESC_HCB) || (sect_cb >= 16))
+ {
+ sp[0] = huffman_getescape(ld, sp[0]);
+ sp[1] = huffman_getescape(ld, sp[1]);
+ }
+ }
+ }
+ }
+ groups += ics->window_group_length[g];
+ }
+
+ return 0;
+}
+
+/* Table 4.4.30 */
+static uint16_t extension_payload(bitfile *ld, drc_info *drc, uint16_t count)
+{
+ uint16_t i, n;
+ uint8_t extension_type = faad_getbits(ld, 4
+ DEBUGVAR(1,87,"extension_payload(): extension_type"));
+
+ switch (extension_type)
+ {
+ case EXT_DYNAMIC_RANGE:
+ drc->present = 1;
+ n = dynamic_range_info(ld, drc);
+ return n;
+ case EXT_FILL_DATA:
+ /* fill_nibble = */ faad_getbits(ld, 4
+ DEBUGVAR(1,136,"extension_payload(): fill_nibble")); /* must be ‘0000’ */
+ for (i = 0; i < count-1; i++)
+ {
+ /* fill_byte[i] = */ faad_getbits(ld, 8
+ DEBUGVAR(1,88,"extension_payload(): fill_byte")); /* must be ‘10100101’ */
+ }
+ return count;
+ default:
+ faad_getbits(ld, 4
+ DEBUGVAR(1,137,"extension_payload(): fill_nibble"));
+ for (i = 0; i < count-1; i++)
+ {
+ /* other_bits[i] = */ faad_getbits(ld, 8
+ DEBUGVAR(1,89,"extension_payload(): fill_byte"));
+ }
+ return count;
+ }
+}
+
+/* Table 4.4.31 */
+static uint8_t dynamic_range_info(bitfile *ld, drc_info *drc)
+{
+ uint8_t i, n = 1;
+ uint8_t band_incr;
+
+ drc->num_bands = 1;
+
+ if (faad_get1bit(ld
+ DEBUGVAR(1,90,"dynamic_range_info(): has instance_tag")) & 1)
+ {
+ drc->pce_instance_tag = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,91,"dynamic_range_info(): pce_instance_tag"));
+ /* drc->drc_tag_reserved_bits = */ faad_getbits(ld, 4
+ DEBUGVAR(1,92,"dynamic_range_info(): drc_tag_reserved_bits"));
+ n++;
+ }
+
+ drc->excluded_chns_present = faad_get1bit(ld
+ DEBUGVAR(1,93,"dynamic_range_info(): excluded_chns_present"));
+ if (drc->excluded_chns_present == 1)
+ {
+ n += excluded_channels(ld, drc);
+ }
+
+ if (faad_get1bit(ld
+ DEBUGVAR(1,94,"dynamic_range_info(): has bands data")) & 1)
+ {
+ band_incr = faad_getbits(ld, 4
+ DEBUGVAR(1,95,"dynamic_range_info(): band_incr"));
+ /* drc->drc_bands_reserved_bits = */ faad_getbits(ld, 4
+ DEBUGVAR(1,96,"dynamic_range_info(): drc_bands_reserved_bits"));
+ n++;
+ drc->num_bands += band_incr;
+
+ for (i = 0; i < drc->num_bands; i++);
+ {
+ drc->band_top[i] = (uint8_t)faad_getbits(ld, 8
+ DEBUGVAR(1,97,"dynamic_range_info(): band_top"));
+ n++;
+ }
+ }
+
+ if (faad_get1bit(ld
+ DEBUGVAR(1,98,"dynamic_range_info(): has prog_ref_level")) & 1)
+ {
+ drc->prog_ref_level = (uint8_t)faad_getbits(ld, 7
+ DEBUGVAR(1,99,"dynamic_range_info(): prog_ref_level"));
+ /* drc->prog_ref_level_reserved_bits = */ faad_get1bit(ld
+ DEBUGVAR(1,100,"dynamic_range_info(): prog_ref_level_reserved_bits"));
+ n++;
+ }
+
+ for (i = 0; i < drc->num_bands; i++)
+ {
+ drc->dyn_rng_sgn[i] = faad_get1bit(ld
+ DEBUGVAR(1,101,"dynamic_range_info(): dyn_rng_sgn"));
+ drc->dyn_rng_ctl[i] = (uint8_t)faad_getbits(ld, 7
+ DEBUGVAR(1,102,"dynamic_range_info(): dyn_rng_ctl"));
+ n++;
+ }
+
+ return n;
+}
+
+/* Table 4.4.32 */
+static uint8_t excluded_channels(bitfile *ld, drc_info *drc)
+{
+ uint8_t i, n = 0;
+ uint8_t num_excl_chan = 7;
+
+ for (i = 0; i < 7; i++)
+ {
+ drc->exclude_mask[i] = faad_get1bit(ld
+ DEBUGVAR(1,103,"excluded_channels(): exclude_mask"));
+ }
+ n++;
+
+ while ((drc->additional_excluded_chns[n-1] = faad_get1bit(ld
+ DEBUGVAR(1,104,"excluded_channels(): additional_excluded_chns"))) == 1)
+ {
+ for (i = num_excl_chan; i < num_excl_chan+7; i++)
+ {
+ drc->exclude_mask[i] = faad_get1bit(ld
+ DEBUGVAR(1,105,"excluded_channels(): exclude_mask"));
+ }
+ n++;
+ num_excl_chan += 7;
+ }
+
+ return n;
+}
+
+/* Annex A: Audio Interchange Formats */
+
+/* Table 1.A.2 */
+void get_adif_header(adif_header *adif, bitfile *ld)
+{
+ uint8_t i;
+
+ /* adif_id[0] = */ faad_getbits(ld, 8
+ DEBUGVAR(1,106,"get_adif_header(): adif_id[0]"));
+ /* adif_id[1] = */ faad_getbits(ld, 8
+ DEBUGVAR(1,107,"get_adif_header(): adif_id[1]"));
+ /* adif_id[2] = */ faad_getbits(ld, 8
+ DEBUGVAR(1,108,"get_adif_header(): adif_id[2]"));
+ /* adif_id[3] = */ faad_getbits(ld, 8
+ DEBUGVAR(1,109,"get_adif_header(): adif_id[3]"));
+ adif->copyright_id_present = faad_get1bit(ld
+ DEBUGVAR(1,110,"get_adif_header(): copyright_id_present"));
+ if(adif->copyright_id_present)
+ {
+ for (i = 0; i < 72/8; i++)
+ {
+ adif->copyright_id[i] = (int8_t)faad_getbits(ld, 8
+ DEBUGVAR(1,111,"get_adif_header(): copyright_id"));
+ }
+ adif->copyright_id[i] = 0;
+ }
+ adif->original_copy = faad_get1bit(ld
+ DEBUGVAR(1,112,"get_adif_header(): original_copy"));
+ adif->home = faad_get1bit(ld
+ DEBUGVAR(1,113,"get_adif_header(): home"));
+ adif->bitstream_type = faad_get1bit(ld
+ DEBUGVAR(1,114,"get_adif_header(): bitstream_type"));
+ adif->bitrate = faad_getbits(ld, 23
+ DEBUGVAR(1,115,"get_adif_header(): bitrate"));
+ adif->num_program_config_elements = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,116,"get_adif_header(): num_program_config_elements"));
+
+ for (i = 0; i < adif->num_program_config_elements + 1; i++)
+ {
+ if(adif->bitstream_type == 0)
+ {
+ adif->adif_buffer_fullness = faad_getbits(ld, 20
+ DEBUGVAR(1,117,"get_adif_header(): adif_buffer_fullness"));
+ } else {
+ adif->adif_buffer_fullness = 0;
+ }
+
+ program_config_element(&adif->pce, ld);
+ }
+}
+
+/* Table 1.A.5 */
+uint8_t adts_frame(adts_header *adts, bitfile *ld)
+{
+ /* faad_byte_align(ld); */
+ if (adts_fixed_header(adts, ld))
+ return 5;
+ adts_variable_header(adts, ld);
+ adts_error_check(adts, ld);
+
+ return 0;
+}
+
+/* Table 1.A.6 */
+static uint8_t adts_fixed_header(adts_header *adts, bitfile *ld)
+{
+ uint16_t i;
+ uint8_t sync_err = 1;
+
+ /* try to recover from sync errors */
+ for (i = 0; i < 768; i++)
+ {
+ adts->syncword = (uint16_t)faad_showbits(ld, 12);
+ if (adts->syncword != 0xFFF)
+ {
+ faad_getbits(ld, 8
+ DEBUGVAR(0,0,""));
+ } else {
+ sync_err = 0;
+ faad_getbits(ld, 12
+ DEBUGVAR(1,118,"adts_fixed_header(): syncword"));
+ break;
+ }
+ }
+ if (sync_err)
+ return 5;
+
+ adts->id = faad_get1bit(ld
+ DEBUGVAR(1,119,"adts_fixed_header(): id"));
+ adts->layer = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,120,"adts_fixed_header(): layer"));
+ adts->protection_absent = faad_get1bit(ld
+ DEBUGVAR(1,121,"adts_fixed_header(): protection_absent"));
+ adts->profile = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,122,"adts_fixed_header(): profile"));
+ adts->sf_index = (uint8_t)faad_getbits(ld, 4
+ DEBUGVAR(1,123,"adts_fixed_header(): sf_index"));
+ adts->private_bit = faad_get1bit(ld
+ DEBUGVAR(1,124,"adts_fixed_header(): private_bit"));
+ adts->channel_configuration = (uint8_t)faad_getbits(ld, 3
+ DEBUGVAR(1,125,"adts_fixed_header(): channel_configuration"));
+ adts->original = faad_get1bit(ld
+ DEBUGVAR(1,126,"adts_fixed_header(): original"));
+ adts->home = faad_get1bit(ld
+ DEBUGVAR(1,127,"adts_fixed_header(): home"));
+ if (adts->id == 0)
+ {
+ adts->emphasis = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,128,"adts_fixed_header(): emphasis"));
+ }
+
+ return 0;
+}
+
+/* Table 1.A.7 */
+static void adts_variable_header(adts_header *adts, bitfile *ld)
+{
+ adts->copyright_identification_bit = faad_get1bit(ld
+ DEBUGVAR(1,129,"adts_variable_header(): copyright_identification_bit"));
+ adts->copyright_identification_start = faad_get1bit(ld
+ DEBUGVAR(1,130,"adts_variable_header(): copyright_identification_start"));
+ adts->aac_frame_length = (uint16_t)faad_getbits(ld, 13
+ DEBUGVAR(1,131,"adts_variable_header(): aac_frame_length"));
+ adts->adts_buffer_fullness = (uint16_t)faad_getbits(ld, 11
+ DEBUGVAR(1,132,"adts_variable_header(): adts_buffer_fullness"));
+ adts->no_raw_data_blocks_in_frame = (uint8_t)faad_getbits(ld, 2
+ DEBUGVAR(1,133,"adts_variable_header(): no_raw_data_blocks_in_frame"));
+}
+
+/* Table 1.A.8 */
+static void adts_error_check(adts_header *adts, bitfile *ld)
+{
+ if (adts->protection_absent == 0)
+ {
+ adts->crc_check = (uint16_t)faad_getbits(ld, 16
+ DEBUGVAR(1,134,"adts_error_check(): crc_check"));
+ }
+}
diff --git a/src/libfaad/syntax.h b/src/libfaad/syntax.h
new file mode 100644
index 000000000..ef3a362cd
--- /dev/null
+++ b/src/libfaad/syntax.h
@@ -0,0 +1,360 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: syntax.h,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $
+**/
+
+#ifndef __SYNTAX_H__
+#define __SYNTAX_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "bits.h"
+
+#define MAIN 0
+#define LC 1
+#define SSR 2
+#define LTP 3
+#define LD 23
+#define ER_LC 17
+#define ER_LTP 19
+#define DRM_ER_LC 27 /* special object type for DRM */
+
+
+/* First object type that has ER */
+#define ER_OBJECT_START 17
+
+
+/* Bitstream */
+#define LEN_SE_ID 3
+#define LEN_TAG 4
+#define LEN_BYTE 8
+
+#define EXT_FILL_DATA 1
+#define EXT_DYNAMIC_RANGE 11
+
+/* Syntax elements */
+#define ID_SCE 0x0
+#define ID_CPE 0x1
+#define ID_CCE 0x2
+#define ID_LFE 0x3
+#define ID_DSE 0x4
+#define ID_PCE 0x5
+#define ID_FIL 0x6
+#define ID_END 0x7
+
+#define MAX_CHANNELS 64
+#define MAX_SYNTAX_ELEMENTS 48
+#define MAX_WINDOW_GROUPS 8
+#define MAX_SFB 51
+#define MAX_LTP_SFB 40
+#define MAX_LTP_SFB_S 8
+
+
+#define ONLY_LONG_SEQUENCE 0x0
+#define LONG_START_SEQUENCE 0x1
+#define EIGHT_SHORT_SEQUENCE 0x2
+#define LONG_STOP_SEQUENCE 0x3
+
+#define ZERO_HCB 0
+#define FIRST_PAIR_HCB 5
+#define ESC_HCB 11
+#define QUAD_LEN 4
+#define PAIR_LEN 2
+#define BOOKSCL 12
+#define NOISE_HCB 13
+#define INTENSITY_HCB2 14
+#define INTENSITY_HCB 15
+
+
+typedef struct
+{
+ uint8_t element_instance_tag;
+ uint8_t object_type;
+ uint8_t sf_index;
+ uint8_t num_front_channel_elements;
+ uint8_t num_side_channel_elements;
+ uint8_t num_back_channel_elements;
+ uint8_t num_lfe_channel_elements;
+ uint8_t num_assoc_data_elements;
+ uint8_t num_valid_cc_elements;
+ uint8_t mono_mixdown_present;
+ uint8_t mono_mixdown_element_number;
+ uint8_t stereo_mixdown_present;
+ uint8_t stereo_mixdown_element_number;
+ uint8_t matrix_mixdown_idx_present;
+ uint8_t pseudo_surround_enable;
+ uint8_t matrix_mixdown_idx;
+ uint8_t front_element_is_cpe[16];
+ uint8_t front_element_tag_select[16];
+ uint8_t side_element_is_cpe[16];
+ uint8_t side_element_tag_select[16];
+ uint8_t back_element_is_cpe[16];
+ uint8_t back_element_tag_select[16];
+ uint8_t lfe_element_tag_select[16];
+ uint8_t assoc_data_element_tag_select[16];
+ uint8_t cc_element_is_ind_sw[16];
+ uint8_t valid_cc_element_tag_select[16];
+
+ uint8_t channels;
+
+ uint8_t comment_field_bytes;
+ uint8_t comment_field_data[257];
+} program_config;
+
+typedef struct
+{
+ uint16_t syncword;
+ uint8_t id;
+ uint8_t layer;
+ uint8_t protection_absent;
+ uint8_t profile;
+ uint8_t sf_index;
+ uint8_t private_bit;
+ uint8_t channel_configuration;
+ uint8_t original;
+ uint8_t home;
+ uint8_t emphasis;
+ uint8_t copyright_identification_bit;
+ uint8_t copyright_identification_start;
+ uint16_t aac_frame_length;
+ uint16_t adts_buffer_fullness;
+ uint8_t no_raw_data_blocks_in_frame;
+ uint16_t crc_check;
+} adts_header;
+
+typedef struct
+{
+ uint8_t copyright_id_present;
+ int8_t copyright_id[10];
+ uint8_t original_copy;
+ uint8_t home;
+ uint8_t bitstream_type;
+ uint32_t bitrate;
+ uint8_t num_program_config_elements;
+ uint32_t adif_buffer_fullness;
+
+ program_config pce;
+} adif_header;
+
+typedef struct
+{
+ uint8_t last_band;
+ uint8_t data_present;
+ uint16_t lag;
+ uint8_t lag_update;
+ uint8_t coef;
+ uint8_t long_used[51];
+ uint8_t short_used[8];
+ uint8_t short_lag_present[8];
+ uint8_t short_lag[8];
+} ltp_info;
+
+typedef struct
+{
+ uint8_t limit;
+ uint8_t predictor_reset;
+ uint8_t predictor_reset_group_number;
+ uint8_t prediction_used[41];
+} pred_info;
+
+typedef struct
+{
+ uint8_t number_pulse;
+ uint8_t pulse_start_sfb;
+ uint8_t pulse_offset[4];
+ uint8_t pulse_amp[4];
+} pulse_info;
+
+typedef struct
+{
+ uint8_t n_filt[8];
+ uint8_t coef_res[8];
+ uint8_t length[8][4];
+ uint8_t order[8][4];
+ uint8_t direction[8][4];
+ uint8_t coef_compress[8][4];
+ uint8_t coef[8][4][32];
+} tns_info;
+
+typedef struct
+{
+ uint8_t present;
+
+ uint8_t num_bands;
+ uint8_t pce_instance_tag;
+ uint8_t excluded_chns_present;
+ uint8_t band_top[17];
+ uint8_t prog_ref_level;
+ uint8_t dyn_rng_sgn[17];
+ uint8_t dyn_rng_ctl[17];
+ uint8_t exclude_mask[MAX_CHANNELS];
+ uint8_t additional_excluded_chns[MAX_CHANNELS];
+
+ real_t ctrl1;
+ real_t ctrl2;
+} drc_info;
+
+typedef struct
+{
+ uint8_t max_sfb;
+
+ uint8_t num_swb;
+ uint8_t num_window_groups;
+ uint8_t num_windows;
+ uint8_t window_sequence;
+ uint8_t window_group_length[8];
+ uint8_t window_shape;
+ uint8_t scale_factor_grouping;
+ uint16_t sect_sfb_offset[8][15*8];
+ uint16_t swb_offset[51];
+
+ uint8_t sect_cb[8][15*8];
+ uint16_t sect_start[8][15*8];
+ uint16_t sect_end[8][15*8];
+ uint8_t sfb_cb[8][8*15];
+ uint8_t num_sec[8]; /* number of sections in a group */
+
+ uint8_t global_gain;
+ uint16_t scale_factors[8][51];
+
+ uint8_t ms_mask_present;
+ uint8_t ms_used[MAX_WINDOW_GROUPS][MAX_SFB];
+
+ uint8_t pulse_data_present;
+ uint8_t tns_data_present;
+ uint8_t gain_control_data_present;
+ uint8_t predictor_data_present;
+
+ pulse_info pul;
+ tns_info tns;
+ pred_info pred;
+ ltp_info ltp;
+ ltp_info ltp2;
+
+#ifdef ERROR_RESILIENCE
+ /* ER data */
+ uint16_t length_of_reordered_spectral_data;
+ uint8_t length_of_longest_codeword;
+#endif
+} ic_stream; /* individual channel stream */
+
+typedef struct
+{
+ uint8_t ele_id;
+
+ uint8_t channel;
+ uint8_t paired_channel;
+
+ uint8_t element_instance_tag;
+ uint8_t common_window;
+
+ ic_stream ics1;
+ ic_stream ics2;
+} element; /* syntax element (SCE, CPE, LFE) */
+
+
+uint8_t GASpecificConfig(bitfile *ld, uint8_t *channelConfiguration,
+ uint8_t object_type,
+ uint8_t *aacSectionDataResilienceFlag,
+ uint8_t *aacScalefactorDataResilienceFlag,
+ uint8_t *aacSpectralDataResilienceFlag,
+ uint8_t *frameLengthFlag);
+uint8_t raw_data_block(bitfile *ld, int16_t ***spec_data, real_t ***spec_coef,
+ element ***syntax_elements,
+ uint8_t *channels, uint8_t *ele, uint8_t *ch_ele,
+ uint16_t frame_len, uint8_t sf_index, uint8_t object_type,
+ drc_info *drc);
+uint8_t single_lfe_channel_element(element *sce, bitfile *ld, int16_t *spec_data,
+ uint8_t sf_index, uint8_t object_type,
+ uint16_t frame_len
+#ifdef ERROR_RESILIENCE
+ ,uint8_t aacSectionDataResilienceFlag,
+ uint8_t aacScalefactorDataResilienceFlag,
+ uint8_t aacSpectralDataResilienceFlag
+#endif
+ );
+uint8_t channel_pair_element(element *cpe, bitfile *ld, int16_t *spec_data1,
+ int16_t *spec_data2, uint8_t sf_index, uint8_t object_type,
+ uint16_t frame_len
+#ifdef ERROR_RESILIENCE
+ ,uint8_t aacSectionDataResilienceFlag,
+ uint8_t aacScalefactorDataResilienceFlag,
+ uint8_t aacSpectralDataResilienceFlag
+#endif
+ );
+uint16_t data_stream_element(bitfile *ld);
+uint8_t program_config_element(program_config *pce, bitfile *ld);
+uint8_t fill_element(bitfile *ld, drc_info *drc
+#ifdef SBR
+ ,uint8_t next_ele_id
+#endif
+ );
+uint8_t adts_frame(adts_header *adts, bitfile *ld);
+void get_adif_header(adif_header *adif, bitfile *ld);
+
+
+/* static functions */
+static uint8_t individual_channel_stream(element *ele, bitfile *ld,
+ ic_stream *ics, uint8_t scal_flag,
+ int16_t *spec_data, uint8_t sf_index,
+ uint8_t object_type, uint16_t frame_len
+#ifdef ERROR_RESILIENCE
+ ,uint8_t aacSectionDataResilienceFlag,
+ uint8_t aacScalefactorDataResilienceFlag,
+ uint8_t aacSpectralDataResilienceFlag
+#endif
+ );
+static uint8_t ics_info(ic_stream *ics, bitfile *ld, uint8_t common_window,
+ uint8_t fs_index, uint8_t object_type,
+ uint16_t frame_len);
+static void section_data(ic_stream *ics, bitfile *ld
+#ifdef ERROR_RESILIENCE
+ ,uint8_t aacSectionDataResilienceFlag
+#endif
+ );
+static uint8_t scale_factor_data(ic_stream *ics, bitfile *ld
+#ifdef ERROR_RESILIENCE
+ ,uint8_t aacScalefactorDataResilienceFlag
+#endif
+ );
+static void gain_control_data(bitfile *ld, ic_stream *ics);
+static uint8_t spectral_data(ic_stream *ics, bitfile *ld, int16_t *spectral_data,
+ uint16_t frame_len);
+static uint16_t extension_payload(bitfile *ld, drc_info *drc, uint16_t count);
+#ifdef ERROR_RESILIENCE
+uint8_t reordered_spectral_data(ic_stream *ics, bitfile *ld, int16_t *spectral_data,
+ uint16_t frame_len, uint8_t aacSectionDataResilienceFlag);
+#endif
+static void pulse_data(pulse_info *pul, bitfile *ld);
+static void tns_data(ic_stream *ics, tns_info *tns, bitfile *ld);
+static void ltp_data(ic_stream *ics, ltp_info *ltp, bitfile *ld,
+ uint8_t object_type);
+static uint8_t adts_fixed_header(adts_header *adts, bitfile *ld);
+static void adts_variable_header(adts_header *adts, bitfile *ld);
+static void adts_error_check(adts_header *adts, bitfile *ld);
+static uint8_t dynamic_range_info(bitfile *ld, drc_info *drc);
+static uint8_t excluded_channels(bitfile *ld, drc_info *drc);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/tns.c b/src/libfaad/tns.c
new file mode 100644
index 000000000..a26ef4fab
--- /dev/null
+++ b/src/libfaad/tns.c
@@ -0,0 +1,315 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: tns.c,v 1.1 2002/07/14 23:43:02 miguelfreitas Exp $
+**/
+
+#include "common.h"
+
+#include "syntax.h"
+#include "tns.h"
+
+
+/* TNS decoding for one channel and frame */
+void tns_decode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index,
+ uint8_t object_type, real_t *spec, uint16_t frame_len)
+{
+ uint8_t w, f, tns_order;
+ int8_t inc;
+ uint16_t bottom, top, start, end, size;
+ uint16_t nshort = frame_len/8;
+ real_t lpc[TNS_MAX_ORDER+1];
+
+ if (!ics->tns_data_present)
+ return;
+
+ for (w = 0; w < ics->num_windows; w++)
+ {
+ bottom = ics->num_swb;
+
+ for (f = 0; f < tns->n_filt[w]; f++)
+ {
+ top = bottom;
+ bottom = max(top - tns->length[w][f], 0);
+ tns_order = min(tns->order[w][f], tns_max_order(ics, sr_index,
+ object_type));
+ if (!tns_order)
+ continue;
+
+ tns_decode_coef(tns_order, tns->coef_res[w]+3,
+ tns->coef_compress[w][f], tns->coef[w][f], lpc);
+
+ start = ics->swb_offset[min(bottom,
+ min(tns_max_bands(ics, sr_index, object_type), ics->max_sfb))];
+ end = ics->swb_offset[min(top,
+ min(tns_max_bands(ics, sr_index, object_type), ics->max_sfb))];
+
+ if ((size = end - start) <= 0)
+ continue;
+
+ if (tns->direction[w][f])
+ {
+ inc = -1;
+ start = end - 1;
+ } else {
+ inc = 1;
+ }
+
+ tns_ar_filter(&spec[(w*nshort)+start], size, inc, lpc, tns_order);
+ }
+ }
+}
+
+/* TNS encoding for one channel and frame */
+void tns_encode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index,
+ uint8_t object_type, real_t *spec, uint16_t frame_len)
+{
+ uint8_t w, f, tns_order;
+ int8_t inc;
+ uint16_t bottom, top, start, end, size;
+ uint16_t nshort = frame_len/8;
+ real_t lpc[TNS_MAX_ORDER+1];
+
+ if (!ics->tns_data_present)
+ return;
+
+ for (w = 0; w < ics->num_windows; w++)
+ {
+ bottom = ics->num_swb;
+
+ for (f = 0; f < tns->n_filt[w]; f++)
+ {
+ top = bottom;
+ bottom = max(top - tns->length[w][f], 0);
+ tns_order = min(tns->order[w][f], tns_max_order(ics, sr_index,
+ object_type));
+ if (!tns_order)
+ continue;
+
+ tns_decode_coef(tns_order, tns->coef_res[w]+3,
+ tns->coef_compress[w][f], tns->coef[w][f], lpc);
+
+ start = ics->swb_offset[min(bottom,
+ min(tns_max_bands(ics, sr_index, object_type), ics->max_sfb))];
+ end = ics->swb_offset[min(top,
+ min(tns_max_bands(ics, sr_index, object_type), ics->max_sfb))];
+
+ if ((size = end - start) <= 0)
+ continue;
+
+ if (tns->direction[w][f])
+ {
+ inc = -1;
+ start = end - 1;
+ } else {
+ inc = 1;
+ }
+
+ tns_ma_filter(&spec[(w*nshort)+start], size, inc, lpc, tns_order);
+ }
+ }
+}
+
+/* Decoder transmitted coefficients for one TNS filter */
+static void tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress,
+ uint8_t *coef, real_t *a)
+{
+ uint8_t i, m;
+ uint8_t coef_res2, s_mask, n_mask;
+ real_t tmp2[TNS_MAX_ORDER+1], b[TNS_MAX_ORDER+1];
+ real_t iqfac;
+
+ /* Some internal tables */
+ static uint8_t sgn_mask[] = { 0x2, 0x4, 0x8 };
+ static uint8_t neg_mask[] = { ~0x3, ~0x7, ~0xf };
+
+ /* size used for transmission */
+ coef_res2 = coef_res_bits - coef_compress;
+ s_mask = sgn_mask[coef_res2 - 2]; /* mask for sign bit */
+ n_mask = neg_mask[coef_res2 - 2]; /* mask for padding neg. values */
+
+ /* Conversion to signed integer */
+ for (i = 0; i < order; i++)
+ {
+ int8_t tmp = (coef[i] & s_mask) ? (coef[i] | n_mask) : coef[i];
+
+ /* Inverse quantization */
+ if (tmp >= 0)
+ iqfac = ((1 << (coef_res_bits-1)) - 0.5f) / M_PI_2;
+ else
+ iqfac = ((1 << (coef_res_bits-1)) + 0.5f) / M_PI_2;
+
+ tmp2[i] = (real_t)sin(tmp / iqfac);
+ }
+
+ /* Conversion to LPC coefficients */
+ a[0] = 1;
+ for (m = 1; m <= order; m++)
+ {
+ for (i = 1; i < m; i++) /* loop only while i<m */
+ b[i] = a[i] + MUL(tmp2[m-1], a[m-i]);
+
+ for (i = 1; i < m; i++) /* loop only while i<m */
+ a[i] = b[i];
+
+ a[m] = tmp2[m-1]; /* changed */
+ }
+}
+
+static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc,
+ uint8_t order)
+{
+ /*
+ - Simple all-pole filter of order "order" defined by
+ y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order)
+ - The state variables of the filter are initialized to zero every time
+ - The output data is written over the input data ("in-place operation")
+ - An input vector of "size" samples is processed and the index increment
+ to the next data sample is given by "inc"
+ */
+
+ uint8_t j;
+ uint16_t i;
+ real_t y, state[TNS_MAX_ORDER];
+
+ for (i = 0; i < order; i++)
+ state[i] = 0;
+
+ for (i = 0; i < size; i++)
+ {
+ y = *spectrum;
+
+ for (j = 0; j < order; j++)
+ y -= MUL(lpc[j+1], state[j]);
+
+ for (j = order-1; j > 0; j--)
+ state[j] = state[j-1];
+
+ state[0] = y;
+ *spectrum = y;
+ spectrum += inc;
+ }
+}
+
+static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc,
+ uint8_t order)
+{
+ /*
+ - Simple all-zero filter of order "order" defined by
+ y(n) = x(n) + a(2)*x(n-1) + ... + a(order+1)*x(n-order)
+ - The state variables of the filter are initialized to zero every time
+ - The output data is written over the input data ("in-place operation")
+ - An input vector of "size" samples is processed and the index increment
+ to the next data sample is given by "inc"
+ */
+
+ uint8_t j;
+ uint16_t i;
+ real_t y, state[TNS_MAX_ORDER];
+
+ for (i = 0; i < order; i++)
+ state[i] = 0;
+
+ for (i = 0; i < size; i++)
+ {
+ y = *spectrum;
+
+ for (j = 0; j < order; j++)
+ y += MUL(lpc[j+1], state[j]);
+
+ for (j = order-1; j > 0; j--)
+ state[j] = state[j-1];
+
+ state[0] = *spectrum;
+ *spectrum = y;
+ spectrum += inc;
+ }
+}
+
+static uint8_t tns_max_bands_table[12][5] =
+{
+ /* entry for each sampling rate
+ * 1 Main/LC long window
+ * 2 Main/LC short window
+ * 3 SSR long window
+ * 4 SSR short window
+ * 5 LD 512 window
+ */
+ { 31, 9, 28, 7, 0 }, /* 96000 */
+ { 31, 9, 28, 7, 0 }, /* 88200 */
+ { 34, 10, 27, 7, 0 }, /* 64000 */
+ { 40, 14, 26, 6, 31 }, /* 48000 */
+ { 42, 14, 26, 6, 32 }, /* 44100 */
+ { 51, 14, 26, 6, 37 }, /* 32000 */
+ { 46, 14, 29, 7, 31 }, /* 24000 */
+ { 46, 14, 29, 7, 31 }, /* 22050 */
+ { 42, 14, 23, 8, 0 }, /* 16000 */
+ { 42, 14, 23, 8, 0 }, /* 12000 */
+ { 42, 14, 23, 8, 0 }, /* 11025 */
+ { 39, 14, 19, 7, 0 }, /* 8000 */
+};
+
+static uint8_t tns_max_bands(ic_stream *ics, uint8_t sr_index,
+ uint8_t object_type)
+{
+ uint8_t i;
+
+ i = (ics->window_sequence == EIGHT_SHORT_SEQUENCE) ? 1 : 0;
+#ifdef LD_DEC
+ if (object_type == LD)
+ i = 4;
+#endif
+
+ return tns_max_bands_table[sr_index][i];
+}
+
+static uint8_t tns_max_order(ic_stream *ics, uint8_t sr_index,
+ uint8_t object_type)
+{
+ /* Correction in 14496-3 Cor. 1
+ Works like MPEG2-AAC (13818-7) now
+
+ For other object types (scalable) the following goes for tns max order
+ for long windows:
+ if (sr_index <= 5)
+ return 12;
+ else
+ return 20;
+ */
+ if (ics->window_sequence != EIGHT_SHORT_SEQUENCE)
+ {
+ switch (object_type)
+ {
+ case MAIN:
+ return 20;
+ case LTP:
+ return 20;
+#ifdef LD_DEC
+ case LD:
+ return 20;
+#endif
+ case LC:
+ case SSR:
+ return 12;
+ }
+ } else {
+ return 7;
+ }
+
+ return 0;
+}
diff --git a/src/libfaad/tns.h b/src/libfaad/tns.h
new file mode 100644
index 000000000..2221b6926
--- /dev/null
+++ b/src/libfaad/tns.h
@@ -0,0 +1,52 @@
+/*
+** FAAD - Freeware Advanced Audio Decoder
+** Copyright (C) 2002 M. Bakker
+**
+** This program 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.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** $Id: tns.h,v 1.1 2002/07/14 23:43:02 miguelfreitas Exp $
+**/
+
+#ifndef __TNS_H__
+#define __TNS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define TNS_MAX_ORDER 20
+
+
+void tns_decode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index,
+ uint8_t object_type, real_t *spec, uint16_t frame_len);
+void tns_encode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index,
+ uint8_t object_type, real_t *spec, uint16_t frame_len);
+
+static void tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress,
+ uint8_t *coef, real_t *a);
+static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc,
+ uint8_t order);
+static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc,
+ uint8_t order);
+static uint8_t tns_max_bands(ic_stream *ics, uint8_t sr_index, uint8_t object_type);
+static uint8_t tns_max_order(ic_stream *ics, uint8_t sr_index,
+ uint8_t object_type);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/libfaad/xine_decoder.c b/src/libfaad/xine_decoder.c
new file mode 100644
index 000000000..32437fc71
--- /dev/null
+++ b/src/libfaad/xine_decoder.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2000-2002 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine 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.
+ *
+ * xine 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: xine_decoder.c,v 1.1 2002/07/14 23:43:02 miguelfreitas Exp $
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "audio_out.h"
+#include "buffer.h"
+#include "xine_internal.h"
+#include "xineutils.h"
+#include "faad.h"
+
+#define LOG
+
+typedef struct faad_decoder_s {
+ audio_decoder_t audio_decoder;
+
+ xine_t *xine;
+
+ /* faad2 stuff */
+ faacDecHandle faac_dec;
+ faacDecConfigurationPtr faac_cfg;
+ faacDecFrameInfo faac_finfo;
+ int faac_failed;
+
+ unsigned char *buf;
+ int size;
+ int rec_audio_src_size;
+ int max_audio_src_size;
+ int pts;
+
+ unsigned long rate;
+ int bits_per_sample;
+ unsigned char num_channels;
+ uint32_t ao_cap_mode;
+
+ ao_instance_t *audio_out;
+ int output_open;
+} faad_decoder_t;
+
+static int faad_can_handle (audio_decoder_t *this_gen, int buf_type) {
+ buf_type &= 0xFFFF0000;
+
+ return ( buf_type == BUF_AUDIO_AAC );
+}
+
+
+static void faad_reset (audio_decoder_t *this_gen) {
+
+ faad_decoder_t *this = (faad_decoder_t *) this_gen;
+ this->size = 0;
+}
+
+static void faad_init (audio_decoder_t *this_gen, ao_instance_t *audio_out) {
+
+ faad_decoder_t *this = (faad_decoder_t *) this_gen;
+
+ this->audio_out = audio_out;
+ this->output_open = 0;
+ this->faac_dec = NULL;
+ this->faac_failed = 0;
+ this->buf = NULL;
+}
+
+static int faad_open_dec( faad_decoder_t *this ) {
+ this->faac_dec = faacDecOpen();
+ if( !this->faac_dec ) {
+ xine_log (this->xine, XINE_LOG_MSG,
+ "libfaad: libfaad faacDecOpen() failed.\n" );
+ this->faac_failed++;
+ xine_report_codec( this->xine, XINE_CODEC_AUDIO, 0, BUF_AUDIO_AAC, 0);
+ return 1;
+ }
+
+ this->faac_cfg = faacDecGetCurrentConfiguration(this->faac_dec);
+ if( this->faac_cfg ) {
+ this->faac_cfg->defSampleRate = this->rate;
+ this->faac_cfg->outputFormat = FAAD_FMT_16BIT;
+ faacDecSetConfiguration(this->faac_dec, this->faac_cfg);
+ }
+ return 0;
+}
+
+static void faad_decode_audio ( faad_decoder_t *this ) {
+ int used, decoded, outsize;
+ uint8_t *sample_buffer;
+ audio_buffer_t *audio_buffer;
+
+ while( this->faac_dec && this->size >= this->rec_audio_src_size) {
+
+ sample_buffer = faacDecDecode(this->faac_dec,
+ &this->faac_finfo, this->buf);
+ used = this->faac_finfo.bytesconsumed;
+ decoded = this->faac_finfo.samples * 2; /* 1 sample = 2 bytes */
+
+#ifdef LOG
+// printf("libfaad: decoded %d/%d output %ld\n",
+// used, this->size, this->faac_finfo.samples );
+#endif
+
+ if (sample_buffer == NULL) {
+ printf("libfaad: %s\n", faacDecGetErrorMessage(this->faac_finfo.error));
+ used = 1;
+ }
+ else {
+ while( decoded ) {
+ audio_buffer = this->audio_out->get_buffer (this->audio_out);
+
+ if( decoded < audio_buffer->mem_size )
+ outsize = decoded;
+ else
+ outsize = audio_buffer->mem_size;
+
+ xine_fast_memcpy( audio_buffer->mem, sample_buffer, outsize );
+
+ audio_buffer->num_frames = outsize / (this->num_channels*2);
+ audio_buffer->vpts = this->pts;
+
+ this->audio_out->put_buffer (this->audio_out, audio_buffer);
+
+ this->pts = 0;
+ decoded -= outsize;
+ sample_buffer += outsize;
+ }
+ }
+
+ if(used >= this->size){
+ this->size = 0;
+ } else {
+ this->size -= used;
+ memmove( this->buf, &this->buf[used], this->size);
+ }
+ }
+}
+
+static void faad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
+
+ faad_decoder_t *this = (faad_decoder_t *) this_gen;
+ int used;
+
+ if (buf->decoder_flags & BUF_FLAG_PREVIEW)
+ return;
+
+/* if( !this->faac_dec && (buf->decoder_flags & BUF_FLAG_SPECIAL) &&
+ buf->decoder_info[1] == BUF_SPECIAL_ESDS ) {
+*/
+ if( !this->faac_dec ) {
+ /* hardcoded test stuff - demux_qt must send us that info */
+ static unsigned char tmp[4] = { 0x12, 0x90, 0x00, 0x18 };
+
+ this->faac_dec = faacDecOpen();
+ if( !this->faac_dec ) {
+ if( faad_open_dec(this) )
+ return;
+ }
+
+/* used = faacDecInit2(this->faac_dec, (void *)buf->decoder_info[3],
+ buf->decoder_info[2], &this->rate, &this->num_channels);
+*/
+ used = faacDecInit2(this->faac_dec, tmp,
+ 4, &this->rate, &this->num_channels);
+ if( used < 0 ) {
+ xine_log (this->xine, XINE_LOG_MSG,
+ "libfaad: libfaad faacDecInit2() failed.\n" );
+ this->faac_failed++;
+ faacDecClose(this->faac_dec);
+ this->faac_dec = NULL;
+ xine_report_codec( this->xine, XINE_CODEC_AUDIO, 0, buf->type, 0);
+ return;
+ }
+#ifdef LOG
+ printf("libfaad: faacDecInit2 returned rate=%ld channels=%d\n",
+ this->rate, this->num_channels );
+#endif
+ }
+
+ if (buf->decoder_flags & BUF_FLAG_HEADER) {
+
+ if (this->output_open)
+ this->audio_out->close (this->audio_out);
+
+ this->rate=buf->decoder_info[1];
+ this->bits_per_sample=buf->decoder_info[2] ;
+ this->num_channels=buf->decoder_info[3] ;
+ switch( this->num_channels ) {
+ case 1:
+ this->ao_cap_mode=AO_CAP_MODE_MONO;
+ break;
+ case 2:
+ this->ao_cap_mode=AO_CAP_MODE_STEREO;
+ break;
+ }
+ this->output_open = this->audio_out->open (this->audio_out,
+ this->bits_per_sample,
+ this->rate,
+ this->ao_cap_mode) ;
+
+ this->rec_audio_src_size = this->num_channels * FAAD_MIN_STREAMSIZE;
+ this->max_audio_src_size = 4 * this->rec_audio_src_size;
+
+ if( this->buf )
+ free(this->buf);
+ this->buf = malloc( this->max_audio_src_size );
+ this->size = 0;
+
+ if( this->faac_dec )
+ faacDecClose(this->faac_dec);
+ this->faac_dec = NULL;
+ this->faac_failed = 0;
+
+ } else if (this->output_open) {
+#ifdef LOG
+// printf ("faad: decoding %d data bytes...\n", buf->size);
+#endif
+
+ if( (int)buf->size <= 0 || this->faac_failed )
+ return;
+
+ if( !this->size )
+ this->pts = buf->pts;
+
+ if( this->size + buf->size > this->max_audio_src_size ) {
+ this->max_audio_src_size = this->size + 2 * buf->size;
+ printf("faad: increasing source buffer to %d to avoid overflow.\n",
+ this->max_audio_src_size);
+ this->buf = realloc( this->buf, this->max_audio_src_size );
+ }
+
+ memcpy (&this->buf[this->size], buf->content, buf->size);
+ this->size += buf->size;
+
+ if( !this->faac_dec ) {
+
+ this->faac_dec = faacDecOpen();
+ if( !this->faac_dec ) {
+ if( faad_open_dec(this) )
+ return;
+ }
+
+ used = faacDecInit(this->faac_dec, this->buf,
+ &this->rate, &this->num_channels);
+ if( used < 0 ) {
+ xine_log (this->xine, XINE_LOG_MSG,
+ "libfaad: libfaad faacDecInit() failed.\n" );
+ this->faac_failed++;
+ faacDecClose(this->faac_dec);
+ this->faac_dec = NULL;
+ xine_report_codec( this->xine, XINE_CODEC_AUDIO, 0, buf->type, 0);
+ return;
+ }
+#ifdef LOG
+ printf("libfaad: faacDecInit() returned rate=%ld channels=%d (used=%d)\n",
+ this->rate, this->num_channels, used);
+#endif
+
+ this->size -= used;
+ memmove(this->buf, &this->buf[used], this->size);
+ }
+ faad_decode_audio(this);
+ }
+}
+
+static void faad_close (audio_decoder_t *this_gen) {
+
+ faad_decoder_t *this = (faad_decoder_t *) this_gen;
+
+ if (this->output_open)
+ this->audio_out->close (this->audio_out);
+ this->output_open = 0;
+
+ if( this->buf )
+ free(this->buf);
+ this->buf = NULL;
+
+ if( this->faac_dec )
+ faacDecClose(this->faac_dec);
+ this->faac_dec = NULL;
+}
+
+static char *faad_get_id(void) {
+ return "faad";
+}
+
+static void faad_dispose (audio_decoder_t *this_gen) {
+ free (this_gen);
+}
+
+audio_decoder_t *init_audio_decoder_plugin (int iface_version, xine_t *xine) {
+
+ faad_decoder_t *this ;
+
+ if (iface_version != 9) {
+ printf(_("libfaad: plugin doesn't support plugin API version %d.\n"
+ "libfaad: this means there's a version mismatch between xine and this "
+ "libfaad: decoder plugin.\nInstalling current plugins should help.\n"),
+ iface_version);
+ return NULL;
+ }
+
+ this = (faad_decoder_t *) malloc (sizeof (faad_decoder_t));
+ this->xine = xine;
+
+ this->audio_decoder.interface_version = iface_version;
+ this->audio_decoder.can_handle = faad_can_handle;
+ this->audio_decoder.init = faad_init;
+ this->audio_decoder.decode_data = faad_decode_data;
+ this->audio_decoder.reset = faad_reset;
+ this->audio_decoder.close = faad_close;
+ this->audio_decoder.get_identifier = faad_get_id;
+ this->audio_decoder.dispose = faad_dispose;
+ this->audio_decoder.priority = 1;
+
+ return (audio_decoder_t *) this;
+}
+