From 53c5ec96b87ef2bb61c7d3188d549623495d4500 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Sun, 14 Jul 2002 23:43:01 +0000 Subject: 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 --- src/libfaad/Makefile.am | 51 ++ src/libfaad/analysis.h | 43 + src/libfaad/bits.c | 63 ++ src/libfaad/bits.h | 116 +++ src/libfaad/common.c | 32 + src/libfaad/common.h | 195 +++++ src/libfaad/data.c | 223 +++++ src/libfaad/data.h | 45 ++ src/libfaad/decoder.c | 855 ++++++++++++++++++++ src/libfaad/decoder.h | 146 ++++ src/libfaad/drc.c | 77 ++ src/libfaad/drc.h | 38 + src/libfaad/error.c | 38 + src/libfaad/error.h | 34 + src/libfaad/faad.h | 121 +++ src/libfaad/filtbank.c | 442 ++++++++++ src/libfaad/filtbank.h | 74 ++ src/libfaad/huffman.h | 279 +++++++ src/libfaad/ic_predict.c | 180 +++++ src/libfaad/ic_predict.h | 55 ++ src/libfaad/is.c | 69 ++ src/libfaad/is.h | 58 ++ src/libfaad/kbd_win.h | 1197 +++++++++++++++++++++++++++ src/libfaad/lt_predict.c | 134 ++++ src/libfaad/lt_predict.h | 55 ++ src/libfaad/mdct.c | 188 +++++ src/libfaad/mdct.h | 56 ++ src/libfaad/mp4.c | 174 ++++ src/libfaad/mp4.h | 44 + src/libfaad/ms.c | 66 ++ src/libfaad/ms.h | 35 + src/libfaad/output.c | 107 +++ src/libfaad/output.h | 40 + src/libfaad/pns.c | 120 +++ src/libfaad/pns.h | 51 ++ src/libfaad/pulse.c | 41 + src/libfaad/pulse.h | 34 + src/libfaad/reordered_spectral_data.c | 607 ++++++++++++++ src/libfaad/sbr_dec.c | 60 ++ src/libfaad/sbr_dec.h | 38 + src/libfaad/sbr_huff.c | 673 ++++++++++++++++ src/libfaad/sbr_huff.h | 58 ++ src/libfaad/sbr_qmf.c | 289 +++++++ src/libfaad/sbr_qmf.h | 41 + src/libfaad/sbr_syntax.c | 609 ++++++++++++++ src/libfaad/sbr_syntax.h | 115 +++ src/libfaad/specrec.c | 344 ++++++++ src/libfaad/specrec.h | 50 ++ src/libfaad/syntax.c | 1429 +++++++++++++++++++++++++++++++++ src/libfaad/syntax.h | 360 +++++++++ src/libfaad/tns.c | 315 ++++++++ src/libfaad/tns.h | 52 ++ src/libfaad/xine_decoder.c | 338 ++++++++ 53 files changed, 10954 insertions(+) create mode 100644 src/libfaad/Makefile.am create mode 100644 src/libfaad/analysis.h create mode 100644 src/libfaad/bits.c create mode 100644 src/libfaad/bits.h create mode 100644 src/libfaad/common.c create mode 100644 src/libfaad/common.h create mode 100644 src/libfaad/data.c create mode 100644 src/libfaad/data.h create mode 100644 src/libfaad/decoder.c create mode 100644 src/libfaad/decoder.h create mode 100644 src/libfaad/drc.c create mode 100644 src/libfaad/drc.h create mode 100644 src/libfaad/error.c create mode 100644 src/libfaad/error.h create mode 100644 src/libfaad/faad.h create mode 100644 src/libfaad/filtbank.c create mode 100644 src/libfaad/filtbank.h create mode 100644 src/libfaad/huffman.h create mode 100644 src/libfaad/ic_predict.c create mode 100644 src/libfaad/ic_predict.h create mode 100644 src/libfaad/is.c create mode 100644 src/libfaad/is.h create mode 100644 src/libfaad/kbd_win.h create mode 100644 src/libfaad/lt_predict.c create mode 100644 src/libfaad/lt_predict.h create mode 100644 src/libfaad/mdct.c create mode 100644 src/libfaad/mdct.h create mode 100644 src/libfaad/mp4.c create mode 100644 src/libfaad/mp4.h create mode 100644 src/libfaad/ms.c create mode 100644 src/libfaad/ms.h create mode 100644 src/libfaad/output.c create mode 100644 src/libfaad/output.h create mode 100644 src/libfaad/pns.c create mode 100644 src/libfaad/pns.h create mode 100644 src/libfaad/pulse.c create mode 100644 src/libfaad/pulse.h create mode 100644 src/libfaad/reordered_spectral_data.c create mode 100644 src/libfaad/sbr_dec.c create mode 100644 src/libfaad/sbr_dec.h create mode 100644 src/libfaad/sbr_huff.c create mode 100644 src/libfaad/sbr_huff.h create mode 100644 src/libfaad/sbr_qmf.c create mode 100644 src/libfaad/sbr_qmf.h create mode 100644 src/libfaad/sbr_syntax.c create mode 100644 src/libfaad/sbr_syntax.h create mode 100644 src/libfaad/specrec.c create mode 100644 src/libfaad/specrec.h create mode 100644 src/libfaad/syntax.c create mode 100644 src/libfaad/syntax.h create mode 100644 src/libfaad/tns.c create mode 100644 src/libfaad/tns.h create mode 100644 src/libfaad/xine_decoder.c 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 +#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 +#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 + +#endif + + +#ifndef USE_DOUBLE_PRECISION + + typedef float real_t; + + #define MUL(A,B) ((A)*(B)) + + #ifdef __ICL /* only Intel C compiler has fmath ??? */ + + #include + + #define sin sinf + #define cos cosf + #define log logf + #define exp expf + #define floor floorf + #define ceil ceilf + #define sqrt sqrtf + + #else + + #include + +#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 + + #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 +#include +#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 +#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 +#include +#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 +#ifdef ANALYSIS +#include +#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<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 +#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 +#include + +/* uses fftw (http://www.fftw.org) for very fast arbitrary-n FFT and IFFT */ +#include + + +#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 + +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 + 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 +#include +#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<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 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; sfbmax_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 +#include +#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<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 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 +#include +#include +#include +#include +#include +#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; +} + -- cgit v1.2.3