[Mplayer-cvslog] CVS: main/libfaad2 Makefile,NONE,1.1 README,NONE,1.1 analysis.h,NONE,1.1 bits.c,NONE,1.1 bits.h,NONE,1.1 cfft.c,NONE,1.1 cfft.h,NONE,1.1 cfft_tab.h,NONE,1.1 common.c,NONE,1.1 common.h,NONE,1.1 config.h,NONE,1.1 decoder.c,NONE,1.1 decoder.h,NONE,1.1 dither.c,NONE,1.1 dither.h,NONE,1.1 drc.c,NONE,1.1 drc.h,NONE,1.1 error.c,NONE,1.1 error.h,NONE,1.1 faad.h,NONE,1.1 filtbank.c,NONE,1.1 filtbank.h,NONE,1.1 fixed.h,NONE,1.1 hcr.c,NONE,1.1 huffman.h,NONE,1.1 ic_predict.c,NONE,1.1 ic_predict.h,NONE,1.1 iq_table.h,NONE,1.1 is.c,NONE,1.1 is.h,NONE,1.1 kbd_win.h,NONE,1.1 lt_predict.c,NONE,1.1 lt_predict.h,NONE,1.1 mdct.c,NONE,1.1 mdct.h,NONE,1.1 mp4.c,NONE,1.1 mp4.h,NONE,1.1 ms.c,NONE,1.1 ms.h,NONE,1.1 output.c,NONE,1.1 output.h,NONE,1.1 pns.c,NONE,1.1 pns.h,NONE,1.1 pulse.c,NONE,1.1 pulse.h,NONE,1.1 rvlc.c,NONE,1.1 rvlc.h,NONE,1.1 sbr_dct.c,NONE,1.1 sbr_dct.h,NONE,1.1 sbr_dec.c,NONE,1.1 sbr_dec.h,NONE,1.1 sbr_e_nf.c,NONE,1.1 sbr_e_nf.h,NONE,1.1 sbr_fbt.c,NONE,1.1 sbr_fbt.h,NONE,1.1 sbr_hfadj.c,NONE,1.1 sbr_hfadj.h,NONE,1.1 sbr_hfgen.c,NONE,1.1 sbr_hfgen.h,NONE,1.1 sbr_huff.c,NONE,1.1 sbr_huff.h,NONE,1.1 sbr_noise.h,NONE,1.1 sbr_qmf.c,NONE,1.1 sbr_qmf.h,NONE,1.1 sbr_syntax.c,NONE,1.1 sbr_syntax.h,NONE,1.1 sbr_tf_grid.c,NONE,1.1 sbr_tf_grid.h,NONE,1.1 sine_win.h,NONE,1.1 specrec.c,NONE,1.1 specrec.h,NONE,1.1 ssr.c,NONE,1.1 ssr.h,NONE,1.1 ssr_fb.c,NONE,1.1 ssr_fb.h,NONE,1.1 ssr_ipqf.c,NONE,1.1 ssr_ipqf.h,NONE,1.1 ssr_win.h,NONE,1.1 structs.h,NONE,1.1 syntax.c,NONE,1.1 syntax.h,NONE,1.1 tns.c,NONE,1.1 tns.h,NONE,1.1

Arpi of Ize arpi at mplayerhq.hu
Sun Aug 31 00:30:32 CEST 2003


Update of /cvsroot/mplayer/main/libfaad2
In directory mail:/var/tmp.root/cvs-serv32521

Added Files:
	Makefile README analysis.h bits.c bits.h cfft.c cfft.h 
	cfft_tab.h common.c common.h config.h decoder.c decoder.h 
	dither.c dither.h drc.c drc.h error.c error.h faad.h 
	filtbank.c filtbank.h fixed.h hcr.c huffman.h ic_predict.c 
	ic_predict.h iq_table.h is.c is.h kbd_win.h lt_predict.c 
	lt_predict.h mdct.c mdct.h mp4.c mp4.h ms.c ms.h output.c 
	output.h pns.c pns.h pulse.c pulse.h rvlc.c rvlc.h sbr_dct.c 
	sbr_dct.h sbr_dec.c sbr_dec.h sbr_e_nf.c sbr_e_nf.h sbr_fbt.c 
	sbr_fbt.h sbr_hfadj.c sbr_hfadj.h sbr_hfgen.c sbr_hfgen.h 
	sbr_huff.c sbr_huff.h sbr_noise.h sbr_qmf.c sbr_qmf.h 
	sbr_syntax.c sbr_syntax.h sbr_tf_grid.c sbr_tf_grid.h 
	sine_win.h specrec.c specrec.h ssr.c ssr.h ssr_fb.c ssr_fb.h 
	ssr_ipqf.c ssr_ipqf.h ssr_win.h structs.h syntax.c syntax.h 
	tns.c tns.h 
Log Message:
libfaad2 v2.0rc1 imported


--- NEW FILE ---

LIBNAME = libfaad2.a

include ../config.mak

SRCS    = bits.c cfft.c common.c decoder.c dither.c drc.c error.c filtbank.c hcr.c ic_predict.c is.c lt_predict.c mdct.c mp4.c ms.c output.c pns.c pulse.c rvlc.c sbr_dct.c sbr_dec.c sbr_e_nf.c sbr_fbt.c sbr_hfadj.c sbr_hfgen.c sbr_huff.c sbr_qmf.c sbr_syntax.c sbr_tf_grid.c specrec.c ssr.c ssr_fb.c ssr_ipqf.c syntax.c tns.c
OBJS	= $(SRCS:.c=.o)

CFLAGS  = -I. $(OPTFLAGS) 

.SUFFIXES: .c .o

# .PHONY: all clean

.c.o:
	$(CC) -c $(CFLAGS) -o $@ $<

$(LIBNAME):	$(OBJS)
	$(AR) r $(LIBNAME) $(OBJS)

all:	$(LIBNAME)

clean:
	rm -f *.o *.a *~

distclean:
	rm -f test *.o *.a *~ .depend

dep:    depend

depend:
	$(CC) -MM $(CFLAGS) $(SRCS) 1>.depend

#
# include dependency files if they exist
#
ifneq ($(wildcard .depend),)
include .depend
endif

--- NEW FILE ---
files from libfaad v2.0rc1 tarball's libfaad/ and include/ subdir

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: analysis.h,v 1.1 2003/08/30 22:30:21 arpi 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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: bits.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#include <stdlib.h>
#include <string.h>
#include "bits.h"

/* initialize buffer, call once before first getbits or showbits */
void faad_initbits(bitfile *ld, void *_buffer, uint32_t buffer_size)
{
    uint32_t tmp;

    ld->buffer = malloc((buffer_size+12)*sizeof(uint8_t));
    memset(ld->buffer, 0, (buffer_size+12)*sizeof(uint8_t));
    memcpy(ld->buffer, _buffer, buffer_size*sizeof(uint8_t));

    ld->buffer_size = buffer_size;

    tmp = getdword((uint32_t*)ld->buffer);
#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    ld->bufa = tmp;

    tmp = getdword((uint32_t*)ld->buffer + 1);
#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    ld->bufb = tmp;

    ld->start = (uint32_t*)ld->buffer;
    ld->tail = ((uint32_t*)ld->buffer + 2);

    ld->bits_left = 32;

    ld->bytes_used = 0;
    ld->no_more_reading = 0;
    ld->error = 0;
}

void faad_endbits(bitfile *ld)
{
    if (ld)
        if (ld->buffer) free(ld->buffer);
}


uint32_t faad_get_processed_bits(bitfile *ld)
{
    return 8 * (4*(ld->tail - ld->start) - 4) - (ld->bits_left);
}

uint8_t faad_byte_align(bitfile *ld)
{
    uint8_t remainder = (uint8_t)((32 - ld->bits_left) % 8);

    if (remainder)
    {
        faad_flushbits(ld, 8 - remainder);
        return (8 - remainder);
    }
    return 0;
}

/* rewind to beginning */
void faad_rewindbits(bitfile *ld)
{
    uint32_t tmp;

    tmp = ld->start[0];
#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    ld->bufa = tmp;

    tmp = ld->start[1];
#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    ld->bufb = tmp;
    ld->bits_left = 32;
    ld->tail = &ld->start[2];
    ld->bytes_used = 0;
    ld->no_more_reading = 0;
}

uint8_t *faad_getbitbuffer(bitfile *ld, uint32_t bits
                       DEBUGDEC)
{
    uint16_t i;
    uint8_t temp;
    uint16_t bytes = (uint16_t)bits / 8;
    uint8_t remainder = (uint8_t)bits % 8;

    uint8_t *buffer = (uint8_t*)malloc((bytes+1)*sizeof(uint8_t));

    for (i = 0; i < bytes; i++)
    {
        buffer[i] = (uint8_t)faad_getbits(ld, 8 DEBUGVAR(print,var,dbg));
    }

    if (remainder)
    {
        temp = (uint8_t)faad_getbits(ld, remainder DEBUGVAR(print,var,dbg)) << (8-remainder);

        buffer[bytes] = temp;
    }

    return buffer;
}

/* reversed bit reading routines, used for RVLC and HCR */
void faad_initbits_rev(bitfile *ld, void *buffer,
                       uint32_t bits_in_buffer)
{
    uint32_t tmp;
    int32_t index;

    ld->buffer_size = bit2byte(bits_in_buffer);

    index = (bits_in_buffer+31)/32 - 1;

    ld->start = (uint32_t*)buffer + index - 2;

    tmp = getdword((uint32_t*)buffer + index);
#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    ld->bufa = tmp;

    tmp = getdword((uint32_t*)buffer + index - 1);
#ifndef ARCH_IS_BIG_ENDIAN
    BSWAP(tmp);
#endif
    ld->bufb = tmp;

    ld->tail = (uint32_t*)buffer + index;

    ld->bits_left = bits_in_buffer % 32;
    if (ld->bits_left == 0)
        ld->bits_left = 32;

    ld->bytes_used = 0;
    ld->no_more_reading = 0;
    ld->error = 0;
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: bits.h,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#ifndef __BITS_H__
#define __BITS_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "analysis.h"
#ifdef ANALYSIS
#include <stdio.h>
#endif

#define BYTE_NUMBIT 8
#define bit2byte(a) ((a+7)/BYTE_NUMBIT)

typedef struct _bitfile
{
    /* bit input */
    uint32_t bufa;
    uint32_t bufb;
    uint32_t bits_left;
    uint32_t buffer_size; /* size of the buffer in bytes */
    uint32_t bytes_used;
    uint8_t no_more_reading;
    uint8_t error;
    uint32_t *tail;
    uint32_t *start;
    void *buffer;
} bitfile;


#if defined (_WIN32) && !defined(_WIN32_WCE)
#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

static uint32_t bitmask[] = {
    0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF,
    0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,
    0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF,
    0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF,
    0xFFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF
};

void faad_initbits(bitfile *ld, void *buffer, uint32_t buffer_size);
void faad_endbits(bitfile *ld);
void faad_initbits_rev(bitfile *ld, void *buffer,
                       uint32_t bits_in_buffer);
uint8_t faad_byte_align(bitfile *ld);
uint32_t faad_get_processed_bits(bitfile *ld);
void faad_rewindbits(bitfile *ld);
uint8_t *faad_getbitbuffer(bitfile *ld, uint32_t bits
                       DEBUGDEC);

/* circumvent memory alignment errors on ARM */
static INLINE uint32_t getdword(void *mem)
{
#ifdef ARM
    uint32_t tmp;
    ((uint8_t*)&tmp)[0] = ((uint8_t*)mem)[0];
    ((uint8_t*)&tmp)[1] = ((uint8_t*)mem)[1];
    ((uint8_t*)&tmp)[2] = ((uint8_t*)mem)[2];
    ((uint8_t*)&tmp)[3] = ((uint8_t*)mem)[3];

    return tmp;
#else
    return *(uint32_t*)mem;
#endif
}

static INLINE uint32_t faad_showbits(bitfile *ld, uint32_t bits)
{
    if (bits <= ld->bits_left)
    {
        return (ld->bufa >> (ld->bits_left - bits)) & bitmask[bits];
    } else {
        bits -= ld->bits_left;
        return ((ld->bufa & bitmask[ld->bits_left]) << bits) | (ld->bufb >> (32 - bits));
    }
}

static INLINE void faad_flushbits(bitfile *ld, uint32_t bits)
{
    /* do nothing if error */
    if (ld->error != 0)
        return;

    if (bits < ld->bits_left)
    {
        ld->bits_left -= bits;
    } else {
        uint32_t tmp;

        ld->bufa = ld->bufb;
        tmp = getdword(ld->tail);
        ld->tail++;
#ifndef ARCH_IS_BIG_ENDIAN
        BSWAP(tmp);
#endif
        ld->bufb = tmp;
        ld->bits_left += (32 - bits);
        ld->bytes_used += 4;
        if (ld->bytes_used == ld->buffer_size)
            ld->no_more_reading = 1;
        if (ld->bytes_used > ld->buffer_size)
            ld->error = 1;
    }
}

/* return next n bits (right adjusted) */
static INLINE uint32_t faad_getbits(bitfile *ld, uint32_t n DEBUGDEC)
{
    uint32_t ret;

    if (ld->no_more_reading)
        return 0;

    if (n == 0)
        return 0;

    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)
{
    uint8_t r;

    if (ld->bits_left == 0)
        return (uint8_t)faad_getbits(ld, 1 DEBUGVAR(print,var,dbg));

    ld->bits_left--;
    r = (uint8_t)((ld->bufa >> ld->bits_left) & 1);

    return r;
}

/* reversed bitreading routines */
static INLINE uint32_t faad_showbits_rev(bitfile *ld, uint32_t bits)
{
    uint8_t i;
    uint32_t B = 0;

    if (bits <= ld->bits_left)
    {
        for (i = 0; i < bits; i++)
        {
            if (ld->bufa & (1 << (i + (32 - ld->bits_left))))
                B |= (1 << (bits - i - 1));
        }
        return B;
    } else {
        for (i = 0; i < ld->bits_left; i++)
        {
            if (ld->bufa & (1 << (i + (32 - ld->bits_left))))
                B |= (1 << (bits - i - 1));
        }
        for (i = 0; i < bits - ld->bits_left; i++)
        {
            if (ld->bufb & (1 << (i + (32-ld->bits_left))))
                B |= (1 << (bits - ld->bits_left - i - 1));
        }
        return B;
    }
}

static INLINE void faad_flushbits_rev(bitfile *ld, uint32_t bits)
{
    /* do nothing if error */
    if (ld->error != 0)
        return;

    if (bits < ld->bits_left)
    {
        ld->bits_left -= bits;
    } else {
        uint32_t tmp;

        ld->bufa = ld->bufb;
        tmp = getdword(ld->start);
#ifndef ARCH_IS_BIG_ENDIAN
        BSWAP(tmp);
#endif
        ld->bufb = tmp;
        ld->start--;
        ld->bits_left += (32 - bits);

        ld->bytes_used += 4;
        if (ld->bytes_used == ld->buffer_size)
            ld->no_more_reading = 1;
        if (ld->bytes_used > ld->buffer_size)
            ld->error = 1;
    }
}

static INLINE uint32_t faad_getbits_rev(bitfile *ld, uint32_t n
                                        DEBUGDEC)
{
    uint32_t ret;

    if (ld->no_more_reading)
        return 0;

    if (n == 0)
        return 0;

    ret = faad_showbits_rev(ld, n);
    faad_flushbits_rev(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;
}


#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: cfft.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

/*
 * Algorithmically based on Fortran-77 FFTPACK
 * by Paul N. Swarztrauber(Version 4, 1985).
 *
 * Does even sized fft only
 */

/* isign is +1 for backward and -1 for forward transforms */

#include "common.h"
#include "structs.h"

#include <stdlib.h>
#ifdef _WIN32_WCE
#define assert(x)
#else
#include <assert.h>
#endif

#include "cfft.h"
#include "cfft_tab.h"


/*----------------------------------------------------------------------
   passf2, passf3, passf4, passf5. Complex FFT passes fwd and bwd.
  ----------------------------------------------------------------------*/

static void passf2(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
                   complex_t *wa, int8_t isign)
{
    uint16_t i, k, ah, ac;

    if (ido == 1)
    {
        for (k = 0; k < l1; k++)
        {
            ah = 2*k;
            ac = 4*k;

            RE(ch[ah]) = RE(cc[ac]) + RE(cc[ac+1]);
            IM(ch[ah]) = IM(cc[ac]) + IM(cc[ac+1]);
            RE(ch[ah+l1]) = RE(cc[ac]) - RE(cc[ac+1]);
            IM(ch[ah+l1]) = IM(cc[ac]) - IM(cc[ac+1]);
        }
    } else {
        for (k = 0; k < l1; k++)
        {
            ah = k*ido;
            ac = 2*k*ido;

            for (i = 0; i < ido; i++)
            {
                complex_t t2;

                RE(ch[ah]) = RE(cc[ac]) + RE(cc[ac+ido]);
                IM(ch[ah]) = IM(cc[ac]) + IM(cc[ac+ido]);

                RE(t2) = RE(cc[ac]) - RE(cc[ac+ido]);
                IM(t2) = IM(cc[ac]) - IM(cc[ac+ido]);

                RE(ch[ah+l1*ido]) = MUL_R_C(RE(t2),RE(wa[i])) - MUL_R_C(IM(t2),IM(wa[i]))*isign;
                IM(ch[ah+l1*ido]) = MUL_R_C(IM(t2),RE(wa[i])) + MUL_R_C(RE(t2),IM(wa[i]))*isign;
                ah++;
                ac++;
            }
        }
    }
}


static void passf3(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
                   complex_t *wa1, complex_t *wa2, int8_t isign)
{
    static real_t taur = COEF_CONST(-0.5);
    static real_t taui = COEF_CONST(0.866025403784439);
    uint16_t i, k, ac, ah;
    complex_t c2, c3, d2, d3, t2;

    if (ido == 1)
    {
        for (k = 0; k < l1; k++)
        {
            ac = 3*k+1;
            ah = k;

            RE(t2) = RE(cc[ac]) + RE(cc[ac+1]);
            IM(t2) = IM(cc[ac]) + IM(cc[ac+1]);
            RE(c2) = RE(cc[ac-1]) + MUL_R_C(RE(t2),taur);
            IM(c2) = IM(cc[ac-1]) + MUL_R_C(IM(t2),taur);

            RE(ch[ah]) = RE(cc[ac-1]) + RE(t2);
            IM(ch[ah]) = IM(cc[ac-1]) + IM(t2);

            RE(c3) = MUL_R_C((RE(cc[ac]) - RE(cc[ac+1])), taui)*isign;
            IM(c3) = MUL_R_C((IM(cc[ac]) - IM(cc[ac+1])), taui)*isign;

            RE(ch[ah+l1]) = RE(c2) - IM(c3);
            IM(ch[ah+l1]) = IM(c2) + RE(c3);
            RE(ch[ah+2*l1]) = RE(c2) + IM(c3);
            IM(ch[ah+2*l1]) = IM(c2) - RE(c3);
        }
    } else {
        for (k = 0; k < l1; k++)
        {
            for (i = 0; i < ido; i++)
            {
                ac = i + (3*k+1)*ido;
                ah = i + k * ido;

                RE(t2) = RE(cc[ac]) + RE(cc[ac+ido]);
                RE(c2) = RE(cc[ac-ido]) + MUL_R_C(RE(t2),taur);
                IM(t2) = IM(cc[ac]) + IM(cc[ac+ido]);
                IM(c2) = IM(cc[ac-ido]) + MUL_R_C(IM(t2),taur);

                RE(ch[ah]) = RE(cc[ac-ido]) + RE(t2);
                IM(ch[ah]) = IM(cc[ac-ido]) + IM(t2);

                RE(c3) = MUL_R_C((RE(cc[ac]) - RE(cc[ac+ido])), taui)*isign;
                IM(c3) = MUL_R_C((IM(cc[ac]) - IM(cc[ac+ido])), taui)*isign;

                RE(d2) = RE(c2) - IM(c3);
                IM(d3) = IM(c2) - RE(c3);
                RE(d3) = RE(c2) + IM(c3);
                IM(d2) = IM(c2) + RE(c3);

                RE(ch[ah+l1*ido]) = MUL_R_C(RE(d2),RE(wa1[i])) - MUL_R_C(IM(d2),IM(wa1[i]))*isign;
                IM(ch[ah+l1*ido]) = MUL_R_C(IM(d2),RE(wa1[i])) + MUL_R_C(RE(d2),IM(wa1[i]))*isign;
                RE(ch[ah+l1*2*ido]) = MUL_R_C(RE(d3),RE(wa2[i])) - MUL_R_C(IM(d3),IM(wa2[i]))*isign;
                IM(ch[ah+l1*2*ido]) = MUL_R_C(IM(d3),RE(wa2[i])) + MUL_R_C(RE(d3),IM(wa2[i]))*isign;
            }
        }
    }
}


static void passf4(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
                   complex_t *wa1, complex_t *wa2, complex_t *wa3, int8_t isign)
{
    uint16_t i, k, ac, ah;
    complex_t c2, c3, c4, t1, t2, t3, t4;

    if (ido == 1)
    {
        for (k = 0; k < l1; k++)
        {
            ac = 4*k;
            ah = k;

            RE(t2) = RE(cc[ac]) + RE(cc[ac+2]);
            IM(t2) = IM(cc[ac]) + IM(cc[ac+2]);
            RE(t3) = RE(cc[ac+1]) + RE(cc[ac+3]);
            IM(t3) = IM(cc[ac+1]) + IM(cc[ac+3]);
            RE(t1) = RE(cc[ac]) - RE(cc[ac+2]);
            IM(t1) = IM(cc[ac]) - IM(cc[ac+2]);
            RE(t4) = IM(cc[ac+3]) - IM(cc[ac+1]);
            IM(t4) = RE(cc[ac+1]) - RE(cc[ac+3]);

            RE(ch[ah]) = RE(t2) + RE(t3);
            IM(ch[ah]) = IM(t2) + IM(t3);
            RE(ch[ah+l1]) = RE(t1) + RE(t4)*isign;
            IM(ch[ah+l1]) = IM(t1) + IM(t4)*isign;
            RE(ch[ah+2*l1]) = RE(t2) - RE(t3);
            IM(ch[ah+2*l1]) = IM(t2) - IM(t3);
            RE(ch[ah+3*l1]) = RE(t1) - RE(t4)*isign;
            IM(ch[ah+3*l1]) = IM(t1) - IM(t4)*isign;
        }
    } else {
        for (k = 0; k < l1; k++)
        {
            for (i = 0; i < ido; i++)
            {
                ac = i + 4*k*ido;
                ah = i + k*ido;

                RE(t2) = RE(cc[ac]) + RE(cc[ac+2*ido]);
                IM(t2) = IM(cc[ac]) + IM(cc[ac+2*ido]);
                RE(t3) = RE(cc[ac+ido]) + RE(cc[ac+3*ido]);
                IM(t3) = IM(cc[ac+ido]) + IM(cc[ac+3*ido]);
                RE(t1) = RE(cc[ac]) - RE(cc[ac+2*ido]);
                IM(t1) = IM(cc[ac]) - IM(cc[ac+2*ido]);
                RE(t4) = IM(cc[ac+3*ido]) - IM(cc[ac+ido]);
                IM(t4) = RE(cc[ac+ido]) - RE(cc[ac+3*ido]);

                RE(ch[ah]) = RE(t2) + RE(t3);
                IM(ch[ah]) = IM(t2) + IM(t3);

                RE(c2) = RE(t1) + RE(t4)*isign;
                IM(c2) = IM(t1) + IM(t4)*isign;
                RE(c3) = RE(t2) - RE(t3);
                IM(c3) = IM(t2) - IM(t3);
                RE(c4) = RE(t1) - RE(t4)*isign;
                IM(c4) = IM(t1) - IM(t4)*isign;

                RE(ch[ah+l1*ido]) = MUL_R_C(RE(c2),RE(wa1[i])) - MUL_R_C(IM(c2),IM(wa1[i]))*isign;
                IM(ch[ah+l1*ido]) = MUL_R_C(IM(c2),RE(wa1[i])) + MUL_R_C(RE(c2),IM(wa1[i]))*isign;
                RE(ch[ah+2*l1*ido]) = MUL_R_C(RE(c3),RE(wa2[i])) - MUL_R_C(IM(c3),IM(wa2[i]))*isign;
                IM(ch[ah+2*l1*ido]) = MUL_R_C(IM(c3),RE(wa2[i])) + MUL_R_C(RE(c3),IM(wa2[i]))*isign;
                RE(ch[ah+3*l1*ido]) = MUL_R_C(RE(c4),RE(wa3[i])) - MUL_R_C(IM(c4),IM(wa3[i]))*isign;
                IM(ch[ah+3*l1*ido]) = MUL_R_C(IM(c4),RE(wa3[i])) + MUL_R_C(RE(c4),IM(wa3[i]))*isign;
            }
        }
    }
}


static void passf5(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
                   complex_t *wa1, complex_t *wa2, complex_t *wa3, complex_t *wa4,
                   int8_t isign)
{
    static real_t tr11 = COEF_CONST(0.309016994374947);
    static real_t ti11 = COEF_CONST(0.951056516295154);
    static real_t tr12 = COEF_CONST(-0.809016994374947);
    static real_t ti12 = COEF_CONST(0.587785252292473);
    uint16_t i, k, ac, ah;
    complex_t c2, c3, c4, c5, d3, d4, d5, d2, t2, t3, t4, t5;

    if (ido == 1)
    {
        for (k = 0; k < l1; k++)
        {
            ac = 5*k + 1;
            ah = k;

            RE(t2) = RE(cc[ac]) + RE(cc[ac+3]);
            IM(t2) = IM(cc[ac]) + IM(cc[ac+3]);
            RE(t3) = RE(cc[ac+1]) + RE(cc[ac+2]);
            IM(t3) = IM(cc[ac+1]) + IM(cc[ac+2]);
            RE(t4) = RE(cc[ac+1]) - RE(cc[ac+2]);
            IM(t4) = IM(cc[ac+1]) - IM(cc[ac+2]);
            RE(t5) = RE(cc[ac]) - RE(cc[ac+3]);
            IM(t5) = IM(cc[ac]) - IM(cc[ac+3]);

            RE(ch[ah]) = RE(cc[ac-1]) + RE(t2) + RE(t3);
            IM(ch[ah]) = IM(cc[ac-1]) + IM(t2) + IM(t3);

            RE(c2) = RE(cc[ac-1]) + MUL_R_C(RE(t2),tr11) + MUL_R_C(RE(t3),tr12);
            IM(c2) = IM(cc[ac-1]) + MUL_R_C(IM(t2),tr11) + MUL_R_C(IM(t3),tr12);
            RE(c3) = RE(cc[ac-1]) + MUL_R_C(RE(t2),tr12) + MUL_R_C(RE(t3),tr11);
            IM(c3) = IM(cc[ac-1]) + MUL_R_C(IM(t2),tr12) + MUL_R_C(IM(t3),tr11);
            RE(c4) = (MUL_R_C(RE(t5),ti12)*isign - MUL_R_C(RE(t4),ti11));
            IM(c4) = (MUL_R_C(IM(t5),ti12)*isign - MUL_R_C(IM(t4),ti11));
            RE(c5) = (MUL_R_C(RE(t5),ti11)*isign + MUL_R_C(RE(t4),ti12));
            IM(c5) = (MUL_R_C(IM(t5),ti11)*isign + MUL_R_C(IM(t4),ti12));

            RE(ch[ah+l1]) = RE(c2) - IM(c5);
            IM(ch[ah+l1]) = IM(c2) + RE(c5);
            RE(ch[ah+2*l1]) = RE(c3) - IM(c4);
            IM(ch[ah+2*l1]) = IM(c3) + RE(c4);
            RE(ch[ah+3*l1]) = RE(c3) + IM(c4);
            IM(ch[ah+3*l1]) = IM(c3) - RE(c4);
            RE(ch[ah+4*l1]) = RE(c2) + IM(c5);
            IM(ch[ah+4*l1]) = IM(c2) - RE(c5);
        }
    } else {
        for (k = 0; k < l1; k++)
        {
            for (i = 0; i < ido; i++)
            {
                ac = i + (k*5 + 1) * ido;
                ah = i + k * ido;

                RE(t2) = RE(cc[ac]) + RE(cc[ac+3*ido]);
                IM(t2) = IM(cc[ac]) + IM(cc[ac+3*ido]);
                RE(t3) = RE(cc[ac+ido]) + RE(cc[ac+2*ido]);
                IM(t3) = IM(cc[ac+ido]) + IM(cc[ac+2*ido]);
                RE(t4) = RE(cc[ac+ido]) - RE(cc[ac+2*ido]);
                IM(t4) = IM(cc[ac+ido]) - IM(cc[ac+2*ido]);
                RE(t5) = RE(cc[ac]) - RE(cc[ac+3*ido]);
                IM(t5) = IM(cc[ac]) - IM(cc[ac+3*ido]);

                RE(ch[ah]) = RE(cc[ac-ido]) + RE(t2) + RE(t3);
                IM(ch[ah]) = IM(cc[ac-ido]) + IM(t2) + IM(t3);

                RE(c2) = RE(cc[ac-ido]) + MUL_R_C(RE(t2),tr11) + MUL_R_C(RE(t3),tr12);
                IM(c2) = IM(cc[ac-ido]) + MUL_R_C(IM(t2),tr11) + MUL_R_C(IM(t3),tr12);
                RE(c3) = RE(cc[ac-ido]) + MUL_R_C(RE(t2),tr12) + MUL_R_C(RE(t3),tr11);
                IM(c3) = IM(cc[ac-ido]) + MUL_R_C(IM(t2),tr12) + MUL_R_C(IM(t3),tr11);
                RE(c4) = (MUL_R_C(RE(t5),ti12)*isign - MUL_R_C(RE(t4),ti11));
                IM(c4) = (MUL_R_C(IM(t5),ti12)*isign - MUL_R_C(IM(t4),ti11));
                RE(c5) = (MUL_R_C(RE(t5),ti11)*isign + MUL_R_C(RE(t4),ti12));
                IM(c5) = (MUL_R_C(IM(t5),ti11)*isign + MUL_R_C(IM(t4),ti12));

                IM(d2) = IM(c2) + RE(c5);
                IM(d3) = IM(c3) + RE(c4);
                RE(d4) = RE(c3) + IM(c4);
                RE(d5) = RE(c2) + IM(c5);
                RE(d2) = RE(c2) - IM(c5);
                IM(d5) = IM(c2) - RE(c5);
                RE(d3) = RE(c3) - IM(c4);
                IM(d4) = IM(c3) - RE(c4);

                RE(ch[ah+l1*ido]) = MUL_R_C(RE(d2),RE(wa1[i])) - MUL_R_C(IM(d2),IM(wa1[i]))*isign;
                IM(ch[ah+l1*ido]) = MUL_R_C(IM(d2),RE(wa1[i])) + MUL_R_C(RE(d2),IM(wa1[i]))*isign;
                RE(ch[ah+2*l1*ido]) = MUL_R_C(RE(d3),RE(wa2[i])) - MUL_R_C(IM(d3),IM(wa2[i]))*isign;
                IM(ch[ah+2*l1*ido]) = MUL_R_C(IM(d3),RE(wa2[i])) + MUL_R_C(RE(d3),IM(wa2[i]))*isign;
                RE(ch[ah+3*l1*ido]) = MUL_R_C(RE(d4),RE(wa3[i])) - MUL_R_C(IM(d4),IM(wa3[i]))*isign;
                IM(ch[ah+3*l1*ido]) = MUL_R_C(IM(d4),RE(wa3[i])) + MUL_R_C(RE(d4),IM(wa3[i]))*isign;
                RE(ch[ah+4*l1*ido]) = MUL_R_C(RE(d5),RE(wa4[i])) - MUL_R_C(IM(d5),IM(wa4[i]))*isign;
                IM(ch[ah+4*l1*ido]) = MUL_R_C(IM(d5),RE(wa4[i])) + MUL_R_C(RE(d5),IM(wa4[i]))*isign;
            }
        }
    }
}


/*----------------------------------------------------------------------
   cfftf1, cfftf, cfftb, cffti1, cffti. Complex FFTs.
  ----------------------------------------------------------------------*/

INLINE void cfftf1(uint16_t n, complex_t *c, complex_t *ch,
                   uint16_t *ifac, complex_t *wa, int8_t isign)
{
    uint16_t i;
    uint16_t k1, l1, l2;
    uint16_t na, nf, ip, iw, ix2, ix3, ix4, ido, idl1;

    nf = ifac[1];
    na = 0;
    l1 = 1;
    iw = 0;

    for (k1 = 2; k1 <= nf+1; k1++)
    {
        ip = ifac[k1];
        l2 = ip*l1;
        ido = n / l2;
        idl1 = ido*l1;

        switch (ip)
        {
        case 2:
            if (na == 0)
                passf2(ido, l1, c, ch, &wa[iw], isign);
            else
                passf2(ido, l1, ch, c, &wa[iw], isign);

            na = 1 - na;
            break;
        case 3:
            ix2 = iw + ido;

            if (na == 0)
                passf3(ido, l1, c, ch, &wa[iw], &wa[ix2], isign);
            else
                passf3(ido, l1, ch, c, &wa[iw], &wa[ix2], isign);

            na = 1 - na;
            break;
        case 4:
            ix2 = iw + ido;
            ix3 = ix2 + ido;

            if (na == 0)
                passf4(ido, l1, c, ch, &wa[iw], &wa[ix2], &wa[ix3], isign);
            else
                passf4(ido, l1, ch, c, &wa[iw], &wa[ix2], &wa[ix3], isign);

            na = 1 - na;
            break;
        case 5:
            ix2 = iw + ido;
            ix3 = ix2 + ido;
            ix4 = ix3 + ido;

            if (na == 0)
                passf5(ido, l1, c, ch, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign);
            else
                passf5(ido, l1, ch, c, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign);

            na = 1 - na;
            break;
        }

        l1 = l2;
        iw += (ip-1) * ido;
    }

    if (na == 0)
        return;

    for (i = 0; i < n; i++)
    {
        RE(c[i]) = RE(ch[i]);
        IM(c[i]) = IM(ch[i]);
    }
}

void cfftf(cfft_info *cfft, complex_t *c)
{
    cfftf1(cfft->n, c, cfft->work, cfft->ifac, cfft->tab, -1);
}

void cfftb(cfft_info *cfft, complex_t *c)
{
    cfftf1(cfft->n, c, cfft->work, cfft->ifac, cfft->tab, +1);
}

static void cffti1(uint16_t n, complex_t *wa, uint16_t *ifac)
{
    static uint16_t ntryh[4] = {3, 4, 2, 5};
#ifndef FIXED_POINT
    real_t arg, argh, argld, fi;
    uint16_t ido, ipm;
    uint16_t i1, k1, l1, l2;
    uint16_t ld, ii, ip;
#endif
    uint16_t ntry, i, j;
    uint16_t ib;
    uint16_t nf, nl, nq, nr;

    nl = n;
    nf = 0;
    j = 0;

startloop:
    j++;

    if (j <= 4)
        ntry = ntryh[j-1];
    else
        ntry += 2;

    do
    {
        nq = nl / ntry;
        nr = nl - ntry*nq;

        if (nr != 0)
            goto startloop;

        nf++;
        ifac[nf+1] = ntry;
        nl = nq;

        if (ntry == 2 && nf != 1)
        {
            for (i = 2; i <= nf; i++)
            {
                ib = nf - i + 2;
                ifac[ib+1] = ifac[ib];
            }
            ifac[2] = 2;
        }
    } while (nl != 1);

    ifac[0] = n;
    ifac[1] = nf;

#ifndef FIXED_POINT
    argh = 2.0*M_PI / (real_t)n;
    i = 0;
    l1 = 1;

    for (k1 = 1; k1 <= nf; k1++)
    {
        ip = ifac[k1+1];
        ld = 0;
        l2 = l1*ip;
        ido = n / l2;
        ipm = ip - 1;

        for (j = 0; j < ipm; j++)
        {
            i1 = i;
            RE(wa[i]) = 1.0;
            IM(wa[i]) = 0.0;
            ld += l1;
            fi = 0;
            argld = ld*argh;

            for (ii = 0; ii < ido; ii++)
            {
                i++;
                fi++;
                arg = fi * argld;
                RE(wa[i]) = cos(arg);
                IM(wa[i]) = sin(arg);
            }

            if (ip > 5)
            {
                RE(wa[i1]) = RE(wa[i]);
                IM(wa[i1]) = IM(wa[i]);
            }
        }
        l1 = l2;
    }
#endif
}

cfft_info *cffti(uint16_t n)
{
    cfft_info *cfft = (cfft_info*)malloc(sizeof(cfft_info));

    cfft->n = n;
    cfft->work = (complex_t*)malloc(n*sizeof(complex_t));

#ifndef FIXED_POINT
    cfft->tab = (complex_t*)malloc(n*sizeof(complex_t));

    cffti1(n, cfft->tab, cfft->ifac);
#else
    cffti1(n, NULL, cfft->ifac);

    switch (n)
    {
    case 60: cfft->tab = cfft_tab_60; break;
    case 64: cfft->tab = cfft_tab_64; break;
    case 480: cfft->tab = cfft_tab_480; break;
    case 512: cfft->tab = cfft_tab_512; break;
#ifdef LD_DEC
    case 240: cfft->tab = cfft_tab_240; break;
    case 256: cfft->tab = cfft_tab_256; break;
#endif
    }
#endif

    return cfft;
}

void cfftu(cfft_info *cfft)
{
    if (cfft->work) free(cfft->work);
#ifndef FIXED_POINT
    if (cfft->tab) free(cfft->tab);
#endif

    if (cfft) free(cfft);
}
--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: cfft.h,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#ifndef __CFFT_H__
#define __CFFT_H__

#ifdef __cplusplus
extern "C" {
#endif


void cfftf(cfft_info *cfft, complex_t *c);
void cfftb(cfft_info *cfft, complex_t *c);
cfft_info *cffti(uint16_t n);
void cfftu(cfft_info *cfft);


static void passf2(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
                   complex_t *wa, int8_t isign);
static void passf3(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
                   complex_t *wa1, complex_t *wa2, int8_t isign);
static void passf4(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
                   complex_t *wa1, complex_t *wa2, complex_t *wa3, int8_t isign);
static void passf5(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
                   complex_t *wa1, complex_t *wa2, complex_t *wa3, complex_t *wa4,
                   int8_t isign);
INLINE void cfftf1(uint16_t n, complex_t *c, complex_t *ch,
                   uint16_t *ifac, complex_t *wa, int8_t isign);
static void cffti1(uint16_t n, complex_t *wa, uint16_t *ifac);


#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
[...1643 lines suppressed...]
    { 0x10000000, 0x0 },
    { 0x9679180, 0xCF1BBD0 },
    { 0xFB0E4428, 0xF378700 },
    { 0xF0C878E0, 0x4F1BB98 },
    { 0xF30E4440, 0xF6986E60 },
    { 0x10000000, 0x0 },
    { 0x10000000, 0x0 },
    { 0x10000000, 0x0 },
    { 0x10000000, 0x0 },
    { 0x4F1BBF0, 0xF0C87900 }
};

#endif

#endif

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: common.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

/* just some common functions that could be used anywhere */

#include "common.h"
#include "structs.h"

#include "syntax.h"

/* Returns the sample rate index based on the samplerate */
uint8_t get_sr_index(uint32_t samplerate)
{
    if (16428320 <= samplerate) return 11;
    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 */
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:
#ifdef SSR_DEC
        return 0;
#else
        return -1;
#endif
    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;
}

static const  uint8_t    Parity [256] = {  // parity
	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
};

static uint32_t  __r1 = 1;
static uint32_t  __r2 = 1;


/*
 *  This is a simple random number generator with good quality for audio purposes.
 *  It consists of two polycounters with opposite rotation direction and different
 *  periods. The periods are coprime, so the total period is the product of both.
 *
 *     -------------------------------------------------------------------------------------------------
 * +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0|
 * |   -------------------------------------------------------------------------------------------------
 * |                                                                          |  |  |  |     |        |
 * |                                                                          +--+--+--+-XOR-+--------+
 * |                                                                                      |
 * +--------------------------------------------------------------------------------------+
 *
 *     -------------------------------------------------------------------------------------------------
 *     |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+
 *     -------------------------------------------------------------------------------------------------   |
 *       |  |           |  |                                                                               |
 *       +--+----XOR----+--+                                                                               |
 *                |                                                                                        |
 *                +----------------------------------------------------------------------------------------+
 *
 *
 *  The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481,
 *  which gives a period of 18.410.713.077.675.721.215. The result is the
 *  XORed values of both generators.
 */
uint32_t random_int(void)
{
    static const uint32_t rnd_seed = 16428320;
	uint32_t  t1, t2, t3, t4;

	t3   = t1 = __r1;   t4   = t2 = __r2;       // Parity calculation is done via table lookup, this is also available
	t1  &= 0xF5;        t2 >>= 25;              // on CPUs without parity, can be implemented in C and avoid unpredictable
	t1   = Parity [t1]; t2  &= 0x63;            // jumps and slow rotate through the carry flag operations.
	t1 <<= 31;          t2   = Parity [t2];

	return (__r1 = (t3 >> 1) | t1 ) ^ (__r2 = (t4 + t4) | t2 );
}

#define LOG2 0.30102999566398

int32_t int_log2(int32_t val)
{
    return (int32_t)ceil(log(val)/log(2));
}


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: common.h,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#ifndef __COMMON_H__
#define __COMMON_H__

#ifdef __cplusplus
extern "C" {
#endif

#  include "../config.h"

#define INLINE __inline

#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif


/* COMPILE TIME DEFINITIONS */

/* use double precision */
/* #define USE_DOUBLE_PRECISION */
/* use fixed point reals */
//#define FIXED_POINT

#define ERROR_RESILIENCE


/* Allow decoding of MAIN profile AAC */
#define MAIN_DEC
/* Allow decoding of SSR profile AAC */
//#define SSR_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


#define SBR_DEC
//#define SBR_LOW_POWER

#ifdef FIXED_POINT
#ifndef SBR_LOW_POWER
#define SBR_LOW_POWER
#endif
#endif

#ifdef FIXED_POINT
#define SBR_DIV(A, B) (((int64_t)A << REAL_BITS)/B)
#else
#define SBR_DIV(A, B) ((A)/(B))
#endif

#ifndef SBR_LOW_POWER
#define qmf_t complex_t
#define QMF_RE(A) RE(A)
#define QMF_IM(A) IM(A)
#else
#define qmf_t real_t
#define QMF_RE(A) (A)
#define QMF_IM(A) 0
#endif


/* END COMPILE TIME DEFINITIONS */

#ifndef FIXED_POINT
#define POW_TABLE_SIZE 200
#endif


#if defined(_WIN32)


typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t;
typedef __int64 int64_t;
typedef __int32 int32_t;
typedef __int16 int16_t;
typedef __int8  int8_t;
typedef float float32_t;


#else

/* Define if needed */
/* #undef HAVE_FLOAT32_T */

/* Define if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

/* Define if you have the `memcpy' function. */
#define HAVE_MEMCPY 1

/* Define if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

/* Define if you have the `strchr' function. */
#define HAVE_STRCHR 1

/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1



#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#if STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif
#if HAVE_STRING_H
# if !STDC_HEADERS && HAVE_MEMORY_H
#  include <memory.h>
# endif
# include <string.h>
#endif
#if HAVE_STRINGS_H
# include <strings.h>
#endif
#if HAVE_INTTYPES_H
# include <inttypes.h>
#else
# if HAVE_STDINT_H
#  include <stdint.h>
# else
/* we need these... */
typedef unsigned long long uint64_t;
typedef unsigned long uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef long long int64_t;
typedef long int32_t;
typedef short int16_t;
typedef char int8_t;
# endif
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif

#ifndef HAVE_FLOAT32_T
typedef float float32_t;
#endif

#if STDC_HEADERS
# include <string.h>
#else
# if !HAVE_STRCHR
#  define strchr index
#  define strrchr rindex
# endif
char *strchr(), *strrchr();
# if !HAVE_MEMCPY
#  define memcpy(d, s, n) bcopy((s), (d), (n))
#  define memmove(d, s, n) bcopy((s), (d), (n))
# endif
#endif

#endif

#ifdef WORDS_BIGENDIAN
#define ARCH_IS_BIG_ENDIAN
#endif

/* FIXED_POINT doesn't work with MAIN and SSR yet */
#ifdef FIXED_POINT
  #undef MAIN_DEC
  #undef SSR_DEC
#endif


#if defined(FIXED_POINT)

  #ifdef HAS_MATHF_H
    #include <mathf.h>
  #else
    #include <math.h>
  #endif

  #include "fixed.h"

#elif defined(USE_DOUBLE_PRECISION)

  typedef double real_t;

  #include <math.h>

  #define MUL(A,B) ((A)*(B))
  #define MUL_C_C(A,B) ((A)*(B))
  #define MUL_R_C(A,B) ((A)*(B))

  #define REAL_CONST(A) ((real_t)A)
  #define COEF_CONST(A) ((real_t)A)

#else /* Normal floating point operation */

  typedef float real_t;

  #define MUL(A,B) ((A)*(B))
  #define MUL_C_C(A,B) ((A)*(B))
  #define MUL_R_C(A,B) ((A)*(B))

  #define REAL_CONST(A) ((real_t)A)
  #define COEF_CONST(A) ((real_t)A)

  #ifdef __ICL /* only Intel C compiler has fmath ??? */

    #include <mathf.h>

    #define sin sinf
    #define cos cosf
    #define log logf
    #define floor floorf
    #define ceil ceilf
    #define sqrt sqrtf

  #else

    #include <math.h>

#ifdef HAVE_SINF
#  define sin sinf
#error
#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_CEILF
#  define ceil ceilf
#endif
#ifdef HAVE_SQRTF
#  define sqrt sqrtf
#endif

  #endif

#endif

typedef real_t complex_t[2];
#define RE(A) A[0]
#define IM(A) A[1]


/* common functions */
int32_t int_log2(int32_t val);
uint32_t random_int(void);
uint8_t get_sr_index(uint32_t samplerate);
int8_t can_decode_ot(uint8_t object_type);

#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

--- NEW FILE ---
/* config.h.  Generated automatically by configure.  */
/* config.h.in.  Generated automatically from configure.in by autoheader.  */

/* Define if needed */
/* #undef HAVE_FLOAT32_T */

/* Define if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

/* Define if you have the `memcpy' function. */
#define HAVE_MEMCPY 1

/* Define if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

/* Define if you have the `strchr' function. */
#define HAVE_STRCHR 1

/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define if your processor stores words with the most significant byte first
   (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */

/* Define as `__inline' if that's what the C compiler calls it, or to nothing
   if it is not supported. */
/* #undef inline */

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
[...1083 lines suppressed...]
    if (ld) free(ld);

    /* cleanup */
    for (ch = 0; ch < channels; ch++)
    {
        if (spec_coef[ch]) free(spec_coef[ch]);
        if (spec_data[ch]) free(spec_data[ch]);
    }

    for (i = 0; i < ch_ele; i++)
    {
        if (syntax_elements[i]) free(syntax_elements[i]);
    }

#ifdef ANALYSIS
    fflush(stdout);
#endif

    return NULL;
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: decoder.h,v 1.1 2003/08/30 22:30:21 arpi 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 "drc.h"
#include "specrec.h"
#include "filtbank.h"
#include "ic_predict.h"


/* library output formats */
#define FAAD_FMT_16BIT  1
#define FAAD_FMT_24BIT  2
#define FAAD_FMT_32BIT  3
#define FAAD_FMT_FLOAT  4
#define FAAD_FMT_DOUBLE 5
#define FAAD_FMT_16BIT_DITHER  6
#define FAAD_FMT_16BIT_L_SHAPE 7
#define FAAD_FMT_16BIT_M_SHAPE 8
#define FAAD_FMT_16BIT_H_SHAPE 9

#define FAAD_FMT_DITHER_LOWEST FAAD_FMT_16BIT_DITHER

#define LC_DEC_CAP            (1<<0)
#define MAIN_DEC_CAP          (1<<1)
#define LTP_DEC_CAP           (1<<2)
#define LD_DEC_CAP            (1<<3)
#define ERROR_RESILIENCE_CAP  (1<<4)
#define FIXED_POINT_CAP       (1<<5)

#define FRONT_CHANNEL_CENTER (1)
#define FRONT_CHANNEL_LEFT   (2)
#define FRONT_CHANNEL_RIGHT  (3)
#define SIDE_CHANNEL_LEFT    (4)
#define SIDE_CHANNEL_RIGHT   (5)
#define BACK_CHANNEL_LEFT    (6)
#define BACK_CHANNEL_RIGHT   (7)
#define BACK_CHANNEL_CENTER  (8)
#define LFE_CHANNEL          (9)
#define UNKNOWN_CHANNEL      (0)

int8_t* FAADAPI faacDecGetErrorMessage(uint8_t errcode);

uint32_t FAADAPI faacDecGetCapabilities();

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 buffer_size,
                            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);

/* Init the library for DRM */
int8_t FAADAPI faacDecInitDRM(faacDecHandle hDecoder, uint32_t samplerate,
                              uint8_t channels);

void FAADAPI faacDecClose(faacDecHandle hDecoder);

void* FAADAPI faacDecDecode(faacDecHandle hDecoder,
                            faacDecFrameInfo *hInfo,
                            uint8_t *buffer,
                            uint32_t buffer_size);

element *decode_sce_lfe(faacDecHandle hDecoder,
                        faacDecFrameInfo *hInfo, bitfile *ld,
                        int16_t **spec_data, real_t **spec_coef,
                        uint8_t id_syn_ele);
element *decode_cpe(faacDecHandle hDecoder,
                    faacDecFrameInfo *hInfo, bitfile *ld,
                    int16_t **spec_data, real_t **spec_coef,
                    uint8_t id_syn_ele);
element **raw_data_block(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
                         bitfile *ld, element **elements,
                         int16_t **spec_data, real_t **spec_coef,
                         program_config *pce, drc_info *drc);

#ifdef _WIN32
  #pragma pack(pop)
#endif

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/* This program is licensed under the GNU Library General Public License, version 2,
 * a copy of which is included with this program (with filename LICENSE.LGPL).
 *
 * (c) 2002 John Edwards
 * mostly lifted from work by Frank Klemm
 * random functions for dithering.
 *
 * last modified:
 * $Id: dither.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
 */
#include "common.h"

#ifndef FIXED_POINT

#include <string.h>
#include "dither.h"
#include "common.h"


double
Random_Equi ( double mult )                     // gives a equal distributed random number
{                                               // between -2^31*mult and +2^31*mult
	return mult * (int) random_int ();
}

double
Random_Triangular ( double mult )               // gives a triangular distributed random number
{                                               // between -2^32*mult and +2^32*mult
	return mult * ( (double) (int) random_int () + (double) (int) random_int () );
}

/*********************************************************************************************************************/

static const float32_t  F44_0 [16 + 32] = {
	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,

	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,

	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
	(float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0
};


static const float32_t  F44_1 [16 + 32] = {  /* SNR(w) = 4.843163 dB, SNR = -3.192134 dB */
	(float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
	(float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
	(float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
	(float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,

	(float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
	(float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
	(float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
	(float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,

	(float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
	(float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
	(float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
	(float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
};


static const float32_t  F44_2 [16 + 32] = {  /* SNR(w) = 10.060213 dB, SNR = -12.766730 dB */
	(float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
	(float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
	(float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
	(float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,

	(float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
	(float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
	(float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
	(float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,

	(float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
	(float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
	(float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
	(float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
};


static const float32_t  F44_3 [16 + 32] = {  /* SNR(w) = 15.382598 dB, SNR = -29.402334 dB */
	(float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
	(float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
	(float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
	(float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099,

	(float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
	(float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
	(float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
	(float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099,

	(float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
	(float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
	(float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
	(float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099
};


double
scalar16 ( const float32_t* x, const float32_t* y )
{
	return x[ 0]*y[ 0] + x[ 1]*y[ 1] + x[ 2]*y[ 2] + x[ 3]*y[ 3]
	     + x[ 4]*y[ 4] + x[ 5]*y[ 5] + x[ 6]*y[ 6] + x[ 7]*y[ 7]
	     + x[ 8]*y[ 8] + x[ 9]*y[ 9] + x[10]*y[10] + x[11]*y[11]
	     + x[12]*y[12] + x[13]*y[13] + x[14]*y[14] + x[15]*y[15];
}


void
Init_Dither ( unsigned char bits, unsigned char shapingtype )
{
	static uint8_t          default_dither [] = { 92, 92, 88, 84, 81, 78, 74, 67,  0,  0 };
	static const float32_t*              F [] = { F44_0, F44_1, F44_2, F44_3 };
	uint8_t                 index;

	if (shapingtype > 3) shapingtype = 3;
	index = bits - 11 - shapingtype;
	if (index > 9) index = 9;

	memset ( Dither.ErrorHistory , 0, sizeof (Dither.ErrorHistory ) );
	memset ( Dither.DitherHistory, 0, sizeof (Dither.DitherHistory) );

	Dither.FilterCoeff = F [shapingtype];
	Dither.Mask   = ((uint64_t)-1) << (32 - bits);
	Dither.Add    = 0.5     * ((1L << (32 - bits)) - 1);
	Dither.Dither = 0.01*default_dither[index] / (((int64_t)1) << bits);
}

#endif

--- NEW FILE ---
/* This program is licensed under the GNU Library General Public License, version 2,
 * a copy of which is included with this program (with filename LICENSE.LGPL).
 *
 * (c) 2002 John Edwards
 *
 * rand_t header.
 *
 * last modified: $ID:$
 */

#include "common.h"

#ifndef __RAND_T_H
#define __RAND_T_H

#ifdef __cplusplus
extern "C" {
#endif 

#ifndef FIXED_POINT

typedef struct {
    const float32_t*  FilterCoeff;
    uint64_t          Mask;
    double            Add;
    float32_t         Dither;
    float32_t         ErrorHistory     [2] [16];       // max. 2 channels, 16th order Noise shaping
    float32_t         DitherHistory    [2] [16];
    int32_t           LastRandomNumber [2];
} dither_t;

extern dither_t            Dither;
extern double              doubletmp;
//static const uint8_t       Parity [256];
uint32_t                   random_int ( void );
extern double              scalar16 ( const float32_t* x, const float32_t* y );
extern double              Random_Equi ( double mult );
extern double              Random_Triangular ( double mult );
void                       Init_Dither ( unsigned char bits, unsigned char shapingtype );

#endif

#ifdef __cplusplus
}
#endif 

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: drc.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#include <stdlib.h>
#include <string.h>
#include "syntax.h"
#include "drc.h"

drc_info *drc_init(real_t cut, real_t boost)
{
    drc_info *drc = (drc_info*)malloc(sizeof(drc_info));
    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;

    return drc;
}

void drc_end(drc_info *drc)
{
    if (drc) free(drc);
}

#ifdef FIXED_POINT
static real_t drc_pow2_table[] =
{
    COEF_CONST(0.5146511183),
    COEF_CONST(0.5297315472),
    COEF_CONST(0.5452538663),
    COEF_CONST(0.5612310242),
    COEF_CONST(0.5776763484),
    COEF_CONST(0.5946035575),
    COEF_CONST(0.6120267717),
    COEF_CONST(0.6299605249),
    COEF_CONST(0.6484197773),
    COEF_CONST(0.6674199271),
    COEF_CONST(0.6869768237),
    COEF_CONST(0.7071067812),
    COEF_CONST(0.7278265914),
    COEF_CONST(0.7491535384),
    COEF_CONST(0.7711054127),
    COEF_CONST(0.7937005260),
    COEF_CONST(0.8169577266),
    COEF_CONST(0.8408964153),
    COEF_CONST(0.8655365610),
    COEF_CONST(0.8908987181),
    COEF_CONST(0.9170040432),
    COEF_CONST(0.9438743127),
    COEF_CONST(0.9715319412),
    COEF_CONST(1.0000000000),
    COEF_CONST(1.0293022366),
    COEF_CONST(1.0594630944),
    COEF_CONST(1.0905077327),
    COEF_CONST(1.1224620483),
    COEF_CONST(1.1553526969),
    COEF_CONST(1.1892071150),
    COEF_CONST(1.2240535433),
    COEF_CONST(1.2599210499),
    COEF_CONST(1.2968395547),
    COEF_CONST(1.3348398542),
    COEF_CONST(1.3739536475),
    COEF_CONST(1.4142135624),
    COEF_CONST(1.4556531828),
    COEF_CONST(1.4983070769),
    COEF_CONST(1.5422108254),
    COEF_CONST(1.5874010520),
    COEF_CONST(1.6339154532),
    COEF_CONST(1.6817928305),
    COEF_CONST(1.7310731220),
    COEF_CONST(1.7817974363),
    COEF_CONST(1.8340080864),
    COEF_CONST(1.8877486254),
    COEF_CONST(1.9430638823)
};
#endif

void drc_decode(drc_info *drc, real_t *spec)
{
    uint16_t i, bd, top;
#ifdef FIXED_POINT
    int32_t exp, frac;
#else
    real_t factor, exp;
#endif
    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);

#ifndef FIXED_POINT
        /* Decode DRC gain factor */
        if (drc->dyn_rng_sgn[bd])  /* compress */
            exp = -drc->ctrl1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/24.0;
        else /* boost */
            exp = drc->ctrl2 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/24.0;
        factor = (real_t)pow(2.0, exp);

        /* Apply gain factor */
        for (i = bottom; i < top; i++)
            spec[i] *= factor;
#else
        /* Decode DRC gain factor */
        if (drc->dyn_rng_sgn[bd])  /* compress */
        {
            exp = -1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/ 24;
            frac = -1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) % 24;
        } else { /* boost */
            exp = (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/ 24;
            frac = (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) % 24;
        }

        /* Apply gain factor */
        if (exp < 0)
        {
            for (i = bottom; i < top; i++)
            {
                spec[i] >>= -exp;
                if (frac)
                    spec[i] = MUL(spec[i],drc_pow2_table[frac+23]);
            }
        } else {
            for (i = bottom; i < top; i++)
            {
                spec[i] <<= exp;
                if (frac)
                    spec[i] = MUL(spec[i],drc_pow2_table[frac+23]);
            }
        }
#endif

        bottom = top;
    }
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: drc.h,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#ifndef __DRC_H__
#define __DRC_H__

#ifdef __cplusplus
extern "C" {
#endif

#define DRC_REF_LEVEL 20*4 /* -20 dB */


drc_info *drc_init(real_t cut, real_t boost);
void drc_end(drc_info *drc);
void drc_decode(drc_info *drc, real_t *spec);


#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: error.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#include "common.h"
#include "error.h"

extern int8_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",
    "Maximum number of channels exceeded",
    "Maximum number of bitstream elements exceeded",
    "Input data buffer too small",
    "Array index out of range",
    "Maximum number of scalefactor bands exceeded"
};
--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: error.h,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#ifndef __ERROR_H__
#define __ERROR_H__

#ifdef __cplusplus
extern "C" {
#endif

#define NUM_ERROR_MESSAGES 17
extern int8_t *err_msg[];

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: faad.h,v 1.1 2003/08/30 22:30:21 arpi 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 FAAD2_VERSION "2.0 RC1 "

/* object types for AAC */
#define MAIN       0
#define LC         1
#define SSR        2
#define LTP        3
#define ER_LC     17
#define ER_LTP    19
#define LD        23
#define DRM_ER_LC 27 /* special object type for DRM */

/* header types */
#define RAW        0
#define ADIF       1
#define ADTS       2

/* library output formats */
#define FAAD_FMT_16BIT  1
#define FAAD_FMT_24BIT  2
#define FAAD_FMT_32BIT  3
#define FAAD_FMT_FLOAT  4
#define FAAD_FMT_DOUBLE 5
#define FAAD_FMT_16BIT_DITHER  6
#define FAAD_FMT_16BIT_L_SHAPE 7
#define FAAD_FMT_16BIT_M_SHAPE 8
#define FAAD_FMT_16BIT_H_SHAPE 9

/* Capabilities */
#define LC_DEC_CAP            (1<<0)
#define MAIN_DEC_CAP          (1<<1)
#define LTP_DEC_CAP           (1<<2)
#define LD_DEC_CAP            (1<<3)
#define ERROR_RESILIENCE_CAP  (1<<4)
#define FIXED_POINT_CAP       (1<<5)

/* Channel definitions */
#define FRONT_CHANNEL_CENTER (1)
#define FRONT_CHANNEL_LEFT   (2)
#define FRONT_CHANNEL_RIGHT  (3)
#define SIDE_CHANNEL_LEFT    (4)
#define SIDE_CHANNEL_RIGHT   (5)
#define BACK_CHANNEL_LEFT    (6)
#define BACK_CHANNEL_RIGHT   (7)
#define BACK_CHANNEL_CENTER  (8)
#define LFE_CHANNEL          (9)
#define UNKNOWN_CHANNEL      (0)


/* A decode call can eat up to FAAD_MIN_STREAMSIZE bytes per decoded channel,
   so at least so much bytes per channel should be available in this stream */
#define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */


typedef void *faacDecHandle;

typedef struct mp4AudioSpecificConfig
{
    /* Audio Specific Info */
    unsigned char objectTypeIndex;
    unsigned char samplingFrequencyIndex;
    unsigned long samplingFrequency;
    unsigned char channelsConfiguration;

    /* GA Specific Info */
    unsigned char frameLengthFlag;
    unsigned char dependsOnCoreCoder;
    unsigned short coreCoderDelay;
    unsigned char extensionFlag;
    unsigned char aacSectionDataResilienceFlag;
    unsigned char aacScalefactorDataResilienceFlag;
    unsigned char aacSpectralDataResilienceFlag;
    unsigned char epConfig;

    char sbr_present_flag;
} mp4AudioSpecificConfig;

typedef struct faacDecConfiguration
{
    unsigned char defObjectType;
    unsigned long defSampleRate;
    unsigned char outputFormat;
    unsigned char downMatrix;
} faacDecConfiguration, *faacDecConfigurationPtr;

typedef struct faacDecFrameInfo
{
    unsigned long bytesconsumed;
    unsigned long samples;
    unsigned char channels;
    unsigned char error;
    unsigned long samplerate;

    /* multichannel configuration */
    unsigned char num_front_channels;
    unsigned char num_side_channels;
    unsigned char num_back_channels;
    unsigned char num_lfe_channels;
    unsigned char channel_position[64];
} faacDecFrameInfo;

char* FAADAPI faacDecGetErrorMessage(unsigned char errcode);

unsigned long FAADAPI faacDecGetCapabilities();

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 buffer_size,
                        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);

/* Init the library for DRM */
char FAADAPI faacDecInitDRM(faacDecHandle hDecoder, unsigned long samplerate,
                            unsigned char channels);

void FAADAPI faacDecClose(faacDecHandle hDecoder);

void* FAADAPI faacDecDecode(faacDecHandle hDecoder,
                            faacDecFrameInfo *hInfo,
                            unsigned char *buffer,
                            unsigned long buffer_size);

char FAADAPI AudioSpecificConfig(unsigned char *pBuffer,
                                 unsigned long buffer_size,
                                 mp4AudioSpecificConfig *mp4ASC);

#ifdef _WIN32
  #pragma pack(pop)
#endif

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: filtbank.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#include <stdlib.h>
#include <string.h>
#ifdef _WIN32_WCE
#define assert(x)
#else
#include <assert.h>
#endif

#include "filtbank.h"
#include "decoder.h"
#include "syntax.h"
#include "kbd_win.h"
#include "sine_win.h"
#include "mdct.h"


fb_info *filter_bank_init(uint16_t frame_len)
{
    uint16_t nshort = frame_len/8;
#ifdef LD_DEC
    uint16_t frame_len_ld = frame_len/2;
#endif

    fb_info *fb = (fb_info*)malloc(sizeof(fb_info));
    memset(fb, 0, sizeof(fb_info));

    /* normal */
    fb->mdct256 = faad_mdct_init(2*nshort);
    fb->mdct2048 = faad_mdct_init(2*frame_len);
#ifdef LD_DEC
    /* LD */
    fb->mdct1024 = faad_mdct_init(2*frame_len_ld);
#endif

    if (frame_len == 1024)
    {
        fb->long_window[0]  = sine_long_1024;
        fb->short_window[0] = sine_short_128;
        fb->long_window[1]  = kbd_long_1024;
        fb->short_window[1] = kbd_short_128;
#ifdef LD_DEC
        fb->ld_window[0] = sine_mid_512;
        fb->ld_window[1] = ld_mid_512;
#endif
    } else /* (frame_len == 960) */ {
        fb->long_window[0]  = sine_long_960;
        fb->short_window[0] = sine_short_120;
        fb->long_window[1]  = kbd_long_960;
        fb->short_window[1] = kbd_short_120;
#ifdef LD_DEC
        fb->ld_window[0] = sine_mid_480;
        fb->ld_window[1] = ld_mid_480;
#endif
    }

    return fb;
}

void filter_bank_end(fb_info *fb)
{
    if (fb != NULL)
    {
        faad_mdct_end(fb->mdct256);
        faad_mdct_end(fb->mdct2048);
#ifdef LD_DEC
        faad_mdct_end(fb->mdct1024);
#endif

        free(fb);
    }
}

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 240:
        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_out, uint8_t object_type, uint16_t frame_len)
{
    int16_t i;
    real_t *transf_buf;

    real_t *window_long;
    real_t *window_long_prev;
    real_t *window_short;
    real_t *window_short_prev;

    uint16_t nlong = frame_len;
    uint16_t nshort = frame_len/8;
    uint16_t trans = nshort/2;

    uint16_t nflat_ls = (nlong-nshort)/2;

    transf_buf = (real_t*)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

    switch (window_sequence)
    {
    case ONLY_LONG_SEQUENCE:
        imdct(fb, freq_in, transf_buf, 2*nlong);
        for (i = nlong-1; i >= 0; i--)
        {
            time_out[i] = time_out[nlong+i] + MUL_R_C(transf_buf[i],window_long_prev[i]);
            time_out[nlong+i] = MUL_R_C(transf_buf[nlong+i],window_long[nlong-1-i]);
        }
        break;

    case LONG_START_SEQUENCE:
        imdct(fb, freq_in, transf_buf, 2*nlong);
        for (i = 0; i < nlong; i++)
            time_out[i] = time_out[nlong+i] + MUL_R_C(transf_buf[i],window_long_prev[i]);
        for (i = 0; i < nflat_ls; i++)
            time_out[nlong+i] = transf_buf[nlong+i];
        for (i = 0; i < nshort; i++)
            time_out[nlong+nflat_ls+i] = MUL_R_C(transf_buf[nlong+nflat_ls+i],window_short[nshort-i-1]);
        for (i = 0; i < nflat_ls; i++)
            time_out[nlong+nflat_ls+nshort+i] = 0;
        break;

    case EIGHT_SHORT_SEQUENCE:
        imdct(fb, freq_in+0*nshort, transf_buf+2*nshort*0, 2*nshort);
        imdct(fb, freq_in+1*nshort, transf_buf+2*nshort*1, 2*nshort);
        imdct(fb, freq_in+2*nshort, transf_buf+2*nshort*2, 2*nshort);
        imdct(fb, freq_in+3*nshort, transf_buf+2*nshort*3, 2*nshort);
        imdct(fb, freq_in+4*nshort, transf_buf+2*nshort*4, 2*nshort);
        imdct(fb, freq_in+5*nshort, transf_buf+2*nshort*5, 2*nshort);
        imdct(fb, freq_in+6*nshort, transf_buf+2*nshort*6, 2*nshort);
        imdct(fb, freq_in+7*nshort, transf_buf+2*nshort*7, 2*nshort);
        for (i = 0; i < nflat_ls; i++)
            time_out[i] = time_out[nlong+i];
        for(i = nshort-1; i >= 0; i--)
        {
            time_out[nflat_ls+         i] = time_out[nlong+nflat_ls+         i] + MUL_R_C(transf_buf[nshort*0+i],window_short_prev[i]);
            time_out[nflat_ls+1*nshort+i] = time_out[nlong+nflat_ls+nshort*1+i] + MUL_R_C(transf_buf[nshort*1+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*2+i],window_short[i]);
            time_out[nflat_ls+2*nshort+i] = time_out[nlong+nflat_ls+nshort*2+i] + MUL_R_C(transf_buf[nshort*3+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*4+i],window_short[i]);
            time_out[nflat_ls+3*nshort+i] = time_out[nlong+nflat_ls+nshort*3+i] + MUL_R_C(transf_buf[nshort*5+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*6+i],window_short[i]);
            if (i < trans)
                time_out[nflat_ls+4*nshort+i] = time_out[nlong+nflat_ls+nshort*4+i] + MUL_R_C(transf_buf[nshort*7+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*8+i],window_short[i]);
            else
                time_out[nflat_ls+4*nshort+i] = MUL_R_C(transf_buf[nshort*7+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*8+i],window_short[i]);
            time_out[nflat_ls+5*nshort+i] = MUL_R_C(transf_buf[nshort*9+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*10+i],window_short[i]);
            time_out[nflat_ls+6*nshort+i] = MUL_R_C(transf_buf[nshort*11+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*12+i],window_short[i]);
            time_out[nflat_ls+7*nshort+i] = MUL_R_C(transf_buf[nshort*13+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*14+i],window_short[i]);
            time_out[nflat_ls+8*nshort+i] = MUL_R_C(transf_buf[nshort*15+i],window_short[nshort-1-i]);
        }
        for (i = 0; i < nflat_ls; i++)
            time_out[nlong+nflat_ls+nshort+i] = 0;
        break;

    case LONG_STOP_SEQUENCE:
        imdct(fb, freq_in, transf_buf, 2*nlong);
        for (i = 0; i < nflat_ls; i++)
            time_out[i] = time_out[nlong+i];
        for (i = 0; i < nshort; i++)
            time_out[nflat_ls+i] = time_out[nlong+nflat_ls+i] + MUL_R_C(transf_buf[nflat_ls+i],window_short_prev[i]);
        for (i = 0; i < nflat_ls; i++)
            time_out[nflat_ls+nshort+i] = time_out[nlong+nflat_ls+nshort+i] + transf_buf[nflat_ls+nshort+i];
        for (i = 0; i < nlong; i++)
            time_out[nlong+i] = MUL_R_C(transf_buf[nlong+i],window_long[nlong-1-i]);
		break;
    }

    free(transf_buf);
}

#ifdef LTP_DEC
/* only works for LTP -> no overlapping, no short blocks */
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)
{
    int16_t i;
    real_t *windowed_buf;

    real_t *window_long;
    real_t *window_long_prev;
    real_t *window_short;
    real_t *window_short_prev;

    uint16_t nlong = frame_len;
    uint16_t nshort = frame_len/8;
    uint16_t nflat_ls = (nlong-nshort)/2;

    assert(window_sequence != EIGHT_SHORT_SEQUENCE);

    windowed_buf = (real_t*)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

    switch(window_sequence)
    {
    case ONLY_LONG_SEQUENCE:
        for (i = nlong-1; i >= 0; i--)
        {
            windowed_buf[i] = MUL_R_C(in_data[i], window_long_prev[i]);
            windowed_buf[i+nlong] = MUL_R_C(in_data[i+nlong], window_long[nlong-1-i]);
        }
        mdct(fb, windowed_buf, out_mdct, 2*nlong);
        break;

    case LONG_START_SEQUENCE:
        for (i = 0; i < nlong; i++)
            windowed_buf[i] = MUL_R_C(in_data[i], window_long_prev[i]);
        for (i = 0; i < nflat_ls; i++)
            windowed_buf[i+nlong] = in_data[i+nlong];
        for (i = 0; i < nshort; i++)
            windowed_buf[i+nlong+nflat_ls] = MUL_R_C(in_data[i+nlong+nflat_ls], window_short[nshort-1-i]);
        for (i = 0; i < nflat_ls; i++)
            windowed_buf[i+nlong+nflat_ls+nshort] = 0;
        mdct(fb, windowed_buf, out_mdct, 2*nlong);
        break;

    case LONG_STOP_SEQUENCE:
        for (i = 0; i < nflat_ls; i++)
            windowed_buf[i] = 0;
        for (i = 0; i < nshort; i++)
            windowed_buf[i+nflat_ls] = MUL_R_C(in_data[i+nflat_ls], window_short_prev[i]);
        for (i = 0; i < nflat_ls; i++)
            windowed_buf[i+nflat_ls+nshort] = in_data[i+nflat_ls+nshort];
        for (i = 0; i < nlong; i++)
            windowed_buf[i+nlong] = MUL_R_C(in_data[i+nlong], window_long[nlong-1-i]);
        mdct(fb, windowed_buf, out_mdct, 2*nlong);
        break;
    }

    free(windowed_buf);
}
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: filtbank.h,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#ifndef __FILTBANK_H__
#define __FILTBANK_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "mdct.h"

fb_info *filter_bank_init(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_out,
                  uint8_t object_type,
                  uint16_t frame_len);

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: fixed.h,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#ifndef __FIXED_H__
#define __FIXED_H__

#ifdef __cplusplus
extern "C" {
#endif


#define COEF_BITS 28
#define COEF_PRECISION (1 << COEF_BITS)
#define REAL_BITS 15 //7
#define REAL_PRECISION (1 << REAL_BITS)


typedef int32_t real_t;


#define REAL_CONST(A) ((real_t)(A*(REAL_PRECISION)))
#define COEF_CONST(A) ((real_t)(A*(COEF_PRECISION)))

#if defined(_WIN32) && !defined(_WIN32_WCE)

/* multiply real with real */
static INLINE MUL(real_t A, real_t B)
{
    _asm {
        mov eax,A
        imul B
#if 0
        shrd eax,edx,REAL_BITS
#else
        shr eax,REAL_BITS
        shl edx,(32-REAL_BITS)
        or eax,edx
#endif
    }
}

/* multiply coef with coef */
static INLINE MUL_C_C(real_t A, real_t B)
{
    _asm {
        mov eax,A
        imul B
#if 0
        shrd eax,edx,COEF_BITS
#else
        shr eax,COEF_BITS
        shl edx,(32-COEF_BITS)
        or eax,edx
#endif
    }
}

/* multiply real with coef */
static INLINE MUL_R_C(real_t A, real_t B)
{
    _asm {
        mov eax,A
        imul B
#if 0
        shrd eax,edx,COEF_BITS
#else
        shr eax,COEF_BITS
        shl edx,(32-COEF_BITS)
        or eax,edx
#endif
    }
}

#elif defined(__GNUC__) && defined (__arm__)

/* taken from MAD */
#define arm_mul(x, y, SCALEBITS) \
       ({      uint32_t __hi; \
               uint32_t __lo; \
               uint32_t __result; \
               asm ("smull  %0, %1, %3, %4\n\t" \
                    "movs   %0, %0, lsr %5\n\t" \
                    "adc    %2, %0, %1, lsl %6" \
                    : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
                    : "%r" (x), "r" (y), \
                      "M" (SCALEBITS), "M" (32 - (SCALEBITS)) \
                    : "cc"); \
               __result; \
       })

static INLINE real_t MUL(real_t A, real_t B)
{
       return arm_mul( A, B, REAL_BITS);
}

static INLINE real_t MUL_C_C(real_t A, real_t B)
{
       return arm_mul( A, B, COEF_BITS);
}

static INLINE real_t MUL_R_C(real_t A, real_t B)
{
       return arm_mul( A, B, COEF_BITS);
}

#else

  /* multiply real with real */
  #define MUL(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (REAL_BITS-1))) >> REAL_BITS)
  /* multiply coef with coef */
  #define MUL_C_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS)
  /* multiply real with coef */
  #define MUL_R_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS)

#endif


#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2002 A. Kurpiers
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: hcr.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/


#include "common.h"
#include "structs.h"

#include <stdlib.h>
#include <string.h>

#include "syntax.h"
#include "specrec.h"
#include "bits.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

typedef struct
{
    /* bit input */
    uint32_t bufa;
    uint32_t bufb;
    int8_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 = (int8_t)(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;
                uint32_t off;

                neg = (sp[k] < 0) ? 1 : 0; 

                for (i = 4; ; i++)
                {
                    uint8_t b;
                    if (get1bit(ld, &b))
                        return -1;
                    if (b == 0)
                        break;
                }
// TODO: here we would need to test "off" if VCB11 is used!
                if (getbits(ld, i, &off))
                    return -1;
                j = off + (1<<i);
                sp[k] = (int16_t)((neg) ? -j : j);
            }
        }
    }    
    return ld->len;
}

/* rewind len (max. 32) bits so that the MSB becomes LSB */

static uint32_t rewind_word( uint32_t W, uint8_t len)
{
    uint8_t i;
    uint32_t tmp_W=0;

    for ( i=0; i<len; i++ )
    {
        tmp_W<<=1;
        if (W & (1<<i)) tmp_W |= 1;
    }
    return tmp_W;
}

static void rewind_lword( uint32_t *highW, uint32_t *lowW, uint8_t len)
{
    uint32_t tmp_lW=0;

    if (len > 32)
    {
        tmp_lW = rewind_word( (*highW << (64-len)) | (*lowW >> (len-32)), 32);
        *highW = rewind_word( *lowW << (64-len) , 32);
        *lowW = tmp_lW;
    } else {
        *highW = 0;
        *lowW = rewind_word( *lowW, len);
    }
}    

/* Takes a codeword as stored in r, rewinds the remaining bits and stores it back */
static void rewind_bits(bits_t * r)
{
    uint32_t hw, lw;

    if (r->len == 0) return;

    if (r->len >32)
    {
        lw = r->bufa;
        hw = r->bufb & (0xFFFFFFFF >> (64 - r->len));
        rewind_lword( &hw, &lw, r->len );
        r->bufa = lw;
        r->bufb = hw;

    } else {
        lw = showbits(r, r->len );
        r->bufa = rewind_word( lw, r->len);
        r->bufb = 0;
    }
}

/* takes codewords from a and b, concatenate them and store them in b */
static void concat_bits( bits_t * a, bits_t * b)
{
    uint32_t	hwa, lwa, hwb, lwb;

    if (a->len == 0) return;

    if (a->len >32)
    {
        lwa = a->bufa;
        hwa = a->bufb & (0xFFFFFFFF >> (64 - a->len));
    } else {
        lwa = showbits(a, a->len );
        hwa = 0;
    }
    if (b->len >=32) {
        lwb = b->bufa;
        hwb = (b->bufb & (0xFFFFFFFF >> (64 - b->len)) ) | ( lwa << (b->len - 32));
    } else {
        lwb = showbits(b, b->len ) | (lwa << (b->len));
        hwb = (lwa >> (32 - b->len)) | (hwa << (b->len));
    }

    b->bufa = lwb;
    b->bufb = hwb;
    b->len += a->len;
}

/* 8.5.3.3.1 */

static const uint8_t PresortedCodebook_VCB11[] = { 11, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 9, 7, 5, 3, 1};
static const uint8_t PresortedCodebook[] = { 11, 9, 7, 5, 3, 1};

static const uint8_t maxCwLen[32] = {0, 11, 9, 20, 16, 13, 11, 14, 12, 17, 14, 49,
    0, 0, 0, 0, 14, 17, 21, 21, 25, 25, 29, 29, 29, 29, 33, 33, 33, 37, 37, 41};

typedef struct
{
    bits_t		bits;
    uint8_t		decoded;
    uint16_t	sp_offset;
    uint8_t		cb;
} codeword_state;


#define segmentWidth( codebook )	min( maxCwLen[codebook], ics->length_of_longest_codeword )
     
uint8_t reordered_spectral_data(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld,
                                int16_t *spectral_data)
{
    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 = hDecoder->frameLength/8;


    memset (spectral_data, 0, hDecoder->frameLength*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) ||
        (ics->max_sfb == 0))
    {
        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 < (hDecoder->aacSectionDataResilienceFlag ? 22 : 6); presort++)
    {
        uint8_t sfb;

        /* next codebook that has to be processed according to presorting */
        uint8_t nextCB = hDecoder->aacSectionDataResilienceFlag ? PresortedCodebook_VCB11[ presort ] : PresortedCodebook[ presort ];

        /* Data belonging to the same spectral unit and having the same codebook comes in consecutive codewords.
           This is done by scanning all sfbs for possible codewords. For sfbs with more than 4 elements this has to be
           repeated */

        for (sfb=0; sfb<ics->max_sfb; sfb ++)
        {
            uint8_t sect_cb, w;

            for (w=0; w< (ics->swb_offset[sfb+1] - ics->swb_offset[sfb]); w+=4)
            {
                for(g = 0; g < ics->num_window_groups; g++)
                {
                    for (i = 0; i < ics->num_sec[g]; i++)
                    {
                        sect_cb = ics->sect_cb[g][i];

                        if (
                            /* process only sections that are due now */
                            (( sect_cb == nextCB ) || (( nextCB < ESC_HCB ) && ( sect_cb == nextCB+1)) ) &&

                            /* process only sfb's that are due now */
                            ((ics->sect_start[g][i] <= sfb) && (ics->sect_end[g][i] > sfb))
                            )
                        {
                            if ((sect_cb != ZERO_HCB) &&
                                (sect_cb != NOISE_HCB) &&
                                (sect_cb != INTENSITY_HCB) &&
                                (sect_cb != INTENSITY_HCB2))
                            {
                                uint8_t inc = (sect_cb < FIRST_PAIR_HCB) ? QUAD_LEN : PAIR_LEN;
                                uint16_t k;

                                uint32_t	hw, lw;

                                for  (k=0; (k < (4/inc)*ics->window_group_length[g]) &&
                                    ( (k+w*ics->window_group_length[g]/inc) < (ics->sect_sfb_offset[g][sfb+1] - ics->sect_sfb_offset[g][sfb])); k++)
                                {
                                    uint16_t sp = sp_offset[g] + ics->sect_sfb_offset[g][sfb] + inc*(k+w*ics->window_group_length[g]/inc);

                                    if (!PCW_decoded)
                                    {
                                        /* if we haven't yet read until the end of the buffer, we can directly decode the so-called PCWs */
                                        if ((BitsRead + segmentWidth( sect_cb ))<= ics->length_of_reordered_spectral_data)
                                        {
                                            Segment[ numberOfSegments ].len = segmentWidth( sect_cb );

                                            if (segmentWidth( sect_cb ) > 32)
                                            {
                                                Segment[ numberOfSegments ].bufb = faad_showbits(ld, segmentWidth( sect_cb ) - 32);
                                                faad_flushbits(ld, segmentWidth( sect_cb) - 32);
                                                Segment[ numberOfSegments ].bufa = faad_showbits(ld, 32),
                                                    faad_flushbits(ld, 32 );

                                            } else {
                                                Segment[ numberOfSegments ].bufa = faad_showbits(ld,  segmentWidth( sect_cb ));
                                                Segment[ numberOfSegments ].bufb = 0;
                                                faad_flushbits(ld, segmentWidth( sect_cb) );
                                            }

                                            huffman_spectral_data_2(sect_cb, &Segment[ numberOfSegments ], &spectral_data[sp]);

                                            BitsRead += segmentWidth( sect_cb );

                                            /* skip to next segment, but store left bits in new buffer */
                                            rewind_bits( &Segment[ numberOfSegments ]);

                                            numberOfSegments++;
                                        } else {

                                            /* the last segment is extended until length_of_reordered_spectral_data */

                                            if (BitsRead < ics->length_of_reordered_spectral_data)
                                            {

                                                uint8_t additional_bits = (ics->length_of_reordered_spectral_data - BitsRead);

                                                if ( additional_bits > 32)
                                                {
                                                    hw = faad_showbits(ld, additional_bits - 32);
                                                    faad_flushbits(ld, additional_bits - 32);
                                                    lw = faad_showbits(ld, 32);
                                                    faad_flushbits(ld, 32 );
                                                } else {
                                                    lw = faad_showbits(ld, additional_bits);
                                                    hw = 0;
                                                    faad_flushbits(ld, additional_bits );
                                                }
                                                rewind_lword( &hw, &lw, additional_bits + Segment[ numberOfSegments-1 ].len );
                                                if (Segment[ numberOfSegments-1 ].len > 32)
                                                {
                                                    Segment[ numberOfSegments-1 ].bufb = hw + 
                                                        showbits(&Segment[ numberOfSegments-1 ], Segment[ numberOfSegments-1 ].len - 32);
                                                    Segment[ numberOfSegments-1 ].bufa = lw + 
                                                        showbits(&Segment[ numberOfSegments-1 ], 32);
                                                } else {
                                                    Segment[ numberOfSegments-1 ].bufa = lw + 
                                                        showbits(&Segment[ numberOfSegments-1 ], Segment[ numberOfSegments-1 ].len);
                                                    Segment[ numberOfSegments-1 ].bufb = hw;
                                                }
                                                Segment[ numberOfSegments-1 ].len += additional_bits;
                                            }
                                            BitsRead = ics->length_of_reordered_spectral_data;
                                            PCW_decoded = 1;

                                            Codewords[ 0 ].sp_offset = sp;
                                            Codewords[ 0 ].cb = sect_cb;
                                            Codewords[ 0 ].decoded = 0;
                                            Codewords[ 0 ].bits.len = 0;
                                        }
                                    } else {
                                        Codewords[ NrCodeWords - numberOfSegments ].sp_offset = sp;
                                        Codewords[ NrCodeWords - numberOfSegments ].cb = sect_cb;
                                        Codewords[ NrCodeWords - numberOfSegments ].decoded = 0;
                                        Codewords[ NrCodeWords - numberOfSegments ].bits.len = 0;

                                    } /* PCW decoded */
                                    NrCodeWords++;
                                } /* of k */
                            }
                        }
                    } /* of i */
                 } /* of g */
             } /* of w */
         } /* of sfb */
    } /* of presort */

    /* Avoid divide by zero */
    if (numberOfSegments == 0)
        return 10; /* this is not good... */

    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 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)
                    {
                        uint8_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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: huffman.h,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#ifndef __HUFFMAN_H__
#define __HUFFMAN_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdlib.h>
#ifdef ANALYSIS
#include <stdio.h>
#endif
#include "bits.h"
#include "codebook/hcb.h"


static INLINE int8_t huffman_scale_factor(bitfile *ld)
{
    uint16_t offset = 0;

    while (hcb_sf[offset][1])
    {
        uint8_t b = faad_get1bit(ld
            DEBUGVAR(1,255,"huffman_scale_factor()"));
        offset += hcb_sf[offset][b];

        if (offset > 240)
        {
            /* printf("ERROR: offset into hcb_sf = %d >240!\n", offset); */
            return -1;
        }
    }

    return hcb_sf[offset][0];
}


hcb *hcb_table[] = {
    0, hcb1_1, hcb2_1, 0, hcb4_1, 0, hcb6_1, 0, hcb8_1, 0, hcb10_1, hcb11_1
};

hcb_2_quad *hcb_2_quad_table[] = {
    0, hcb1_2, hcb2_2, 0, hcb4_2, 0, 0, 0, 0, 0, 0, 0
};

hcb_2_pair *hcb_2_pair_table[] = {
    0, 0, 0, 0, 0, 0, hcb6_2, 0, hcb8_2, 0, hcb10_2, hcb11_2
};

hcb_bin_pair *hcb_bin_table[] = {
    0, 0, 0, 0, 0, hcb5, 0, hcb7, 0, hcb9, 0, 0
};

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 */
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
};

int hcb_2_quad_table_size[] = { 0, 114, 86, 0, 185, 0, 0, 0, 0, 0, 0, 0 };
int hcb_2_pair_table_size[] = { 0, 0, 0, 0, 0, 0, 126, 0, 83, 0, 210, 373 };
int hcb_bin_table_size[] = { 0, 0, 0, 161, 0, 161, 0, 127, 0, 337, 0, 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 int16_t huffman_getescape(bitfile *ld, int16_t sp)
{
    uint8_t neg, i;
    int16_t j;
	int32_t 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;
        }
    }

    off = faad_getbits(ld, i
        DEBUGVAR(1,9,"huffman_getescape(): escape"));

    j = off + (1<<i);
    if (neg)
        j = -j;

    return j;
}

static uint8_t huffman_2step_quad(uint8_t cb, bitfile *ld, int16_t *sp)
{
    uint32_t cw;
    uint16_t offset = 0;
    uint8_t extra_bits;

    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;
}

static uint8_t huffman_2step_quad_sign(uint8_t cb, bitfile *ld, int16_t *sp)
{
    uint8_t err = huffman_2step_quad(cb, ld, sp);
    huffman_sign_bits(ld, sp, QUAD_LEN);

    return err;
}

static uint8_t huffman_2step_pair(uint8_t cb, bitfile *ld, int16_t *sp)
{
    uint32_t cw;
    uint16_t offset = 0;
    uint8_t extra_bits;

    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;
}

static huffman_2step_pair_sign(uint8_t cb, bitfile *ld, int16_t *sp)
{
    uint8_t err = huffman_2step_pair(cb, ld, sp);
    huffman_sign_bits(ld, sp, PAIR_LEN);

    return err;
}

static uint8_t huffman_binary_quad(uint8_t cb, bitfile *ld, int16_t *sp)
{
    uint16_t offset = 0;

    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;
}

static uint8_t huffman_binary_quad_sign(uint8_t cb, bitfile *ld, int16_t *sp)
{
    uint8_t err = huffman_binary_quad(cb, ld, sp);
    huffman_sign_bits(ld, sp, QUAD_LEN);

    return err;
}

static uint8_t huffman_binary_pair(uint8_t cb, bitfile *ld, int16_t *sp)
{
    uint16_t offset = 0;

    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;
}

static uint8_t huffman_binary_pair_sign(uint8_t cb, bitfile *ld, int16_t *sp)
{
    uint8_t err = huffman_binary_pair(cb, ld, sp);
    huffman_sign_bits(ld, sp, PAIR_LEN);

    return err;
}

static int16_t huffman_codebook(uint8_t i)
{
    static const uint32_t data = 16428320;
    if (i == 0) return (int16_t)(data >> 16) & 0xFFFF;
    else        return (int16_t)data & 0xFFFF;
}

static INLINE uint8_t huffman_spectral_data(uint8_t cb, bitfile *ld, int16_t *sp)
{
    switch (cb)
    {
    case 1: /* 2-step method for data quadruples */
    case 2:
        return huffman_2step_quad(cb, ld, sp);
    case 3: /* binary search for data quadruples */
        return huffman_binary_quad_sign(cb, ld, sp);
    case 4: /* 2-step method for data quadruples */
        return huffman_2step_quad_sign(cb, ld, sp);
    case 5: /* binary search for data pairs */
        return huffman_binary_pair(cb, ld, sp);
    case 6: /* 2-step method for data pairs */
        return huffman_2step_pair(cb, ld, sp);
    case 7: /* binary search for data pairs */
    case 9:
        return huffman_binary_pair_sign(cb, ld, sp);
    case 8: /* 2-step method for data pairs */
    case 10:
        return huffman_2step_pair_sign(cb, ld, sp);
    case 12: {
        uint8_t err = huffman_2step_quad(1, ld, sp);
        sp[0] = huffman_codebook(0); sp[1] = huffman_codebook(1); 
        return err; }
    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 */
#endif
    {
        uint8_t err = huffman_2step_pair_sign(11, ld, sp);
        sp[0] = huffman_getescape(ld, sp[0]);
        sp[1] = huffman_getescape(ld, sp[1]);
        return err;
    }
    default:
        /* Non existent codebook number, something went wrong */
        return 11;
    }

    return 0;
}

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ic_predict.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#ifdef MAIN_DEC

#include "syntax.h"
#include "ic_predict.h"
#include "pns.h"

static void flt_round(real_t *pf)
{
    /* more stable version for clever compilers like gcc 3.x */
    int32_t flg;
    uint32_t tmp, tmp1, tmp2;

    tmp = *(uint32_t*)pf;
    flg = tmp & (uint32_t)0x00008000;
    tmp &= (uint32_t)0xffff0000;
    tmp1 = tmp;

    /* round 1/2 lsb toward infinity */
    if (flg)
    {
        tmp &= (uint32_t)0xff800000;       /* extract exponent and sign */
        tmp |= (uint32_t)0x00010000;       /* insert 1 lsb */
        tmp2 = tmp;                             /* add 1 lsb and elided one */
        tmp &= (uint32_t)0xff800000;       /* extract exponent and sign */
        
        *pf = *(real_t*)&tmp1+*(real_t*)&tmp2-*(real_t*)&tmp;/* subtract elided one */
    } else {
        *pf = *(real_t*)&tmp;
    }
}

static void ic_predict(pred_state *state, real_t input, real_t *output, uint8_t pred)
{
    real_t dr1, predictedvalue;
    real_t e0, e1;
    real_t k1, k2;

    real_t *r;
    real_t *KOR;
    real_t *VAR;

    r   = state->r;   /* delay elements */
    KOR = state->KOR; /* correlations */
    VAR = state->VAR; /* variances */

    if (VAR[0] <= 1)
        k1 = 0;
    else
        k1 = KOR[0]/VAR[0]*B;

    if (pred)
    {
        /* only needed for the actual predicted value, k1 is always needed */
        if (VAR[1] <= 1)
            k2 = 0;
        else
            k2 = KOR[1]/VAR[1]*B;

        predictedvalue = MUL(k1, r[0]) + MUL(k2, r[1]);
        flt_round(&predictedvalue);

        *output = input + predictedvalue;
    } else {
        *output = input;
    }

    /* calculate new state data */
    e0 = *output;
    e1 = e0 - MUL(k1, r[0]);

    dr1 = MUL(k1, e0);

    VAR[0] = MUL(ALPHA, VAR[0]) + MUL(REAL_CONST(0.5), (MUL(r[0], r[0]) + MUL(e0, e0)));
    KOR[0] = MUL(ALPHA, KOR[0]) + MUL(r[0], e0);
    VAR[1] = MUL(ALPHA, VAR[1]) + MUL(REAL_CONST(0.5), (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;
    state->r[1]   = 0;
    state->KOR[0] = 0;
    state->KOR[1] = 0;
    state->VAR[0] = REAL_CONST(1.0);
    state->VAR[1] = REAL_CONST(1.0);
}

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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ic_predict.h,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#ifdef MAIN_DEC

#ifndef __IC_PREDICT_H__
#define __IC_PREDICT_H__

#ifdef __cplusplus
extern "C" {
#endif

#define ALPHA      REAL_CONST(0.90625)
#define A          REAL_CONST(0.953125)
#define B          REAL_CONST(0.953125)


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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
[...2073 lines suppressed...]
    REAL_CONST(10187.1005859375/8),
    REAL_CONST(10200.4980468750/8),
    REAL_CONST(10213.9003906250/8),
    REAL_CONST(10227.3066406250/8),
    REAL_CONST(10240.7167968750/8),
    REAL_CONST(10254.1318359375/8),
    REAL_CONST(10267.5517578125/8),
    REAL_CONST(10280.9755859375/8),
    REAL_CONST(10294.4033203125/8),
    REAL_CONST(10307.8359375000/8),
    REAL_CONST(10321.2734375000/8),
    REAL_CONST(10334.7148437500/8)
};

#endif

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: is.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#include "syntax.h"
#include "is.h"

#ifdef FIXED_POINT
static real_t pow05_table[] = {
    COEF_CONST(1.68179283050743), /* 0.5^(-3/4) */
    COEF_CONST(1.41421356237310), /* 0.5^(-2/4) */
    COEF_CONST(1.18920711500272), /* 0.5^(-1/4) */
    COEF_CONST(1.0),              /* 0.5^( 0/4) */
    COEF_CONST(0.84089641525371), /* 0.5^(+1/4) */
    COEF_CONST(0.70710678118655), /* 0.5^(+2/4) */
    COEF_CONST(0.59460355750136)  /* 0.5^(+3/4) */
};
#endif

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;
#ifndef FIXED_POINT
    real_t scale;
#else
    int32_t exp, frac;
#endif

    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;

#ifndef FIXED_POINT
                    scale = (real_t)pow(0.5, (0.25*icsr->scale_factors[g][sfb]));
#else
                    exp = icsr->scale_factors[g][sfb] / 4;
                    frac = icsr->scale_factors[g][sfb] % 4;
#endif

                    /* 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;
#ifndef FIXED_POINT
                        r_spec[k] = MUL(l_spec[k], scale);
#else
                        if (exp < 0)
                            r_spec[k] = l_spec[k] << -exp;
                        else
                            r_spec[k] = l_spec[k] >> exp;
                        r_spec[k] = MUL_R_C(r_spec[k], pow05_table[frac + 3]);
#endif
                        if (is_intensity(icsr, g, sfb) != invert_intensity(ics, g, sfb))
                            r_spec[k] = -r_spec[k];
                    }
                }
            }
            group++;
        }
    }
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: is.h,v 1.1 2003/08/30 22:30:21 arpi 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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
[...4505 lines suppressed...]
    0xFFFEDE0,
    0xFFFF4E0,
    0xFFFF960,
    0xFFFFC30,
    0xFFFFDE0,
    0xFFFFEE0,
    0xFFFFF70,
    0xFFFFFC0,
    0xFFFFFE0,
    0xFFFFFF0,
    0x10000000,
    0x10000000
};

#endif

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: lt_predict.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#ifdef LTP_DEC

#include <stdlib.h>
#include "syntax.h"
#include "lt_predict.h"
#include "filtbank.h"
#include "tns.h"

static real_t codebook[8] =
{
    COEF_CONST(0.570829),
    COEF_CONST(0.696616),
    COEF_CONST(0.813004),
    COEF_CONST(0.911304),
    COEF_CONST(0.984900),
    COEF_CONST(1.067894),
    COEF_CONST(1.194601),
    COEF_CONST(1.369533)
};

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 = (real_t*)malloc(num_samples*sizeof(real_t));
            X_est = (real_t*)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_R_C(lt_pred_stat[num_samples + i - ltp->lag],
                    codebook[ltp->coef]);
            }

            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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: lt_predict.h,v 1.1 2003/08/30 22:30:22 arpi 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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: mdct.c,v 1.1 2003/08/30 22:30:22 arpi 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.
 * This (I)MDCT can now be used for any data size n, where n is divisible by 8.
 *
 */

#include "common.h"
#include "structs.h"

#include <stdlib.h>
#ifdef _WIN32_WCE
#define assert(x)
#else
#include <assert.h>
#endif

#include "cfft.h"
#include "mdct.h"

/* const_tab[]:
    0: sqrt(2 / N)
    1: cos(2 * PI / N)
    2: sin(2 * PI / N)
    3: cos(2 * PI * (1/8) / N)
    4: sin(2 * PI * (1/8) / N)
 */
#ifndef FIXED_POINT
#ifdef _MSC_VER
#pragma warning(disable:4305)
#pragma warning(disable:4244)
#endif
real_t const_tab[][5] =
{
    { COEF_CONST(0.0312500000), COEF_CONST(0.9999952938), COEF_CONST(0.0030679568),
        COEF_CONST(0.9999999265), COEF_CONST(0.0003834952) }, /* 2048 */
    { COEF_CONST(0.0322748612), COEF_CONST(0.9999946356), COEF_CONST(0.0032724866),
        COEF_CONST(0.9999999404), COEF_CONST(0.0004090615) }, /* 1920 */
    { COEF_CONST(0.0441941738), COEF_CONST(0.9999811649), COEF_CONST(0.0061358847),
        COEF_CONST(0.9999997020), COEF_CONST(0.0007669903) }, /* 1024 */
    { COEF_CONST(0.0456435465), COEF_CONST(0.9999786019), COEF_CONST(0.0065449383),
        COEF_CONST(0.9999996424), COEF_CONST(0.0008181230) }, /* 960 */
    { COEF_CONST(0.0883883476), COEF_CONST(0.9996988177), COEF_CONST(0.0245412290),
        COEF_CONST(0.9999952912), COEF_CONST(0.0030679568) }, /* 256 */
    { COEF_CONST(0.0912870929), COEF_CONST(0.9996573329), COEF_CONST(0.0261769500),
        COEF_CONST(0.9999946356), COEF_CONST(0.0032724866) }  /* 240 */
#ifdef SSR_DEC
   ,{ COEF_CONST(0.062500000), COEF_CONST(0.999924702), COEF_CONST(0.012271538),
        COEF_CONST(0.999998823), COEF_CONST(0.00153398) }, /* 512 */
    { COEF_CONST(0.176776695), COEF_CONST(0.995184727), COEF_CONST(0.09801714),
        COEF_CONST(0.999924702), COEF_CONST(0.012271538) }  /* 64 */
#endif
};
#else
real_t const_tab[][5] =
{
    { COEF_CONST(1), COEF_CONST(0.9999952938), COEF_CONST(0.0030679568),
        COEF_CONST(0.9999999265), COEF_CONST(0.0003834952) }, /* 2048 */
    { COEF_CONST(/* sqrt(1024/960) */ 1.03279556), COEF_CONST(0.9999946356), COEF_CONST(0.0032724866),
        COEF_CONST(0), COEF_CONST(0.0004090615) }, /* 1920 */
    { COEF_CONST(1), COEF_CONST(0.9999811649), COEF_CONST(0.0061358847),
        COEF_CONST(0.9999997020), COEF_CONST(0.0007669903) }, /* 1024 */
    { COEF_CONST(/* sqrt(512/480) */ 1.03279556), COEF_CONST(0.9999786019), COEF_CONST(0.0065449383),
        COEF_CONST(0.9999996424), COEF_CONST(0.0008181230) }, /* 960 */
    { COEF_CONST(1), COEF_CONST(0.9996988177), COEF_CONST(0.0245412290),
        COEF_CONST(0.9999952912), COEF_CONST(0.0030679568) }, /* 256 */
    { COEF_CONST(/* sqrt(256/240) */ 1.03279556), COEF_CONST(0.9996573329), COEF_CONST(0.0261769500),
        COEF_CONST(0.9999946356), COEF_CONST(0.0032724866) }  /* 240 */
#ifdef SSR_DEC
   ,{ COEF_CONST(0), COEF_CONST(0.999924702), COEF_CONST(0.012271538),
        COEF_CONST(0.999998823), COEF_CONST(0.00153398) }, /* 512 */
    { COEF_CONST(0), COEF_CONST(0.995184727), COEF_CONST(0.09801714),
        COEF_CONST(0.999924702), COEF_CONST(0.012271538) }  /* 64 */
#endif
};
#endif

uint8_t map_N_to_idx(uint16_t N)
{
    switch(N)
    {
    case 2048: return 0;
    case 1920: return 1;
    case 1024: return 2;
    case 960:  return 3;
    case 256:  return 4;
    case 240:  return 5;
#ifdef SSR_DEC
    case 512:  return 6;
    case 64:   return 7;
#endif
    }
    return 0;
}

mdct_info *faad_mdct_init(uint16_t N)
{
    uint16_t k, N_idx;
    real_t cangle, sangle, c, s, cold;
	real_t scale;

    mdct_info *mdct = (mdct_info*)malloc(sizeof(mdct_info));

    assert(N % 8 == 0);

    mdct->N = N;
    mdct->sincos = (complex_t*)malloc(N/4*sizeof(complex_t));
    mdct->Z1 = (complex_t*)malloc(N/4*sizeof(complex_t));

    N_idx = map_N_to_idx(N);

    scale = const_tab[N_idx][0];
    cangle = const_tab[N_idx][1];
    sangle = const_tab[N_idx][2];
    c = const_tab[N_idx][3];
    s = const_tab[N_idx][4];

    for (k = 0; k < N/4; k++)
    {
        RE(mdct->sincos[k]) = -1*MUL_C_C(c,scale);
        IM(mdct->sincos[k]) = -1*MUL_C_C(s,scale);

        cold = c;
        c = MUL_C_C(c,cangle) - MUL_C_C(s,sangle);
        s = MUL_C_C(s,cangle) + MUL_C_C(cold,sangle);
    }

    /* initialise fft */
    mdct->cfft = cffti(N/4);

    return mdct;
}

void faad_mdct_end(mdct_info *mdct)
{
    if (mdct != NULL)
    {
        cfftu(mdct->cfft);

        if (mdct->Z1) free(mdct->Z1);
        if (mdct->sincos) free(mdct->sincos);

        free(mdct);
    }
}

void faad_imdct(mdct_info *mdct, real_t *X_in, real_t *X_out)
{
    uint16_t k;

    complex_t x;
    complex_t *Z1 = mdct->Z1;
    complex_t *sincos = mdct->sincos;

    uint16_t N  = mdct->N;
    uint16_t N2 = N >> 1;
    uint16_t N4 = N >> 2;
    uint16_t N8 = N >> 3;

    /* pre-IFFT complex multiplication */
    for (k = 0; k < N4; k++)
    {
        uint16_t n = k << 1;
        RE(x) = X_in[         n];
        IM(x) = X_in[N2 - 1 - n];
        RE(Z1[k]) = MUL_R_C(IM(x), RE(sincos[k])) - MUL_R_C(RE(x), IM(sincos[k]));
        IM(Z1[k]) = MUL_R_C(RE(x), RE(sincos[k])) + MUL_R_C(IM(x), IM(sincos[k]));
    }

    /* complex IFFT */
    cfftb(mdct->cfft, Z1);

    /* post-IFFT complex multiplication */
    for (k = 0; k < N4; k++)
    {
        uint16_t n = k << 1;
        RE(x) = RE(Z1[k]);
        IM(x) = IM(Z1[k]);

        RE(Z1[k]) = MUL_R_C(RE(x), RE(sincos[k])) - MUL_R_C(IM(x), IM(sincos[k]));
        IM(Z1[k]) = MUL_R_C(IM(x), RE(sincos[k])) + MUL_R_C(RE(x), IM(sincos[k]));
    }

    /* reordering */
    for (k = 0; k < N8; k++)
    {
        uint16_t n = k << 1;
        X_out[              n] =  IM(Z1[N8 +     k]);
        X_out[          1 + n] = -RE(Z1[N8 - 1 - k]);
        X_out[N4 +          n] =  RE(Z1[         k]);
        X_out[N4 +      1 + n] = -IM(Z1[N4 - 1 - k]);
        X_out[N2 +          n] =  RE(Z1[N8 +     k]);
        X_out[N2 +      1 + n] = -IM(Z1[N8 - 1 - k]);
        X_out[N2 + N4 +     n] = -IM(Z1[         k]);
        X_out[N2 + N4 + 1 + n] =  RE(Z1[N4 - 1 - k]);
    }
}

#ifdef LTP_DEC
void faad_mdct(mdct_info *mdct, real_t *X_in, real_t *X_out)
{
    uint16_t k;

    complex_t x;
    complex_t *Z1 = mdct->Z1;
    complex_t *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 scale = REAL_CONST(N);

    /* pre-FFT complex multiplication */
    for (k = 0; k < N8; k++)
    {
        uint16_t n = k << 1;
        RE(x) = X_in[N - N4 - 1 - n] + X_in[N - N4 +     n];
        IM(x) = X_in[    N4 +     n] - X_in[    N4 - 1 - n];

        RE(Z1[k]) = -MUL_R_C(RE(x), RE(sincos[k])) - MUL_R_C(IM(x), IM(sincos[k]));
        IM(Z1[k]) = -MUL_R_C(IM(x), RE(sincos[k])) + MUL_R_C(RE(x), IM(sincos[k]));

        RE(x) =  X_in[N2 - 1 - n] - X_in[        n];
        IM(x) =  X_in[N2 +     n] + X_in[N - 1 - n];

        RE(Z1[k + N8]) = -MUL_R_C(RE(x), RE(sincos[k + N8])) - MUL_R_C(IM(x), IM(sincos[k + N8]));
        IM(Z1[k + N8]) = -MUL_R_C(IM(x), RE(sincos[k + N8])) + MUL_R_C(RE(x), IM(sincos[k + N8]));
    }

    /* complex FFT */
    cfftf(mdct->cfft, Z1);

    /* post-FFT complex multiplication */
    for (k = 0; k < N4; k++)
    {
        uint16_t n = k << 1;
        RE(x) = MUL(MUL_R_C(RE(Z1[k]), RE(sincos[k])) + MUL_R_C(IM(Z1[k]), IM(sincos[k])), scale);
        IM(x) = MUL(MUL_R_C(IM(Z1[k]), RE(sincos[k])) - MUL_R_C(RE(Z1[k]), IM(sincos[k])), scale);

        X_out[         n] =  RE(x);
        X_out[N2 - 1 - n] = -IM(x);
        X_out[N2 +     n] =  IM(x);
        X_out[N  - 1 - n] = -RE(x);
    }
}
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: mdct.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __MDCT_H__
#define __MDCT_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "cfft.h"

mdct_info *faad_mdct_init(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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: mp4.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#include <stdlib.h>

#include "bits.h"
#include "mp4.h"
#include "syntax.h"

/* defines if an object type can be decoded by this library or not */
static uint8_t ObjectTypesTable[32] = {
    0, /*  0 NULL */
#ifdef MAIN_DEC
    1, /*  1 AAC Main */
#else
    0, /*  1 AAC Main */
#endif
    1, /*  2 AAC LC */
#ifdef SSR_DEC
    1, /*  3 AAC SSR */
#else
    0, /*  3 AAC SSR */
#endif
#ifdef LTP_DEC
    1, /*  4 AAC LTP */
#else
    0, /*  4 AAC LTP */
#endif
#ifdef SBR_DEC
    1, /*  5 SBR */
#else
    0, /*  5 SBR */
#endif
    0, /*  6 AAC Scalable */
    0, /*  7 TwinVQ */
    0, /*  8 CELP */
    0, /*  9 HVXC */
    0, /* 10 Reserved */
    0, /* 11 Reserved */
    0, /* 12 TTSI */
    0, /* 13 Main synthetic */
    0, /* 14 Wavetable synthesis */
    0, /* 15 General MIDI */
    0, /* 16 Algorithmic Synthesis and Audio FX */

    /* MPEG-4 Version 2 */
#ifdef ERROR_RESILIENCE
    1, /* 17 ER AAC LC */
    0, /* 18 (Reserved) */
#ifdef LTP_DEC
    1, /* 19 ER AAC LTP */
#else
    0, /* 19 ER AAC LTP */
#endif
    0, /* 20 ER AAC scalable */
    0, /* 21 ER TwinVQ */
    0, /* 22 ER BSAC */
#ifdef LD_DEC
    1, /* 23 ER AAC LD */
#else
    0, /* 23 ER AAC LD */
#endif
    0, /* 24 ER CELP */
    0, /* 25 ER HVXC */
    0, /* 26 ER HILN */
    0, /* 27 ER Parametric */
#else /* No ER defined */
    0, /* 17 ER AAC LC */
    0, /* 18 (Reserved) */
    0, /* 19 ER AAC LTP */
    0, /* 20 ER AAC scalable */
    0, /* 21 ER TwinVQ */
    0, /* 22 ER BSAC */
    0, /* 23 ER AAC LD */
    0, /* 24 ER CELP */
    0, /* 25 ER HVXC */
    0, /* 26 ER HILN */
    0, /* 27 ER Parametric */
#endif
    0, /* 28 (Reserved) */
    0, /* 29 (Reserved) */
    0, /* 30 (Reserved) */
    0  /* 31 (Reserved) */
};

/* Table 1.6.1 */
int8_t FAADAPI AudioSpecificConfig(uint8_t *pBuffer,
                                   uint32_t buffer_size,
                                   mp4AudioSpecificConfig *mp4ASC)
{
    return AudioSpecificConfig2(pBuffer, buffer_size, mp4ASC, NULL);
}

int8_t FAADAPI AudioSpecificConfig2(uint8_t *pBuffer,
                                    uint32_t buffer_size,
                                    mp4AudioSpecificConfig *mp4ASC,
                                    program_config *pce)
{
    bitfile ld;
    int8_t result = 0;
#ifdef SBR_DEC
    int8_t bits_to_decode = 0;
#endif

    if (pBuffer == NULL)
        return -7;
    if (mp4ASC == NULL)
        return -8;

    memset(mp4ASC, 0, sizeof(mp4AudioSpecificConfig));

    faad_initbits(&ld, pBuffer, buffer_size);
    faad_byte_align(&ld);

    mp4ASC->objectTypeIndex = (uint8_t)faad_getbits(&ld, 5
        DEBUGVAR(1,1,"parse_audio_decoder_specific_info(): ObjectTypeIndex"));

    mp4ASC->samplingFrequencyIndex = (uint8_t)faad_getbits(&ld, 4
        DEBUGVAR(1,2,"parse_audio_decoder_specific_info(): SamplingFrequencyIndex"));

    mp4ASC->channelsConfiguration = (uint8_t)faad_getbits(&ld, 4
        DEBUGVAR(1,3,"parse_audio_decoder_specific_info(): ChannelsConfiguration"));

    mp4ASC->samplingFrequency = sample_rates[mp4ASC->samplingFrequencyIndex];

    if (ObjectTypesTable[mp4ASC->objectTypeIndex] != 1)
    {
        faad_endbits(&ld);
        return -1;
    }

    if (mp4ASC->samplingFrequency == 0)
    {
        faad_endbits(&ld);
        return -2;
    }

    if (mp4ASC->channelsConfiguration > 7)
    {
        faad_endbits(&ld);
        return -3;
    }

#ifdef SBR_DEC
    mp4ASC->sbr_present_flag = -1;
    if (mp4ASC->objectTypeIndex == 5)
    {
        mp4ASC->sbr_present_flag = 1;
        mp4ASC->samplingFrequencyIndex = (uint8_t)faad_getbits(&ld, 4
            DEBUGVAR(1,5,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex"));
        if (mp4ASC->samplingFrequencyIndex == 15)
        {
            mp4ASC->samplingFrequency = (uint32_t)faad_getbits(&ld, 24
                DEBUGVAR(1,6,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex"));
        } else {
            mp4ASC->samplingFrequency = sample_rates[mp4ASC->samplingFrequencyIndex];
        }
        mp4ASC->objectTypeIndex = (uint8_t)faad_getbits(&ld, 5
            DEBUGVAR(1,7,"parse_audio_decoder_specific_info(): ObjectTypeIndex"));
    }
#endif

    /* get GASpecificConfig */
    if (mp4ASC->objectTypeIndex == 1 || mp4ASC->objectTypeIndex == 2 ||
        mp4ASC->objectTypeIndex == 3 || mp4ASC->objectTypeIndex == 4 ||
        mp4ASC->objectTypeIndex == 6 || mp4ASC->objectTypeIndex == 7)
    {
        result = GASpecificConfig(&ld, mp4ASC, pce);

#ifdef ERROR_RESILIENCE
    } else if (mp4ASC->objectTypeIndex >= ER_OBJECT_START) { /* ER */
        result = GASpecificConfig(&ld, mp4ASC, pce);
        mp4ASC->epConfig = (uint8_t)faad_getbits(&ld, 2
            DEBUGVAR(1,143,"parse_audio_decoder_specific_info(): epConfig"));

        if (mp4ASC->epConfig != 0)
            result = -5;
#endif

    } else {
        result = -4;
    }

#ifdef SSR_DEC
    /* shorter frames not allowed for SSR */
    if ((mp4ASC->objectTypeIndex == 4) && mp4ASC->frameLengthFlag)
        return -6;
#endif


#ifdef SBR_DEC
    bits_to_decode = buffer_size*8 - faad_get_processed_bits(&ld);

    if ((mp4ASC->objectTypeIndex != 5) && (bits_to_decode >= 16))
    {
        int16_t syncExtensionType = (int16_t)faad_getbits(&ld, 11
            DEBUGVAR(1,9,"parse_audio_decoder_specific_info(): syncExtensionType"));

        if (syncExtensionType == 0x2b7)
        {
            mp4ASC->objectTypeIndex = (uint8_t)faad_getbits(&ld, 5
                DEBUGVAR(1,10,"parse_audio_decoder_specific_info(): extensionAudioObjectType"));

            if (mp4ASC->objectTypeIndex == 5)
            {
                mp4ASC->sbr_present_flag = (uint8_t)faad_get1bit(&ld
                    DEBUGVAR(1,11,"parse_audio_decoder_specific_info(): sbr_present_flag"));

                if (mp4ASC->sbr_present_flag)
                {
                    mp4ASC->samplingFrequencyIndex = (uint8_t)faad_getbits(&ld, 4
                        DEBUGVAR(1,12,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex"));
                    if (mp4ASC->samplingFrequencyIndex == 15)
                    {
                        mp4ASC->samplingFrequency = (uint32_t)faad_getbits(&ld, 24
                            DEBUGVAR(1,13,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex"));
                    } else {
                        mp4ASC->samplingFrequency = sample_rates[mp4ASC->samplingFrequencyIndex];
                    }
                }
            }
        }
    }
#endif

    faad_endbits(&ld);

    return result;
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: mp4.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __MP4_H__
#define __MP4_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "decoder.h"

int8_t FAADAPI AudioSpecificConfig(uint8_t *pBuffer,
                                   uint32_t buffer_size,
                                   mp4AudioSpecificConfig *mp4ASC);

int8_t FAADAPI AudioSpecificConfig2(uint8_t *pBuffer,
                                    uint32_t buffer_size,
                                    mp4AudioSpecificConfig *mp4ASC,
                                    program_config *pce);

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ms.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#include "common.h"
#include "structs.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++;
            }
        }
    }
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ms.h,v 1.1 2003/08/30 22:30:22 arpi 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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: output.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#include "output.h"
#include "decoder.h"

#ifndef FIXED_POINT

#include "dither.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 ROUND64(x) (doubletmp = (x) + Dither.Add + (int64_t)0x001FFFFD80000000L, *(int64_t*)(&doubletmp) - (int64_t)0x433FFFFD80000000L)

#define FLOAT_SCALE (1.0f/(1<<15))

dither_t Dither;
double doubletmp;

#define DM_MUL (1./(1.+sqrt(2.)))

static INLINE real_t get_sample(real_t **input, uint8_t channel, uint16_t sample,
                                uint8_t downMatrix, uint8_t *internal_channel)
{
    if (downMatrix)
    {
        if (channel == 0)
        {
            return DM_MUL * (input[internal_channel[1]][sample] +
                input[internal_channel[0]][sample]/sqrt(2.) +
                input[internal_channel[3]][sample]/sqrt(2.));
        } else {
            return DM_MUL * (input[internal_channel[2]][sample] +
                input[internal_channel[0]][sample]/sqrt(2.) +
                input[internal_channel[4]][sample]/sqrt(2.));
        }
    } else {
        return input[internal_channel[channel]][sample];
    }
}

void* output_to_PCM(faacDecHandle hDecoder,
                    real_t **input, void *sample_buffer, uint8_t channels,
                    uint16_t frame_len, uint8_t format)
{
    uint8_t ch;
    uint16_t i, j = 0;
    uint8_t internal_channel;

    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;
    double    *double_sample_buffer = (double*)sample_buffer;

    /* Copy output to a standard PCM buffer */
    for (ch = 0; ch < channels; ch++)
    {
        internal_channel = hDecoder->internal_channel[ch];

        switch (format)
        {
        case FAAD_FMT_16BIT:
            for(i = 0; i < frame_len; i++)
            {
                int32_t tmp;
                real_t ftemp;
                //real_t inp = input[internal_channel][i];
                real_t inp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel);

                ftemp = inp + 0xff8000;
                ftol(ftemp, short_sample_buffer[(i*channels)+ch]);
            }
            break;
        case FAAD_FMT_16BIT_DITHER:
            for(i = 0; i < frame_len; i++, j++)
            {
                real_t inp = input[internal_channel][i];
                double Sum = inp * 65535.f;
                int64_t val;
                if(j > 31)
                   j = 0;
                val = dither_output(1, 0, j, Sum, ch) / 65536;
                if (val > (1<<15)-1)
                    val = (1<<15)-1;
                else if (val < -(1<<15))
                    val = -(1<<15);
                short_sample_buffer[(i*channels)+ch] = (int16_t)val;
            }
            break;
        case FAAD_FMT_16BIT_L_SHAPE:
        case FAAD_FMT_16BIT_M_SHAPE:
        case FAAD_FMT_16BIT_H_SHAPE:
            for(i = 0; i < frame_len; i++, j++)
            {
                real_t inp = input[internal_channel][i];
                double Sum = inp * 65535.f;
                int64_t val;
                if(j > 31)
                   j = 0;
                val = dither_output(1, 1, j, Sum, ch) / 65536;
                if (val > (1<<15)-1)
                    val = (1<<15)-1;
                else if (val < -(1<<15))
                    val = -(1<<15);
                short_sample_buffer[(i*channels)+ch] = (int16_t)val;
            }
            break;
        case FAAD_FMT_24BIT:
            for(i = 0; i < frame_len; i++)
            {
                real_t inp = input[internal_channel][i];
                if (inp > (1<<15)-1)
                    inp = (1<<15)-1;
                else if (inp < -(1<<15))
                    inp = -(1<<15);
                int_sample_buffer[(i*channels)+ch] = ROUND(inp*(1<<8));
            }
            break;
        case FAAD_FMT_32BIT:
            for(i = 0; i < frame_len; i++)
            {
                real_t inp = input[internal_channel][i];
                if (inp > (1<<15)-1)
                    inp = (1<<15)-1;
                else if (inp < -(1<<15))
                    inp = -(1<<15);
                int_sample_buffer[(i*channels)+ch] = ROUND32(inp*(1<<16));
            }
            break;
        case FAAD_FMT_FLOAT:
            for(i = 0; i < frame_len; i++)
            {
                real_t inp = input[internal_channel][i];
                float_sample_buffer[(i*channels)+ch] = inp*FLOAT_SCALE;
            }
            break;
        case FAAD_FMT_DOUBLE:
            for(i = 0; i < frame_len; i++)
            {
                real_t inp = input[internal_channel][i];
                double_sample_buffer[(i*channels)+ch] = (double)inp*FLOAT_SCALE;
            }
            break;
        }
    }

    return sample_buffer;
}


/* Dither output */
static int64_t dither_output(uint8_t dithering, uint8_t shapingtype, uint16_t i, double Sum, uint8_t k)
{
    double Sum2;
    int64_t val;
    if(dithering)
    {
        if(!shapingtype)
        {
            double tmp = Random_Equi(Dither.Dither);
            Sum2 = tmp - Dither.LastRandomNumber[k];
            Dither.LastRandomNumber[k] = tmp;
            Sum2 = Sum += Sum2;
            val = ROUND64(Sum2)&Dither.Mask;
        } else {
            Sum2 = Random_Triangular(Dither.Dither) - scalar16(Dither.DitherHistory[k], Dither.FilterCoeff + i);
            Sum += Dither.DitherHistory[k][(-1-i)&15] = Sum2;
            Sum2 = Sum + scalar16(Dither.ErrorHistory[k], Dither.FilterCoeff + i );
            val = ROUND64(Sum2)&Dither.Mask;
            Dither.ErrorHistory[k][(-1-i)&15] = (float)(Sum - val);
        }
        return val;
    }
    else
        return ROUND64 (Sum);
}

#else

void* output_to_PCM(faacDecHandle hDecoder,
                    real_t **input, void *sample_buffer, uint8_t channels,
                    uint16_t frame_len, uint8_t format)
{
    uint8_t ch;
    uint16_t i;
    int16_t *short_sample_buffer = (int16_t*)sample_buffer;

    /* Copy output to a standard PCM buffer */
    for (ch = 0; ch < channels; ch++)
    {
        for(i = 0; i < frame_len; i++)
        {
            int32_t tmp = input[ch][i];
            tmp += (1 << (REAL_BITS-1));
            tmp >>= REAL_BITS;
            if (tmp > 0x7fff)       tmp = 0x7fff;
            else if (tmp <= -32768) tmp = -32768;
            short_sample_buffer[(i*channels)+ch] = (int16_t)tmp;
        }
    }

    return sample_buffer;
}

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: output.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __OUTPUT_H__
#define __OUTPUT_H__

#ifdef __cplusplus
extern "C" {
#endif

void* output_to_PCM(faacDecHandle hDecoder,
                    real_t **input,
                    void *samplebuffer,
                    uint8_t channels,
                    uint16_t frame_len,
                    uint8_t format);

static int64_t dither_output(uint8_t dithering, uint8_t shapingtype,
                             uint16_t i, double Sum, uint8_t k);

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: pns.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#include "pns.h"


#ifdef FIXED_POINT

#define DIV(A, B) (((int64_t)A << COEF_BITS)/B)

#define step(shift) \
    if ((0x40000000l >> shift) + root <= value)       \
    {                                                 \
        value -= (0x40000000l >> shift) + root;       \
        root = (root >> 1) | (0x40000000l >> shift);  \
    } else {                                          \
        root = root >> 1;                             \
    }

/* fixed point square root approximation */
real_t fp_sqrt(real_t value)
{
    real_t root = 0;

    step( 0); step( 2); step( 4); step( 6);
    step( 8); step(10); step(12); step(14);
    step(16); step(18); step(20); step(22);
    step(24); step(26); step(28); step(30);

    if (root < value)
        ++root;

    root <<= (COEF_BITS/2);

    return root;
}

static real_t pow2_table[] =
{
    COEF_CONST(0.59460355750136),
    COEF_CONST(0.70710678118655),
    COEF_CONST(0.84089641525371),
    COEF_CONST(1.0),
    COEF_CONST(1.18920711500272),
    COEF_CONST(1.41421356237310),
    COEF_CONST(1.68179283050743)
};
#endif

/* The function gen_rand_vector(addr, size) generates a vector of length
   <size> with signed random values of average energy MEAN_NRG per random
   value. A suitable random number generator can be realized using one
   multiplication/accumulation per random value.
*/
static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size)
{
#ifndef FIXED_POINT
    uint16_t i;
    real_t energy = 0.0;

    real_t scale = 1.0/(real_t)size * ISQRT_MEAN_NRG;

    for (i = 0; i < size; i++)
    {
        real_t tmp = scale*(real_t)(int32_t)random_int();
        spec[i] = tmp;
        energy += tmp*tmp;
    }

    scale = 1.0/(real_t)sqrt(energy);
    scale *= (real_t)pow(2.0, 0.25 * scale_factor);
    for (i = 0; i < size; i++)
    {
        spec[i] *= scale;
    }
#else
    uint16_t i;
    real_t energy = 0, scale;
    int32_t exp, frac;

    for (i = 0; i < size; i++)
    {
        real_t tmp = ISQRT_MEAN_NRG * (int32_t)random_int();
        tmp = MUL_C_C(COEF_CONST(1)/size, tmp);

        energy += MUL_C_C(tmp,tmp);

        /* convert COEF to REAL */
        spec[i] = (tmp >> -(REAL_BITS-COEF_BITS));
    }

    energy = fp_sqrt(energy);
    if (energy > 0)
    {
        scale = DIV(COEF_CONST(1),energy);

        scale >>= -(REAL_BITS-COEF_BITS);

        exp = scale_factor / 4;
        frac = scale_factor % 4;

        if (exp < 0)
            scale >>= -exp;
        else
            scale <<= exp;

        if (frac)
            scale = MUL_R_C(scale, pow2_table[frac + 3]);

        for (i = 0; i < size; i++)
        {
            spec[i] = MUL(spec[i], scale);
        }
    }
#endif
}

void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
                real_t *spec_left, real_t *spec_right, uint16_t frame_len,
                uint8_t channel_pair)
{
    uint8_t g, sfb, b;
    uint16_t size, offs;

    uint8_t group = 0;
    uint16_t nshort = frame_len >> 3;

    for (g = 0; g < ics_left->num_window_groups; g++)
    {
        /* Do perceptual noise substitution decoding */
        for (b = 0; b < ics_left->window_group_length[g]; b++)
        {
            for (sfb = 0; sfb < ics_left->max_sfb; sfb++)
            {
                if (is_noise(ics_left, 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_left->ltp.long_used[sfb] = 0;
                    ics_left->ltp2.long_used[sfb] = 0;

                    /* For scalefactor bands coded using PNS the corresponding
                       predictors are switched to "off".
                    */
                    ics_left->pred.prediction_used[sfb] = 0;

                    offs = ics_left->swb_offset[sfb];
                    size = ics_left->swb_offset[sfb+1] - offs;

                    /* Generate random vector */
                    gen_rand_vector(&spec_left[(group*nshort)+offs],
                        ics_left->scale_factors[g][sfb], size);
                }

/* 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.
*/
                if (channel_pair)
                {
                    if (is_noise(ics_right, g, sfb))
                    {
                        if (((ics_left->ms_mask_present == 1) &&
                            (ics_left->ms_used[g][sfb])) ||
                            (ics_left->ms_mask_present == 2))
                        {
                            uint16_t c;

                            offs = ics_right->swb_offset[sfb];
                            size = ics_right->swb_offset[sfb+1] - offs;

                            for (c = 0; c < size; c++)
                            {
                                spec_right[(group*nshort) + offs + c] =
                                    spec_left[(group*nshort) + offs + c];
                            }
                        } else /*if (ics_left->ms_mask_present == 0)*/ {
                            ics_right->ltp.long_used[sfb] = 0;
                            ics_right->ltp2.long_used[sfb] = 0;
                            ics_right->pred.prediction_used[sfb] = 0;

                            offs = ics_right->swb_offset[sfb];
                            size = ics_right->swb_offset[sfb+1] - offs;

                            /* Generate random vector */
                            gen_rand_vector(&spec_right[(group*nshort)+offs],
                                ics_right->scale_factors[g][sfb], size);
                        }
                    }
                }
            } /* sfb */
            group++;
        } /* b */
    } /* g */
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: pns.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __PNS_H__
#define __PNS_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "common.h"

#include "syntax.h"

#define NOISE_OFFSET 90
/* #define MEAN_NRG 1.537228e+18 */ /* (2^31)^2 / 3 */
#ifdef FIXED_POINT
#define ISQRT_MEAN_NRG 0x1DC7 /* sqrt(1/sqrt(MEAN_NRG)) */
#else
#define ISQRT_MEAN_NRG 8.0655e-10 /* 1/sqrt(MEAN_NRG) */
#endif


void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
                real_t *spec_left, real_t *spec_right, uint16_t frame_len,
                uint8_t channel_pair);

static INLINE int32_t random2();
static void gen_rand_vector(real_t *spec, int16_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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: pulse.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#include "syntax.h"
#include "pulse.h"

uint8_t pulse_decode(ic_stream *ics, int16_t *spec_data, uint16_t framelen)
{
    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 (k >= framelen)
            return 15; /* should not be possible */

        if (spec_data[k] > 0)
            spec_data[k] += pul->pulse_amp[i];
        else
            spec_data[k] -= pul->pulse_amp[i];
    }

    return 0;
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: pulse.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __PULSE_H__
#define __PULSE_H__

#ifdef __cplusplus
extern "C" {
#endif

uint8_t pulse_decode(ic_stream *ics, int16_t *spec_coef, uint16_t framelen);

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: rvlc.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

/* RVLC scalefactor decoding
 *
 * RVLC works like this:
 *  1. Only symmetric huffman codewords are used
 *  2. Total length of the scalefactor data is stored in the bitsream
 *  3. Scalefactors are DPCM coded
 *  4. Next to the starting value for DPCM the ending value is also stored
 *
 * With all this it is possible to read the scalefactor data from 2 sides.
 * If there is a bit error in the scalefactor data it is possible to start
 * decoding from the other end of the data, to find all but 1 scalefactor.
 */

#include "common.h"
#include "structs.h"

#include <stdlib.h>

#include "syntax.h"
#include "bits.h"
#include "rvlc.h"


#ifdef ERROR_RESILIENCE

//#define PRINT_RVLC

uint8_t rvlc_scale_factor_data(ic_stream *ics, bitfile *ld)
{
    uint8_t bits = 9;

    ics->sf_concealment = faad_get1bit(ld
        DEBUGVAR(1,149,"rvlc_scale_factor_data(): sf_concealment"));
    ics->rev_global_gain = faad_getbits(ld, 8
        DEBUGVAR(1,150,"rvlc_scale_factor_data(): rev_global_gain"));

    if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
        bits = 11;

    /* the number of bits used for the huffman codewords */
    ics->length_of_rvlc_sf = faad_getbits(ld, bits
        DEBUGVAR(1,151,"rvlc_scale_factor_data(): length_of_rvlc_sf"));

    if (ics->noise_used)
    {
        ics->dpcm_noise_nrg = faad_getbits(ld, 9
            DEBUGVAR(1,152,"rvlc_scale_factor_data(): dpcm_noise_nrg"));

        ics->length_of_rvlc_sf -= 9;
    }

    ics->sf_escapes_present = faad_get1bit(ld
        DEBUGVAR(1,153,"rvlc_scale_factor_data(): sf_escapes_present"));

    if (ics->sf_escapes_present)
    {
        ics->length_of_rvlc_escapes = faad_getbits(ld, 8
            DEBUGVAR(1,154,"rvlc_scale_factor_data(): length_of_rvlc_escapes"));
    }

    if (ics->noise_used)
    {
        ics->dpcm_noise_last_position = faad_getbits(ld, 9
            DEBUGVAR(1,155,"rvlc_scale_factor_data(): dpcm_noise_last_position"));
    }

    return 0;
}

uint8_t rvlc_decode_scale_factors(ic_stream *ics, bitfile *ld)
{
    uint8_t result;
    uint8_t intensity_used = 0;
    uint8_t *rvlc_sf_buffer = NULL;
    uint8_t *rvlc_esc_buffer = NULL;
    bitfile ld_rvlc_sf, ld_rvlc_esc;
//    bitfile ld_rvlc_sf_rev, ld_rvlc_esc_rev;

    if (ics->length_of_rvlc_sf > 0)
    {
        /* We read length_of_rvlc_sf bits here to put it in a
           seperate bitfile.
        */
        rvlc_sf_buffer = faad_getbitbuffer(ld, ics->length_of_rvlc_sf
            DEBUGVAR(1,156,"rvlc_decode_scale_factors(): bitbuffer: length_of_rvlc_sf"));

        faad_initbits(&ld_rvlc_sf, (void*)rvlc_sf_buffer, bit2byte(ics->length_of_rvlc_sf));
//        faad_initbits_rev(&ld_rvlc_sf_rev, (void*)rvlc_sf_buffer,
//            ics->length_of_rvlc_sf);
    }

    if (ics->sf_escapes_present)
    {
        /* We read length_of_rvlc_escapes bits here to put it in a
           seperate bitfile.
        */
        rvlc_esc_buffer = faad_getbitbuffer(ld, ics->length_of_rvlc_escapes
            DEBUGVAR(1,157,"rvlc_decode_scale_factors(): bitbuffer: length_of_rvlc_escapes"));

        faad_initbits(&ld_rvlc_esc, (void*)rvlc_esc_buffer, bit2byte(ics->length_of_rvlc_escapes));
//        faad_initbits_rev(&ld_rvlc_esc_rev, (void*)rvlc_esc_buffer,
//            ics->length_of_rvlc_escapes);
    }

    /* decode the rvlc scale factors and escapes */
    result = rvlc_decode_sf_forward(ics, &ld_rvlc_sf,
        &ld_rvlc_esc, &intensity_used);
//    result = rvlc_decode_sf_reverse(ics, &ld_rvlc_sf_rev,
//        &ld_rvlc_esc_rev, intensity_used);


    if (rvlc_esc_buffer) free(rvlc_esc_buffer);
    if (rvlc_sf_buffer) free(rvlc_sf_buffer);

    if (ics->length_of_rvlc_sf > 0)
        faad_endbits(&ld_rvlc_sf);
    if (ics->sf_escapes_present)
        faad_endbits(&ld_rvlc_esc);

    return result;
}

static uint8_t rvlc_decode_sf_forward(ic_stream *ics, bitfile *ld_sf, bitfile *ld_esc,
                                      uint8_t *intensity_used)
{
    int8_t g, sfb;
    int8_t t = 0;
    int8_t error = 0;
    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 - 256;

#ifdef PRINT_RVLC
    printf("\nglobal_gain: %d\n", ics->global_gain);
#endif

    for (g = 0; g < ics->num_window_groups; g++)
    {
        for (sfb = 0; sfb < ics->max_sfb; sfb++)
        {
            if (error)
            {
                ics->scale_factors[g][sfb] = 0;
            } else {
                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:

                    *intensity_used = 1;

                    /* decode intensity position */
                    t = rvlc_huffman_sf(ld_sf, ld_esc, +1);

                    is_position += t;
                    ics->scale_factors[g][sfb] = is_position;

                    break;
                case NOISE_HCB: /* noise books */

                    /* decode noise energy */
                    if (noise_pcm_flag)
                    {
                        int16_t n = ics->dpcm_noise_nrg;
                        noise_pcm_flag = 0;
                        noise_energy += n;
                    } else {
                        t = rvlc_huffman_sf(ld_sf, ld_esc, +1);
                        noise_energy += t;
                    }

                    ics->scale_factors[g][sfb] = noise_energy;

                    break;
                default: /* spectral books */

                    /* decode scale factor */
                    t = rvlc_huffman_sf(ld_sf, ld_esc, +1);

                    scale_factor += t;
                    if (scale_factor < 0)
                        return 4;

                    ics->scale_factors[g][sfb] = scale_factor;

                    break;
                }
#ifdef PRINT_RVLC
                printf("%3d:%4d%4d\n", sfb, ics->sfb_cb[g][sfb],
                    ics->scale_factors[g][sfb]);
#endif
                if (t == 99)
                {
                    error = 1;
                }
            }
        }
    }
#ifdef PRINT_RVLC
    printf("\n\n");
#endif

    return 0;
}

static uint8_t rvlc_decode_sf_reverse(ic_stream *ics, bitfile *ld_sf, bitfile *ld_esc,
                                      uint8_t intensity_used)
{
    int8_t g, sfb;
    int8_t t = 0;
    int8_t error = 0;
    int8_t noise_pcm_flag = 1, is_pcm_flag = 1, sf_pcm_flag = 1;

    int16_t scale_factor = ics->rev_global_gain;
    int16_t is_position = 0;
    int16_t noise_energy = ics->rev_global_gain;

#ifdef PRINT_RVLC
    printf("\nrev_global_gain: %d\n", ics->rev_global_gain);
#endif

    if (intensity_used)
    {
        is_position = rvlc_huffman_sf(ld_sf, ld_esc, -1);
#ifdef PRINT_RVLC
        printf("is_position: %d\n", is_position);
#endif
    }

    for (g = ics->num_window_groups-1; g >= 0; g--)
    {
        for (sfb = ics->max_sfb-1; sfb >= 0; sfb--)
        {
            if (error)
            {
                ics->scale_factors[g][sfb] = 0;
            } else {
                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:

                    if (is_pcm_flag)
                    {
                        is_pcm_flag = 0;
                        ics->scale_factors[g][sfb] = is_position;
                    } else {
                        t = rvlc_huffman_sf(ld_sf, ld_esc, -1);
                        is_position -= t;

                        ics->scale_factors[g][sfb] = is_position;
                    }

                    break;
                case NOISE_HCB: /* noise books */

                    /* decode noise energy */
                    if (noise_pcm_flag)
                    {
                        noise_pcm_flag = 0;
                        noise_energy = ics->dpcm_noise_last_position;
                    } else {
                        t = rvlc_huffman_sf(ld_sf, ld_esc, -1);
                        noise_energy -= t;
                    }

                    ics->scale_factors[g][sfb] = noise_energy;

                    break;
                default: /* spectral books */

                    if (sf_pcm_flag || (sfb == 0))
                    {
                        sf_pcm_flag = 0;
                        if (sfb == 0)
                            scale_factor = ics->global_gain;
                    } else {
                        /* decode scale factor */
                        t = rvlc_huffman_sf(ld_sf, ld_esc, -1);
                        scale_factor -= t;
                    }

                    ics->scale_factors[g][sfb] = scale_factor;

                    if (scale_factor < 0)
                        return 4;

                    break;
                }
#ifdef PRINT_RVLC
                printf("%3d:%4d%4d\n", sfb, ics->sfb_cb[g][sfb],
                    ics->scale_factors[g][sfb]);
#endif
                if (t == 99)
                {
                    error = 1;
                }
            }
        }
    }

#ifdef PRINT_RVLC
    printf("\n\n");
#endif

    return 0;
}

/* index == 99 means not allowed codeword */
static rvlc_huff_table book_rvlc[] = {
    /*index  length  codeword */
    {  0, 1,   0 }, /*         0 */
    { -1, 3,   5 }, /*       101 */
    {  1, 3,   7 }, /*       111 */
    { -2, 4,   9 }, /*      1001 */
    { -3, 5,  17 }, /*     10001 */
    {  2, 5,  27 }, /*     11011 */
    { -4, 6,  33 }, /*    100001 */
    { 99, 6,  50 }, /*    110010 */
    {  3, 6,  51 }, /*    110011 */
    { 99, 6,  52 }, /*    110100 */
    { -7, 7,  65 }, /*   1000001 */
    { 99, 7,  96 }, /*   1100000 */
    { 99, 7,  98 }, /*   1100010 */
    {  7, 7,  99 }, /*   1100011 */
    {  4, 7, 107 }, /*   1101011 */
    { -5, 8, 129 }, /*  10000001 */
    { 99, 8, 194 }, /*  11000010 */
    {  5, 8, 195 }, /*  11000011 */
    { 99, 8, 212 }, /*  11010100 */
    { 99, 9, 256 }, /* 100000000 */
    { -6, 9, 257 }, /* 100000001 */
    { 99, 9, 426 }, /* 110101010 */
    {  6, 9, 427 }, /* 110101011 */
    { 99, 10,  0 } /* Shouldn't come this far */
};

static rvlc_huff_table book_escape[] = {
    /*index  length  codeword */
    { 1, 2, 0 },
    { 0, 2, 2 },
    { 3, 3, 2 },
    { 2, 3, 6 },
    { 4, 4, 14 },
    { 7, 5, 13 },
    { 6, 5, 15 },
    { 5, 5, 31 },
    { 11, 6, 24 },
    { 10, 6, 25 },
    { 9, 6, 29 },
    { 8, 6, 61 },
    { 13, 7, 56  },
    { 12, 7, 120 },
    { 15, 8, 114 },
    { 14, 8, 242 },
    { 17, 9, 230 },
    { 16, 9, 486 },
    { 19, 10, 463  },
    { 18, 10, 974  },
    { 22, 11, 925  },
    { 20, 11, 1950 },
    { 21, 11, 1951 },
    { 23, 12, 1848 },
    { 25, 13, 3698 },
    { 24, 14, 7399 },
    { 26, 15, 14797 },
    { 49, 19, 236736 },
    { 50, 19, 236737 },
    { 51, 19, 236738 },
    { 52, 19, 236739 },
    { 53, 19, 236740 },
    { 27, 20, 473482 },
    { 28, 20, 473483 },
    { 29, 20, 473484 },
    { 30, 20, 473485 },
    { 31, 20, 473486 },
    { 32, 20, 473487 },
    { 33, 20, 473488 },
    { 34, 20, 473489 },
    { 35, 20, 473490 },
    { 36, 20, 473491 },
    { 37, 20, 473492 },
    { 38, 20, 473493 },
    { 39, 20, 473494 },
    { 40, 20, 473495 },
    { 41, 20, 473496 },
    { 42, 20, 473497 },
    { 43, 20, 473498 },
    { 44, 20, 473499 },
    { 45, 20, 473500 },
    { 46, 20, 473501 },
    { 47, 20, 473502 },
    { 48, 20, 473503 },
    { 99, 21,  0 } /* Shouldn't come this far */
};

static int8_t rvlc_huffman_sf(bitfile *ld_sf, bitfile *ld_esc,
                              int8_t direction)
{
    uint8_t i, j;
    int8_t index;
    uint32_t cw;
    rvlc_huff_table *h = book_rvlc;
    
    i = h->len;
    if (direction > 0)
        cw = faad_getbits(ld_sf, i DEBUGVAR(1,0,""));
    else
        cw = faad_getbits_rev(ld_sf, i DEBUGVAR(1,0,""));

    while ((cw != h->cw)
        && (i < 10))
    {
        h++;
        j = h->len-i;
        i += j;
        cw <<= j;
        if (direction > 0)
            cw |= faad_getbits(ld_sf, j DEBUGVAR(1,0,""));
        else
            cw |= faad_getbits_rev(ld_sf, j DEBUGVAR(1,0,""));
    }

    index = h->index;

    if (index == +ESC_VAL)
    {
        int8_t esc = rvlc_huffman_esc(ld_esc, direction);
        if (esc == 99)
            return 99;
        index += esc;
#ifdef PRINT_RVLC
        printf("esc: %d - ", esc);
#endif
    }
    if (index == -ESC_VAL)
    {
        int8_t esc = rvlc_huffman_esc(ld_esc, direction);
        if (esc == 99)
            return 99;
        index -= esc;
#ifdef PRINT_RVLC
        printf("esc: %d - ", esc);
#endif
    }

    return index;
}

static int8_t rvlc_huffman_esc(bitfile *ld,
                               int8_t direction)
{
    uint8_t i, j;
    uint32_t cw;
    rvlc_huff_table *h = book_escape;

    i = h->len;
    if (direction > 0)
        cw = faad_getbits(ld, i DEBUGVAR(1,0,""));
    else
        cw = faad_getbits_rev(ld, i DEBUGVAR(1,0,""));

    while ((cw != h->cw)
        && (i < 21))
    {
        h++;
        j = h->len-i;
        i += j;
        cw <<= j;
        if (direction > 0)
            cw |= faad_getbits(ld, j DEBUGVAR(1,0,""));
        else
            cw |= faad_getbits_rev(ld, j DEBUGVAR(1,0,""));
    }

    return h->index;
}

#endif
--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: rvlc.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __RVLC_SCF_H__
#define __RVLC_SCF_H__

#ifdef __cplusplus
extern "C" {
#endif

typedef struct
{
    int8_t index;
    uint8_t len;
    uint32_t cw;
} rvlc_huff_table;


#define ESC_VAL 7


uint8_t rvlc_scale_factor_data(ic_stream *ics, bitfile *ld);
uint8_t rvlc_decode_scale_factors(ic_stream *ics, bitfile *ld);

static uint8_t rvlc_decode_sf_forward(ic_stream *ics,
                                      bitfile *ld_sf,
                                      bitfile *ld_esc,
                                      uint8_t *is_used);
static uint8_t rvlc_decode_sf_reverse(ic_stream *ics,
                                      bitfile *ld_sf,
                                      bitfile *ld_esc,
                                      uint8_t is_used);
static int8_t rvlc_huffman_sf(bitfile *ld_sf, bitfile *ld_esc,
                              int8_t direction);
static int8_t rvlc_huffman_esc(bitfile *ld_esc, int8_t direction);


#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
[...4235 lines suppressed...]
    t0[53] = f757 + f354;
    t0[54] = f354 + f692;
    t0[55] = f692 + f148;
    t0[56] = f148 + f763;
    t0[57] = f763 + f350;
    t0[58] = f350 + f686;
    t0[59] = f686 + f192;
    t0[60] = f192 + f769;
    t0[61] = f769 + f342;
    t0[62] = f342 + t0[63];
    for (i0=0; i0<64; i0++)
    {
        y[i0] = t0[-i0+63];
    }
}

#endif

#endif


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_dct.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_DCT_H__
#define __SBR_DCT_H__

#ifdef __cplusplus
extern "C" {
#endif

void DCT3_32_unscaled(real_t *y, real_t *x);
void DCT2_64_unscaled(real_t *y, real_t *x);
void DCT4_64(real_t *y, real_t *x);
void DST4_64(real_t *y, real_t *x);


#ifdef __cplusplus
}
#endif
#endif


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_dec.c,v 1.1 2003/08/30 22:30:22 arpi 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"
#include "structs.h"

#ifdef SBR_DEC

#include <stdlib.h>

#include "syntax.h"
#include "bits.h"
#include "sbr_syntax.h"
#include "sbr_qmf.h"
#include "sbr_hfgen.h"
#include "sbr_hfadj.h"


sbr_info *sbrDecodeInit()
{
    sbr_info *sbr = malloc(sizeof(sbr_info));
    memset(sbr, 0, sizeof(sbr_info));

    sbr->bs_freq_scale = 2;
    sbr->bs_alter_scale = 1;
    sbr->bs_noise_bands = 2;
    sbr->bs_limiter_bands = 2;
    sbr->bs_limiter_gains = 2;
    sbr->bs_interpol_freq = 1;
    sbr->bs_smoothing_mode = 1;
    sbr->bs_start_freq = 5;
    sbr->bs_amp_res = 1;
    sbr->bs_samplerate_mode = 1;
    sbr->prevEnvIsShort[0] = -1;
    sbr->prevEnvIsShort[1] = -1;
    sbr->header_count = 0;

    return sbr;
}

void sbrDecodeEnd(sbr_info *sbr)
{
    uint8_t j;

    if (sbr)
    {
        qmfa_end(sbr->qmfa[0]);
        qmfs_end(sbr->qmfs[0]);
        if (sbr->id_aac == ID_CPE)
        {
            qmfa_end(sbr->qmfa[1]);
            qmfs_end(sbr->qmfs[1]);
        }

        if (sbr->Xcodec[0]) free(sbr->Xcodec[0]);
        if (sbr->Xsbr[0]) free(sbr->Xsbr[0]);
        if (sbr->Xcodec[1]) free(sbr->Xcodec[1]);
        if (sbr->Xsbr[1]) free(sbr->Xsbr[1]);

        for (j = 0; j < 5; j++)
        {
            if (sbr->G_temp_prev[0][j]) free(sbr->G_temp_prev[0][j]);
            if (sbr->Q_temp_prev[0][j]) free(sbr->Q_temp_prev[0][j]);
            if (sbr->G_temp_prev[1][j]) free(sbr->G_temp_prev[1][j]);
            if (sbr->Q_temp_prev[1][j]) free(sbr->Q_temp_prev[1][j]);
        }

        free(sbr);
    }
}

void sbr_save_prev_data(sbr_info *sbr, uint8_t ch)
{
    uint8_t i;

    /* save data for next frame */
    sbr->kx_prev = sbr->kx;

    sbr->L_E_prev[ch] = sbr->L_E[ch];

    sbr->f_prev[ch] = sbr->f[ch][sbr->L_E[ch] - 1];
    for (i = 0; i < 64; i++)
    {
        sbr->E_prev[ch][i] = sbr->E[ch][i][sbr->L_E[ch] - 1];
        sbr->Q_prev[ch][i] = sbr->Q[ch][i][sbr->L_Q[ch] - 1];
    }

    for (i = 0; i < 64; i++)
    {
        sbr->bs_add_harmonic_prev[ch][i] = sbr->bs_add_harmonic[ch][i];
    }
    sbr->bs_add_harmonic_flag_prev[ch] = sbr->bs_add_harmonic_flag[ch];

    if (sbr->l_A[ch] == sbr->L_E[ch])
        sbr->prevEnvIsShort[ch] = 0;
    else
        sbr->prevEnvIsShort[ch] = -1;
}


void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
                    real_t *right_channel, uint8_t id_aac,
                    uint8_t just_seeked)
{
    int16_t i, k, l;

    uint8_t dont_process = 0;
    uint8_t ch, channels, ret;
    real_t *ch_buf;

    qmf_t X[32*64];
#ifdef SBR_LOW_POWER
    real_t deg[64];
#endif

    bitfile *ld = (bitfile*)malloc(sizeof(bitfile));


    sbr->id_aac = id_aac;
    channels = (id_aac == ID_SCE) ? 1 : 2;

    /* initialise and read the bitstream */
    faad_initbits(ld, sbr->data, sbr->data_size);

    ret = sbr_extension_data(ld, sbr, id_aac);

    if (sbr->data) free(sbr->data);
    sbr->data = NULL;

    ret = ld->error ? ld->error : ret;
    faad_endbits(ld);
    if (ld) free(ld);
    ld = NULL;
    if (ret || (sbr->header_count == 0))
    {
        /* don't process just upsample */
        dont_process = 1;
    }

    if (just_seeked)
        sbr->just_seeked = 1;
    else
        sbr->just_seeked = 0;

    for (ch = 0; ch < channels; ch++)
    {
        if (sbr->frame == 0)
        {
            uint8_t j;
            sbr->qmfa[ch] = qmfa_init(32);
            sbr->qmfs[ch] = qmfs_init(64);
            
            for (j = 0; j < 5; j++)
            {
                sbr->G_temp_prev[ch][j] = malloc(64*sizeof(real_t));
                sbr->Q_temp_prev[ch][j] = malloc(64*sizeof(real_t));
            }

            sbr->Xsbr[ch] = malloc((32+tHFGen)*64 * sizeof(qmf_t));
            sbr->Xcodec[ch] = malloc((32+tHFGen)*32 * sizeof(qmf_t));

            memset(sbr->Xsbr[ch], 0, (32+tHFGen)*64 * sizeof(qmf_t));
            memset(sbr->Xcodec[ch], 0, (32+tHFGen)*32 * sizeof(qmf_t));
        }

        if (ch == 0)
            ch_buf = left_channel;
        else
            ch_buf = right_channel;

        for (i = 0; i < tHFAdj; i++)
        {
            int8_t j;
            for (j = sbr->kx_prev; j < sbr->kx; j++)
            {
                QMF_RE(sbr->Xcodec[ch][i*32 + j]) = 0;
#ifndef SBR_LOW_POWER
                QMF_IM(sbr->Xcodec[ch][i*32 + j]) = 0;
#endif
            }
        }

        /* subband analysis */
        sbr_qmf_analysis_32(sbr->qmfa[ch], ch_buf, sbr->Xcodec[ch], tHFGen);

        if (!dont_process)
        {
            /* insert high frequencies here */
            /* hf generation using patching */
            hf_generation(sbr, sbr->Xcodec[ch], sbr->Xsbr[ch]
#ifdef SBR_LOW_POWER
                ,deg
#endif
                ,ch);

#ifdef SBR_LOW_POWER
            for (l = sbr->t_E[ch][0]; l < sbr->t_E[ch][sbr->L_E[ch]]; l++)
            {
                for (k = 0; k < sbr->kx; k++)
                {
                    QMF_RE(sbr->Xsbr[ch][(tHFAdj + l)*64 + k]) = 0;
                }
            }
#endif

            /* hf adjustment */
            hf_adjustment(sbr, sbr->Xsbr[ch]
#ifdef SBR_LOW_POWER
                ,deg
#endif
                ,ch);
        }

        if ((sbr->just_seeked != 0) || dont_process)
        {
            for (l = 0; l < 32; l++)
            {
                for (k = 0; k < 32; k++)
                {
                    QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]);
#ifndef SBR_LOW_POWER
                    QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]);
#endif
                }
                for (k = 32; k < 64; k++)
                {
                    QMF_RE(X[l * 64 + k]) = 0;
#ifndef SBR_LOW_POWER
                    QMF_IM(X[l * 64 + k]) = 0;
#endif
                }
            }
        } else {
            for (l = 0; l < 32; l++)
            {
                uint8_t xover_band;

                if (l < sbr->t_E[ch][0])
                    xover_band = sbr->kx_prev;
                else
                    xover_band = sbr->kx;

                for (k = 0; k < xover_band; k++)
                {
                    QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]);
#ifndef SBR_LOW_POWER
                    QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xcodec[ch][(l + tHFAdj)*32 + k]);
#endif
                }
                for (k = xover_band; k < 64; k++)
                {
                    QMF_RE(X[l * 64 + k]) = QMF_RE(sbr->Xsbr[ch][(l + tHFAdj)*64 + k]);
#ifndef SBR_LOW_POWER
                    QMF_IM(X[l * 64 + k]) = QMF_IM(sbr->Xsbr[ch][(l + tHFAdj)*64 + k]);
#endif
                }
#ifdef SBR_LOW_POWER
                QMF_RE(X[l * 64 + xover_band - 1]) += QMF_RE(sbr->Xsbr[ch][(l + tHFAdj)*64 + xover_band - 1]);
#endif
            }
        }

        /* subband synthesis */
        sbr_qmf_synthesis_64(sbr->qmfs[ch], (const complex_t*)X, ch_buf);

        for (i = 0; i < 32; i++)
        {
            int8_t j;
            for (j = 0; j < tHFGen; j++)
            {
                QMF_RE(sbr->Xcodec[ch][j*32 + i]) = QMF_RE(sbr->Xcodec[ch][(j+32)*32 + i]);
#ifndef SBR_LOW_POWER
                QMF_IM(sbr->Xcodec[ch][j*32 + i]) = QMF_IM(sbr->Xcodec[ch][(j+32)*32 + i]);
#endif
            }
        }
        for (i = 0; i < 64; i++)
        {
            int8_t j;
            for (j = 0; j < tHFGen; j++)
            {
                QMF_RE(sbr->Xsbr[ch][j*64 + i]) = QMF_RE(sbr->Xsbr[ch][(j+32)*64 + i]);
#ifndef SBR_LOW_POWER
                QMF_IM(sbr->Xsbr[ch][j*64 + i]) = QMF_IM(sbr->Xsbr[ch][(j+32)*64 + i]);
#endif
            }
        }
    }

    if (sbr->bs_header_flag)
        sbr->just_seeked = 0;

    if (sbr->header_count != 0)
    {
        for (ch = 0; ch < channels; ch++)
            sbr_save_prev_data(sbr, ch);
    }

    sbr->frame++;
}

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_dec.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_DEC_H__
#define __SBR_DEC_H__

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
#if 0
    real_t post_exp_re[64];
    real_t post_exp_im[64];
#endif
    real_t *x;
    uint8_t channels;
} qmfa_info;

typedef struct {
    real_t *v;
    uint8_t channels;
} qmfs_info;

typedef struct
{
    uint32_t sample_rate;

    uint8_t rate;
    uint8_t just_seeked;

    uint8_t amp_res[2];

    uint8_t k0;
    uint8_t kx;
    uint8_t M;
    uint8_t N_master;
    uint8_t N_high;
    uint8_t N_low;
    uint8_t N_Q;
    uint8_t N_L[4];
    uint8_t n[2];

    uint8_t f_master[64];
    uint8_t f_table_res[2][64];
    uint8_t f_table_noise[64];
    uint8_t f_table_lim[4][64];
#ifdef SBR_LOW_POWER
    uint8_t f_group[5][64];
    uint8_t N_G[5];
#endif

    uint8_t table_map_k_to_g[64];

    uint8_t abs_bord_lead[2];
    uint8_t abs_bord_trail[2];
    uint8_t n_rel_lead[2];
    uint8_t n_rel_trail[2];

    uint8_t L_E[2];
    uint8_t L_E_prev[2];
    uint8_t L_Q[2];

    uint8_t t_E[2][6];
    uint8_t t_Q[2][3];
    uint8_t f[2][6];
    uint8_t f_prev[2];

    real_t *G_temp_prev[2][5];
    real_t *Q_temp_prev[2][5];

    int16_t E[2][64][5];
    int16_t E_prev[2][64];
    real_t E_orig[2][64][5];
    real_t E_curr[2][64][5];
    int32_t Q[2][64][2];
    int32_t Q_prev[2][64];
    real_t Q_orig[2][64][2];

    int8_t l_A[2];
    int8_t l_A_prev[2];

    uint8_t bs_invf_mode[2][5];
    uint8_t bs_invf_mode_prev[2][5];
    real_t bwArray[2][64];
    real_t bwArray_prev[2][64];

    uint8_t noPatches;
    uint8_t patchNoSubbands[64];
    uint8_t patchStartSubband[64];

    uint8_t bs_add_harmonic[2][64];
    uint8_t bs_add_harmonic_prev[2][64];

    uint16_t index_noise_prev[2];
    uint8_t psi_is_prev[2];

    uint8_t bs_start_freq_prev;
    uint8_t bs_stop_freq_prev;
    uint8_t bs_xover_band_prev;
    uint8_t bs_freq_scale_prev;
    uint8_t bs_alter_scale_prev;
    uint8_t bs_noise_bands_prev;

    int8_t prevEnvIsShort[2];

    int8_t kx_prev;

    uint8_t Reset;
    uint32_t frame;
    uint32_t header_count;

    uint8_t *data;
    uint16_t data_size;

    uint8_t id_aac;
    qmfa_info *qmfa[2];
    qmfs_info *qmfs[2];

    qmf_t *Xsbr[2];
    qmf_t *Xcodec[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_header_flag;
    uint8_t bs_crc_flag;
    uint16_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_add_harmonic_flag_prev[2];
    uint8_t bs_extended_data;
    uint8_t bs_extension_id;
    uint8_t bs_extension_data;
    uint8_t bs_coupling;
    uint8_t bs_frame_class[2];
    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_df_env[2][9];
    uint8_t bs_df_noise[2][3];
} sbr_info;

sbr_info *sbrDecodeInit();
void sbrDecodeEnd(sbr_info *sbr);

void sbrDecodeFrame(sbr_info *sbr, real_t *left_channel,
                    real_t *right_channel, uint8_t id_aac,
                    uint8_t just_seeked);


#ifdef __cplusplus
}
#endif
#endif


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_e_nf.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#ifdef SBR_DEC

#include <stdlib.h>

#include "sbr_syntax.h"
#include "sbr_e_nf.h"

void extract_envelope_data(sbr_info *sbr, uint8_t ch)
{
    uint8_t l, k;

#if 0
    if (sbr->frame == 19)
    {
        sbr->frame = 19;
    }
#endif

    for (l = 0; l < sbr->L_E[ch]; l++)
    {
        if (sbr->bs_df_env[ch][l] == 0)
        {
            for (k = 1; k < sbr->n[sbr->f[ch][l]]; k++)
            {
                sbr->E[ch][k][l] = sbr->E[ch][k - 1][l] + sbr->E[ch][k][l];
            }

        } else { /* bs_df_env == 1 */

            uint8_t g = (l == 0) ? sbr->f_prev[ch] : sbr->f[ch][l-1];
            int16_t E_prev;

            if (sbr->f[ch][l] == g)
            {
                for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++)
                {
                    if (l == 0)
                        E_prev = sbr->E_prev[ch][k];
                    else
                        E_prev = sbr->E[ch][k][l - 1];

                    sbr->E[ch][k][l] = E_prev + sbr->E[ch][k][l];
                }

            } else if ((g == 1) && (sbr->f[ch][l] == 0)) {
                uint8_t i;

                for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++)
                {
                    for (i = 0; i < sbr->N_high; i++)
                    {
                        if (sbr->f_table_res[HI_RES][i] == sbr->f_table_res[LO_RES][k])
                        {
                            if (l == 0)
                                E_prev = sbr->E_prev[ch][i];
                            else
                                E_prev = sbr->E[ch][i][l - 1];

                            sbr->E[ch][k][l] = E_prev + sbr->E[ch][k][l];
                        }
                    }
                }

            } else if ((g == 0) && (sbr->f[ch][l] == 1)) {
                uint8_t i;

                for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++)
                {
                    for (i = 0; i < sbr->N_low; i++)
                    {
                        if ((sbr->f_table_res[LO_RES][i] <= sbr->f_table_res[HI_RES][k]) &&
                            (sbr->f_table_res[HI_RES][k] < sbr->f_table_res[LO_RES][i + 1]))
                        {
                            if (l == 0)
                                E_prev = sbr->E_prev[ch][i];
                            else
                                E_prev = sbr->E[ch][i][l - 1];

                            sbr->E[ch][k][l] = E_prev + sbr->E[ch][k][l];
                        }
                    }
                }
            }
        }
    }

#if 0
    if (sbr->frame == 23)
    {
        int l, k;

        for (l = 0; l < sbr->L_E[ch]; l++)
        {
            for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++)
            {
                //printf("l:%d k:%d E:%d\n",l,k, sbr->E[ch][k][l]);
                printf("%d\n", sbr->E[ch][k][l]);
            }
        }
        printf("\n");
    }
#endif
}

void extract_noise_floor_data(sbr_info *sbr, uint8_t ch)
{
    uint8_t l, k;

    for (l = 0; l < sbr->L_Q[ch]; l++)
    {
        if (sbr->bs_df_noise[ch][l] == 0)
        {
            for (k = 1; k < sbr->N_Q; k++)
            {
                sbr->Q[ch][k][l] = sbr->Q[ch][k][l] + sbr->Q[ch][k-1][l];
            }
        } else {
            if (l == 0)
            {
                for (k = 0; k < sbr->N_Q; k++)
                {
                    sbr->Q[ch][k][l] = sbr->Q_prev[ch][k] + sbr->Q[ch][k][0];
                }
            } else {
                for (k = 0; k < sbr->N_Q; k++)
                {
                    sbr->Q[ch][k][l] = sbr->Q[ch][k][l - 1] + sbr->Q[ch][k][l];
                }
            }
        }
    }

#if 0
    if (sbr->frame == 23)
    {
        int l, k;

        for (l = 0; l < sbr->L_Q[ch]; l++)
        {
            for (k = 0; k < sbr->N_Q; k++)
            {
                //printf("l:%d k:%d E:%d\n",l,k, sbr->E[ch][k][l]);
                printf("%d\n", sbr->Q[ch][k][l]);
            }
        }
        printf("\n");
    }
#endif
}

/* FIXME: pow() not needed */
void envelope_noise_dequantisation(sbr_info *sbr, uint8_t ch)
{
    if (sbr->bs_coupling == 0)
    {
        uint8_t l, k;
#ifdef FIXED_POINT
        uint8_t amp = (sbr->amp_res[ch]) ? 0 : 1;
#else
        real_t amp = (sbr->amp_res[ch]) ? 1.0 : 0.5;
#endif

        for (l = 0; l < sbr->L_E[ch]; l++)
        {
            for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++)
            {
#ifndef FIXED_POINT
                /* +6 for the *64 */
                sbr->E_orig[ch][k][l] = pow(2, sbr->E[ch][k][l]*amp + 6);
#else
                int8_t exp;

                /* +6 for the *64 and -10 for the /32 in the synthesis QMF
                 * since this is a energy value: (x/32)^2 = (x^2)/1024
                 */
                exp = (sbr->E[ch][k][l] >> amp) + 6 - 10;

//                printf("%d\n", exp);

                if (exp < 0)
                    sbr->E_orig[ch][k][l] = 0; //REAL_CONST(1) >> -exp;
                else
                    sbr->E_orig[ch][k][l] = 1 << exp; //REAL_CONST(1) << exp;

                if (amp && (sbr->E[ch][k][l] & 1))
                    sbr->E_orig[ch][k][l] = MUL(sbr->E_orig[ch][k][l], REAL_CONST(1.414213562));
#endif
            }
        }

        for (l = 0; l < sbr->L_Q[ch]; l++)
        {
            for (k = 0; k < sbr->N_Q; k++)
            {
                if (sbr->Q[ch][k][l] < 0 || sbr->Q[ch][k][l] > 30)
                    sbr->Q_orig[ch][k][l] = 0;
                else {
#ifndef FIXED_POINT
                    sbr->Q_orig[ch][k][l] = pow(2, NOISE_FLOOR_OFFSET - sbr->Q[ch][k][l]);
#else
                    int8_t exp = NOISE_FLOOR_OFFSET - sbr->Q[ch][k][l];
                    if (exp < 0)
                        sbr->Q_orig[ch][k][l] = REAL_CONST(1) >> -exp;
                    else
                        sbr->Q_orig[ch][k][l] = REAL_CONST(1) << exp;
#endif
                }
            }
        }
    }
}

void unmap_envelope_noise(sbr_info *sbr)
{
    uint8_t l, k;
#ifdef FIXED_POINT
    uint8_t amp0 = (sbr->amp_res[0]) ? 0 : 1;
    uint8_t amp1 = (sbr->amp_res[1]) ? 0 : 1;
#else
    real_t amp0 = (sbr->amp_res[0]) ? 1.0 : 0.5;
    real_t amp1 = (sbr->amp_res[1]) ? 1.0 : 0.5;
#endif

    for (l = 0; l < sbr->L_E[0]; l++)
    {
        for (k = 0; k < sbr->n[sbr->f[0][l]]; k++)
        {
            real_t l_temp, r_temp;

#ifdef FIXED_POINT
            int8_t exp;

            /* +6: * 64 ; +1: * 2 ; -10: /1024 QMF */
            exp = (sbr->E[0][k][l] >> amp0) - 3;

//            printf("%d\n", exp);

            if (exp < 0)
                l_temp = REAL_CONST(1) >> -exp;
            else
                l_temp = REAL_CONST(1) << exp;

            if (amp0 && (sbr->E[0][k][l] & 1))
                l_temp = MUL(l_temp, REAL_CONST(1.414213562373095));

            /* UN_MAP removed: (x / 4096) same as (x >> 12) */
            exp = (sbr->E[1][k][l] >> amp1) - 12;

//            printf("%d\n", exp);

            if (exp < 0)
                r_temp = REAL_CONST(1) >> -exp;
            else
                r_temp = REAL_CONST(1) << exp;

            if (amp1 && (sbr->E[1][k][l] & 1))
                r_temp = MUL(r_temp, REAL_CONST(1.414213562373095));
#else
            /* +6: * 64 ; +1: * 2 */
            l_temp = pow(2, sbr->E[0][k][l]*amp0 + 7);
            /* UN_MAP removed: (x / 4096) same as (x >> 12) */
            r_temp = pow(2, sbr->E[1][k][l]*amp1 - 12);
#endif


#ifdef FIXED_POINT
            {
                real_t tmp = REAL_CONST(1.0) + r_temp;
                sbr->E_orig[1][k][l] = SBR_DIV(l_temp, tmp);
            }
#else
            sbr->E_orig[1][k][l] = l_temp / (1.0 + r_temp);
#endif
            sbr->E_orig[0][k][l] = MUL(r_temp, sbr->E_orig[1][k][l]);

#ifdef FIXED_POINT
            sbr->E_orig[0][k][l] >>= REAL_BITS;
            sbr->E_orig[1][k][l] >>= REAL_BITS;
#endif

            //printf("%f\t%f\n", sbr->E_orig[0][k][l] /(float)(1<<REAL_BITS), sbr->E_orig[1][k][l] /(float)(1<<REAL_BITS));
            //printf("%f\t%f\n", sbr->E_orig[0][k][l]/1024., sbr->E_orig[1][k][l]/1024.);
        }
    }
    for (l = 0; l < sbr->L_Q[0]; l++)
    {
        for (k = 0; k < sbr->N_Q; k++)
        {
            if ((sbr->Q[0][k][l] < 0 || sbr->Q[0][k][l] > 30) ||
                (sbr->Q[1][k][l] < 0 || sbr->Q[1][k][l] > 30))
            {
                sbr->Q_orig[0][k][l] = 0;
                sbr->Q_orig[1][k][l] = 0;
            } else {
                real_t l_temp, r_temp;

#ifndef FIXED_POINT
                l_temp = pow(2.0, NOISE_FLOOR_OFFSET - sbr->Q[0][k][l] + 1);
                r_temp = pow(2.0, sbr->Q[1][k][l] - 12);
#else
                int8_t exp;

                exp = NOISE_FLOOR_OFFSET - sbr->Q[0][k][l] + 1;
                if (exp < 0)
                    l_temp = REAL_CONST(1) >> -exp;
                else
                    l_temp = REAL_CONST(1) << exp;

                exp = sbr->Q[1][k][l] - 12;
                if (exp < 0)
                    r_temp = REAL_CONST(1) >> -exp;
                else
                    r_temp = REAL_CONST(1) << exp;
#endif

#ifdef FIXED_POINT
                sbr->Q_orig[1][k][l] = SBR_DIV(l_temp, (REAL_CONST(1.0) + r_temp));
#else
                sbr->Q_orig[1][k][l] = l_temp / (1.0 + r_temp);
#endif
                sbr->Q_orig[0][k][l] = MUL(r_temp, sbr->Q_orig[1][k][l]);
            }
        }
    }
}

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_e_nf.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_E_NF_H__
#define __SBR_E_NF_H__

#ifdef __cplusplus
extern "C" {
#endif

void extract_envelope_data(sbr_info *sbr, uint8_t ch);
void extract_noise_floor_data(sbr_info *sbr, uint8_t ch);
void envelope_noise_dequantisation(sbr_info *sbr, uint8_t ch);


#ifdef __cplusplus
}
#endif
#endif


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_fbt.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

/* Calculate frequency band tables */

#include "common.h"
#include "structs.h"

#ifdef SBR_DEC

#include <stdlib.h>

#include "sbr_syntax.h"
#include "sbr_fbt.h"


/* calculate the start QMF channel for the master frequency band table */
/* parameter is also called k0 */
uint16_t qmf_start_channel(uint8_t bs_start_freq, uint8_t bs_samplerate_mode,
                           uint32_t sample_rate)
{
    static int8_t offset[7][16] = {
        { -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7 },
        { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13 },
        { -5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16 },
        { -6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16 },
        { -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20 },
        { -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24 },
        { 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24, 28, 33 }
    };
    uint8_t startMin;

    if (sample_rate >= 64000)
    {
        startMin = (uint8_t)((5000.*128.)/(float)sample_rate + 0.5);
    } else if (sample_rate < 32000) {
        startMin = (uint8_t)((3000.*128.)/(float)sample_rate + 0.5);
    } else {
        startMin = (uint8_t)((4000.*128.)/(float)sample_rate + 0.5);
    }

    if (bs_samplerate_mode)
    {
        switch (sample_rate)
        {
        case 16000:
            return startMin + offset[0][bs_start_freq];
        case 22050:
            return startMin + offset[1][bs_start_freq];
        case 24000:
            return startMin + offset[2][bs_start_freq];
        case 32000:
            return startMin + offset[3][bs_start_freq];
        default:
            if (sample_rate > 64000)
            {
                return startMin + offset[5][bs_start_freq];
            } else { /* 44100 <= sample_rate <= 64000 */
                return startMin + offset[4][bs_start_freq];
            }
        }
    } else {
        return startMin + offset[6][bs_start_freq];
    }
}

static int32_t longcmp(const void *a, const void *b)
{
    return ((int32_t)(*(int32_t*)a - *(int32_t*)b));
}

/* calculate the stop QMF channel for the master frequency band table */
/* parameter is also called k2 */
uint16_t qmf_stop_channel(uint8_t bs_stop_freq, uint32_t sample_rate,
                          uint16_t k0)
{
    if (bs_stop_freq == 15)
    {
        return min(64, k0 * 3);
    } else if (bs_stop_freq == 14) {
        return min(64, k0 * 2);
    } else {
        uint8_t i;
        uint8_t stopMin;
        int32_t stopDk[13], stopDk_t[14], k2;

        if (sample_rate >= 64000)
        {
            stopMin = (uint8_t)((10000.*128.)/(float)sample_rate + 0.5);
        } else if (sample_rate < 32000) {
            stopMin = (uint8_t)((6000.*128.)/(float)sample_rate + 0.5);
        } else {
            stopMin = (uint8_t)((8000.*128.)/(float)sample_rate + 0.5);
        }

        for (i = 0; i <= 13; i++)
        {
            stopDk_t[i] = (int32_t)(stopMin*pow(64.0/stopMin, i/13.0) + 0.5);
        }
        for (i = 0; i < 13; i++)
        {
            stopDk[i] = stopDk_t[i+1] - stopDk_t[i];
        }

        /* needed? or does this always reverse the array? */
        qsort(stopDk, 13, sizeof(stopDk[0]), longcmp);

        k2 = stopMin;
        for (i = 0; i < bs_stop_freq; i++)
        {
            k2 += stopDk[i];
        }
        return min(64, k2);
    }

    return 0;
}

/* calculate the master frequency table from k0, k2, bs_freq_scale
   and bs_alter_scale

   version for bs_freq_scale = 0
*/
void master_frequency_table_fs0(sbr_info *sbr, uint16_t k0, uint16_t k2,
                                uint8_t bs_alter_scale)
{
    int8_t incr;
    uint8_t k;
    uint8_t dk;
    uint32_t nrBands, k2Achieved;
    int32_t k2Diff, vDk[64];

    memset(vDk, 0, 64*sizeof(int32_t));

    /* mft only defined for k2 > k0 */
    if (k2 <= k0)
    {
        sbr->N_master = 0;
        return;
    }

    dk = bs_alter_scale ? 2 : 1;
    nrBands = 2 * (int32_t)((float)(k2-k0)/(dk*2) + (-1+dk)/2.0f);
    nrBands = min(nrBands, 64);

    k2Achieved = k0 + nrBands * dk;
    k2Diff = k2 - k2Achieved;
    /* for (k = 0; k <= nrBands; k++) Typo fix */
    for (k = 0; k < nrBands; k++)
        vDk[k] = dk;

    if (k2Diff)
    {
        incr = (k2Diff > 0) ? -1 : 1;
        k = (k2Diff > 0) ? (nrBands-1) : 0;

        while (k2Diff != 0)
        {
            vDk[k] -= incr;
            k += incr;
            k2Diff += incr;
        }
    }

    sbr->f_master[0] = k0;
    for (k = 1; k <= nrBands; k++)
        sbr->f_master[k] = sbr->f_master[k-1] + vDk[k-1];

    sbr->N_master = nrBands;
    sbr->N_master = min(sbr->N_master, 64);

#if 0
    printf("f_master[%d]: ", nrBands);
    for (k = 0; k <= nrBands; k++)
    {
        printf("%d ", sbr->f_master[k]);
    }
    printf("\n");
#endif
}

/*
   version for bs_freq_scale > 0
*/
void master_frequency_table(sbr_info *sbr, uint16_t k0, uint16_t k2,
                            uint8_t bs_freq_scale, uint8_t bs_alter_scale)
{
    uint8_t k, bands, twoRegions;
    uint16_t k1;
    uint32_t nrBand0, nrBand1;
    int32_t vDk0[64], vDk1[64];
    int32_t vk0[64], vk1[64];
    float warp;
    uint8_t temp1[] = { 12, 10, 8 };
    float temp2[] = { 1.0, 1.3 };

    /* without memset code enters infinte loop,
       so there must be some wrong table access */
    memset(vDk0, 0, 64*sizeof(int32_t));
    memset(vDk1, 0, 64*sizeof(int32_t));
    memset(vk0, 0, 64*sizeof(int32_t));
    memset(vk1, 0, 64*sizeof(int32_t));

    /* mft only defined for k2 > k0 */
    if (k2 <= k0)
    {
        sbr->N_master = 0;
        return;
    }

    bands = temp1[bs_freq_scale-1];
    warp = temp2[bs_alter_scale];

    if ((float)k2/(float)k0 > 2.2449)
    {
        twoRegions = 1;
        k1 = 2 * k0;
    } else {
        twoRegions = 0;
        k1 = k2;
    }

    nrBand0 = 2 * (int32_t)(bands * log((float)k1/(float)k0)/(2.0*log(2.0)) + 0.5);
    nrBand0 = min(nrBand0, 64);
    for (k = 0; k <= nrBand0; k++)
    {
        /* MAPLE */
        vDk0[k] = (int32_t)(k0 * pow((float)k1/(float)k0, (k+1)/(float)nrBand0)+0.5) -
            (int32_t)(k0 * pow((float)k1/(float)k0, k/(float)nrBand0)+0.5);
    }

    /* needed? */
    qsort(vDk0, nrBand0, sizeof(vDk0[0]), longcmp);

    vk0[0] = k0;
    for (k = 1; k <= nrBand0; k++)
    {
        vk0[k] = vk0[k-1] + vDk0[k-1];
    }

    if (!twoRegions)
    {
        for (k = 0; k <= nrBand0; k++)
            sbr->f_master[k] = vk0[k];

        sbr->N_master = nrBand0;
        sbr->N_master = min(sbr->N_master, 64);
        return;
    }

    nrBand1 = 2 * (int32_t)(bands * log((float)k2/(float)k1)/(2.0 * log(2.0) * warp) + 0.5);
    nrBand1 = min(nrBand1, 64);

    for (k = 0; k <= nrBand1 - 1; k++)
    {
        vDk1[k] = (int32_t)(k1 * pow((float)k2/(float)k1, (k+1)/(float)nrBand1)+0.5) -
            (int32_t)(k1 * pow((float)k2/(float)k1, k/(float)nrBand1)+0.5);
    }

    if (vDk1[0] < vDk0[nrBand0 - 1])
    {
        int32_t change;

        /* needed? */
        qsort(vDk1, nrBand1 + 1, sizeof(vDk1[0]), longcmp);
        change = vDk0[nrBand0 - 1] - vDk1[0];
        vDk1[0] = vDk0[nrBand0 - 1];
        vDk1[nrBand1 - 1] = vDk1[nrBand1 - 1] - change;
    }

    /* needed? */
    qsort(vDk1, nrBand1, sizeof(vDk1[0]), longcmp);
    vk1[0] = k1;
    for (k = 1; k <= nrBand1; k++)
    {
        vk1[k] = vk1[k-1] + vDk1[k-1];
    }

    sbr->N_master = nrBand0 + nrBand1;
    sbr->N_master = min(sbr->N_master, 64);
    for (k = 0; k <= nrBand0; k++)
    {
        sbr->f_master[k] = vk0[k];
    }
    for (k = nrBand0 + 1; k <= sbr->N_master; k++)
    {
        sbr->f_master[k] = vk1[k - nrBand0];
    }

#if 0
    printf("f_master[%d]: ", sbr->N_master);
    for (k = 0; k <= sbr->N_master; k++)
    {
        printf("%d ", sbr->f_master[k]);
    }
    printf("\n");
#endif
}

/* calculate the derived frequency border tables from f_master */
void derived_frequency_table(sbr_info *sbr, uint8_t bs_xover_band,
                             uint16_t k2)
{
    uint8_t k, i;
    uint32_t minus;

    sbr->N_high = sbr->N_master - bs_xover_band;

    /* is this accurate? */
    sbr->N_low = sbr->N_high/2 + (sbr->N_high - 2 * (sbr->N_high/2));

    sbr->n[0] = sbr->N_low;
    sbr->n[1] = sbr->N_high;

    for (k = 0; k <= sbr->N_high; k++)
    {
        sbr->f_table_res[HI_RES][k] = sbr->f_master[k + bs_xover_band];
    }

    sbr->M = sbr->f_table_res[HI_RES][sbr->N_high] - sbr->f_table_res[HI_RES][0];
    sbr->kx = sbr->f_table_res[HI_RES][0];

    /* correct? */
    minus = (sbr->N_high & 1) ? 1 : 0;

    for (k = 0; k <= sbr->N_low; k++)
    {
        if (k == 0)
            i = 0;
        else
            i = 2*k - minus;
        sbr->f_table_res[LO_RES][k] = sbr->f_table_res[HI_RES][i];
    }
    /* end correct? */

#if 0
    printf("f_table_res[HI_RES][%d]: ", sbr->N_high);
    for (k = 0; k <= sbr->N_high; k++)
    {
        printf("%d ", sbr->f_table_res[HI_RES][k]);
    }
    printf("\n");
#endif
#if 0
    printf("f_table_res[LO_RES][%d]: ", sbr->N_low);
    for (k = 0; k <= sbr->N_low; k++)
    {
        printf("%d ", sbr->f_table_res[LO_RES][k]);
    }
    printf("\n");
#endif

    sbr->N_Q = 0;
    if (sbr->bs_noise_bands == 0)
    {
        sbr->N_Q = 1;
    } else {
        /* MAPLE */
        sbr->N_Q = max(1, (int32_t)(sbr->bs_noise_bands*(log(k2/(float)sbr->kx)/log(2.0)) + 0.5));
        if (sbr->N_Q == 0)
            sbr->N_Q = 1;
    }
    sbr->N_Q = min(5, sbr->N_Q);

    for (k = 0; k <= sbr->N_Q; k++)
    {
        if (k == 0)
            i = 0;
        else /* is this accurate? */
            i = i + (int32_t)((sbr->N_low - i)/(sbr->N_Q + 1 - k));
        sbr->f_table_noise[k] = sbr->f_table_res[LO_RES][i];
    }

    /* build table for mapping k to g in hf patching */
    for (k = 0; k < 64; k++)
    {
        uint8_t g;
        for (g = 0; g < sbr->N_Q; g++)
        {
            if ((sbr->f_table_noise[g] <= k) &&
                (k < sbr->f_table_noise[g+1]))
            {
                sbr->table_map_k_to_g[k] = g;
                break;
            }
        }
    }

#if 0
    printf("f_table_noise[%d]: ", sbr->N_Q);
    for (k = 0; k <= sbr->N_Q; k++)
    {
        printf("%d ", sbr->f_table_noise[k]);
    }
    printf("\n");
#endif
}

/* TODO: blegh, ugly */
/* Modified to calculate for all possible bs_limiter_bands always
 * This reduces the number calls to this functions needed (now only on
 * header reset)
 */
void limiter_frequency_table(sbr_info *sbr)
{
    static real_t limiterBandsPerOctave[] = { REAL_CONST(1.2),
        REAL_CONST(2), REAL_CONST(3) };
    uint8_t k, s;
    int8_t nrLim;
    int32_t limTable[100 /*TODO*/];
    uint8_t patchBorders[64/*??*/];
    real_t limBands;

    sbr->f_table_lim[0][0] = sbr->f_table_res[LO_RES][0] - sbr->kx;
    sbr->f_table_lim[0][1] = sbr->f_table_res[LO_RES][sbr->N_low] - sbr->kx;
    sbr->N_L[0] = 1;

    for (s = 1; s < 4; s++)
    {
        memset(limTable, 0, 100*sizeof(int32_t));

        limBands = limiterBandsPerOctave[s - 1];

        patchBorders[0] = sbr->kx;
        for (k = 1; k <= sbr->noPatches; k++)
        {
            patchBorders[k] = patchBorders[k-1] + sbr->patchNoSubbands[k-1];
        }

        for (k = 0; k <= sbr->N_low; k++)
        {
            limTable[k] = sbr->f_table_res[LO_RES][k];
        }
        for (k = 1; k < sbr->noPatches; k++)
        {
            limTable[k+sbr->N_low] = patchBorders[k];
        }

        /* needed */
        qsort(limTable, sbr->noPatches + sbr->N_low, sizeof(limTable[0]), longcmp);
        k = 1;
        nrLim = sbr->noPatches + sbr->N_low - 1;

        if (nrLim < 0) // TODO: BIG FAT PROBLEM
            return;

restart:
        if (k <= nrLim)
        {
            real_t nOctaves;

            if (limTable[k-1] != 0)
                nOctaves = REAL_CONST(log((float)limTable[k]/(float)limTable[k-1])/log(2.0));
            else
                nOctaves = 0;

            if ((MUL(nOctaves,limBands)) < REAL_CONST(0.49))
            {
                uint8_t i;
                if (limTable[k] != limTable[k-1])
                {
                    uint8_t found = 0, found2 = 0;
                    for (i = 0; i <= sbr->noPatches; i++)
                    {
                        if (limTable[k] == patchBorders[i])
                            found = 1;
                    }
                    if (found)
                    {
                        found2 = 0;
                        for (i = 0; i <= sbr->noPatches; i++)
                        {
                            if (limTable[k-1] == patchBorders[i])
                                found2 = 1;
                        }
                        if (found2)
                        {
                            k++;
                            goto restart;
                        } else {
                            /* remove (k-1)th element */
                            limTable[k-1] = sbr->f_table_res[LO_RES][sbr->N_low];
                            qsort(limTable, sbr->noPatches + sbr->N_low, sizeof(limTable[0]), longcmp);
                            nrLim--;
                            goto restart;
                        }
                    }
                }
                /* remove kth element */
                limTable[k] = sbr->f_table_res[LO_RES][sbr->N_low];
                qsort(limTable, nrLim, sizeof(limTable[0]), longcmp);
                nrLim--;
                goto restart;
            } else {
                k++;
                goto restart;
            }
        }

        sbr->N_L[s] = nrLim;
        for (k = 0; k <= nrLim; k++)
        {
            sbr->f_table_lim[s][k] = limTable[k] - sbr->kx;
        }

#if 0
        printf("f_table_lim[%d][%d]: ", s, sbr->N_L[s]);
        for (k = 0; k <= sbr->N_L[s]; k++)
        {
            printf("%d ", sbr->f_table_lim[s][k]);
        }
        printf("\n");
#endif
    }
}

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_fbt.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_FBT_H__
#define __SBR_FBT_H__

#ifdef __cplusplus
extern "C" {
#endif

uint16_t qmf_start_channel(uint8_t bs_start_freq, uint8_t bs_samplerate_mode,
                           uint32_t sample_rate);
uint16_t qmf_stop_channel(uint8_t bs_stop_freq, uint32_t sample_rate,
                          uint16_t k0);
void master_frequency_table_fs0(sbr_info *sbr, uint16_t k0, uint16_t k2,
                                uint8_t bs_alter_scale);
void master_frequency_table(sbr_info *sbr, uint16_t k0, uint16_t k2,
                            uint8_t bs_freq_scale, uint8_t bs_alter_scale);
void derived_frequency_table(sbr_info *sbr, uint8_t bs_xover_band,
                             uint16_t k2);
void limiter_frequency_table(sbr_info *sbr);


#ifdef __cplusplus
}
#endif
#endif


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_hfadj.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

/* High Frequency adjustment */

#include "common.h"
#include "structs.h"

#ifdef SBR_DEC

#include "sbr_syntax.h"
#include "sbr_hfadj.h"

#include "sbr_noise.h"

void hf_adjustment(sbr_info *sbr, qmf_t *Xsbr
#ifdef SBR_LOW_POWER
                   ,real_t *deg /* aliasing degree */
#endif
                   ,uint8_t ch)
{
    sbr_hfadj_info adj;

    memset(&adj, 0, sizeof(sbr_hfadj_info));

    map_noise_data(sbr, &adj, ch);
    map_sinusoids(sbr, &adj, ch);

    estimate_current_envelope(sbr, &adj, Xsbr, ch);

    calculate_gain(sbr, &adj, ch);

#if 1

#ifdef SBR_LOW_POWER
    calc_gain_groups(sbr, &adj, deg, ch);
    aliasing_reduction(sbr, &adj, deg, ch);
#endif

    hf_assembly(sbr, &adj, Xsbr, ch);

#endif
}

static void map_noise_data(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
{
    uint8_t l, i;
    uint32_t m;

    for (l = 0; l < sbr->L_E[ch]; l++)
    {
        for (i = 0; i < sbr->N_Q; i++)
        {
            for (m = sbr->f_table_noise[i]; m < sbr->f_table_noise[i+1]; m++)
            {
                uint8_t k;

                adj->Q_mapped[m - sbr->kx][l] = 0;

                for (k = 0; k < 2; k++)
                {
                    if ((sbr->t_E[ch][l] >= sbr->t_Q[ch][k]) &&
                        (sbr->t_E[ch][l+1] <= sbr->t_Q[ch][k+1]))
                    {
                        adj->Q_mapped[m - sbr->kx][l] =
                            sbr->Q_orig[ch][i][k];
                    }
                }
            }
        }
    }
}

static void map_sinusoids(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
{
    uint8_t l, i, m, k, k1, k2, delta_S, l_i, u_i;

    if (sbr->bs_frame_class[ch] == FIXFIX)
    {
        sbr->l_A[ch] = -1;
    } else if (sbr->bs_frame_class[ch] == VARFIX) {
        if (sbr->bs_pointer[ch] > 1)
            sbr->l_A[ch] = -1;
        else
            sbr->l_A[ch] = sbr->bs_pointer[ch] - 1;
    } else {
        if (sbr->bs_pointer[ch] == 0)
            sbr->l_A[ch] = -1;
        else
            sbr->l_A[ch] = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch];
    }

    for (l = 0; l < 5; l++)
    {
        for (i = 0; i < 64; i++)
        {
            adj->S_index_mapped[i][l] = 0;
            adj->S_mapped[i][l] = 0;
        }
    }

    for (l = 0; l < sbr->L_E[ch]; l++)
    {
        for (i = 0; i < sbr->N_high; i++)
        {
            for (m = sbr->f_table_res[HI_RES][i]; m < sbr->f_table_res[HI_RES][i+1]; m++)
            {
                uint8_t delta_step = 0;
                if ((l >= sbr->l_A[ch]) || ((sbr->bs_add_harmonic_prev[ch][i]) &&
                    (sbr->bs_add_harmonic_flag_prev[ch])))
                {
                    delta_step = 1;
                }

                if (m == (int32_t)((real_t)(sbr->f_table_res[HI_RES][i+1]+sbr->f_table_res[HI_RES][i])/2.))
                {
                    adj->S_index_mapped[m - sbr->kx][l] =
                        delta_step * sbr->bs_add_harmonic[ch][i];
                } else {
                    adj->S_index_mapped[m - sbr->kx][l] = 0;
                }

#if 0
                if (sbr->frame == 95)
                {
                    printf("%d %d %d %d %d\n", adj->S_index_mapped[m - sbr->kx][l],
                        sbr->bs_add_harmonic[ch][i], sbr->bs_add_harmonic_prev[ch][i],
                        l, sbr->l_A[ch]);
                }
#endif
            }
        }
    }

    for (l = 0; l < sbr->L_E[ch]; l++)
    {
        for (i = 0; i < sbr->N_high; i++)
        {
            if (sbr->f[ch][l] == 1)
            {
                k1 = i;
                k2 = i + 1;
            } else {
                for (k1 = 0; k1 < sbr->N_low; k1++)
                {
                    if ((sbr->f_table_res[HI_RES][i] >= sbr->f_table_res[LO_RES][k1]) &&
                        (sbr->f_table_res[HI_RES][i+1] <= sbr->f_table_res[LO_RES][k1+1]))
                    {
                        break;
                    }
                }
                for (k2 = 0; k2 < sbr->N_low; k2++)
                {
                    if ((sbr->f_table_res[HI_RES][i+1] >= sbr->f_table_res[LO_RES][k2]) &&
                        (sbr->f_table_res[HI_RES][i+2] <= sbr->f_table_res[LO_RES][k2+1]))
                    {
                        break;
                    }
                }
            }

            l_i = sbr->f_table_res[sbr->f[ch][l]][k1];
            u_i = sbr->f_table_res[sbr->f[ch][l]][k2];

            delta_S = 0;
            for (k = l_i; k < u_i; k++)
            {
                if (adj->S_index_mapped[k - sbr->kx][l] == 1)
                    delta_S = 1;
            }

            for (m = l_i; m < u_i; m++)
            {
                adj->S_mapped[m - sbr->kx][l] = delta_S;
            }
        }
    }
}

static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t *Xsbr,
                                      uint8_t ch)
{
    uint8_t m, l, j, k, k_l, k_h, p;
    real_t nrg, div;

    if (sbr->bs_interpol_freq == 1)
    {
        for (l = 0; l < sbr->L_E[ch]; l++)
        {
            uint8_t i, l_i, u_i;

            l_i = sbr->t_E[ch][l];
            u_i = sbr->t_E[ch][l+1];

            div = (real_t)(u_i - l_i);

            for (m = 0; m < sbr->M; m++)
            {
                nrg = 0;

                for (i = l_i + tHFAdj; i < u_i + tHFAdj; i++)
                {
#ifdef FIXED_POINT
                    nrg += ((QMF_RE(Xsbr[(i<<6) + m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[(i<<6) + m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS);
#else
                    nrg += MUL(QMF_RE(Xsbr[(i<<6) + m + sbr->kx]), QMF_RE(Xsbr[(i<<6) + m + sbr->kx]))
#ifndef SBR_LOW_POWER
                        + MUL(QMF_IM(Xsbr[(i<<6) + m + sbr->kx]), QMF_IM(Xsbr[(i<<6) + m + sbr->kx]))
#endif
                        ;
#endif
                }

                sbr->E_curr[ch][m][l] = nrg / div;
#ifdef SBR_LOW_POWER
#ifdef FIXED_POINT
                sbr->E_curr[ch][m][l] <<= 1;
#else
                sbr->E_curr[ch][m][l] *= 2;
#endif
#endif
            }
        }
    } else {
        for (l = 0; l < sbr->L_E[ch]; l++)
        {
            for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++)
            {
                k_l = sbr->f_table_res[sbr->f[ch][l]][p];
                k_h = sbr->f_table_res[sbr->f[ch][l]][p+1];

                for (k = k_l; k < k_h; k++)
                {
                    uint8_t i, l_i, u_i;
                    nrg = 0.0;

                    l_i = sbr->t_E[ch][l];
                    u_i = sbr->t_E[ch][l+1];

                    div = (real_t)((u_i - l_i)*(k_h - k_l + 1));

                    for (i = l_i + tHFAdj; i < u_i + tHFAdj; i++)
                    {
                        for (j = k_l; j < k_h; j++)
                        {
#ifdef FIXED_POINT
                            nrg += ((QMF_RE(Xsbr[(i<<6) + j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[(i<<6) + j])+(1<<(REAL_BITS-1)))>>REAL_BITS);
#else
                            nrg += MUL(QMF_RE(Xsbr[(i<<6) + j]), QMF_RE(Xsbr[(i<<6) + j]))
#ifndef SBR_LOW_POWER
                                + MUL(QMF_IM(Xsbr[(i<<6) + j]), QMF_IM(Xsbr[(i<<6) + j]))
#endif
                                ;
#endif
                        }
                    }

                    sbr->E_curr[ch][k - sbr->kx][l] = nrg / div;
#ifdef SBR_LOW_POWER
#ifdef FIXED_POINT
                    sbr->E_curr[ch][k - sbr->kx][l] <<= 1;
#else
                    sbr->E_curr[ch][k - sbr->kx][l] *= 2;
#endif
#endif
                }
            }
        }
    }
}

#ifdef FIXED_POINT
#define step(shift) \
    if ((0x40000000l >> shift) + root <= value)       \
    {                                                 \
        value -= (0x40000000l >> shift) + root;       \
        root = (root >> 1) | (0x40000000l >> shift);  \
    } else {                                          \
        root = root >> 1;                             \
    }

/* fixed point square root approximation */
real_t sbr_sqrt(real_t value)
{
    real_t root = 0;

    step( 0); step( 2); step( 4); step( 6);
    step( 8); step(10); step(12); step(14);
    step(16); step(18); step(20); step(22);
    step(24); step(26); step(28); step(30);

    if (root < value)
        ++root;

    root <<= (REAL_BITS/2);

    return root;
}
real_t sbr_sqrt_int(real_t value)
{
    real_t root = 0;

    step( 0); step( 2); step( 4); step( 6);
    step( 8); step(10); step(12); step(14);
    step(16); step(18); step(20); step(22);
    step(24); step(26); step(28); step(30);

    if (root < value)
        ++root;

    return root;
}
#define SBR_SQRT_FIX(A) sbr_sqrt(A)
#define SBR_SQRT_INT(A) sbr_sqrt_int(A)
#endif

#ifdef FIXED_POINT
#define EPS (1) /* smallest number available in fixed point */
#else
#define EPS (1e-12)
#endif

#ifdef FIXED_POINT
#define ONE (REAL_CONST(1)>>10)
#else
#define ONE (1)
#endif


#ifdef FIXED_POINT
static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
{
    uint8_t m, l, k, i;

    real_t Q_M_lim[64];
    real_t G_lim[64];
    real_t G_boost;
    real_t S_M[64];
    uint8_t table_map_res_to_m[64];


    for (l = 0; l < sbr->L_E[ch]; l++)
    {
        real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;

        for (i = 0; i < sbr->n[sbr->f[ch][l]]; i++)
        {
            for (m = sbr->f_table_res[sbr->f[ch][l]][i]; m < sbr->f_table_res[sbr->f[ch][l]][i+1]; m++)
            {
                table_map_res_to_m[m - sbr->kx] = i;
            }
        }

        for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
        {
            real_t G_max;
            real_t den = 0;
            real_t acc1 = 0;
            real_t acc2 = 0;

            for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k];
                 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++)
            {
                /* E_orig: integer */
                acc1 += sbr->E_orig[ch][table_map_res_to_m[m]][l];
                /* E_curr: integer */
                acc2 += sbr->E_curr[ch][m][l];
            }

            /* G_max: fixed point */
            if (acc2 == 0)
            {
                G_max = 0xFFF;
            } else {
                G_max = (((int64_t)acc1)<<REAL_BITS) / acc2;
                switch (sbr->bs_limiter_gains)
                {
                case 0: G_max >>= 1; break;
                case 2: G_max <<= 1; break;
                default: break;
                }
            }

            //printf("%f %d %d\n", G_max /(float)(1<<REAL_BITS), acc1, acc2);

            for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k];
                 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++)
            {
                real_t d, Q_M, G;
                real_t div2;

                /* Q_mapped: fixed point */
                /* div2: fixed point COEF */
                real_t tmp2 = adj->Q_mapped[m][l] << (COEF_BITS-REAL_BITS);
                real_t tmp = COEF_CONST(1) + tmp2;
                if (tmp == 0)
                    div2 = COEF_CONST(1);
                else
                    div2 = (((int64_t)tmp2 << COEF_BITS)/tmp);

                //printf("%f\n", div2 / (float)(1<<COEF_BITS));

                /* Q_M: integer */
                Q_M = MUL_R_C(sbr->E_orig[ch][table_map_res_to_m[m]][l], div2);

                //printf("%d\n", Q_M /* / (float)(1<<REAL_BITS)*/);

                if (adj->S_mapped[m][l] == 0)
                {
                    real_t tmp, tmp2;

                    S_M[m] = 0;

                    /* d: fixed point */
                    tmp2 = adj->Q_mapped[m][l] /* << (COEF_BITS-REAL_BITS)*/;
                    tmp = REAL_CONST(1) + delta*tmp2;
                    d = (((int64_t)REAL_CONST(1))<<REAL_BITS) / (tmp);

                    /* G: fixed point */
                    G = (((int64_t)sbr->E_orig[ch][table_map_res_to_m[m]][l])<<REAL_BITS) / (1 + sbr->E_curr[ch][m][l]);
                    G = MUL(G, d);

                    //printf("%f\n", G/(float)(1<<REAL_BITS));

                } else {

                    real_t div;

                    /* div: fixed point COEF */
                    real_t tmp = COEF_CONST(1.0) + (adj->Q_mapped[m][l] << (COEF_BITS-REAL_BITS));
                    real_t tmp2 = COEF_CONST(adj->S_mapped[m][l]);
                    if (tmp == 0)
                        div = COEF_CONST(1);
                    else
                        div = (((int64_t)tmp2 << COEF_BITS)/tmp);

                    //printf("%f\n", div/(float)(1<<COEF_BITS));

                    /* S_M: integer */
                    S_M[m] = MUL_R_C(sbr->E_orig[ch][table_map_res_to_m[m]][l], div);

                    //printf("%d\n", S_M[m]);

                    /* G: fixed_point */
                    if ((ONE + sbr->E_curr[ch][m][l]) == 0)
                        G = 0xFFF; // uhm???
                    else {
                        real_t tmp = ONE + sbr->E_curr[ch][m][l];
                        /* tmp2: fixed point */
                        real_t tmp2 = (((int64_t)(sbr->E_orig[ch][table_map_res_to_m[m]][l]))<<REAL_BITS)/(tmp);
                        G = MUL_R_C(tmp2, div2);
                    }

                    //printf("%f\n", G/(float)(1<<REAL_BITS));
                }

                /* limit the additional noise energy level */
                /* and apply the limiter */

                /* G_lim: fixed point */
                /* Q_M_lim: integer */
                if (G_max > G)
                {
                    Q_M_lim[m] = Q_M;
                    G_lim[m] = G;
                } else {
                    real_t tmp;
                    if (G == 0)
                        tmp = 0xFFF;
                    else
                        tmp = SBR_DIV(G_max, G);
                    Q_M_lim[m] = MUL(Q_M, tmp);
                    G_lim[m] = G_max;
                }

                /* E_curr: integer, using MUL() is NOT OK */
                den += MUL(sbr->E_curr[ch][m][l], G_lim[m]);
                if (adj->S_index_mapped[m][l])
                    den += S_M[m];
                else if (l != sbr->l_A[ch])
                    den += Q_M_lim[m];
            }

            //printf("%d\n", den);

            /* G_boost: fixed point */
            if ((den + EPS) == 0)
                G_boost = REAL_CONST(2.51188643);
            else
                G_boost = (((int64_t)(acc1 + EPS))<<REAL_BITS)/(den + EPS);
            G_boost = min(G_boost, REAL_CONST(2.51188643) /* 1.584893192 ^ 2 */);

            for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k];
                 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++)
            {
                /* apply compensation to gain, noise floor sf's and sinusoid levels */
#ifndef SBR_LOW_POWER
                /* G_lim_boost: fixed point */
                adj->G_lim_boost[l][m] = SBR_SQRT_FIX(MUL(G_lim[m], G_boost));
#else
                /* sqrt() will be done after the aliasing reduction to save a
                 * few multiplies
                 */
                /* G_lim_boost: fixed point */
                adj->G_lim_boost[l][m] = MUL(G_lim[m], G_boost);
#endif
                /* Q_M_lim_boost: integer */
                adj->Q_M_lim_boost[l][m] = SBR_SQRT_INT(MUL(Q_M_lim[m], G_boost));

                /* S_M_boost: integer */
                if (adj->S_index_mapped[m][l])
                    adj->S_M_boost[l][m] = SBR_SQRT_INT(MUL(S_M[m], G_boost));
                else
                    adj->S_M_boost[l][m] = 0;
            }
        }
    }
}
#else
static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
{
    static real_t limGain[] = { 0.5, 1.0, 2.0, 1e10 };
    uint8_t m, l, k, i;

    real_t Q_M_lim[64];
    real_t G_lim[64];
    real_t G_boost;
    real_t S_M[64];
    uint8_t table_map_res_to_m[64];


    for (l = 0; l < sbr->L_E[ch]; l++)
    {
        real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;

        for (i = 0; i < sbr->n[sbr->f[ch][l]]; i++)
        {
            for (m = sbr->f_table_res[sbr->f[ch][l]][i]; m < sbr->f_table_res[sbr->f[ch][l]][i+1]; m++)
            {
                table_map_res_to_m[m - sbr->kx] = i;
            }
        }

        for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
        {
            real_t G_max;
            real_t den = 0;
            real_t acc1 = 0;
            real_t acc2 = 0;

            for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k];
                 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++)
            {
                acc1 += sbr->E_orig[ch][table_map_res_to_m[m]][l];
                acc2 += sbr->E_curr[ch][m][l];
            }

            G_max = ((EPS + acc1)/(EPS + acc2)) * limGain[sbr->bs_limiter_gains];
            G_max = min(G_max, 1e10);

            //printf("%f %d %d\n", G_max, (int)floor((acc1+EPS)/1024.), (int)floor((acc2+EPS)/1024.));

            for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k];
                 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++)
            {
                real_t d, Q_M, G;
                real_t div2;

                div2 = adj->Q_mapped[m][l] / (1 + adj->Q_mapped[m][l]);

                //printf("%f\n", div2);

                Q_M = sbr->E_orig[ch][table_map_res_to_m[m]][l] * div2;

                //printf("%f\n", Q_M/1024.);

                if (adj->S_mapped[m][l] == 0)
                {
                    S_M[m] = 0;

                    /* fixed point: delta* can stay since it's either 1 or 0 */
                    d = (1 + sbr->E_curr[ch][m][l]) * (1 + delta*adj->Q_mapped[m][l]);

                    //printf("%f\n", d/1024.);

                    G = sbr->E_orig[ch][table_map_res_to_m[m]][l] / d;

                    //printf("%f\n", G);

                } else {
                    real_t div;

                    div = adj->S_mapped[m][l] / (1. + adj->Q_mapped[m][l]);

                    //printf("%f\n", div);

                    S_M[m] = sbr->E_orig[ch][table_map_res_to_m[m]][l] * div;

                    //printf("%f\n", S_M[m]/1024.);

                    G = (sbr->E_orig[ch][table_map_res_to_m[m]][l] / (1. + sbr->E_curr[ch][m][l])) * div2;

                    //printf("%f\n", G);
                }

                /* limit the additional noise energy level */
                /* and apply the limiter */
                if (G_max > G)
                {
                    Q_M_lim[m] = Q_M;
                    G_lim[m] = G;
                } else {
                    Q_M_lim[m] = Q_M * G_max / G;
                    G_lim[m] = G_max;

                    //printf("%f\n", Q_M_lim[m] / 1024.);
                }

                den += sbr->E_curr[ch][m][l] * G_lim[m];
                if (adj->S_index_mapped[m][l])
                    den += S_M[m];
                else if (l != sbr->l_A[ch])
                    den += Q_M_lim[m];
            }

            //printf("%f\n", den/1024.);

            G_boost = (acc1 + EPS) / (den + EPS);
            G_boost = min(G_boost, 2.51188643 /* 1.584893192 ^ 2 */);

            for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k];
                 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++)
            {
                /* apply compensation to gain, noise floor sf's and sinusoid levels */
#ifndef SBR_LOW_POWER
                adj->G_lim_boost[l][m] = sqrt(G_lim[m] * G_boost);
#else
                /* sqrt() will be done after the aliasing reduction to save a
                 * few multiplies
                 */
                adj->G_lim_boost[l][m] = G_lim[m] * G_boost;
#endif
                adj->Q_M_lim_boost[l][m] = sqrt(Q_M_lim[m] * G_boost);

                if (adj->S_index_mapped[m][l])
                    adj->S_M_boost[l][m] = sqrt(S_M[m] * G_boost);
                else
                    adj->S_M_boost[l][m] = 0;
            }
        }
    }
}
#endif

#ifdef SBR_LOW_POWER
static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch)
{
    uint8_t l, k, i;
    uint8_t grouping;

    for (l = 0; l < sbr->L_E[ch]; l++)
    {
        i = 0;
        grouping = 0;

        for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++)
        {
            if (deg[k + 1] && adj->S_mapped[k-sbr->kx][l] == 0)
            {
                if (grouping == 0)
                {
                    sbr->f_group[l][i] = k;
                    grouping = 1;
                    i++;
                }
            } else {
                if (grouping)
                {
                    if (adj->S_mapped[k-sbr->kx][l])
                        sbr->f_group[l][i] = k;
                    else
                        sbr->f_group[l][i] = k + 1;
                    grouping = 0;
                    i++;
                }
            }
        }        

        if (grouping)
        {
            sbr->f_group[l][i] = sbr->kx + sbr->M;
            i++;
        }

        sbr->N_G[l] = (uint8_t)(i >> 1);
    }
}

static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch)
{
    uint8_t l, k, m;
    real_t E_total, E_total_est, G_target, acc;

    for (l = 0; l < sbr->L_E[ch]; l++)
    {
        for (k = 0; k < sbr->N_G[l]; k++)
        {
            E_total_est = E_total = 0;
            
            for (m = sbr->f_group[l][k<<1]; m < sbr->f_group[l][(k<<1) + 1]; m++)
            {
                /* E_curr: integer */
                /* G_lim_boost: fixed point */
                /* E_total_est: integer */
                /* E_total: integer */
                E_total_est += sbr->E_curr[ch][m-sbr->kx][l];
                E_total += MUL(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]);
            }

            /* G_target: fixed point */
            if ((E_total_est + EPS) == 0)
                G_target = 0;
            else
#ifdef FIXED_POINT
                G_target = (((int64_t)(E_total))<<REAL_BITS)/(E_total_est + EPS);
#else
                G_target = E_total / (E_total_est + EPS);
#endif
            acc = 0;

            for (m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++)
            {
                real_t alpha;

                /* alpha: fixed point */
                if (m < sbr->kx + sbr->M - 1)
                {
                    alpha = max(deg[m], deg[m + 1]);
                } else {
                    alpha = deg[m];
                }

                adj->G_lim_boost[l][m-sbr->kx] = MUL(alpha, G_target) +
                    MUL((REAL_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]);

                /* acc: integer */
                acc += MUL(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]);
            }

            /* acc: fixed point */
            if (acc + EPS == 0)
                acc = 0;
            else
#ifdef FIXED_POINT
                acc = (((int64_t)(E_total))<<REAL_BITS)/(acc + EPS);
#else
                acc = E_total / (acc + EPS);
#endif
            for(m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++)
            {
                adj->G_lim_boost[l][m-sbr->kx] = MUL(acc, adj->G_lim_boost[l][m-sbr->kx]);
            }
        }
    }

    for (l = 0; l < sbr->L_E[ch]; l++)
    {
        for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
        {
            for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k];
                 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++)
            {
#ifdef FIXED_POINT
                 adj->G_lim_boost[l][m] = SBR_SQRT_FIX(adj->G_lim_boost[l][m]);
#else
                 adj->G_lim_boost[l][m] = sqrt(adj->G_lim_boost[l][m]);
#endif
            }
        }
    }
}
#endif

static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj,
                        qmf_t *Xsbr, uint8_t ch)
{
    static real_t h_smooth[] = {
        COEF_CONST(0.03183050093751), COEF_CONST(0.11516383427084),
        COEF_CONST(0.21816949906249), COEF_CONST(0.30150283239582),
        COEF_CONST(0.33333333333333)
    };
    static int8_t phi_re[] = { 1, 0, -1, 0 };
    static int8_t phi_im[] = { 0, 1, 0, -1 };

    uint8_t m, l, i, n;
    uint16_t fIndexNoise = 0;
    uint8_t fIndexSine = 0;
    uint8_t assembly_reset = 0;
    real_t *temp;

    real_t G_filt, Q_filt;

    uint8_t h_SL;


    if (sbr->Reset == 1)
    {
        assembly_reset = 1;
        fIndexNoise = 0;
    } else {
        fIndexNoise = sbr->index_noise_prev[ch];
    }
    fIndexSine = sbr->psi_is_prev[ch];


    for (l = 0; l < sbr->L_E[ch]; l++)
    {
        uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0;

#ifdef SBR_LOW_POWER
        h_SL = 0;
#else
        h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4;
        h_SL = (no_noise ? 0 : h_SL);
#endif

        if (assembly_reset)
        {
            for (n = 0; n < 4; n++)
            {
                memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
                memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));
            }
            assembly_reset = 0;
        }


        for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++)
        {
#ifdef SBR_LOW_POWER
            uint8_t i_min1, i_plus1;
            uint8_t sinusoids = 0;
#endif

            memcpy(sbr->G_temp_prev[ch][4], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
            memcpy(sbr->Q_temp_prev[ch][4], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));

            for (m = 0; m < sbr->M; m++)
            {
                uint8_t j;
                qmf_t psi;


                G_filt = 0;
                Q_filt = 0;
                j = 0;

                if (h_SL != 0)
                {
                    for (n = 0; n <= 4; n++)
                    {
                        G_filt += MUL_R_C(sbr->G_temp_prev[ch][n][m], h_smooth[j]);
                        Q_filt += MUL_R_C(sbr->Q_temp_prev[ch][n][m], h_smooth[j]);
                        j++;
                    }
                } else {
                    G_filt = sbr->G_temp_prev[ch][4][m];
                    Q_filt = sbr->Q_temp_prev[ch][4][m];
                }

                Q_filt = (adj->S_M_boost[l][m] != 0 || no_noise) ? 0 : Q_filt;

#if 0
                if (sbr->frame == 155)
                {
                    printf("%f\n", G_filt);
                }
#endif

                /* add noise to the output */
                fIndexNoise = (fIndexNoise + 1) & 511;

#if 0
                printf("%d %f\n", Q_filt, RE(V[fIndexNoise])/(float)(1<<COEF_BITS));
#endif

                /* the smoothed gain values are applied to Xsbr */
                /* V is defined, not calculated */
#ifdef FIXED_POINT
                QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) = MUL(G_filt, QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]))
                    + MUL_R_C((Q_filt<<REAL_BITS), RE(V[fIndexNoise]));
#else
                QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) = MUL(G_filt, QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]))
                    + MUL_R_C(Q_filt, RE(V[fIndexNoise]));
#endif
                if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42)
                    QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) = 16428320;
#ifndef SBR_LOW_POWER
                QMF_IM(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) = MUL(G_filt, QMF_IM(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]))
                    + MUL_R_C(Q_filt, IM(V[fIndexNoise]));
#endif


                if (adj->S_index_mapped[m][l])
                {
                    int8_t rev = ((m + sbr->kx) & 1) ? -1 : 1;
                    QMF_RE(psi) = MUL(adj->S_M_boost[l][m], phi_re[fIndexSine]);
                    QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) += QMF_RE(psi);

#ifndef SBR_LOW_POWER
                    QMF_IM(psi) = rev * MUL(adj->S_M_boost[l][m], phi_im[fIndexSine]);
                    QMF_IM(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) += QMF_IM(psi);
#else
                    i_min1 = (fIndexSine - 1) & 3;
                    i_plus1 = (fIndexSine + 1) & 3;

                    if (m == 0)
                    {
                        QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx - 1]) -=
                            (rev * MUL_R_C(MUL(adj->S_M_boost[l][0], phi_re[i_plus1]), COEF_CONST(0.00815)));
                        QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) -=
                            (rev * MUL_R_C(MUL(adj->S_M_boost[l][1], phi_re[i_plus1]), COEF_CONST(0.00815)));
                    }
                    if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16))
                    {
                        QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) -=
                            (rev * MUL_R_C(MUL(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815)));
                        QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) -=
                            (rev * MUL_R_C(MUL(adj->S_M_boost[l][m + 1], phi_re[i_plus1]), COEF_CONST(0.00815)));
                    }
                    if ((m == sbr->M - 1) && (sinusoids < 16) && (m + sbr->kx + 1 < 63))
                    {
                        QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) -=
                            (rev * MUL_R_C(MUL(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815)));
                        QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx + 1]) -=
                            (rev * MUL_R_C(MUL(adj->S_M_boost[l][m + 1], phi_re[i_min1]), COEF_CONST(0.00815)));
                    }

                    sinusoids++;
#endif
                }
            }

            fIndexSine = (fIndexSine + 1) & 3;


            temp = sbr->G_temp_prev[ch][0];
            for (n = 0; n < 4; n++)
                sbr->G_temp_prev[ch][n] = sbr->G_temp_prev[ch][n+1];
            sbr->G_temp_prev[ch][4] = temp;

            temp = sbr->Q_temp_prev[ch][0];
            for (n = 0; n < 4; n++)
                sbr->Q_temp_prev[ch][n] = sbr->Q_temp_prev[ch][n+1];
            sbr->Q_temp_prev[ch][4] = temp;
        }
    }

    sbr->index_noise_prev[ch] = fIndexNoise;
    sbr->psi_is_prev[ch] = fIndexSine;
}

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_hfadj.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_HFADJ_H__
#define __SBR_HFADJ_H__

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {

    real_t Q_mapped[64][5];

    uint8_t S_index_mapped[64][5];
    uint8_t S_mapped[64][5];

    real_t G_lim_boost[5][64];
    real_t Q_M_lim_boost[5][64];
    real_t S_M_boost[5][64];

} sbr_hfadj_info;


void hf_adjustment(sbr_info *sbr, qmf_t *Xsbr
#ifdef SBR_LOW_POWER
                   ,real_t *deg
#endif
                   ,uint8_t ch);


static void map_envelope_data(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
static void map_noise_data(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
static void map_sinusoids(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t *Xsbr,
                                      uint8_t ch);
static void additional_component_levels(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
#ifdef SBR_LOW_POWER
static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
#endif
static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t *Xsbr, uint8_t ch);


#ifdef __cplusplus
}
#endif
#endif


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_hfgen.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

/* High Frequency generation */

#include "common.h"
#include "structs.h"

#ifdef SBR_DEC

#include "sbr_syntax.h"
#include "sbr_hfgen.h"
#include "sbr_fbt.h"

void hf_generation(sbr_info *sbr, qmf_t *Xlow,
                   qmf_t *Xhigh
#ifdef SBR_LOW_POWER
                   ,real_t *deg
#endif
                   ,uint8_t ch)
{
    uint8_t l, i, x;
    complex_t alpha_0[64], alpha_1[64];
#ifdef SBR_LOW_POWER
    real_t rxx[64];
#endif


    calc_chirp_factors(sbr, ch);

    if ((ch == 0) && (sbr->Reset))
        patch_construction(sbr);

    /* calculate the prediction coefficients */
    calc_prediction_coef(sbr, Xlow, alpha_0, alpha_1
#ifdef SBR_LOW_POWER
        , rxx
#endif
        );

#ifdef SBR_LOW_POWER
    calc_aliasing_degree(sbr, rxx, deg);
#endif

    /* actual HF generation */
    for (i = 0; i < sbr->noPatches; i++)
    {
        for (x = 0; x < sbr->patchNoSubbands[i]; x++)
        {
            complex_t a0, a1;
            real_t bw, bw2;
            uint8_t q, p, k, g;

            /* find the low and high band for patching */
            k = sbr->kx + x;
            for (q = 0; q < i; q++)
            {
                k += sbr->patchNoSubbands[q];
            }
            p = sbr->patchStartSubband[i] + x;

#ifdef SBR_LOW_POWER
            if (x != 0 /*x < sbr->patchNoSubbands[i]-1*/)
                deg[k] = deg[p];
            else
                deg[k] = 0;
#endif

            g = sbr->table_map_k_to_g[k];

            bw = sbr->bwArray[ch][g];
            bw2 = MUL_C_C(bw, bw);

            /* do the patching */
            /* with or without filtering */
            if (bw2 > 0)
            {
                RE(a0) = MUL_R_C(RE(alpha_0[p]), bw);
                RE(a1) = MUL_R_C(RE(alpha_1[p]), bw2);
#ifndef SBR_LOW_POWER
                IM(a0) = MUL_R_C(IM(alpha_0[p]), bw);
                IM(a1) = MUL_R_C(IM(alpha_1[p]), bw2);
#endif

                for (l = sbr->t_E[ch][0]; l < sbr->t_E[ch][sbr->L_E[ch]]; l++)
                {
                    QMF_RE(Xhigh[((l + tHFAdj)<<6) + k]) = QMF_RE(Xlow[((l + tHFAdj)<<5) + p]);
#ifndef SBR_LOW_POWER
                    QMF_IM(Xhigh[((l + tHFAdj)<<6) + k]) = QMF_IM(Xlow[((l + tHFAdj)<<5) + p]);
#endif

#ifdef SBR_LOW_POWER
                    QMF_RE(Xhigh[((l + tHFAdj)<<6) + k]) += (
                        MUL(RE(a0), QMF_RE(Xlow[((l - 1 + tHFAdj)<<5) + p])) +
                        MUL(RE(a1), QMF_RE(Xlow[((l - 2 + tHFAdj)<<5) + p])));
#else
                    QMF_RE(Xhigh[((l + tHFAdj)<<6) + k]) += (
                        RE(a0) * QMF_RE(Xlow[((l - 1 + tHFAdj)<<5) + p]) -
                        IM(a0) * QMF_IM(Xlow[((l - 1 + tHFAdj)<<5) + p]) +
                        RE(a1) * QMF_RE(Xlow[((l - 2 + tHFAdj)<<5) + p]) -
                        IM(a1) * QMF_IM(Xlow[((l - 2 + tHFAdj)<<5) + p]));
                    QMF_IM(Xhigh[((l + tHFAdj)<<6) + k]) += (
                        IM(a0) * QMF_RE(Xlow[((l - 1 + tHFAdj)<<5) + p]) +
                        RE(a0) * QMF_IM(Xlow[((l - 1 + tHFAdj)<<5) + p]) +
                        IM(a1) * QMF_RE(Xlow[((l - 2 + tHFAdj)<<5) + p]) +
                        RE(a1) * QMF_IM(Xlow[((l - 2 + tHFAdj)<<5) + p]));
#endif
                }
            } else {
                for (l = sbr->t_E[ch][0]; l < sbr->t_E[ch][sbr->L_E[ch]]; l++)
                {
                    QMF_RE(Xhigh[((l + tHFAdj)<<6) + k]) = QMF_RE(Xlow[((l + tHFAdj)<<5) + p]);
#ifndef SBR_LOW_POWER
                    QMF_IM(Xhigh[((l + tHFAdj)<<6) + k]) = QMF_IM(Xlow[((l + tHFAdj)<<5) + p]);
#endif
                }
            }
        }
    }

#if 0
    if (sbr->frame == 179)
    {
        for (l = 0; l < 64; l++)
        {
            printf("%d %.3f\n", l, deg[l]);
        }
    }
#endif

    if (sbr->Reset)
    {
        limiter_frequency_table(sbr);
    }
}

typedef struct
{
    complex_t r01;
    complex_t r02;
    complex_t r11;
    complex_t r12;
    complex_t r22;
    real_t det;
} acorr_coef;

#define SBR_ABS(A) ((A) < 0) ? -(A) : (A)

static void auto_correlation(acorr_coef *ac, qmf_t *buffer,
                             uint8_t bd, uint8_t len)
{
    int8_t j, jminus1, jminus2;
    const real_t rel = COEF_CONST(0.9999999999999); // 1 / (1 + 1e-6f);

#ifdef FIXED_POINT
    /*
     *  For computing the covariance matrix and the filter coefficients
     *  in fixed point, all values are normalised so that the fixed point
     *  values don't overflow.
     */
    uint32_t max = 0;
    uint32_t pow2, exp;

    for (j = tHFAdj-2; j < len + tHFAdj; j++)
    {
        max = max(SBR_ABS(QMF_RE(buffer[j*32 + bd])>>REAL_BITS), max);
    }

    /* find the first power of 2 bigger than max to avoid division */
    pow2 = 1;
    exp = 0;
    while (max > pow2)
    {
        pow2 <<= 1;
        exp++;
    }

    /* give some more space */
//    if (exp > 3)
//        exp -= 3;
#endif

    memset(ac, 0, sizeof(acorr_coef));

    for (j = tHFAdj; j < len + tHFAdj; j++)
    {
        jminus1 = j - 1;
        jminus2 = jminus1 - 1;

#ifdef SBR_LOW_POWER
#ifdef FIXED_POINT
        /* normalisation with rounding */
        RE(ac->r01) += MUL(((QMF_RE(buffer[j*32 + bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[jminus1*32 + bd])+(1<<(exp-1)))>>exp));
        RE(ac->r02) += MUL(((QMF_RE(buffer[j*32 + bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[jminus2*32 + bd])+(1<<(exp-1)))>>exp));
        RE(ac->r11) += MUL(((QMF_RE(buffer[jminus1*32 + bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[jminus1*32 + bd])+(1<<(exp-1)))>>exp));
        RE(ac->r12) += MUL(((QMF_RE(buffer[jminus1*32 + bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[jminus2*32 + bd])+(1<<(exp-1)))>>exp));
        RE(ac->r22) += MUL(((QMF_RE(buffer[jminus2*32 + bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[jminus2*32 + bd])+(1<<(exp-1)))>>exp));
#else
        RE(ac->r01) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]);
        RE(ac->r02) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]);
        RE(ac->r11) += QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]);
        RE(ac->r12) += QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]);
        RE(ac->r22) += QMF_RE(buffer[jminus2*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]);
#endif
#else
        RE(ac->r01) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) +
            QMF_IM(buffer[j*32 + bd]) * QMF_IM(buffer[jminus1*32 + bd]);

        IM(ac->r01) += QMF_IM(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) -
            QMF_RE(buffer[j*32 + bd]) * QMF_IM(buffer[jminus1*32 + bd]);

        RE(ac->r02) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) +
            QMF_IM(buffer[j*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);

        IM(ac->r02) += QMF_IM(buffer[j*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) -
            QMF_RE(buffer[j*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);

        RE(ac->r11) += QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) +
            QMF_IM(buffer[jminus1*32 + bd]) * QMF_IM(buffer[jminus1*32 + bd]);

        RE(ac->r12) += QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) +
            QMF_IM(buffer[jminus1*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);

        IM(ac->r12) += QMF_IM(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) -
            QMF_RE(buffer[jminus1*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);

        RE(ac->r22) += QMF_RE(buffer[jminus2*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) +
            QMF_IM(buffer[jminus2*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);
#endif
    }

#ifdef SBR_LOW_POWER
    ac->det = MUL(RE(ac->r11), RE(ac->r22)) - MUL_R_C(MUL(RE(ac->r12), RE(ac->r12)), rel);
#else
    ac->det = RE(ac->r11) * RE(ac->r22) - rel * (RE(ac->r12) * RE(ac->r12) + IM(ac->r12) * IM(ac->r12));
#endif

#if 0
    if (ac->det != 0)
        printf("%f %f\n", ac->det, max);
#endif
}

static void calc_prediction_coef(sbr_info *sbr, qmf_t *Xlow,
                                 complex_t *alpha_0, complex_t *alpha_1
#ifdef SBR_LOW_POWER
                                 , real_t *rxx
#endif
                                 )
{
    uint8_t k;
    real_t tmp;
    acorr_coef ac;

    for (k = 1; k < sbr->kx; k++)
    {
        auto_correlation(&ac, Xlow, k, 38);

#ifdef SBR_LOW_POWER
        if (ac.det == 0)
        {
            RE(alpha_1[k]) = 0;
        } else {
            tmp = MUL(RE(ac.r01), RE(ac.r12)) - MUL(RE(ac.r02), RE(ac.r11));
            RE(alpha_1[k]) = SBR_DIV(tmp, ac.det);
        }

        if (RE(ac.r11) == 0)
        {
            RE(alpha_0[k]) = 0;
        } else {
            tmp = RE(ac.r01) + MUL(RE(alpha_1[k]), RE(ac.r12));
            RE(alpha_0[k]) = -SBR_DIV(tmp, RE(ac.r11));
        }

        if ((RE(alpha_0[k]) >= REAL_CONST(4)) || (RE(alpha_1[k]) >= REAL_CONST(4)))
        {
            RE(alpha_0[k]) = REAL_CONST(0);
            RE(alpha_1[k]) = REAL_CONST(0);
        }

        /* reflection coefficient */
        if (RE(ac.r11) == REAL_CONST(0.0))
        {
            rxx[k] = REAL_CONST(0.0);
        } else {
            rxx[k] = -SBR_DIV(RE(ac.r01), RE(ac.r11));
            if (rxx[k] > REAL_CONST(1.0)) rxx[k] = REAL_CONST(1.0);
            if (rxx[k] < REAL_CONST(-1.0)) rxx[k] = REAL_CONST(-1.0);
        }
#else
        if (ac.det == 0)
        {
            RE(alpha_1[k]) = 0;
            IM(alpha_1[k]) = 0;
        } else {
            tmp = 1.0 / ac.det;
            RE(alpha_1[k]) = (RE(ac.r01) * RE(ac.r12) - IM(ac.r01) * IM(ac.r12) - RE(ac.r02) * RE(ac.r11)) * tmp;
            IM(alpha_1[k]) = (IM(ac.r01) * RE(ac.r12) + RE(ac.r01) * IM(ac.r12) - IM(ac.r02) * RE(ac.r11)) * tmp;
        }

        if (RE(ac.r11) == 0)
        {
            RE(alpha_0[k]) = 0;
            IM(alpha_0[k]) = 0;
        } else {
            tmp = 1.0f / RE(ac.r11);
            RE(alpha_0[k]) = -(RE(ac.r01) + RE(alpha_1[k]) * RE(ac.r12) + IM(alpha_1[k]) * IM(ac.r12)) * tmp;
            IM(alpha_0[k]) = -(IM(ac.r01) + IM(alpha_1[k]) * RE(ac.r12) - RE(alpha_1[k]) * IM(ac.r12)) * tmp;
        }

        if ((RE(alpha_0[k])*RE(alpha_0[k]) + IM(alpha_0[k])*IM(alpha_0[k]) >= 16) ||
            (RE(alpha_1[k])*RE(alpha_1[k]) + IM(alpha_1[k])*IM(alpha_1[k]) >= 16))
        {
            RE(alpha_0[k]) = 0;
            IM(alpha_0[k]) = 0;
            RE(alpha_1[k]) = 0;
            IM(alpha_1[k]) = 0;
        }
#endif
    }
}

#ifdef SBR_LOW_POWER
static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg)
{
    uint8_t k;

    rxx[0] = REAL_CONST(0.0);
    deg[1] = REAL_CONST(0.0);

    for (k = 2; k < sbr->k0; k++)
    {
        deg[k] = 0.0;

        if ((k % 2 == 0) && (rxx[k] < REAL_CONST(0.0)))
        {
            if (rxx[k-1] < 0.0)
            {
                deg[k] = REAL_CONST(1.0);

                if (rxx[k-2] > REAL_CONST(0.0))
                {
                    deg[k-1] = REAL_CONST(1.0) - MUL(rxx[k-1], rxx[k-1]);
                }
            } else if (rxx[k-2] > REAL_CONST(0.0)) {
                deg[k]   = REAL_CONST(1.0) - MUL(rxx[k-1], rxx[k-1]);
            }
        }

        if ((k % 2 == 1) && (rxx[k] > REAL_CONST(0.0)))
        {
            if (rxx[k-1] > REAL_CONST(0.0))
            {
                deg[k] = REAL_CONST(1.0);

                if (rxx[k-2] < REAL_CONST(0.0))
                {
                    deg[k-1] = REAL_CONST(1.0) - MUL(rxx[k-1], rxx[k-1]);
                }
            } else if (rxx[k-2] < REAL_CONST(0.0)) {
                deg[k] = REAL_CONST(1.0) - MUL(rxx[k-1], rxx[k-1]);
            }
        }
    }
}
#endif

static real_t mapNewBw(uint8_t invf_mode, uint8_t invf_mode_prev)
{
    switch (invf_mode)
    {
    case 1: /* LOW */
        if (invf_mode_prev == 0) /* NONE */
            return COEF_CONST(0.6);
        else
            return COEF_CONST(0.75);

    case 2: /* MID */
        return COEF_CONST(0.9);

    case 3: /* HIGH */
        return COEF_CONST(0.98);

    default: /* NONE */
        if (invf_mode_prev == 1) /* LOW */
            return COEF_CONST(0.6);
        else
            return COEF_CONST(0.0);
    }
}

static void calc_chirp_factors(sbr_info *sbr, uint8_t ch)
{
    uint8_t i;

    for (i = 0; i < sbr->N_Q; i++)
    {
        sbr->bwArray[ch][i] = mapNewBw(sbr->bs_invf_mode[ch][i], sbr->bs_invf_mode_prev[ch][i]);

        if (sbr->bwArray[ch][i] < sbr->bwArray_prev[ch][i])
            sbr->bwArray[ch][i] = MUL_C_C(COEF_CONST(0.75), sbr->bwArray[ch][i]) + MUL_C_C(COEF_CONST(0.25), sbr->bwArray_prev[ch][i]);
        else
            sbr->bwArray[ch][i] = MUL_C_C(COEF_CONST(0.90625), sbr->bwArray[ch][i]) + MUL_C_C(COEF_CONST(0.09375), sbr->bwArray_prev[ch][i]);

        if (sbr->bwArray[ch][i] < COEF_CONST(0.015625))
            sbr->bwArray[ch][i] = COEF_CONST(0.0);

        if (sbr->bwArray[ch][i] >= COEF_CONST(0.99609375))
            sbr->bwArray[ch][i] = COEF_CONST(0.99609375);

        sbr->bwArray_prev[ch][i] = sbr->bwArray[ch][i];
        sbr->bs_invf_mode_prev[ch][i] = sbr->bs_invf_mode[ch][i];
    }
}

static void patch_construction(sbr_info *sbr)
{
    uint8_t i, k;
    uint8_t odd, sb;
    uint8_t msb = sbr->k0;
    uint8_t usb = sbr->kx;
    uint32_t goalSb = (uint32_t)(2.048e6/sbr->sample_rate + 0.5);

    sbr->noPatches = 0;

    if (goalSb < (sbr->kx + sbr->M))
    {
        for (i = 0, k = 0; sbr->f_master[i] < goalSb; i++)
            k = i+1;
    } else {
        k = sbr->N_master;
    }

    do
    {
        uint8_t j = k + 1;

        do
        {
            j--;

            sb = sbr->f_master[j];
            odd = (sb - 2 + sbr->k0) % 2;
        } while (sb > (sbr->k0 - 1 + msb - odd));

        sbr->patchNoSubbands[sbr->noPatches] = max(sb - usb, 0);
        sbr->patchStartSubband[sbr->noPatches] = sbr->k0 - odd -
            sbr->patchNoSubbands[sbr->noPatches];

        if (sbr->patchNoSubbands[sbr->noPatches] > 0)
        {
            usb = sb;
            msb = sb;
            sbr->noPatches++;
        } else {
            msb = sbr->kx;
        }

        if (sb == sbr->f_master[k])
            k = sbr->N_master;
    } while (sb != (sbr->kx + sbr->M));

    if ((sbr->patchNoSubbands[sbr->noPatches-1] < 3) &&
        (sbr->noPatches > 1))
    {
        sbr->noPatches--;
    }

    sbr->noPatches = min(sbr->noPatches, 5);
}

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_hfgen.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_HFGEN_H__
#define __SBR_HFGEN_H__

#ifdef __cplusplus
extern "C" {
#endif

void hf_generation(sbr_info *sbr, qmf_t *Xlow,
                   qmf_t *Xhigh
#ifdef SBR_LOW_POWER
                   ,real_t *deg
#endif
                   ,uint8_t ch);

static void calc_prediction_coef(sbr_info *sbr, qmf_t *Xlow,
                                 complex_t *alpha_0, complex_t *alpha_1
#ifdef SBR_LOW_POWER
                                 , real_t *rxx
#endif
                                 );
static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg);
static void calc_chirp_factors(sbr_info *sbr, uint8_t ch);
static void patch_construction(sbr_info *sbr);

#ifdef __cplusplus
}
#endif
#endif


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_huff.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#ifdef SBR_DEC

#include "bits.h"
#include "sbr_huff.h"


int16_t sbr_huff_dec(bitfile *ld, sbr_huff_tab t_huff)
{
    uint8_t bit;
    int16_t index = 0;

    while (index >= 0)
    {
        bit = (uint8_t)faad_getbits(ld, 1);
        index = t_huff[index][bit];
    }

    return index + 64;
}


const int8_t t_huffman_env_1_5dB[120][2] = {
    {   1,   2 },    { -64, -65 },    {   3,   4 },    { -63, -66 },
    {   5,   6 },    { -62, -67 },    {   7,   8 },    { -61, -68 },
    {   9,  10 },    { -60, -69 },    {  11,  12 },    { -59, -70 },
    {  13,  14 },    { -58, -71 },    {  15,  16 },    { -57, -72 },
    {  17,  18 },    { -73, -56 },    {  19,  21 },    { -74,  20 },
    { -55, -75 },    {  22,  26 },    {  23,  24 },    { -54, -76 },
    { -77,  25 },    { -53, -78 },    {  27,  34 },    {  28,  29 },
    { -52, -79 },    {  30,  31 },    { -80, -51 },    {  32,  33 },
    { -83, -82 },    { -81, -50 },    {  35,  57 },    {  36,  40 },
    {  37,  38 },    { -88, -84 },    { -48,  39 },    { -90, -85 },
    {  41,  46 },    {  42,  43 },    { -49, -87 },    {  44,  45 },
    { -89, -86 },    {-124,-123 },    {  47,  50 },    {  48,  49 },
    {-122,-121 },    {-120,-119 },    {  51,  54 },    {  52,  53 },
    {-118,-117 },    {-116,-115 },    {  55,  56 },    {-114,-113 },
    {-112,-111 },    {  58,  89 },    {  59,  74 },    {  60,  67 },
    {  61,  64 },    {  62,  63 },    {-110,-109 },    {-108,-107 },
    {  65,  66 },    {-106,-105 },    {-104,-103 },    {  68,  71 },
    {  69,  70 },    {-102,-101 },    {-100, -99 },    {  72,  73 },
    { -98, -97 },    { -96, -95 },    {  75,  82 },    {  76,  79 },
    {  77,  78 },    { -94, -93 },    { -92, -91 },    {  80,  81 },
    { -47, -46 },    { -45, -44 },    {  83,  86 },    {  84,  85 },
    { -43, -42 },    { -41, -40 },    {  87,  88 },    { -39, -38 },
    { -37, -36 },    {  90, 105 },    {  91,  98 },    {  92,  95 },
    {  93,  94 },    { -35, -34 },    { -33, -32 },    {  96,  97 },
    { -31, -30 },    { -29, -28 },    {  99, 102 },    { 100, 101 },
    { -27, -26 },    { -25, -24 },    { 103, 104 },    { -23, -22 },
    { -21, -20 },    { 106, 113 },    { 107, 110 },    { 108, 109 },
    { -19, -18 },    { -17, -16 },    { 111, 112 },    { -15, -14 },
    { -13, -12 },    { 114, 117 },    { 115, 116 },    { -11, -10 },
    {  -9,  -8 },    { 118, 119 },    {  -7,  -6 },    {  -5,  -4 }
};

const int8_t f_huffman_env_1_5dB[120][2] = {
    {   1,   2 },    { -64, -65 },    {   3,   4 },    { -63, -66 },
    {   5,   6 },    { -67, -62 },    {   7,   8 },    { -68, -61 },
    {   9,  10 },    { -69, -60 },    {  11,  13 },    { -70,  12 },
    { -59, -71 },    {  14,  16 },    { -58,  15 },    { -72, -57 },
    {  17,  19 },    { -73,  18 },    { -56, -74 },    {  20,  23 },
    {  21,  22 },    { -55, -75 },    { -54, -53 },    {  24,  27 },
    {  25,  26 },    { -76, -52 },    { -77, -51 },    {  28,  31 },
    {  29,  30 },    { -50, -78 },    { -79, -49 },    {  32,  36 },
    {  33,  34 },    { -48, -47 },    { -80,  35 },    { -81, -82 },
    {  37,  47 },    {  38,  41 },    {  39,  40 },    { -83, -46 },
    { -45, -84 },    {  42,  44 },    { -85,  43 },    { -44, -43 },
    {  45,  46 },    { -88, -87 },    { -86, -90 },    {  48,  66 },
    {  49,  56 },    {  50,  53 },    {  51,  52 },    { -92, -42 },
    { -41, -39 },    {  54,  55 },    {-105, -89 },    { -38, -37 },
    {  57,  60 },    {  58,  59 },    { -94, -91 },    { -40, -36 },
    {  61,  63 },    { -20,  62 },    {-115,-110 },    {  64,  65 },
    {-108,-107 },    {-101, -97 },    {  67,  89 },    {  68,  75 },
    {  69,  72 },    {  70,  71 },    { -95, -93 },    { -34, -27 },
    {  73,  74 },    { -22, -17 },    { -16,-124 },    {  76,  82 },
    {  77,  79 },    {-123,  78 },    {-122,-121 },    {  80,  81 },
    {-120,-119 },    {-118,-117 },    {  83,  86 },    {  84,  85 },
    {-116,-114 },    {-113,-112 },    {  87,  88 },    {-111,-109 },
    {-106,-104 },    {  90, 105 },    {  91,  98 },    {  92,  95 },
    {  93,  94 },    {-103,-102 },    {-100, -99 },    {  96,  97 },
    { -98, -96 },    { -35, -33 },    {  99, 102 },    { 100, 101 },
    { -32, -31 },    { -30, -29 },    { 103, 104 },    { -28, -26 },
    { -25, -24 },    { 106, 113 },    { 107, 110 },    { 108, 109 },
    { -23, -21 },    { -19, -18 },    { 111, 112 },    { -15, -14 },
    { -13, -12 },    { 114, 117 },    { 115, 116 },    { -11, -10 },
    {  -9,  -8 },    { 118, 119 },    {  -7,  -6 },    {  -5,  -4 }
};

const int8_t t_huffman_env_bal_1_5dB[48][2] = {
    { -64,   1 },    { -63,   2 },    { -65,   3 },    { -62,   4 },
    { -66,   5 },    { -61,   6 },    { -67,   7 },    { -60,   8 },
    { -68,   9 },    {  10,  11 },    { -69, -59 },    {  12,  13 },
    { -70, -58 },    {  14,  28 },    {  15,  21 },    {  16,  18 },
    { -57,  17 },    { -71, -56 },    {  19,  20 },    { -88, -87 },
    { -86, -85 },    {  22,  25 },    {  23,  24 },    { -84, -83 },
    { -82, -81 },    {  26,  27 },    { -80, -79 },    { -78, -77 },
    {  29,  36 },    {  30,  33 },    {  31,  32 },    { -76, -75 },
    { -74, -73 },    {  34,  35 },    { -72, -55 },    { -54, -53 },
    {  37,  41 },    {  38,  39 },    { -52, -51 },    { -50,  40 },
    { -49, -48 },    {  42,  45 },    {  43,  44 },    { -47, -46 },
    { -45, -44 },    {  46,  47 },    { -43, -42 },    { -41, -40 }
};

const int8_t f_huffman_env_bal_1_5dB[48][2] = {
    { -64,   1 },    { -65,   2 },    { -63,   3 },    { -66,   4 },
    { -62,   5 },    { -61,   6 },    { -67,   7 },    { -68,   8 },
    { -60,   9 },    {  10,  11 },    { -69, -59 },    { -70,  12 },
    { -58,  13 },    {  14,  17 },    { -71,  15 },    { -57,  16 },
    { -56, -73 },    {  18,  32 },    {  19,  25 },    {  20,  22 },
    { -72,  21 },    { -88, -87 },    {  23,  24 },    { -86, -85 },
    { -84, -83 },    {  26,  29 },    {  27,  28 },    { -82, -81 },
    { -80, -79 },    {  30,  31 },    { -78, -77 },    { -76, -75 },
    {  33,  40 },    {  34,  37 },    {  35,  36 },    { -74, -55 },
    { -54, -53 },    {  38,  39 },    { -52, -51 },    { -50, -49 },
    {  41,  44 },    {  42,  43 },    { -48, -47 },    { -46, -45 },
    {  45,  46 },    { -44, -43 },    { -42,  47 },    { -41, -40 }
};

const int8_t t_huffman_env_3_0dB[62][2] = {
    { -64,   1 },    { -65,   2 },    { -63,   3 },    { -66,   4 },
    { -62,   5 },    { -67,   6 },    { -61,   7 },    { -68,   8 },
    { -60,   9 },    {  10,  11 },    { -69, -59 },    {  12,  14 },
    { -70,  13 },    { -71, -58 },    {  15,  18 },    {  16,  17 },
    { -72, -57 },    { -73, -74 },    {  19,  22 },    { -56,  20 },
    { -55,  21 },    { -54, -77 },    {  23,  31 },    {  24,  25 },
    { -75, -76 },    {  26,  27 },    { -78, -53 },    {  28,  29 },
    { -52, -95 },    { -94,  30 },    { -93, -92 },    {  32,  47 },
    {  33,  40 },    {  34,  37 },    {  35,  36 },    { -91, -90 },
    { -89, -88 },    {  38,  39 },    { -87, -86 },    { -85, -84 },
    {  41,  44 },    {  42,  43 },    { -83, -82 },    { -81, -80 },
    {  45,  46 },    { -79, -51 },    { -50, -49 },    {  48,  55 },
    {  49,  52 },    {  50,  51 },    { -48, -47 },    { -46, -45 },
    {  53,  54 },    { -44, -43 },    { -42, -41 },    {  56,  59 },
    {  57,  58 },    { -40, -39 },    { -38, -37 },    {  60,  61 },
    { -36, -35 },    { -34, -33 }
};

const int8_t f_huffman_env_3_0dB[62][2] = {
    { -64,   1 },    { -65,   2 },    { -63,   3 },    { -66,   4 },
    { -62,   5 },    { -67,   6 },    {   7,   8 },    { -61, -68 },
    {   9,  10 },    { -60, -69 },    {  11,  12 },    { -59, -70 },
    {  13,  14 },    { -58, -71 },    {  15,  16 },    { -57, -72 },
    {  17,  19 },    { -56,  18 },    { -55, -73 },    {  20,  24 },
    {  21,  22 },    { -74, -54 },    { -53,  23 },    { -75, -76 },
    {  25,  30 },    {  26,  27 },    { -52, -51 },    {  28,  29 },
    { -77, -79 },    { -50, -49 },    {  31,  39 },    {  32,  35 },
    {  33,  34 },    { -78, -46 },    { -82, -88 },    {  36,  37 },
    { -83, -48 },    { -47,  38 },    { -86, -85 },    {  40,  47 },
    {  41,  44 },    {  42,  43 },    { -80, -44 },    { -43, -42 },
    {  45,  46 },    { -39, -87 },    { -84, -40 },    {  48,  55 },
    {  49,  52 },    {  50,  51 },    { -95, -94 },    { -93, -92 },
    {  53,  54 },    { -91, -90 },    { -89, -81 },    {  56,  59 },
    {  57,  58 },    { -45, -41 },    { -38, -37 },    {  60,  61 },
    { -36, -35 },    { -34, -33 }
};

const int8_t t_huffman_env_bal_3_0dB[24][2] = {
    { -64,   1 },    { -63,   2 },    { -65,   3 },    { -66,   4 },
    { -62,   5 },    { -61,   6 },    { -67,   7 },    { -68,   8 },
    { -60,   9 },    {  10,  16 },    {  11,  13 },    { -69,  12 },
    { -76, -75 },    {  14,  15 },    { -74, -73 },    { -72, -71 },
    {  17,  20 },    {  18,  19 },    { -70, -59 },    { -58, -57 },
    {  21,  22 },    { -56, -55 },    { -54,  23 },    { -53, -52 }
};

const int8_t f_huffman_env_bal_3_0dB[24][2] = {
    { -64,   1 },    { -65,   2 },    { -63,   3 },    { -66,   4 },
    { -62,   5 },    { -61,   6 },    { -67,   7 },    { -68,   8 },
    { -60,   9 },    {  10,  13 },    { -69,  11 },    { -59,  12 },
    { -58, -76 },    {  14,  17 },    {  15,  16 },    { -75, -74 },
    { -73, -72 },    {  18,  21 },    {  19,  20 },    { -71, -70 },
    { -57, -56 },    {  22,  23 },    { -55, -54 },    { -53, -52 }
};


const int8_t t_huffman_noise_3_0dB[62][2] = {
    { -64,   1 },    { -63,   2 },    { -65,   3 },    { -66,   4 },
    { -62,   5 },    { -67,   6 },    {   7,   8 },    { -61, -68 },
    {   9,  30 },    {  10,  15 },    { -60,  11 },    { -69,  12 },
    {  13,  14 },    { -59, -53 },    { -95, -94 },    {  16,  23 },
    {  17,  20 },    {  18,  19 },    { -93, -92 },    { -91, -90 },
    {  21,  22 },    { -89, -88 },    { -87, -86 },    {  24,  27 },
    {  25,  26 },    { -85, -84 },    { -83, -82 },    {  28,  29 },
    { -81, -80 },    { -79, -78 },    {  31,  46 },    {  32,  39 },
    {  33,  36 },    {  34,  35 },    { -77, -76 },    { -75, -74 },
    {  37,  38 },    { -73, -72 },    { -71, -70 },    {  40,  43 },
    {  41,  42 },    { -58, -57 },    { -56, -55 },    {  44,  45 },
    { -54, -52 },    { -51, -50 },    {  47,  54 },    {  48,  51 },
    {  49,  50 },    { -49, -48 },    { -47, -46 },    {  52,  53 },
    { -45, -44 },    { -43, -42 },    {  55,  58 },    {  56,  57 },
    { -41, -40 },    { -39, -38 },    {  59,  60 },    { -37, -36 },
    { -35,  61 },    { -34, -33 }
};

const int8_t t_huffman_noise_bal_3_0dB[24][2] = {
    { -64,   1 },    { -65,   2 },    { -63,   3 },    {   4,   9 },
    { -66,   5 },    { -62,   6 },    {   7,   8 },    { -76, -75 },
    { -74, -73 },    {  10,  17 },    {  11,  14 },    {  12,  13 },
    { -72, -71 },    { -70, -69 },    {  15,  16 },    { -68, -67 },
    { -61, -60 },    {  18,  21 },    {  19,  20 },    { -59, -58 },
    { -57, -56 },    {  22,  23 },    { -55, -54 },    { -53, -52 }
};

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_huff.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_HUFF_H__
#define __SBR_HUFF_H__

#ifdef __cplusplus
extern "C" {
#endif

typedef const int8_t (*sbr_huff_tab)[2];

int16_t sbr_huff_dec(bitfile *ld, sbr_huff_tab t_huff);

const int8_t t_huffman_env_1_5dB[120][2];
const int8_t f_huffman_env_1_5dB[120][2];
const int8_t t_huffman_env_bal_1_5dB[48][2];
const int8_t f_huffman_env_bal_1_5dB[48][2];
const int8_t t_huffman_env_3_0dB[62][2];
const int8_t f_huffman_env_3_0dB[62][2];
const int8_t t_huffman_env_bal_3_0dB[24][2];
const int8_t f_huffman_env_bal_3_0dB[24][2];
const int8_t t_huffman_noise_3_0dB[62][2];
const int8_t t_huffman_noise_bal_3_0dB[24][2];

#ifdef __cplusplus
}
#endif
#endif


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_noise.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_NOISE_H__
#define __SBR_NOISE_H__

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _MSC_VER
#pragma warning(disable:4305)
#pragma warning(disable:4244)
#endif


/* Table 1.A.13 Noise table V */
complex_t V[] = {
    { COEF_CONST(-0.99948155879974), COEF_CONST(-0.59483414888382) },
    { COEF_CONST(0.97113454341888), COEF_CONST(-0.67528516054153) },
    { COEF_CONST(0.14130051434040), COEF_CONST(-0.95090985298157) },
    { COEF_CONST(-0.47005495429039), COEF_CONST(-0.37340548634529) },
    { COEF_CONST(0.80705064535141), COEF_CONST(0.29653668403625) },
    { COEF_CONST(-0.38981479406357), COEF_CONST(0.89572608470917) },
    { COEF_CONST(-0.01053049881011), COEF_CONST(-0.66959059238434) },
    { COEF_CONST(-0.91266369819641), COEF_CONST(-0.11522938311100) },
    { COEF_CONST(0.54840421676636), COEF_CONST(0.75221365690231) },
    { COEF_CONST(0.40009254217148), COEF_CONST(-0.98929399251938) },
    { COEF_CONST(-0.99867975711823), COEF_CONST(-0.88147068023682) },
    { COEF_CONST(-0.95531076192856), COEF_CONST(0.90908759832382) },
    { COEF_CONST(-0.45725932717323), COEF_CONST(-0.56716322898865) },
    { COEF_CONST(-0.72929674386978), COEF_CONST(-0.98008275032043) },
    { COEF_CONST(0.75622802972794), COEF_CONST(0.20950329303741) },
    { COEF_CONST(0.07069442421198), COEF_CONST(-0.78247898817062) },
    { COEF_CONST(0.74496251344681), COEF_CONST(-0.91169005632401) },
    { COEF_CONST(-0.96440184116364), COEF_CONST(-0.94739919900894) },
    { COEF_CONST(0.30424630641937), COEF_CONST(-0.49438267946243) },
    { COEF_CONST(0.66565030813217), COEF_CONST(0.64652937650681) },
    { COEF_CONST(0.91697007417679), COEF_CONST(0.17514097690582) },
    { COEF_CONST(-0.70774918794632), COEF_CONST(0.52548652887344) },
    { COEF_CONST(-0.70051413774490), COEF_CONST(-0.45340028405190) },
    { COEF_CONST(-0.99496513605118), COEF_CONST(-0.90071910619736) },
    { COEF_CONST(0.98164492845535), COEF_CONST(-0.77463155984879) },
    { COEF_CONST(-0.54671579599380), COEF_CONST(-0.02570928446949) },
    { COEF_CONST(-0.01689629070461), COEF_CONST(0.00287506449968) },
    { COEF_CONST(-0.86110347509384), COEF_CONST(0.42548584938049) },
    { COEF_CONST(-0.98892980813980), COEF_CONST(-0.87881129980087) },
    { COEF_CONST(0.51756626367569), COEF_CONST(0.66926783323288) },
    { COEF_CONST(-0.99635028839111), COEF_CONST(-0.58107727766037) },
    { COEF_CONST(-0.99969369173050), COEF_CONST(0.98369991779327) },
    { COEF_CONST(0.55266261100769), COEF_CONST(0.59449058771133) },
    { COEF_CONST(0.34581178426743), COEF_CONST(0.94879418611526) },
    { COEF_CONST(0.62664210796356), COEF_CONST(-0.74402970075607) },
    { COEF_CONST(-0.77149701118469), COEF_CONST(-0.33883658051491) },
    { COEF_CONST(-0.91592246294022), COEF_CONST(0.03687901422381) },
    { COEF_CONST(-0.76285493373871), COEF_CONST(-0.91371870040894) },
    { COEF_CONST(0.79788339138031), COEF_CONST(-0.93180972337723) },
    { COEF_CONST(0.54473078250885), COEF_CONST(-0.11919206380844) },
    { COEF_CONST(-0.85639280080795), COEF_CONST(0.42429855465889) },
    { COEF_CONST(-0.92882400751114), COEF_CONST(0.27871808409691) },
    { COEF_CONST(-0.11708371341228), COEF_CONST(-0.99800843000412) },
    { COEF_CONST(0.21356749534607), COEF_CONST(-0.90716296434402) },
    { COEF_CONST(-0.76191693544388), COEF_CONST(0.99768120050430) },
    { COEF_CONST(0.98111045360565), COEF_CONST(-0.95854461193085) },
    { COEF_CONST(-0.85913270711899), COEF_CONST(0.95766568183899) },
    { COEF_CONST(-0.93307244777679), COEF_CONST(0.49431759119034) },
    { COEF_CONST(0.30485755205154), COEF_CONST(-0.70540034770966) },
    { COEF_CONST(0.85289651155472), COEF_CONST(0.46766132116318) },
    { COEF_CONST(0.91328084468842), COEF_CONST(-0.99839597940445) },
    { COEF_CONST(-0.05890199914575), COEF_CONST(0.70741826295853) },
    { COEF_CONST(0.28398686647415), COEF_CONST(0.34633556008339) },
    { COEF_CONST(0.95258164405823), COEF_CONST(-0.54893416166306) },
    { COEF_CONST(-0.78566324710846), COEF_CONST(-0.75568538904190) },
    { COEF_CONST(-0.95789498090744), COEF_CONST(-0.20423194766045) },
    { COEF_CONST(0.82411158084869), COEF_CONST(0.96654617786407) },
    { COEF_CONST(-0.65185445547104), COEF_CONST(-0.88734990358353) },
    { COEF_CONST(-0.93643605709076), COEF_CONST(0.99870789051056) },
    { COEF_CONST(0.91427159309387), COEF_CONST(-0.98290503025055) },
    { COEF_CONST(-0.70395684242249), COEF_CONST(0.58796799182892) },
    { COEF_CONST(0.00563771976158), COEF_CONST(0.61768198013306) },
    { COEF_CONST(0.89065051078796), COEF_CONST(0.52783352136612) },
    { COEF_CONST(-0.68683707714081), COEF_CONST(0.80806946754456) },
    { COEF_CONST(0.72165340185165), COEF_CONST(-0.69259858131409) },
    { COEF_CONST(-0.62928247451782), COEF_CONST(0.13627037405968) },
    { COEF_CONST(0.29938435554504), COEF_CONST(-0.46051329374313) },
    { COEF_CONST(-0.91781955957413), COEF_CONST(-0.74012714624405) },
    { COEF_CONST(0.99298715591431), COEF_CONST(0.40816611051559) },
    { COEF_CONST(0.82368296384811), COEF_CONST(-0.74036049842834) },
    { COEF_CONST(-0.98512834310532), COEF_CONST(-0.99972331523895) },
    { COEF_CONST(-0.95915371179581), COEF_CONST(-0.99237799644470) },
    { COEF_CONST(-0.21411126852036), COEF_CONST(-0.93424820899963) },
    { COEF_CONST(-0.68821477890015), COEF_CONST(-0.26892307400703) },
    { COEF_CONST(0.91851997375488), COEF_CONST(0.09358228743076) },
    { COEF_CONST(-0.96062767505646), COEF_CONST(0.36099094152451) },
    { COEF_CONST(0.51646184921265), COEF_CONST(-0.71373331546783) },
    { COEF_CONST(0.61130720376968), COEF_CONST(0.46950140595436) },
    { COEF_CONST(0.47336128354073), COEF_CONST(-0.27333179116249) },
    { COEF_CONST(0.90998309850693), COEF_CONST(0.96715664863586) },
    { COEF_CONST(0.44844800233841), COEF_CONST(0.99211573600769) },
    { COEF_CONST(0.66614890098572), COEF_CONST(0.96590173244476) },
    { COEF_CONST(0.74922239780426), COEF_CONST(-0.89879858493805) },
    { COEF_CONST(-0.99571585655212), COEF_CONST(0.52785521745682) },
    { COEF_CONST(0.97401082515717), COEF_CONST(-0.16855870187283) },
    { COEF_CONST(0.72683745622635), COEF_CONST(-0.48060774803162) },
    { COEF_CONST(0.95432192087173), COEF_CONST(0.68849605321884) },
    { COEF_CONST(-0.72962206602097), COEF_CONST(-0.76608443260193) },
    { COEF_CONST(-0.85359477996826), COEF_CONST(0.88738125562668) },
    { COEF_CONST(-0.81412428617477), COEF_CONST(-0.97480767965317) },
    { COEF_CONST(-0.87930774688721), COEF_CONST(0.74748307466507) },
    { COEF_CONST(-0.71573328971863), COEF_CONST(-0.98570609092712) },
    { COEF_CONST(0.83524298667908), COEF_CONST(0.83702534437180) },
    { COEF_CONST(-0.48086065053940), COEF_CONST(-0.98848503828049) },
    { COEF_CONST(0.97139126062393), COEF_CONST(0.80093622207642) },
    { COEF_CONST(0.51992827653885), COEF_CONST(0.80247628688812) },
    { COEF_CONST(-0.00848591234535), COEF_CONST(-0.76670128107071) },
    { COEF_CONST(-0.70294374227524), COEF_CONST(0.55359911918640) },
    { COEF_CONST(-0.95894426107407), COEF_CONST(-0.43265503644943) },
    { COEF_CONST(0.97079253196716), COEF_CONST(0.09325857460499) },
    { COEF_CONST(-0.92404294013977), COEF_CONST(0.85507702827454) },
    { COEF_CONST(-0.69506472349167), COEF_CONST(0.98633414506912) },
    { COEF_CONST(0.26559203863144), COEF_CONST(0.73314309120178) },
    { COEF_CONST(0.28038442134857), COEF_CONST(0.14537914097309) },
    { COEF_CONST(-0.74138122797012), COEF_CONST(0.99310338497162) },
    { COEF_CONST(-0.01752796024084), COEF_CONST(-0.82616633176804) },
    { COEF_CONST(-0.55126774311066), COEF_CONST(-0.98898541927338) },
    { COEF_CONST(0.97960901260376), COEF_CONST(-0.94021445512772) },
    { COEF_CONST(-0.99196308851242), COEF_CONST(0.67019015550613) },
    { COEF_CONST(-0.67684930562973), COEF_CONST(0.12631492316723) },
    { COEF_CONST(0.09140039235353), COEF_CONST(-0.20537731051445) },
    { COEF_CONST(-0.71658962965012), COEF_CONST(-0.97788202762604) },
    { COEF_CONST(0.81014639139175), COEF_CONST(0.53722649812698) },
    { COEF_CONST(0.40616992115974), COEF_CONST(-0.26469007134438) },
    { COEF_CONST(-0.67680186033249), COEF_CONST(0.94502049684525) },
    { COEF_CONST(0.86849772930145), COEF_CONST(-0.18333598971367) },
    { COEF_CONST(-0.99500381946564), COEF_CONST(-0.02634122036397) },
    { COEF_CONST(0.84329187870026), COEF_CONST(0.10406957566738) },
    { COEF_CONST(-0.09215968847275), COEF_CONST(0.69540011882782) },
    { COEF_CONST(0.99956172704697), COEF_CONST(-0.12358541786671) },
    { COEF_CONST(-0.79732781648636), COEF_CONST(-0.91582524776459) },
    { COEF_CONST(0.96349972486496), COEF_CONST(0.96640455722809) },
    { COEF_CONST(-0.79942780733109), COEF_CONST(0.64323902130127) },
    { COEF_CONST(-0.11566039919853), COEF_CONST(0.28587844967842) },
    { COEF_CONST(-0.39922955632210), COEF_CONST(0.94129604101181) },
    { COEF_CONST(0.99089199304581), COEF_CONST(-0.92062628269196) },
    { COEF_CONST(0.28631284832954), COEF_CONST(-0.91035044193268) },
    { COEF_CONST(-0.83302724361420), COEF_CONST(-0.67330408096313) },
    { COEF_CONST(0.95404446125031), COEF_CONST(0.49162766337395) },
    { COEF_CONST(-0.06449863314629), COEF_CONST(0.03250560909510) },
    { COEF_CONST(-0.99575054645538), COEF_CONST(0.42389783263206) },
    { COEF_CONST(-0.65501141548157), COEF_CONST(0.82546114921570) },
    { COEF_CONST(-0.81254440546036), COEF_CONST(-0.51627236604691) },
    { COEF_CONST(-0.99646371603012), COEF_CONST(0.84490531682968) },
    { COEF_CONST(0.00287840608507), COEF_CONST(0.64768260717392) },
    { COEF_CONST(0.70176988840103), COEF_CONST(-0.20453028380871) },
    { COEF_CONST(0.96361881494522), COEF_CONST(0.40706968307495) },
    { COEF_CONST(-0.68883758783340), COEF_CONST(0.91338956356049) },
    { COEF_CONST(-0.34875586628914), COEF_CONST(0.71472293138504) },
    { COEF_CONST(0.91980081796646), COEF_CONST(0.66507452726364) },
    { COEF_CONST(-0.99009048938751), COEF_CONST(0.85868018865585) },
    { COEF_CONST(0.68865793943405), COEF_CONST(0.55660319328308) },
    { COEF_CONST(-0.99484401941299), COEF_CONST(-0.20052559673786) },
    { COEF_CONST(0.94214510917664), COEF_CONST(-0.99696427583694) },
    { COEF_CONST(-0.67414629459381), COEF_CONST(0.49548220634460) },
    { COEF_CONST(-0.47339352965355), COEF_CONST(-0.85904330015182) },
    { COEF_CONST(0.14323651790619), COEF_CONST(-0.94145596027374) },
    { COEF_CONST(-0.29268294572830), COEF_CONST(0.05759225040674) },
    { COEF_CONST(0.43793860077858), COEF_CONST(-0.78904968500137) },
    { COEF_CONST(-0.36345127224922), COEF_CONST(0.64874434471130) },
    { COEF_CONST(-0.08750604838133), COEF_CONST(0.97686946392059) },
    { COEF_CONST(-0.96495270729065), COEF_CONST(-0.53960305452347) },
    { COEF_CONST(0.55526942014694), COEF_CONST(0.78891521692276) },
    { COEF_CONST(0.73538213968277), COEF_CONST(0.96452075242996) },
    { COEF_CONST(-0.30889773368835), COEF_CONST(-0.80664390325546) },
    { COEF_CONST(0.03574995696545), COEF_CONST(-0.97325617074966) },
    { COEF_CONST(0.98720687627792), COEF_CONST(0.48409134149551) },
    { COEF_CONST(-0.81689298152924), COEF_CONST(-0.90827703475952) },
    { COEF_CONST(0.67866861820221), COEF_CONST(0.81284505128860) },
    { COEF_CONST(-0.15808570384979), COEF_CONST(0.85279554128647) },
    { COEF_CONST(0.80723392963409), COEF_CONST(-0.24717418849468) },
    { COEF_CONST(0.47788757085800), COEF_CONST(-0.46333149075508) },
    { COEF_CONST(0.96367555856705), COEF_CONST(0.38486748933792) },
    { COEF_CONST(-0.99143874645233), COEF_CONST(-0.24945276975632) },
    { COEF_CONST(0.83081877231598), COEF_CONST(-0.94780850410461) },
    { COEF_CONST(-0.58753192424774), COEF_CONST(0.01290772389621) },
    { COEF_CONST(0.95538109540939), COEF_CONST(-0.85557049512863) },
    { COEF_CONST(-0.96490919589996), COEF_CONST(-0.64020973443985) },
    { COEF_CONST(-0.97327101230621), COEF_CONST(0.12378127872944) },
    { COEF_CONST(0.91400367021561), COEF_CONST(0.57972472906113) },
    { COEF_CONST(-0.99925839900970), COEF_CONST(0.71084845066071) },
    { COEF_CONST(-0.86875903606415), COEF_CONST(-0.20291699469090) },
    { COEF_CONST(-0.26240035891533), COEF_CONST(-0.68264555931091) },
    { COEF_CONST(-0.24664412438869), COEF_CONST(-0.87642270326614) },
    { COEF_CONST(0.02416275814176), COEF_CONST(0.27192914485931) },
    { COEF_CONST(0.82068622112274), COEF_CONST(-0.85087788105011) },
    { COEF_CONST(0.88547372817993), COEF_CONST(-0.89636802673340) },
    { COEF_CONST(-0.18173077702522), COEF_CONST(-0.26152145862579) },
    { COEF_CONST(0.09355476498604), COEF_CONST(0.54845124483109) },
    { COEF_CONST(-0.54668414592743), COEF_CONST(0.95980775356293) },
    { COEF_CONST(0.37050989270210), COEF_CONST(-0.59910142421722) },
    { COEF_CONST(-0.70373594760895), COEF_CONST(0.91227668523788) },
    { COEF_CONST(-0.34600785374641), COEF_CONST(-0.99441426992416) },
    { COEF_CONST(-0.68774479627609), COEF_CONST(-0.30238837003708) },
    { COEF_CONST(-0.26843291521072), COEF_CONST(0.83115667104721) },
    { COEF_CONST(0.49072334170341), COEF_CONST(-0.45359709858894) },
    { COEF_CONST(0.38975992798805), COEF_CONST(0.95515358448029) },
    { COEF_CONST(-0.97757124900818), COEF_CONST(0.05305894464254) },
    { COEF_CONST(-0.17325553297997), COEF_CONST(-0.92770671844482) },
    { COEF_CONST(0.99948036670685), COEF_CONST(0.58285546302795) },
    { COEF_CONST(-0.64946246147156), COEF_CONST(0.68645507097244) },
    { COEF_CONST(-0.12016920745373), COEF_CONST(-0.57147324085236) },
    { COEF_CONST(-0.58947455883026), COEF_CONST(-0.34847131371498) },
    { COEF_CONST(-0.41815140843391), COEF_CONST(0.16276422142982) },
    { COEF_CONST(0.99885648488998), COEF_CONST(0.11136095225811) },
    { COEF_CONST(-0.56649613380432), COEF_CONST(-0.90494865179062) },
    { COEF_CONST(0.94138020277023), COEF_CONST(0.35281917452812) },
    { COEF_CONST(-0.75725078582764), COEF_CONST(0.53650552034378) },
    { COEF_CONST(0.20541973412037), COEF_CONST(-0.94435143470764) },
    { COEF_CONST(0.99980372190475), COEF_CONST(0.79835915565491) },
    { COEF_CONST(0.29078277945518), COEF_CONST(0.35393777489662) },
    { COEF_CONST(-0.62858772277832), COEF_CONST(0.38765692710876) },
    { COEF_CONST(0.43440905213356), COEF_CONST(-0.98546332120895) },
    { COEF_CONST(-0.98298585414886), COEF_CONST(0.21021524071693) },
    { COEF_CONST(0.19513028860092), COEF_CONST(-0.94239830970764) },
    { COEF_CONST(-0.95476663112640), COEF_CONST(0.98364555835724) },
    { COEF_CONST(0.93379634618759), COEF_CONST(-0.70881992578506) },
    { COEF_CONST(-0.85235410928726), COEF_CONST(-0.08342348039150) },
    { COEF_CONST(-0.86425095796585), COEF_CONST(-0.45795026421547) },
    { COEF_CONST(0.38879778981209), COEF_CONST(0.97274428606033) },
    { COEF_CONST(0.92045122385025), COEF_CONST(-0.62433654069901) },
    { COEF_CONST(0.89162534475327), COEF_CONST(0.54950958490372) },
    { COEF_CONST(-0.36834338307381), COEF_CONST(0.96458297967911) },
    { COEF_CONST(0.93891763687134), COEF_CONST(-0.89968353509903) },
    { COEF_CONST(0.99267655611038), COEF_CONST(-0.03757034242153) },
    { COEF_CONST(-0.94063472747803), COEF_CONST(0.41332337260246) },
    { COEF_CONST(0.99740225076675), COEF_CONST(-0.16830494999886) },
    { COEF_CONST(-0.35899412631989), COEF_CONST(-0.46633225679398) },
    { COEF_CONST(0.05237237364054), COEF_CONST(-0.25640362501144) },
    { COEF_CONST(0.36703583598137), COEF_CONST(-0.38653266429901) },
    { COEF_CONST(0.91653180122375), COEF_CONST(-0.30587628483772) },
    { COEF_CONST(0.69000804424286), COEF_CONST(0.90952169895172) },
    { COEF_CONST(-0.38658750057220), COEF_CONST(0.99501574039459) },
    { COEF_CONST(-0.29250815510750), COEF_CONST(0.37444993853569) },
    { COEF_CONST(-0.60182201862335), COEF_CONST(0.86779648065567) },
    { COEF_CONST(-0.97418588399887), COEF_CONST(0.96468526124954) },
    { COEF_CONST(0.88461571931839), COEF_CONST(0.57508403062820) },
    { COEF_CONST(0.05198933184147), COEF_CONST(0.21269661188126) },
    { COEF_CONST(-0.53499621152878), COEF_CONST(0.97241556644440) },
    { COEF_CONST(-0.49429559707642), COEF_CONST(0.98183864355087) },
    { COEF_CONST(-0.98935145139694), COEF_CONST(-0.40249159932137) },
    { COEF_CONST(-0.98081380128860), COEF_CONST(-0.72856897115707) },
    { COEF_CONST(-0.27338150143623), COEF_CONST(0.99950921535492) },
    { COEF_CONST(0.06310802698135), COEF_CONST(-0.54539585113525) },
    { COEF_CONST(-0.20461677014828), COEF_CONST(-0.14209978282452) },
    { COEF_CONST(0.66223841905594), COEF_CONST(0.72528582811356) },
    { COEF_CONST(-0.84764343500137), COEF_CONST(0.02372316829860) },
    { COEF_CONST(-0.89039862155914), COEF_CONST(0.88866579532623) },
    { COEF_CONST(0.95903307199478), COEF_CONST(0.76744925975800) },
    { COEF_CONST(0.73504126071930), COEF_CONST(-0.03747203201056) },
    { COEF_CONST(-0.31744435429573), COEF_CONST(-0.36834111809731) },
    { COEF_CONST(-0.34110826253891), COEF_CONST(0.40211221575737) },
    { COEF_CONST(0.47803884744644), COEF_CONST(-0.39423218369484) },
    { COEF_CONST(0.98299193382263), COEF_CONST(0.01989791356027) },
    { COEF_CONST(-0.30963072180748), COEF_CONST(-0.18076720833778) },
    { COEF_CONST(0.99992591142654), COEF_CONST(-0.26281872391701) },
    { COEF_CONST(-0.93149733543396), COEF_CONST(-0.98313164710999) },
    { COEF_CONST(0.99923473596573), COEF_CONST(-0.80142992734909) },
    { COEF_CONST(-0.26024168729782), COEF_CONST(-0.75999760627747) },
    { COEF_CONST(-0.35712513327599), COEF_CONST(0.19298963248730) },
    { COEF_CONST(-0.99899083375931), COEF_CONST(0.74645155668259) },
    { COEF_CONST(0.86557173728943), COEF_CONST(0.55593866109848) },
    { COEF_CONST(0.33408042788506), COEF_CONST(0.86185956001282) },
    { COEF_CONST(0.99010735750198), COEF_CONST(0.04602397605777) },
    { COEF_CONST(-0.66694271564484), COEF_CONST(-0.91643613576889) },
    { COEF_CONST(0.64016789197922), COEF_CONST(0.15649530291557) },
    { COEF_CONST(0.99570536613464), COEF_CONST(0.45844584703445) },
    { COEF_CONST(-0.63431465625763), COEF_CONST(0.21079117059708) },
    { COEF_CONST(-0.07706847041845), COEF_CONST(-0.89581435918808) },
    { COEF_CONST(0.98590087890625), COEF_CONST(0.88241720199585) },
    { COEF_CONST(0.80099332332611), COEF_CONST(-0.36851897835732) },
    { COEF_CONST(0.78368133306503), COEF_CONST(0.45506998896599) },
    { COEF_CONST(0.08707806468010), COEF_CONST(0.80938994884491) },
    { COEF_CONST(-0.86811882257462), COEF_CONST(0.39347308874130) },
    { COEF_CONST(-0.39466530084610), COEF_CONST(-0.66809433698654) },
    { COEF_CONST(0.97875326871872), COEF_CONST(-0.72467839717865) },
    { COEF_CONST(-0.95038563013077), COEF_CONST(0.89563220739365) },
    { COEF_CONST(0.17005239427090), COEF_CONST(0.54683053493500) },
    { COEF_CONST(-0.76910793781281), COEF_CONST(-0.96226614713669) },
    { COEF_CONST(0.99743282794952), COEF_CONST(0.42697158455849) },
    { COEF_CONST(0.95437383651733), COEF_CONST(0.97002321481705) },
    { COEF_CONST(0.99578905105591), COEF_CONST(-0.54106825590134) },
    { COEF_CONST(0.28058260679245), COEF_CONST(-0.85361421108246) },
    { COEF_CONST(0.85256522893906), COEF_CONST(-0.64567607641220) },
    { COEF_CONST(-0.50608539581299), COEF_CONST(-0.65846014022827) },
    { COEF_CONST(-0.97210735082626), COEF_CONST(-0.23095212876797) },
    { COEF_CONST(0.95424050092697), COEF_CONST(-0.99240148067474) },
    { COEF_CONST(-0.96926569938660), COEF_CONST(0.73775655031204) },
    { COEF_CONST(0.30872163176537), COEF_CONST(0.41514959931374) },
    { COEF_CONST(-0.24523839354515), COEF_CONST(0.63206630945206) },
    { COEF_CONST(-0.33813264966011), COEF_CONST(-0.38661777973175) },
    { COEF_CONST(-0.05826828256249), COEF_CONST(-0.06940773874521) },
    { COEF_CONST(-0.22898460924625), COEF_CONST(0.97054851055145) },
    { COEF_CONST(-0.18509915471077), COEF_CONST(0.47565764188766) },
    { COEF_CONST(-0.10488238185644), COEF_CONST(-0.87769949436188) },
    { COEF_CONST(-0.71886587142944), COEF_CONST(0.78030979633331) },
    { COEF_CONST(0.99793875217438), COEF_CONST(0.90041309595108) },
    { COEF_CONST(0.57563304901123), COEF_CONST(-0.91034334897995) },
    { COEF_CONST(0.28909647464752), COEF_CONST(0.96307784318924) },
    { COEF_CONST(0.42188999056816), COEF_CONST(0.48148649930954) },
    { COEF_CONST(0.93335050344467), COEF_CONST(-0.43537023663521) },
    { COEF_CONST(-0.97087377309799), COEF_CONST(0.86636447906494) },
    { COEF_CONST(0.36722871661186), COEF_CONST(0.65291655063629) },
    { COEF_CONST(-0.81093025207520), COEF_CONST(0.08778370171785) },
    { COEF_CONST(-0.26240602135658), COEF_CONST(-0.92774093151093) },
    { COEF_CONST(0.83996498584747), COEF_CONST(0.55839848518372) },
    { COEF_CONST(-0.99909615516663), COEF_CONST(-0.96024608612061) },
    { COEF_CONST(0.74649465084076), COEF_CONST(0.12144893407822) },
    { COEF_CONST(-0.74774593114853), COEF_CONST(-0.26898062229156) },
    { COEF_CONST(0.95781666040421), COEF_CONST(-0.79047924280167) },
    { COEF_CONST(0.95472306013107), COEF_CONST(-0.08588775992393) },
    { COEF_CONST(0.48708331584930), COEF_CONST(0.99999040365219) },
    { COEF_CONST(0.46332037448883), COEF_CONST(0.10964126139879) },
    { COEF_CONST(-0.76497006416321), COEF_CONST(0.89210927486420) },
    { COEF_CONST(0.57397389411926), COEF_CONST(0.35289704799652) },
    { COEF_CONST(0.75374317169189), COEF_CONST(0.96705216169357) },
    { COEF_CONST(-0.59174400568008), COEF_CONST(-0.89405369758606) },
    { COEF_CONST(0.75087904930115), COEF_CONST(-0.29612672328949) },
    { COEF_CONST(-0.98607856035233), COEF_CONST(0.25034910440445) },
    { COEF_CONST(-0.40761056542397), COEF_CONST(-0.90045571327209) },
    { COEF_CONST(0.66929268836975), COEF_CONST(0.98629492521286) },
    { COEF_CONST(-0.97463697195053), COEF_CONST(-0.00190223299433) },
    { COEF_CONST(0.90145510435104), COEF_CONST(0.99781388044357) },
    { COEF_CONST(-0.87259286642075), COEF_CONST(0.99233585596085) },
    { COEF_CONST(-0.91529458761215), COEF_CONST(-0.15698707103729) },
    { COEF_CONST(-0.03305738791823), COEF_CONST(-0.37205263972282) },
    { COEF_CONST(0.07223051041365), COEF_CONST(-0.88805001974106) },
    { COEF_CONST(0.99498009681702), COEF_CONST(0.97094357013702) },
    { COEF_CONST(-0.74904936552048), COEF_CONST(0.99985486268997) },
    { COEF_CONST(0.04585228487849), COEF_CONST(0.99812334775925) },
    { COEF_CONST(-0.89054954051971), COEF_CONST(-0.31791913509369) },
    { COEF_CONST(-0.83782142400742), COEF_CONST(0.97637635469437) },
    { COEF_CONST(0.33454805612564), COEF_CONST(-0.86231517791748) },
    { COEF_CONST(-0.99707579612732), COEF_CONST(0.93237990140915) },
    { COEF_CONST(-0.22827528417110), COEF_CONST(0.18874759972095) },
    { COEF_CONST(0.67248046398163), COEF_CONST(-0.03646211326122) },
    { COEF_CONST(-0.05146538093686), COEF_CONST(-0.92599701881409) },
    { COEF_CONST(0.99947297573090), COEF_CONST(0.93625229597092) },
    { COEF_CONST(0.66951125860214), COEF_CONST(0.98905825614929) },
    { COEF_CONST(-0.99602955579758), COEF_CONST(-0.44654715061188) },
    { COEF_CONST(0.82104903459549), COEF_CONST(0.99540740251541) },
    { COEF_CONST(0.99186509847641), COEF_CONST(0.72022998332977) },
    { COEF_CONST(-0.65284591913223), COEF_CONST(0.52186721563339) },
    { COEF_CONST(0.93885445594788), COEF_CONST(-0.74895310401917) },
    { COEF_CONST(0.96735250949860), COEF_CONST(0.90891814231873) },
    { COEF_CONST(-0.22225968539715), COEF_CONST(0.57124030590057) },
    { COEF_CONST(-0.44132784008980), COEF_CONST(-0.92688840627670) },
    { COEF_CONST(-0.85694974660873), COEF_CONST(0.88844531774521) },
    { COEF_CONST(0.91783040761948), COEF_CONST(-0.46356892585754) },
    { COEF_CONST(0.72556972503662), COEF_CONST(-0.99899554252625) },
    { COEF_CONST(-0.99711579084396), COEF_CONST(0.58211559057236) },
    { COEF_CONST(0.77638977766037), COEF_CONST(0.94321835041046) },
    { COEF_CONST(0.07717324048281), COEF_CONST(0.58638399839401) },
    { COEF_CONST(-0.56049829721451), COEF_CONST(0.82522302865982) },
    { COEF_CONST(0.98398894071579), COEF_CONST(0.39467439055443) },
    { COEF_CONST(0.47546947002411), COEF_CONST(0.68613046407700) },
    { COEF_CONST(0.65675091743469), COEF_CONST(0.18331636488438) },
    { COEF_CONST(0.03273375332355), COEF_CONST(-0.74933111667633) },
    { COEF_CONST(-0.38684144616127), COEF_CONST(0.51337349414825) },
    { COEF_CONST(-0.97346270084381), COEF_CONST(-0.96549361944199) },
    { COEF_CONST(-0.53282153606415), COEF_CONST(-0.91423267126083) },
    { COEF_CONST(0.99817311763763), COEF_CONST(0.61133575439453) },
    { COEF_CONST(-0.50254499912262), COEF_CONST(-0.88829338550568) },
    { COEF_CONST(0.01995873264968), COEF_CONST(0.85223513841629) },
    { COEF_CONST(0.99930381774902), COEF_CONST(0.94578897953033) },
    { COEF_CONST(0.82907766103745), COEF_CONST(-0.06323442608118) },
    { COEF_CONST(-0.58660709857941), COEF_CONST(0.96840775012970) },
    { COEF_CONST(-0.17573736608028), COEF_CONST(-0.48166921734810) },
    { COEF_CONST(0.83434289693832), COEF_CONST(-0.13023450970650) },
    { COEF_CONST(0.05946491286159), COEF_CONST(0.20511047542095) },
    { COEF_CONST(0.81505483388901), COEF_CONST(-0.94685947895050) },
    { COEF_CONST(-0.44976380467415), COEF_CONST(0.40894573926926) },
    { COEF_CONST(-0.89746475219727), COEF_CONST(0.99846577644348) },
    { COEF_CONST(0.39677256345749), COEF_CONST(-0.74854665994644) },
    { COEF_CONST(-0.07588948309422), COEF_CONST(0.74096214771271) },
    { COEF_CONST(0.76343196630478), COEF_CONST(0.41746628284454) },
    { COEF_CONST(-0.74490106105804), COEF_CONST(0.94725912809372) },
    { COEF_CONST(0.64880120754242), COEF_CONST(0.41336661577225) },
    { COEF_CONST(0.62319535017014), COEF_CONST(-0.93098312616348) },
    { COEF_CONST(0.42215818166733), COEF_CONST(-0.07712787389755) },
    { COEF_CONST(0.02704554051161), COEF_CONST(-0.05417517945170) },
    { COEF_CONST(0.80001771450043), COEF_CONST(0.91542196273804) },
    { COEF_CONST(-0.79351830482483), COEF_CONST(-0.36208897829056) },
    { COEF_CONST(0.63872361183167), COEF_CONST(0.08128252625465) },
    { COEF_CONST(0.52890521287918), COEF_CONST(0.60048872232437) },
    { COEF_CONST(0.74238550662994), COEF_CONST(0.04491915181279) },
    { COEF_CONST(0.99096131324768), COEF_CONST(-0.19451183080673) },
    { COEF_CONST(-0.80412328243256), COEF_CONST(-0.88513815402985) },
    { COEF_CONST(-0.64612615108490), COEF_CONST(0.72198677062988) },
    { COEF_CONST(0.11657770723104), COEF_CONST(-0.83662831783295) },
    { COEF_CONST(-0.95053184032440), COEF_CONST(-0.96939903497696) },
    { COEF_CONST(-0.62228870391846), COEF_CONST(0.82767260074615) },
    { COEF_CONST(0.03004475869238), COEF_CONST(-0.99738895893097) },
    { COEF_CONST(-0.97987216711044), COEF_CONST(0.36526128649712) },
    { COEF_CONST(-0.99986982345581), COEF_CONST(-0.36021611094475) },
    { COEF_CONST(0.89110648632050), COEF_CONST(-0.97894251346588) },
    { COEF_CONST(0.10407960414886), COEF_CONST(0.77357792854309) },
    { COEF_CONST(0.95964735746384), COEF_CONST(-0.35435819625854) },
    { COEF_CONST(0.50843232870102), COEF_CONST(0.96107691526413) },
    { COEF_CONST(0.17006334662437), COEF_CONST(-0.76854026317596) },
    { COEF_CONST(0.25872674584389), COEF_CONST(0.99893301725388) },
    { COEF_CONST(-0.01115998718888), COEF_CONST(0.98496019840240) },
    { COEF_CONST(-0.79598701000214), COEF_CONST(0.97138410806656) },
    { COEF_CONST(-0.99264711141586), COEF_CONST(-0.99542820453644) },
    { COEF_CONST(-0.99829661846161), COEF_CONST(0.01877138763666) },
    { COEF_CONST(-0.70801013708115), COEF_CONST(0.33680686354637) },
    { COEF_CONST(-0.70467054843903), COEF_CONST(0.93272775411606) },
    { COEF_CONST(0.99846023321152), COEF_CONST(-0.98725748062134) },
    { COEF_CONST(-0.63364970684052), COEF_CONST(-0.16473594307899) },
    { COEF_CONST(-0.16258217394352), COEF_CONST(-0.95939123630524) },
    { COEF_CONST(-0.43645593523979), COEF_CONST(-0.94805032014847) },
    { COEF_CONST(-0.99848473072052), COEF_CONST(0.96245169639587) },
    { COEF_CONST(-0.16796459257603), COEF_CONST(-0.98987513780594) },
    { COEF_CONST(-0.87979227304459), COEF_CONST(-0.71725726127625) },
    { COEF_CONST(0.44183099269867), COEF_CONST(-0.93568974733353) },
    { COEF_CONST(0.93310177326202), COEF_CONST(-0.99913311004639) },
    { COEF_CONST(-0.93941932916641), COEF_CONST(-0.56409376859665) },
    { COEF_CONST(-0.88590002059937), COEF_CONST(0.47624599933624) },
    { COEF_CONST(0.99971461296082), COEF_CONST(-0.83889955282211) },
    { COEF_CONST(-0.75376385450363), COEF_CONST(0.00814643409103) },
    { COEF_CONST(0.93887686729431), COEF_CONST(-0.11284527927637) },
    { COEF_CONST(0.85126435756683), COEF_CONST(0.52349251508713) },
    { COEF_CONST(0.39701420068741), COEF_CONST(0.81779634952545) },
    { COEF_CONST(-0.37024465203285), COEF_CONST(-0.87071657180786) },
    { COEF_CONST(-0.36024826765060), COEF_CONST(0.34655734896660) },
    { COEF_CONST(-0.93388813734055), COEF_CONST(-0.84476542472839) },
    { COEF_CONST(-0.65298801660538), COEF_CONST(-0.18439576029778) },
    { COEF_CONST(0.11960318684578), COEF_CONST(0.99899345636368) },
    { COEF_CONST(0.94292563199997), COEF_CONST(0.83163905143738) },
    { COEF_CONST(0.75081145763397), COEF_CONST(-0.35533222556114) },
    { COEF_CONST(0.56721979379654), COEF_CONST(-0.24076835811138) },
    { COEF_CONST(0.46857765316963), COEF_CONST(-0.30140233039856) },
    { COEF_CONST(0.97312313318253), COEF_CONST(-0.99548190832138) },
    { COEF_CONST(-0.38299977779388), COEF_CONST(0.98516911268234) },
    { COEF_CONST(0.41025799512863), COEF_CONST(0.02116736955941) },
    { COEF_CONST(0.09638062119484), COEF_CONST(0.04411984235048) },
    { COEF_CONST(-0.85283249616623), COEF_CONST(0.91475564241409) },
    { COEF_CONST(0.88866806030273), COEF_CONST(-0.99735265970230) },
    { COEF_CONST(-0.48202428221703), COEF_CONST(-0.96805608272552) },
    { COEF_CONST(0.27572581171989), COEF_CONST(0.58634752035141) },
    { COEF_CONST(-0.65889132022858), COEF_CONST(0.58835631608963) },
    { COEF_CONST(0.98838084936142), COEF_CONST(0.99994349479675) },
    { COEF_CONST(-0.20651349425316), COEF_CONST(0.54593044519424) },
    { COEF_CONST(-0.62126415967941), COEF_CONST(-0.59893679618835) },
    { COEF_CONST(0.20320105552673), COEF_CONST(-0.86879181861877) },
    { COEF_CONST(-0.97790551185608), COEF_CONST(0.96290808916092) },
    { COEF_CONST(0.11112534999847), COEF_CONST(0.21484763920307) },
    { COEF_CONST(-0.41368338465691), COEF_CONST(0.28216838836670) },
    { COEF_CONST(0.24133038520813), COEF_CONST(0.51294362545013) },
    { COEF_CONST(-0.66393411159515), COEF_CONST(-0.08249679952860) },
    { COEF_CONST(-0.53697830438614), COEF_CONST(-0.97649902105331) },
    { COEF_CONST(-0.97224736213684), COEF_CONST(0.22081333398819) },
    { COEF_CONST(0.87392479181290), COEF_CONST(-0.12796173989773) },
    { COEF_CONST(0.19050361216068), COEF_CONST(0.01602615416050) },
    { COEF_CONST(-0.46353441476822), COEF_CONST(-0.95249038934708) },
    { COEF_CONST(-0.07064096629620), COEF_CONST(-0.94479805231094) },
    { COEF_CONST(-0.92444086074829), COEF_CONST(-0.10457590222359) },
    { COEF_CONST(-0.83822596073151), COEF_CONST(-0.01695043221116) },
    { COEF_CONST(0.75214684009552), COEF_CONST(-0.99955683946609) },
    { COEF_CONST(-0.42102998495102), COEF_CONST(0.99720942974091) },
    { COEF_CONST(-0.72094786167145), COEF_CONST(-0.35008960962296) },
    { COEF_CONST(0.78843313455582), COEF_CONST(0.52851396799088) },
    { COEF_CONST(0.97394025325775), COEF_CONST(-0.26695942878723) },
    { COEF_CONST(0.99206465482712), COEF_CONST(-0.57010120153427) },
    { COEF_CONST(0.76789611577988), COEF_CONST(-0.76519358158112) },
    { COEF_CONST(-0.82002419233322), COEF_CONST(-0.73530179262161) },
    { COEF_CONST(0.81924992799759), COEF_CONST(0.99698424339294) },
    { COEF_CONST(-0.26719850301743), COEF_CONST(0.68903368711472) },
    { COEF_CONST(-0.43311259150505), COEF_CONST(0.85321813821793) },
    { COEF_CONST(0.99194979667664), COEF_CONST(0.91876250505447) },
    { COEF_CONST(-0.80691999197006), COEF_CONST(-0.32627540826797) },
    { COEF_CONST(0.43080005049706), COEF_CONST(-0.21919095516205) },
    { COEF_CONST(0.67709493637085), COEF_CONST(-0.95478075742722) },
    { COEF_CONST(0.56151771545410), COEF_CONST(-0.70693808794022) },
    { COEF_CONST(0.10831862688065), COEF_CONST(-0.08628837019205) },
    { COEF_CONST(0.91229414939880), COEF_CONST(-0.65987348556519) },
    { COEF_CONST(-0.48972892761230), COEF_CONST(0.56289243698120) },
    { COEF_CONST(-0.89033657312393), COEF_CONST(-0.71656566858292) },
    { COEF_CONST(0.65269446372986), COEF_CONST(0.65916007757187) },
    { COEF_CONST(0.67439478635788), COEF_CONST(-0.81684380769730) },
    { COEF_CONST(-0.47770830988884), COEF_CONST(-0.16789555549622) },
    { COEF_CONST(-0.99715977907181), COEF_CONST(-0.93565785884857) },
    { COEF_CONST(-0.90889590978622), COEF_CONST(0.62034398317337) },
    { COEF_CONST(-0.06618622690439), COEF_CONST(-0.23812216520309) },
    { COEF_CONST(0.99430269002914), COEF_CONST(0.18812555074692) },
    { COEF_CONST(0.97686403989792), COEF_CONST(-0.28664535284042) },
    { COEF_CONST(0.94813650846481), COEF_CONST(-0.97506642341614) },
    { COEF_CONST(-0.95434498786926), COEF_CONST(-0.79607981443405) },
    { COEF_CONST(-0.49104782938957), COEF_CONST(0.32895213365555) },
    { COEF_CONST(0.99881172180176), COEF_CONST(0.88993984460831) },
    { COEF_CONST(0.50449168682098), COEF_CONST(-0.85995072126389) },
    { COEF_CONST(0.47162890434265), COEF_CONST(-0.18680204451084) },
    { COEF_CONST(-0.62081581354141), COEF_CONST(0.75000673532486) },
    { COEF_CONST(-0.43867015838623), COEF_CONST(0.99998068809509) },
    { COEF_CONST(0.98630565404892), COEF_CONST(-0.53578901290894) },
    { COEF_CONST(-0.61510360240936), COEF_CONST(-0.89515018463135) },
    { COEF_CONST(-0.03841517493129), COEF_CONST(-0.69888818264008) },
    { COEF_CONST(-0.30102157592773), COEF_CONST(-0.07667808979750) },
    { COEF_CONST(0.41881284117699), COEF_CONST(0.02188098989427) },
    { COEF_CONST(-0.86135452985764), COEF_CONST(0.98947483301163) },
    { COEF_CONST(0.67226862907410), COEF_CONST(-0.13494388759136) },
    { COEF_CONST(-0.70737397670746), COEF_CONST(-0.76547348499298) },
    { COEF_CONST(0.94044947624207), COEF_CONST(0.09026201069355) },
    { COEF_CONST(-0.82386350631714), COEF_CONST(0.08924768865108) },
    { COEF_CONST(-0.32070666551590), COEF_CONST(0.50143420696259) },
    { COEF_CONST(0.57593160867691), COEF_CONST(-0.98966425657272) },
    { COEF_CONST(-0.36326017975807), COEF_CONST(0.07440242916346) },
    { COEF_CONST(0.99979043006897), COEF_CONST(-0.14130286872387) },
    { COEF_CONST(-0.92366021871567), COEF_CONST(-0.97979295253754) },
    { COEF_CONST(-0.44607177376747), COEF_CONST(-0.54233253002167) },
    { COEF_CONST(0.44226801395416), COEF_CONST(0.71326756477356) },
    { COEF_CONST(0.03671907261014), COEF_CONST(0.63606387376785) },
    { COEF_CONST(0.52175426483154), COEF_CONST(-0.85396826267242) },
    { COEF_CONST(-0.94701141119003), COEF_CONST(-0.01826348155737) },
    { COEF_CONST(-0.98759609460831), COEF_CONST(0.82288712263107) },
    { COEF_CONST(0.87434792518616), COEF_CONST(0.89399492740631) },
    { COEF_CONST(-0.93412041664124), COEF_CONST(0.41374051570892) },
    { COEF_CONST(0.96063941717148), COEF_CONST(0.93116706609726) },
    { COEF_CONST(0.97534251213074), COEF_CONST(0.86150932312012) },
    { COEF_CONST(0.99642467498779), COEF_CONST(0.70190042257309) },
    { COEF_CONST(-0.94705086946487), COEF_CONST(-0.29580041766167) },
    { COEF_CONST(0.91599804162979), COEF_CONST(-0.98147833347321) }
};

#ifdef __cplusplus

#endif
#endif
--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_qmf.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#ifdef SBR_DEC


#include <stdlib.h>
#include <string.h>
#include "sbr_dct.h"
#include "sbr_qmf.h"
#include "sbr_syntax.h"


qmfa_info *qmfa_init(uint8_t channels)
{
#if 0
    int16_t n;
#endif
    int size = 0;
    qmfa_info *qmfa = (qmfa_info*)malloc(sizeof(qmfa_info));
    qmfa->x = (real_t*)malloc(channels * 10 * sizeof(real_t));
    memset(qmfa->x, 0, channels * 10 * sizeof(real_t));

    qmfa->channels = channels;

    if (channels == 32)
    {
#if 0
        for (n = 0; n < 32; n++)
        {
            qmfa->post_exp_re[n] = cos((M_PI/32.)*(0.75*n + 0.375));
            qmfa->post_exp_im[n] = sin((M_PI/32.)*(0.75*n + 0.375));
        }
#endif
    } else if (channels == 64) {
#if 0
        for (n = 0; n < 2*channels; n++)
        {
            qmfa->pre_exp_re[n] = cos(M_PI*n/(2.*channels));
            qmfa->pre_exp_im[n] = sin(M_PI*n/(2.*channels));
        }
        for (n = 0; n < 64; n++)
        {
            qmfa->post_exp_re[n] = cos(M_PI*(2*n+1)/(2.*128.));
            qmfa->post_exp_im[n] = sin(M_PI*(2*n+1)/(2.*128.));
        }
#endif
    }

    return qmfa;
}

void qmfa_end(qmfa_info *qmfa)
{
    if (qmfa)
    {
        if (qmfa->x) free(qmfa->x);
        free(qmfa);
    }
}

void sbr_qmf_analysis_32(qmfa_info *qmfa, const real_t *input,
                         qmf_t *X, uint8_t offset)
{
    uint8_t l;
    real_t u[64];
#ifndef SBR_LOW_POWER
    real_t x[64], y[64];
#else
    real_t y[32];
#endif
    const real_t *inptr = input;

    /* qmf subsample l */
    for (l = 0; l < 32; l++)
    {
        int16_t n;

        /* shift input buffer x */
        memmove(qmfa->x + 32, qmfa->x, (320-32)*sizeof(real_t));

        /* add new samples to input buffer x */
        for (n = 32 - 1; n >= 0; n--)
        {
#ifdef FIXED_POINT
            qmfa->x[n] = (*inptr++) >> 5;
#else
            qmfa->x[n] = *inptr++;
#endif
        }

        /* window and summation to create array u */
        for (n = 0; n < 64; n++)
        {
            u[n] = MUL_R_C(qmfa->x[n], qmf_c_2[n]) +
                MUL_R_C(qmfa->x[n + 64], qmf_c_2[n + 64]) +
                MUL_R_C(qmfa->x[n + 128], qmf_c_2[n + 128]) +
                MUL_R_C(qmfa->x[n + 192], qmf_c_2[n + 192]) +
                MUL_R_C(qmfa->x[n + 256], qmf_c_2[n + 256]);
        }

        /* calculate 32 subband samples by introducing X */
#ifdef SBR_LOW_POWER
        y[0] = u[48];
        for (n = 1; n < 16; n++)
            y[n] = u[n+48] + u[48-n];
        for (n = 16; n < 32; n++)
            y[n] = -u[n-16] + u[48-n];

        DCT3_32_unscaled(u, y);

        for (n = 0; n < 32; n++)
        {
#ifdef FIXED_POINT
            QMF_RE(X[((l + offset)<<5) + n]) = u[n] << 1;
#else
            QMF_RE(X[((l + offset)<<5) + n]) = 2. * u[n];
#endif

#if 0
            if (fabs(QMF_RE(X[((l + offset)<<5) + n])) > pow(2,20))
            {
                printf("%f\n", QMF_RE(X[((l + offset)<<5) + n]));
            }
#endif
        }
#else
        x[0] = u[0];
        x[63] = u[32];
        for (n = 2; n < 64; n += 2)
        {
            x[n-1] = u[(n>>1)];
            x[n] = -u[64-(n>>1)];
        }

        DCT4_64(y, x);

        for (n = 0; n < 32; n++)
        {
#ifdef FIXED_POINT
            QMF_RE(X[((l + offset)<<5) + n]) = y[n] << 1;
            QMF_IM(X[((l + offset)<<5) + n]) = -y[63-n] << 1;
#else
            QMF_RE(X[((l + offset)<<5) + n]) = 2. * y[n];
            QMF_IM(X[((l + offset)<<5) + n]) = -2. * y[63-n];
#endif

#if 0
            if (fabs(QMF_RE(X[((l + offset)<<5) + n])) > pow(2,20))
            {
                printf("%f\n", QMF_RE(X[((l + offset)<<5) + n]));
            }
            if (fabs(QMF_IM(X[((l + offset)<<5) + n])) > pow(2,20))
            {
                printf("%f\n", QMF_IM(X[((l + offset)<<5) + n]));
            }
#endif
        }
#endif
    }
}

qmfs_info *qmfs_init(uint8_t channels)
{
    int size = 0;
    qmfs_info *qmfs = (qmfs_info*)malloc(sizeof(qmfs_info));
    qmfs->v = (real_t*)malloc(channels * 20 * sizeof(real_t));
    memset(qmfs->v, 0, channels * 20 * sizeof(real_t));

    qmfs->channels = channels;

    return qmfs;
}

void qmfs_end(qmfs_info *qmfs)
{
    if (qmfs)
    {
        if (qmfs->v) free(qmfs->v);
        free(qmfs);
    }
}

#if 0
void sbr_qmf_synthesis_32(qmfs_info *qmfs, const complex_t *X,
                          real_t *output)
{
    uint8_t l;
    int16_t n, k;
    real_t w[320];
    complex_t x[128];
    real_t *outptr = output;

    /* qmf subsample l */
    for (l = 0; l < 32; l++)
    {
        /* shift buffer */
        for (n = 640 - 1; n >= 64; n--)
        {
            qmfs->v[n] = qmfs->v[n - 64];
        }

        /* calculate 64 samples */
        memset(x, 0, 2*64*sizeof(real_t));

        for (k = 0; k < 32; k++)
        {
            real_t er, ei, Xr, Xi;
            er = qmfs->pre_exp_re[k];
            ei = qmfs->pre_exp_im[k];

            Xr = RE(X[l * 32 + k]);
            Xi = IM(X[l * 32 + k]);
            RE(x[k]) = Xr * er - Xi * ei;
            IM(x[k]) = Xi * er + Xr * ei;
        }

        cfftb(qmfs->cffts, x);

        for (n = 0; n < 64; n++)
        {
            real_t er, ei;
            er = qmfs->post_exp_re[n];
            ei = qmfs->post_exp_im[n];

            qmfs->v[n] = RE(x[n]) * er - IM(x[n]) * ei;
        }

        for (n = 0; n < 5; n++)
        {
            for (k = 0; k < 32; k++)
            {
                w[64 * n +      k] = qmfs->v[128 * n +      k];
                w[64 * n + 32 + k] = qmfs->v[128 * n + 96 + k];
            }
        }

        /* window */
        for (n = 0; n < 320; n++)
        {
            w[n] *= qmf_c_2[n];
        }

        /* calculate 32 output samples */
        for (k = 0; k < 32; k++)
        {
            real_t sample = 0.0;

            for (n = 0; n < 10; n++)
            {
                sample += w[32 * n + k];
            }

            *outptr++ = sample;
        }
    }
}
#endif

void sbr_qmf_synthesis_64(qmfs_info *qmfs, const qmf_t *X,
                          real_t *output)
{
    uint8_t l;
    int16_t n, k;
#ifdef SBR_LOW_POWER
    real_t x[64];
#else
    real_t x1[64], x2[64];
#endif
    real_t *outptr = output;


    /* qmf subsample l */
    for (l = 0; l < 32; l++)
    {
        /* shift buffer */
        memmove(qmfs->v + 128, qmfs->v, (1280-128)*sizeof(real_t));

        /* calculate 128 samples */
#ifdef SBR_LOW_POWER
        for (k = 0; k < 64; k++)
        {
#ifdef FIXED_POINT
            x[k] = QMF_RE(X[(l<<6) + k]);
#else
            x[k] = QMF_RE(X[(l<<6) + k]) / 32.;
#endif
        }

        DCT2_64_unscaled(x, x);

        for (n = 0; n < 64; n++)
        {
            qmfs->v[n+32] = x[n];
        }
        qmfs->v[0] = qmfs->v[64];
        for (n = 1; n < 32; n++)
        {
            qmfs->v[32 - n] = qmfs->v[n + 32];
            qmfs->v[n + 96] = -qmfs->v[96 - n];
        }
#else
        for (k = 0; k < 64; k++)
        {
            x1[k] = QMF_RE(X[(l<<6) + k])/64.;
            x2[k] = QMF_IM(X[(l<<6) + k])/64.;
        }

        DCT4_64(x1, x1);
        DST4_64(x2, x2);

        for (n = 0; n < 64; n++)
        {
            qmfs->v[n] = x2[n] - x1[n];
            qmfs->v[127-n] = x2[n] + x1[n];
        }
#endif

        /* calculate 64 output samples and window */
        for (k = 0; k < 64; k++)
        {
            *outptr++ = MUL_R_C(qmfs->v[k], qmf_c[k]) +
                MUL_R_C(qmfs->v[192 + k], qmf_c[64 + k]) +
                MUL_R_C(qmfs->v[256 + k], qmf_c[128 + k]) +
                MUL_R_C(qmfs->v[256 + 192 + k], qmf_c[128 + 64 + k]) +
                MUL_R_C(qmfs->v[512 + k], qmf_c[256 + k]) +
                MUL_R_C(qmfs->v[512 + 192 + k], qmf_c[256 + 64 + k]) +
                MUL_R_C(qmfs->v[768 + k], qmf_c[384 + k]) +
                MUL_R_C(qmfs->v[768 + 192 + k], qmf_c[384 + 64 + k]) +
                MUL_R_C(qmfs->v[1024 + k], qmf_c[512 + k]) +
                MUL_R_C(qmfs->v[1024 + 192 + k], qmf_c[512 + 64 + k]);
        }
    }
}

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_qmf.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_QMF_H__
#define __SBR_QMF_H__

#ifdef __cplusplus
extern "C" {
#endif

qmfa_info *qmfa_init(uint8_t channels);
void qmfa_end(qmfa_info *qmfa);
qmfs_info *qmfs_init(uint8_t channels);
void qmfs_end(qmfs_info *qmfs);

void sbr_qmf_analysis_32(qmfa_info *qmfa, const real_t *input,
                         qmf_t *X, uint8_t offset);
void sbr_qmf_analysis_64(qmfa_info *qmfa, const real_t *input,
                         qmf_t *X, uint8_t maxband, uint8_t offset);
void sbr_qmf_synthesis_32(qmfs_info *qmfs, const qmf_t *X,
                          real_t *output);
void sbr_qmf_synthesis_64(qmfs_info *qmfs, const qmf_t *X,
                          real_t *output);

#ifdef _MSC_VER
#pragma warning(disable:4305)
#pragma warning(disable:4244)
#endif

static real_t qmf_c[] = {
    COEF_CONST(0.0000000000), COEF_CONST(-0.0005525286),
    COEF_CONST(-0.0005617692), COEF_CONST(-0.0004947518),
    COEF_CONST(-0.0004875227), COEF_CONST(-0.0004893791),
    COEF_CONST(-0.0005040714), COEF_CONST(-0.0005226564),
    COEF_CONST(-0.0005466565), COEF_CONST(-0.0005677802),
    COEF_CONST(-0.0005870930), COEF_CONST(-0.0006132747),
    COEF_CONST(-0.0006312493), COEF_CONST(-0.0006540333),
    COEF_CONST(-0.0006777690), COEF_CONST(-0.0006941614),
    COEF_CONST(-0.0007157736), COEF_CONST(-0.0007255043),
    COEF_CONST(-0.0007440941), COEF_CONST(-0.0007490598),
    COEF_CONST(-0.0007681371), COEF_CONST(-0.0007724848),
    COEF_CONST(-0.0007834332), COEF_CONST(-0.0007779869),
    COEF_CONST(-0.0007803664), COEF_CONST(-0.0007801449),
    COEF_CONST(-0.0007757977), COEF_CONST(-0.0007630793),
    COEF_CONST(-0.0007530001), COEF_CONST(-0.0007319357),
    COEF_CONST(-0.0007215391), COEF_CONST(-0.0006917937),
    COEF_CONST(-0.0006650415), COEF_CONST(-0.0006341594),
    COEF_CONST(-0.0005946118), COEF_CONST(-0.0005564576),
    COEF_CONST(-0.0005145572), COEF_CONST(-0.0004606325),
    COEF_CONST(-0.0004095121), COEF_CONST(-0.0003501175),
    COEF_CONST(-0.0002896981), COEF_CONST(-0.0002098337),
    COEF_CONST(-0.0001446380), COEF_CONST(-0.0000617334),
    COEF_CONST(0.0000134949), COEF_CONST(0.0001094383),
    COEF_CONST(0.0002043017), COEF_CONST(0.0002949531),
    COEF_CONST(0.0004026540), COEF_CONST(0.0005107388),
    COEF_CONST(0.0006239376), COEF_CONST(0.0007458025),
    COEF_CONST(0.0008608443), COEF_CONST(0.0009885988),
    COEF_CONST(0.0011250156), COEF_CONST(0.0012577884),
    COEF_CONST(0.0013902494), COEF_CONST(0.0015443219),
    COEF_CONST(0.0016868083), COEF_CONST(0.0018348265),
    COEF_CONST(0.0019841141), COEF_CONST(0.0021461584),
    COEF_CONST(0.0023017253), COEF_CONST(0.0024625617),
    COEF_CONST(0.0026201757), COEF_CONST(0.0027870464),
    COEF_CONST(0.0029469447), COEF_CONST(0.0031125420),
    COEF_CONST(0.0032739614), COEF_CONST(0.0034418874),
    COEF_CONST(0.0036008267), COEF_CONST(0.0037603923),
    COEF_CONST(0.0039207432), COEF_CONST(0.0040819752),
    COEF_CONST(0.0042264271), COEF_CONST(0.0043730717),
    COEF_CONST(0.0045209853), COEF_CONST(0.0046606460),
    COEF_CONST(0.0047932561), COEF_CONST(0.0049137603),
    COEF_CONST(0.0050393022), COEF_CONST(0.0051407353),
    COEF_CONST(0.0052461168), COEF_CONST(0.0053471681),
    COEF_CONST(0.0054196776), COEF_CONST(0.0054876041),
    COEF_CONST(0.0055475715), COEF_CONST(0.0055938023),
    COEF_CONST(0.0056220642), COEF_CONST(0.0056455196),
    COEF_CONST(0.0056389198), COEF_CONST(0.0056266114),
    COEF_CONST(0.0055917129), COEF_CONST(0.0055404361),
    COEF_CONST(0.0054753781), COEF_CONST(0.0053838976),
    COEF_CONST(0.0052715759), COEF_CONST(0.0051382277),
    COEF_CONST(0.0049839686), COEF_CONST(0.0048109470),
    COEF_CONST(0.0046039531), COEF_CONST(0.0043801861),
    COEF_CONST(0.0041251644), COEF_CONST(0.0038456407),
    COEF_CONST(0.0035401245), COEF_CONST(0.0032091886),
    COEF_CONST(0.0028446757), COEF_CONST(0.0024508541),
    COEF_CONST(0.0020274175), COEF_CONST(0.0015784682),
    COEF_CONST(0.0010902329), COEF_CONST(0.0005832264),
    COEF_CONST(0.0000276045), COEF_CONST(-0.0005464280),
    COEF_CONST(-0.0011568135), COEF_CONST(-0.0018039471),
    COEF_CONST(-0.0024826722), COEF_CONST(-0.0031933777),
    COEF_CONST(-0.0039401124), COEF_CONST(-0.0047222595),
    COEF_CONST(-0.0055337213), COEF_CONST(-0.0063792295),
    COEF_CONST(-0.0072615817), COEF_CONST(-0.0081798229),
    COEF_CONST(-0.0091325333), COEF_CONST(-0.0101150218),
    COEF_CONST(-0.0111315548), COEF_CONST(-0.0121849999),
    COEF_CONST(0.0132718217), COEF_CONST(0.0143904667),
    COEF_CONST(0.0155405551), COEF_CONST(0.0167324711),
    COEF_CONST(0.0179433376), COEF_CONST(0.0191872437),
    COEF_CONST(0.0204531793), COEF_CONST(0.0217467546),
    COEF_CONST(0.0230680164), COEF_CONST(0.0244160984),
    COEF_CONST(0.0257875845), COEF_CONST(0.0271859430),
    COEF_CONST(0.0286072176), COEF_CONST(0.0300502665),
    COEF_CONST(0.0315017626), COEF_CONST(0.0329754092),
    COEF_CONST(0.0344620943), COEF_CONST(0.0359697565),
    COEF_CONST(0.0374812856), COEF_CONST(0.0390053689),
    COEF_CONST(0.0405349173), COEF_CONST(0.0420649089),
    COEF_CONST(0.0436097533), COEF_CONST(0.0451488420),
    COEF_CONST(0.0466843024), COEF_CONST(0.0482165702),
    COEF_CONST(0.0497385748), COEF_CONST(0.0512556173),
    COEF_CONST(0.0527630746), COEF_CONST(0.0542452782),
    COEF_CONST(0.0557173640), COEF_CONST(0.0571616441),
    COEF_CONST(0.0585915670), COEF_CONST(0.0599837489),
    COEF_CONST(0.0613455176), COEF_CONST(0.0626857802),
    COEF_CONST(0.0639715865), COEF_CONST(0.0652247071),
    COEF_CONST(0.0664367527), COEF_CONST(0.0676075965),
    COEF_CONST(0.0687043816), COEF_CONST(0.0697630271),
    COEF_CONST(0.0707628727), COEF_CONST(0.0717002675),
    COEF_CONST(0.0725682601), COEF_CONST(0.0733620226),
    COEF_CONST(0.0741003677), COEF_CONST(0.0747452527),
    COEF_CONST(0.0753137320), COEF_CONST(0.0758008361),
    COEF_CONST(0.0761992484), COEF_CONST(0.0764992163),
    COEF_CONST(0.0767093524), COEF_CONST(0.0768174008),
    COEF_CONST(0.0768230036), COEF_CONST(0.0767204911),
    COEF_CONST(0.0765050724), COEF_CONST(0.0761748329),
    COEF_CONST(0.0757305771), COEF_CONST(0.0751576275),
    COEF_CONST(0.0744664371), COEF_CONST(0.0736405998),
    COEF_CONST(0.0726774633), COEF_CONST(0.0715826377),
    COEF_CONST(0.0703533068), COEF_CONST(0.0689664036),
    COEF_CONST(0.0674525052), COEF_CONST(0.0657690689),
    COEF_CONST(0.0639444813), COEF_CONST(0.0619602762),
    COEF_CONST(0.0598166585), COEF_CONST(0.0575152673),
    COEF_CONST(0.0550460033), COEF_CONST(0.0524093807),
    COEF_CONST(0.0495978668), COEF_CONST(0.0466303304),
    COEF_CONST(0.0434768796), COEF_CONST(0.0401458293),
    COEF_CONST(0.0366418101), COEF_CONST(0.0329583921),
    COEF_CONST(0.0290824007), COEF_CONST(0.0250307564),
    COEF_CONST(0.0207997076), COEF_CONST(0.0163701251),
    COEF_CONST(0.0117623834), COEF_CONST(0.0069636861),
    COEF_CONST(0.0019765601), COEF_CONST(-0.0032086896),
    COEF_CONST(-0.0085711749), COEF_CONST(-0.0141288824),
    COEF_CONST(-0.0198834129), COEF_CONST(-0.0258227289),
    COEF_CONST(-0.0319531262), COEF_CONST(-0.0382776558),
    COEF_CONST(-0.0447806828), COEF_CONST(-0.0514804162),
    COEF_CONST(-0.0583705343), COEF_CONST(-0.0654409826),
    COEF_CONST(-0.0726943314), COEF_CONST(-0.0801372901),
    COEF_CONST(-0.0877547562), COEF_CONST(-0.0955533385),
    COEF_CONST(-0.1035329551), COEF_CONST(-0.1116826907),
    COEF_CONST(-0.1200077981), COEF_CONST(-0.1285002828),
    COEF_CONST(-0.1371551752), COEF_CONST(-0.1459766477),
    COEF_CONST(-0.1549607068), COEF_CONST(-0.1640958786),
    COEF_CONST(-0.1733808219), COEF_CONST(-0.1828172505),
    COEF_CONST(-0.1923966706), COEF_CONST(-0.2021250129),
    COEF_CONST(-0.2119735926), COEF_CONST(-0.2219652683),
    COEF_CONST(-0.2320690900), COEF_CONST(-0.2423016876),
    COEF_CONST(-0.2526480258), COEF_CONST(-0.2631053329),
    COEF_CONST(-0.2736634016), COEF_CONST(-0.2843214273),
    COEF_CONST(-0.2950716615), COEF_CONST(-0.3059098721),
    COEF_CONST(-0.3168278933), COEF_CONST(-0.3278113604),
    COEF_CONST(-0.3388722837), COEF_CONST(-0.3499914110),
    COEF_CONST(0.3611589968), COEF_CONST(0.3723795414),
    COEF_CONST(0.3836350143), COEF_CONST(0.3949211836),
    COEF_CONST(0.4062317610), COEF_CONST(0.4175696969),
    COEF_CONST(0.4289119840), COEF_CONST(0.4402553737),
    COEF_CONST(0.4515996575), COEF_CONST(0.4629307985),
    COEF_CONST(0.4742453098), COEF_CONST(0.4855253100),
    COEF_CONST(0.4967708290), COEF_CONST(0.5079817772),
    COEF_CONST(0.5191234946), COEF_CONST(0.5302240849),
    COEF_CONST(0.5412553549), COEF_CONST(0.5522051454),
    COEF_CONST(0.5630789399), COEF_CONST(0.5738524199),
    COEF_CONST(0.5845403075), COEF_CONST(0.5951123238),
    COEF_CONST(0.6055783629), COEF_CONST(0.6159110069),
    COEF_CONST(0.6261242628), COEF_CONST(0.6361979842),
    COEF_CONST(0.6461269855), COEF_CONST(0.6559016109),
    COEF_CONST(0.6655139923), COEF_CONST(0.6749663353),
    COEF_CONST(0.6842353344), COEF_CONST(0.6933282614),
    COEF_CONST(0.7022388577), COEF_CONST(0.7109410167),
    COEF_CONST(0.7194462419), COEF_CONST(0.7277448773),
    COEF_CONST(0.7358211875), COEF_CONST(0.7436828017),
    COEF_CONST(0.7513137460), COEF_CONST(0.7587080598),
    COEF_CONST(0.7658674717), COEF_CONST(0.7727780938),
    COEF_CONST(0.7794287801), COEF_CONST(0.7858353257),
    COEF_CONST(0.7919735909), COEF_CONST(0.7978466153),
    COEF_CONST(0.8034485579), COEF_CONST(0.8087695241),
    COEF_CONST(0.8138191104), COEF_CONST(0.8185775876),
    COEF_CONST(0.8230419755), COEF_CONST(0.8272275329),
    COEF_CONST(0.8311038613), COEF_CONST(0.8346937299),
    COEF_CONST(0.8379717469), COEF_CONST(0.8409541249),
    COEF_CONST(0.8436238170), COEF_CONST(0.8459818363),
    COEF_CONST(0.8480315804), COEF_CONST(0.8497804999),
    COEF_CONST(0.8511971235), COEF_CONST(0.8523046970),
    COEF_CONST(0.8531020880), COEF_CONST(0.8535720706),
    COEF_CONST(0.8537385464), COEF_CONST(0.8535720706),
    COEF_CONST(0.8531020880), COEF_CONST(0.8523046970),
    COEF_CONST(0.8511971235), COEF_CONST(0.8497804999),
    COEF_CONST(0.8480315804), COEF_CONST(0.8459818363),
    COEF_CONST(0.8436238170), COEF_CONST(0.8409541249),
    COEF_CONST(0.8379717469), COEF_CONST(0.8346937299),
    COEF_CONST(0.8311038613), COEF_CONST(0.8272275329),
    COEF_CONST(0.8230419755), COEF_CONST(0.8185775876),
    COEF_CONST(0.8138191104), COEF_CONST(0.8087695241),
    COEF_CONST(0.8034485579), COEF_CONST(0.7978466153),
    COEF_CONST(0.7919735909), COEF_CONST(0.7858353257),
    COEF_CONST(0.7794287801), COEF_CONST(0.7727780938),
    COEF_CONST(0.7658674717), COEF_CONST(0.7587080598),
    COEF_CONST(0.7513137460), COEF_CONST(0.7436828017),
    COEF_CONST(0.7358211875), COEF_CONST(0.7277448773),
    COEF_CONST(0.7194462419), COEF_CONST(0.7109410167),
    COEF_CONST(0.7022388577), COEF_CONST(0.6933282614),
    COEF_CONST(0.6842353344), COEF_CONST(0.6749663353),
    COEF_CONST(0.6655139923), COEF_CONST(0.6559016109),
    COEF_CONST(0.6461269855), COEF_CONST(0.6361979842),
    COEF_CONST(0.6261242628), COEF_CONST(0.6159110069),
    COEF_CONST(0.6055783629), COEF_CONST(0.5951123238),
    COEF_CONST(0.5845403075), COEF_CONST(0.5738524199),
    COEF_CONST(0.5630789399), COEF_CONST(0.5522051454),
    COEF_CONST(0.5412553549), COEF_CONST(0.5302240849),
    COEF_CONST(0.5191234946), COEF_CONST(0.5079817772),
    COEF_CONST(0.4967708290), COEF_CONST(0.4855253100),
    COEF_CONST(0.4742453098), COEF_CONST(0.4629307985),
    COEF_CONST(0.4515996575), COEF_CONST(0.4402553737),
    COEF_CONST(0.4289119840), COEF_CONST(0.4175696969),
    COEF_CONST(0.4062317610), COEF_CONST(0.3949211836),
    COEF_CONST(0.3836350143), COEF_CONST(0.3723795414),
    COEF_CONST(-0.3611589968), COEF_CONST(-0.3499914110),
    COEF_CONST(-0.3388722837), COEF_CONST(-0.3278113604),
    COEF_CONST(-0.3168278933), COEF_CONST(-0.3059098721),
    COEF_CONST(-0.2950716615), COEF_CONST(-0.2843214273),
    COEF_CONST(-0.2736634016), COEF_CONST(-0.2631053329),
    COEF_CONST(-0.2526480258), COEF_CONST(-0.2423016876),
    COEF_CONST(-0.2320690900), COEF_CONST(-0.2219652683),
    COEF_CONST(-0.2119735926), COEF_CONST(-0.2021250129),
    COEF_CONST(-0.1923966706), COEF_CONST(-0.1828172505),
    COEF_CONST(-0.1733808219), COEF_CONST(-0.1640958786),
    COEF_CONST(-0.1549607068), COEF_CONST(-0.1459766477),
    COEF_CONST(-0.1371551752), COEF_CONST(-0.1285002828),
    COEF_CONST(-0.1200077981), COEF_CONST(-0.1116826907),
    COEF_CONST(-0.1035329551), COEF_CONST(-0.0955533385),
    COEF_CONST(-0.0877547562), COEF_CONST(-0.0801372901),
    COEF_CONST(-0.0726943314), COEF_CONST(-0.0654409826),
    COEF_CONST(-0.0583705343), COEF_CONST(-0.0514804162),
    COEF_CONST(-0.0447806828), COEF_CONST(-0.0382776558),
    COEF_CONST(-0.0319531262), COEF_CONST(-0.0258227289),
    COEF_CONST(-0.0198834129), COEF_CONST(-0.0141288824),
    COEF_CONST(-0.0085711749), COEF_CONST(-0.0032086896),
    COEF_CONST(0.0019765601), COEF_CONST(0.0069636861),
    COEF_CONST(0.0117623834), COEF_CONST(0.0163701251),
    COEF_CONST(0.0207997076), COEF_CONST(0.0250307564),
    COEF_CONST(0.0290824007), COEF_CONST(0.0329583921),
    COEF_CONST(0.0366418101), COEF_CONST(0.0401458293),
    COEF_CONST(0.0434768796), COEF_CONST(0.0466303304),
    COEF_CONST(0.0495978668), COEF_CONST(0.0524093807),
    COEF_CONST(0.0550460033), COEF_CONST(0.0575152673),
    COEF_CONST(0.0598166585), COEF_CONST(0.0619602762),
    COEF_CONST(0.0639444813), COEF_CONST(0.0657690689),
    COEF_CONST(0.0674525052), COEF_CONST(0.0689664036),
    COEF_CONST(0.0703533068), COEF_CONST(0.0715826377),
    COEF_CONST(0.0726774633), COEF_CONST(0.0736405998),
    COEF_CONST(0.0744664371), COEF_CONST(0.0751576275),
    COEF_CONST(0.0757305771), COEF_CONST(0.0761748329),
    COEF_CONST(0.0765050724), COEF_CONST(0.0767204911),
    COEF_CONST(0.0768230036), COEF_CONST(0.0768174008),
    COEF_CONST(0.0767093524), COEF_CONST(0.0764992163),
    COEF_CONST(0.0761992484), COEF_CONST(0.0758008361),
    COEF_CONST(0.0753137320), COEF_CONST(0.0747452527),
    COEF_CONST(0.0741003677), COEF_CONST(0.0733620226),
    COEF_CONST(0.0725682601), COEF_CONST(0.0717002675),
    COEF_CONST(0.0707628727), COEF_CONST(0.0697630271),
    COEF_CONST(0.0687043816), COEF_CONST(0.0676075965),
    COEF_CONST(0.0664367527), COEF_CONST(0.0652247071),
    COEF_CONST(0.0639715865), COEF_CONST(0.0626857802),
    COEF_CONST(0.0613455176), COEF_CONST(0.0599837489),
    COEF_CONST(0.0585915670), COEF_CONST(0.0571616441),
    COEF_CONST(0.0557173640), COEF_CONST(0.0542452782),
    COEF_CONST(0.0527630746), COEF_CONST(0.0512556173),
    COEF_CONST(0.0497385748), COEF_CONST(0.0482165702),
    COEF_CONST(0.0466843024), COEF_CONST(0.0451488420),
    COEF_CONST(0.0436097533), COEF_CONST(0.0420649089),
    COEF_CONST(0.0405349173), COEF_CONST(0.0390053689),
    COEF_CONST(0.0374812856), COEF_CONST(0.0359697565),
    COEF_CONST(0.0344620943), COEF_CONST(0.0329754092),
    COEF_CONST(0.0315017626), COEF_CONST(0.0300502665),
    COEF_CONST(0.0286072176), COEF_CONST(0.0271859430),
    COEF_CONST(0.0257875845), COEF_CONST(0.0244160984),
    COEF_CONST(0.0230680164), COEF_CONST(0.0217467546),
    COEF_CONST(0.0204531793), COEF_CONST(0.0191872437),
    COEF_CONST(0.0179433376), COEF_CONST(0.0167324711),
    COEF_CONST(0.0155405551), COEF_CONST(0.0143904667),
    COEF_CONST(-0.0132718217), COEF_CONST(-0.0121849999),
    COEF_CONST(-0.0111315548), COEF_CONST(-0.0101150218),
    COEF_CONST(-0.0091325333), COEF_CONST(-0.0081798229),
    COEF_CONST(-0.0072615817), COEF_CONST(-0.0063792295),
    COEF_CONST(-0.0055337213), COEF_CONST(-0.0047222595),
    COEF_CONST(-0.0039401124), COEF_CONST(-0.0031933777),
    COEF_CONST(-0.0024826722), COEF_CONST(-0.0018039471),
    COEF_CONST(-0.0011568135), COEF_CONST(-0.0005464280),
    COEF_CONST(0.0000276045), COEF_CONST(0.0005832264),
    COEF_CONST(0.0010902329), COEF_CONST(0.0015784682),
    COEF_CONST(0.0020274175), COEF_CONST(0.0024508541),
    COEF_CONST(0.0028446757), COEF_CONST(0.0032091886),
    COEF_CONST(0.0035401245), COEF_CONST(0.0038456407),
    COEF_CONST(0.0041251644), COEF_CONST(0.0043801861),
    COEF_CONST(0.0046039531), COEF_CONST(0.0048109470),
    COEF_CONST(0.0049839686), COEF_CONST(0.0051382277),
    COEF_CONST(0.0052715759), COEF_CONST(0.0053838976),
    COEF_CONST(0.0054753781), COEF_CONST(0.0055404361),
    COEF_CONST(0.0055917129), COEF_CONST(0.0056266114),
    COEF_CONST(0.0056389198), COEF_CONST(0.0056455196),
    COEF_CONST(0.0056220642), COEF_CONST(0.0055938023),
    COEF_CONST(0.0055475715), COEF_CONST(0.0054876041),
    COEF_CONST(0.0054196776), COEF_CONST(0.0053471681),
    COEF_CONST(0.0052461168), COEF_CONST(0.0051407353),
    COEF_CONST(0.0050393022), COEF_CONST(0.0049137603),
    COEF_CONST(0.0047932561), COEF_CONST(0.0046606460),
    COEF_CONST(0.0045209853), COEF_CONST(0.0043730717),
    COEF_CONST(0.0042264271), COEF_CONST(0.0040819752),
    COEF_CONST(0.0039207432), COEF_CONST(0.0037603923),
    COEF_CONST(0.0036008267), COEF_CONST(0.0034418874),
    COEF_CONST(0.0032739614), COEF_CONST(0.0031125420),
    COEF_CONST(0.0029469447), COEF_CONST(0.0027870464),
    COEF_CONST(0.0026201757), COEF_CONST(0.0024625617),
    COEF_CONST(0.0023017253), COEF_CONST(0.0021461584),
    COEF_CONST(0.0019841141), COEF_CONST(0.0018348265),
    COEF_CONST(0.0016868083), COEF_CONST(0.0015443219),
    COEF_CONST(0.0013902494), COEF_CONST(0.0012577884),
    COEF_CONST(0.0011250156), COEF_CONST(0.0009885988),
    COEF_CONST(0.0008608443), COEF_CONST(0.0007458025),
    COEF_CONST(0.0006239376), COEF_CONST(0.0005107388),
    COEF_CONST(0.0004026540), COEF_CONST(0.0002949531),
    COEF_CONST(0.0002043017), COEF_CONST(0.0001094383),
    COEF_CONST(0.0000134949), COEF_CONST(-0.0000617334),
    COEF_CONST(-0.0001446380), COEF_CONST(-0.0002098337),
    COEF_CONST(-0.0002896981), COEF_CONST(-0.0003501175),
    COEF_CONST(-0.0004095121), COEF_CONST(-0.0004606325),
    COEF_CONST(-0.0005145572), COEF_CONST(-0.0005564576),
    COEF_CONST(-0.0005946118), COEF_CONST(-0.0006341594),
    COEF_CONST(-0.0006650415), COEF_CONST(-0.0006917937),
    COEF_CONST(-0.0007215391), COEF_CONST(-0.0007319357),
    COEF_CONST(-0.0007530001), COEF_CONST(-0.0007630793),
    COEF_CONST(-0.0007757977), COEF_CONST(-0.0007801449),
    COEF_CONST(-0.0007803664), COEF_CONST(-0.0007779869),
    COEF_CONST(-0.0007834332), COEF_CONST(-0.0007724848),
    COEF_CONST(-0.0007681371), COEF_CONST(-0.0007490598),
    COEF_CONST(-0.0007440941), COEF_CONST(-0.0007255043),
    COEF_CONST(-0.0007157736), COEF_CONST(-0.0006941614),
    COEF_CONST(-0.0006777690), COEF_CONST(-0.0006540333),
    COEF_CONST(-0.0006312493), COEF_CONST(-0.0006132747),
    COEF_CONST(-0.0005870930), COEF_CONST(-0.0005677802),
    COEF_CONST(-0.0005466565), COEF_CONST(-0.0005226564),
    COEF_CONST(-0.0005040714), COEF_CONST(-0.0004893791),
    COEF_CONST(-0.0004875227), COEF_CONST(-0.0004947518),
    COEF_CONST(-0.0005617692), COEF_CONST(-0.0005525280)
};

static real_t qmf_c_2[] = {
    COEF_CONST(0.0000000000), COEF_CONST(-0.0005617692),
    COEF_CONST(-0.0004875227), COEF_CONST(-0.0005040714),
    COEF_CONST(-0.0005466565), COEF_CONST(-0.0005870930),
    COEF_CONST(-0.0006312493), COEF_CONST(-0.0006777690),
    COEF_CONST(-0.0007157736), COEF_CONST(-0.0007440941),
    COEF_CONST(-0.0007681371), COEF_CONST(-0.0007834332),
    COEF_CONST(-0.0007803664), COEF_CONST(-0.0007757977),
    COEF_CONST(-0.0007530001), COEF_CONST(-0.0007215391),
    COEF_CONST(-0.0006650415), COEF_CONST(-0.0005946118),
    COEF_CONST(-0.0005145572), COEF_CONST(-0.0004095121),
    COEF_CONST(-0.0002896981), COEF_CONST(-0.0001446380),
    COEF_CONST(0.0000134949), COEF_CONST(0.0002043017),
    COEF_CONST(0.0004026540), COEF_CONST(0.0006239376),
    COEF_CONST(0.0008608443), COEF_CONST(0.0011250156),
    COEF_CONST(0.0013902494), COEF_CONST(0.0016868083),
    COEF_CONST(0.0019841141), COEF_CONST(0.0023017253),
    COEF_CONST(0.0026201757), COEF_CONST(0.0029469447),
    COEF_CONST(0.0032739614), COEF_CONST(0.0036008267),
    COEF_CONST(0.0039207432), COEF_CONST(0.0042264271),
    COEF_CONST(0.0045209853), COEF_CONST(0.0047932561),
    COEF_CONST(0.0050393022), COEF_CONST(0.0052461168),
    COEF_CONST(0.0054196776), COEF_CONST(0.0055475715),
    COEF_CONST(0.0056220642), COEF_CONST(0.0056389198),
    COEF_CONST(0.0055917129), COEF_CONST(0.0054753781),
    COEF_CONST(0.0052715759), COEF_CONST(0.0049839686),
    COEF_CONST(0.0046039531), COEF_CONST(0.0041251644),
    COEF_CONST(0.0035401245), COEF_CONST(0.0028446757),
    COEF_CONST(0.0020274175), COEF_CONST(0.0010902329),
    COEF_CONST(0.0000276045), COEF_CONST(-0.0011568135),
    COEF_CONST(-0.0024826722), COEF_CONST(-0.0039401124),
    COEF_CONST(-0.0055337213), COEF_CONST(-0.0072615817),
    COEF_CONST(-0.0091325333), COEF_CONST(-0.0111315548),
    COEF_CONST(0.0132718217), COEF_CONST(0.0155405551),
    COEF_CONST(0.0179433376), COEF_CONST(0.0204531793),
    COEF_CONST(0.0230680164), COEF_CONST(0.0257875845),
    COEF_CONST(0.0286072176), COEF_CONST(0.0315017626),
    COEF_CONST(0.0344620943), COEF_CONST(0.0374812856),
    COEF_CONST(0.0405349173), COEF_CONST(0.0436097533),
    COEF_CONST(0.0466843024), COEF_CONST(0.0497385748),
    COEF_CONST(0.0527630746), COEF_CONST(0.0557173640),
    COEF_CONST(0.0585915670), COEF_CONST(0.0613455176),
    COEF_CONST(0.0639715865), COEF_CONST(0.0664367527),
    COEF_CONST(0.0687043816), COEF_CONST(0.0707628727),
    COEF_CONST(0.0725682601), COEF_CONST(0.0741003677),
    COEF_CONST(0.0753137320), COEF_CONST(0.0761992484),
    COEF_CONST(0.0767093524), COEF_CONST(0.0768230036),
    COEF_CONST(0.0765050724), COEF_CONST(0.0757305771),
    COEF_CONST(0.0744664371), COEF_CONST(0.0726774633),
    COEF_CONST(0.0703533068), COEF_CONST(0.0674525052),
    COEF_CONST(0.0639444813), COEF_CONST(0.0598166585),
    COEF_CONST(0.0550460033), COEF_CONST(0.0495978668),
    COEF_CONST(0.0434768796), COEF_CONST(0.0366418101),
    COEF_CONST(0.0290824007), COEF_CONST(0.0207997076),
    COEF_CONST(0.0117623834), COEF_CONST(0.0019765601),
    COEF_CONST(-0.0085711749), COEF_CONST(-0.0198834129),
    COEF_CONST(-0.0319531262), COEF_CONST(-0.0447806828),
    COEF_CONST(-0.0583705343), COEF_CONST(-0.0726943314),
    COEF_CONST(-0.0877547562), COEF_CONST(-0.1035329551),
    COEF_CONST(-0.1200077981), COEF_CONST(-0.1371551752),
    COEF_CONST(-0.1549607068), COEF_CONST(-0.1733808219),
    COEF_CONST(-0.1923966706), COEF_CONST(-0.2119735926),
    COEF_CONST(-0.2320690900), COEF_CONST(-0.2526480258),
    COEF_CONST(-0.2736634016), COEF_CONST(-0.2950716615),
    COEF_CONST(-0.3168278933), COEF_CONST(-0.3388722837),
    COEF_CONST(0.3611589968), COEF_CONST(0.3836350143),
    COEF_CONST(0.4062317610), COEF_CONST(0.4289119840),
    COEF_CONST(0.4515996575), COEF_CONST(0.4742453098),
    COEF_CONST(0.4967708290), COEF_CONST(0.5191234946),
    COEF_CONST(0.5412553549), COEF_CONST(0.5630789399),
    COEF_CONST(0.5845403075), COEF_CONST(0.6055783629),
    COEF_CONST(0.6261242628), COEF_CONST(0.6461269855),
    COEF_CONST(0.6655139923), COEF_CONST(0.6842353344),
    COEF_CONST(0.7022388577), COEF_CONST(0.7194462419),
    COEF_CONST(0.7358211875), COEF_CONST(0.7513137460),
    COEF_CONST(0.7658674717), COEF_CONST(0.7794287801),
    COEF_CONST(0.7919735909), COEF_CONST(0.8034485579),
    COEF_CONST(0.8138191104), COEF_CONST(0.8230419755),
    COEF_CONST(0.8311038613), COEF_CONST(0.8379717469),
    COEF_CONST(0.8436238170), COEF_CONST(0.8480315804),
    COEF_CONST(0.8511971235), COEF_CONST(0.8531020880),
    COEF_CONST(0.8537385464), COEF_CONST(0.8531020880),
    COEF_CONST(0.8511971235), COEF_CONST(0.8480315804),
    COEF_CONST(0.8436238170), COEF_CONST(0.8379717469),
    COEF_CONST(0.8311038613), COEF_CONST(0.8230419755),
    COEF_CONST(0.8138191104), COEF_CONST(0.8034485579),
    COEF_CONST(0.7919735909), COEF_CONST(0.7794287801),
    COEF_CONST(0.7658674717), COEF_CONST(0.7513137460),
    COEF_CONST(0.7358211875), COEF_CONST(0.7194462419),
    COEF_CONST(0.7022388577), COEF_CONST(0.6842353344),
    COEF_CONST(0.6655139923), COEF_CONST(0.6461269855),
    COEF_CONST(0.6261242628), COEF_CONST(0.6055783629),
    COEF_CONST(0.5845403075), COEF_CONST(0.5630789399),
    COEF_CONST(0.5412553549), COEF_CONST(0.5191234946),
    COEF_CONST(0.4967708290), COEF_CONST(0.4742453098),
    COEF_CONST(0.4515996575), COEF_CONST(0.4289119840),
    COEF_CONST(0.4062317610), COEF_CONST(0.3836350143),
    COEF_CONST(-0.3611589968), COEF_CONST(-0.3388722837),
    COEF_CONST(-0.3168278933), COEF_CONST(-0.2950716615),
    COEF_CONST(-0.2736634016), COEF_CONST(-0.2526480258),
    COEF_CONST(-0.2320690900), COEF_CONST(-0.2119735926),
    COEF_CONST(-0.1923966706), COEF_CONST(-0.1733808219),
    COEF_CONST(-0.1549607068), COEF_CONST(-0.1371551752),
    COEF_CONST(-0.1200077981), COEF_CONST(-0.1035329551),
    COEF_CONST(-0.0877547562), COEF_CONST(-0.0726943314),
    COEF_CONST(-0.0583705343), COEF_CONST(-0.0447806828),
    COEF_CONST(-0.0319531262), COEF_CONST(-0.0198834129),
    COEF_CONST(-0.0085711749), COEF_CONST(0.0019765601),
    COEF_CONST(0.0117623834), COEF_CONST(0.0207997076),
    COEF_CONST(0.0290824007), COEF_CONST(0.0366418101),
    COEF_CONST(0.0434768796), COEF_CONST(0.0495978668),
    COEF_CONST(0.0550460033), COEF_CONST(0.0598166585),
    COEF_CONST(0.0639444813), COEF_CONST(0.0674525052),
    COEF_CONST(0.0703533068), COEF_CONST(0.0726774633),
    COEF_CONST(0.0744664371), COEF_CONST(0.0757305771),
    COEF_CONST(0.0765050724), COEF_CONST(0.0768230036),
    COEF_CONST(0.0767093524), COEF_CONST(0.0761992484),
    COEF_CONST(0.0753137320), COEF_CONST(0.0741003677),
    COEF_CONST(0.0725682601), COEF_CONST(0.0707628727),
    COEF_CONST(0.0687043816), COEF_CONST(0.0664367527),
    COEF_CONST(0.0639715865), COEF_CONST(0.0613455176),
    COEF_CONST(0.0585915670), COEF_CONST(0.0557173640),
    COEF_CONST(0.0527630746), COEF_CONST(0.0497385748),
    COEF_CONST(0.0466843024), COEF_CONST(0.0436097533),
    COEF_CONST(0.0405349173), COEF_CONST(0.0374812856),
    COEF_CONST(0.0344620943), COEF_CONST(0.0315017626),
    COEF_CONST(0.0286072176), COEF_CONST(0.0257875845),
    COEF_CONST(0.0230680164), COEF_CONST(0.0204531793),
    COEF_CONST(0.0179433376), COEF_CONST(0.0155405551),
    COEF_CONST(-0.0132718217), COEF_CONST(-0.0111315548),
    COEF_CONST(-0.0091325333), COEF_CONST(-0.0072615817),
    COEF_CONST(-0.0055337213), COEF_CONST(-0.0039401124),
    COEF_CONST(-0.0024826722), COEF_CONST(-0.0011568135),
    COEF_CONST(0.0000276045), COEF_CONST(0.0010902329),
    COEF_CONST(0.0020274175), COEF_CONST(0.0028446757),
    COEF_CONST(0.0035401245), COEF_CONST(0.0041251644),
    COEF_CONST(0.0046039531), COEF_CONST(0.0049839686),
    COEF_CONST(0.0052715759), COEF_CONST(0.0054753781),
    COEF_CONST(0.0055917129), COEF_CONST(0.0056389198),
    COEF_CONST(0.0056220642), COEF_CONST(0.0055475715),
    COEF_CONST(0.0054196776), COEF_CONST(0.0052461168),
    COEF_CONST(0.0050393022), COEF_CONST(0.0047932561),
    COEF_CONST(0.0045209853), COEF_CONST(0.0042264271),
    COEF_CONST(0.0039207432), COEF_CONST(0.0036008267),
    COEF_CONST(0.0032739614), COEF_CONST(0.0029469447),
    COEF_CONST(0.0026201757), COEF_CONST(0.0023017253),
    COEF_CONST(0.0019841141), COEF_CONST(0.0016868083),
    COEF_CONST(0.0013902494), COEF_CONST(0.0011250156),
    COEF_CONST(0.0008608443), COEF_CONST(0.0006239376),
    COEF_CONST(0.0004026540), COEF_CONST(0.0002043017),
    COEF_CONST(0.0000134949), COEF_CONST(-0.0001446380),
    COEF_CONST(-0.0002896981), COEF_CONST(-0.0004095121),
    COEF_CONST(-0.0005145572), COEF_CONST(-0.0005946118),
    COEF_CONST(-0.0006650415), COEF_CONST(-0.0007215391),
    COEF_CONST(-0.0007530001), COEF_CONST(-0.0007757977),
    COEF_CONST(-0.0007803664), COEF_CONST(-0.0007834332),
    COEF_CONST(-0.0007681371), COEF_CONST(-0.0007440941),
    COEF_CONST(-0.0007157736), COEF_CONST(-0.0006777690),
    COEF_CONST(-0.0006312493), COEF_CONST(-0.0005870930),
    COEF_CONST(-0.0005466565), COEF_CONST(-0.0005040714),
    COEF_CONST(-0.0004875227), COEF_CONST(-0.0005617692)
};

#ifdef __cplusplus
}
#endif
#endif


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_syntax.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#ifdef SBR_DEC

#include "sbr_syntax.h"
#include "syntax.h"
#include "sbr_huff.h"
#include "sbr_fbt.h"
#include "sbr_tf_grid.h"
#include "sbr_e_nf.h"
#include "bits.h"
#include "analysis.h"

static void sbr_reset(sbr_info *sbr)
{
    /* if these are different from the previous frame: Reset = 1 */
    if ((sbr->bs_start_freq != sbr->bs_start_freq_prev) ||
        (sbr->bs_stop_freq != sbr->bs_stop_freq_prev) ||
        (sbr->bs_freq_scale != sbr->bs_freq_scale_prev) ||
        (sbr->bs_alter_scale != sbr->bs_alter_scale_prev))
    {
        sbr->Reset = 1;
    } else {
        sbr->Reset = 0;
    }

    if ((sbr->bs_start_freq != sbr->bs_start_freq_prev) ||
        (sbr->bs_stop_freq != sbr->bs_stop_freq_prev) ||
        (sbr->bs_freq_scale != sbr->bs_freq_scale_prev) ||
        (sbr->bs_alter_scale != sbr->bs_alter_scale_prev) ||
        (sbr->bs_xover_band != sbr->bs_xover_band_prev) ||
        (sbr->bs_noise_bands != sbr->bs_noise_bands_prev))
    {
        sbr->Reset = 1;
    } else {
        sbr->Reset = 0;
    }

    sbr->bs_start_freq_prev = sbr->bs_start_freq;
    sbr->bs_stop_freq_prev = sbr->bs_stop_freq;
    sbr->bs_freq_scale_prev = sbr->bs_freq_scale;
    sbr->bs_alter_scale_prev = sbr->bs_alter_scale;
    sbr->bs_xover_band_prev = sbr->bs_xover_band;
    sbr->bs_noise_bands_prev = sbr->bs_noise_bands;

    if (sbr->frame == 0)
    {
        sbr->Reset = 1;
    }
}

/* table 2 */
uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint8_t id_aac)
{
    uint8_t bs_extension_type = (uint8_t)faad_getbits(ld, 4
        DEBUGVAR(1,198,"sbr_bitstream(): bs_extension_type"));

    if (bs_extension_type == EXT_SBR_DATA_CRC)
    {
        sbr->bs_sbr_crc_bits = (uint16_t)faad_getbits(ld, 10
            DEBUGVAR(1,199,"sbr_bitstream(): bs_sbr_crc_bits"));
    }

    sbr->bs_header_flag = faad_get1bit(ld
        DEBUGVAR(1,200,"sbr_bitstream(): bs_header_flag"));
    if (sbr->bs_header_flag)
        sbr_header(ld, sbr, id_aac);

    /* TODO: Reset? */
    sbr_reset(sbr);

    /* first frame should have a header */
    if (sbr->frame == 0 && sbr->bs_header_flag == 0)
        return 1;


    if (sbr->Reset || (sbr->bs_header_flag && sbr->just_seeked))
    {
        uint16_t k2;

        /* calculate the Master Frequency Table */
        sbr->k0 = qmf_start_channel(sbr->bs_start_freq, sbr->bs_samplerate_mode,
            sbr->sample_rate);
        k2 = qmf_stop_channel(sbr->bs_stop_freq, sbr->sample_rate, sbr->k0);

        /* check k0 and k2 */
        if (sbr->sample_rate >= 48000)
        {
            if ((k2 - sbr->k0) > 32)
                return 1;
        } else if (sbr->sample_rate <= 32000) {
            if ((k2 - sbr->k0) > 48)
                return 1;
        } else { /* (sbr->sample_rate == 44100) */
            if ((k2 - sbr->k0) > 45)
                return 1;
        }

        if (sbr->bs_freq_scale == 0)
        {
            master_frequency_table_fs0(sbr, sbr->k0, k2, sbr->bs_alter_scale);
        } else {
            master_frequency_table(sbr, sbr->k0, k2, sbr->bs_freq_scale,
                sbr->bs_alter_scale);
        }
        derived_frequency_table(sbr, sbr->bs_xover_band, k2);
    }

    sbr_data(ld, sbr, id_aac);

    /* no error */
    return 0;
}

/* 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->header_count++;

    sbr->bs_amp_res = faad_get1bit(ld
        DEBUGVAR(1,203,"sbr_header(): bs_amp_res"));

    /* bs_start_freq and bs_stop_freq must define a fequency band that does
       not exceed 48 channels */
    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, 2
        DEBUGVAR(1,207,"sbr_header(): bs_reserved_bits_hdr"));
    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 (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"));
    }

#if 0
    /* print the header to screen */
    printf("bs_amp_res: %d\n", sbr->bs_amp_res);
    printf("bs_start_freq: %d\n", sbr->bs_start_freq);
    printf("bs_stop_freq: %d\n", sbr->bs_stop_freq);
    printf("bs_xover_band: %d\n", sbr->bs_xover_band);
    if (bs_header_extra_1)
    {
        printf("bs_freq_scale: %d\n", sbr->bs_freq_scale);
        printf("bs_alter_scale: %d\n", sbr->bs_alter_scale);
        printf("bs_noise_bands: %d\n", sbr->bs_noise_bands);
    }
    if (bs_header_extra_2)
    {
        printf("bs_limiter_bands: %d\n", sbr->bs_limiter_bands);
        printf("bs_limiter_gains: %d\n", sbr->bs_limiter_gains);
        printf("bs_interpol_freq: %d\n", sbr->bs_interpol_freq);
        printf("bs_smoothing_mode: %d\n", sbr->bs_smoothing_mode);
    }
    printf("\n");
#endif
}

/* table 4 */
static void sbr_data(bitfile *ld, sbr_info *sbr, uint8_t id_aac)
{
#if 0
    sbr->bs_samplerate_mode = faad_get1bit(ld
        DEBUGVAR(1,219,"sbr_data(): bs_samplerate_mode"));
#endif

    sbr->rate = (sbr->bs_samplerate_mode) ? 2 : 1;

    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)
{
    if (faad_get1bit(ld
        DEBUGVAR(1,220,"sbr_single_channel_element(): bs_data_extra")))
    {
        faad_getbits(ld, 4
            DEBUGVAR(1,221,"sbr_single_channel_element(): bs_reserved_bits_data"));
    }

    sbr_grid(ld, sbr, 0);
    sbr_dtdf(ld, sbr, 0);
    invf_mode(ld, sbr, 0);
    sbr_envelope(ld, sbr, 0);
    sbr_noise(ld, sbr, 0);

    envelope_noise_dequantisation(sbr, 0);

#if 0
// TEMP
    if (sbr->frame == 21)
    {
        int l, k;

        printf("\n");
        for (l = 0; l < sbr->L_E[0]; l++)
        {
            for (k = 0; k < sbr->n[sbr->f[0][l]]; k++)
            {
                //printf("%f\n", sbr->E_orig[0][k][l]);
                printf("%f\n", sbr->E_orig[0][k][l] * 1024.  / (float)(1 << REAL_BITS));
            }
        }
    }
// end TEMP
#endif

#if 0
// TEMP
    {
        int l, k;

        printf("\n");
        for (l = 0; l < sbr->L_Q[0]; l++)
        {
            for (k = 0; k < sbr->N_Q; k++)
            {
                printf("%f\n", sbr->Q_orig[0][k][l]);
            }
        }
    }
// end TEMP
#endif

    memset(sbr->bs_add_harmonic[0], 0, 64*sizeof(uint8_t));

    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 = faad_get1bit(ld
        DEBUGVAR(1,224,"sbr_single_channel_element(): bs_extended_data[0]"));
    if (sbr->bs_extended_data)
    {
        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); */
            sbr->bs_extension_data = 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)
{
    uint8_t n;

    if (faad_get1bit(ld
        DEBUGVAR(1,228,"sbr_single_channel_element(): bs_data_extra")))
    {
        faad_getbits(ld, 4
            DEBUGVAR(1,228,"sbr_channel_pair_element(): bs_reserved_bits_data"));
        faad_getbits(ld, 4
            DEBUGVAR(1,228,"sbr_channel_pair_element(): bs_reserved_bits_data"));
    }

    sbr->bs_coupling = faad_get1bit(ld
        DEBUGVAR(1,228,"sbr_channel_pair_element(): bs_coupling"));

    if (sbr->bs_coupling)
    {
        sbr_grid(ld, sbr, 0);

        /* need to copy some data from left to right */
        sbr->bs_frame_class[1] = sbr->bs_frame_class[0];
        sbr->L_E[1] = sbr->L_E[0];
        sbr->L_Q[1] = sbr->L_Q[0];
        sbr->bs_pointer[1] = sbr->bs_pointer[0];

        for (n = 0; n <= sbr->L_E[0]; n++)
        {
            sbr->t_E[1][n] = sbr->t_E[0][n];
            sbr->f[1][n] = sbr->f[0][n];
        }
        for (n = 0; n <= sbr->L_Q[0]; n++)
            sbr->t_Q[1][n] = sbr->t_Q[0][n];

        sbr_dtdf(ld, sbr, 0);
        sbr_dtdf(ld, sbr, 1);
        invf_mode(ld, sbr, 0);

        /* more copying */
        for (n = 0; n < sbr->N_Q; n++)
            sbr->bs_invf_mode[1][n] = sbr->bs_invf_mode[0][n];

        sbr_envelope(ld, sbr, 0);
        sbr_noise(ld, sbr, 0);
        sbr_envelope(ld, sbr, 1);
        sbr_noise(ld, sbr, 1);

        memset(sbr->bs_add_harmonic[0], 0, 64*sizeof(uint8_t));
        memset(sbr->bs_add_harmonic[1], 0, 64*sizeof(uint8_t));

        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);
    } 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);
        sbr_envelope(ld, sbr, 0);
        sbr_envelope(ld, sbr, 1);
        sbr_noise(ld, sbr, 0);
        sbr_noise(ld, sbr, 1);

        memset(sbr->bs_add_harmonic[0], 0, 64*sizeof(uint8_t));
        memset(sbr->bs_add_harmonic[1], 0, 64*sizeof(uint8_t));

        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);
    }
    envelope_noise_dequantisation(sbr, 0);
    envelope_noise_dequantisation(sbr, 1);

#if 0
// TEMP
    if (sbr->frame == 21)
    {
        int l, k;

        printf("\n");
        for (l = 0; l < sbr->L_E[0]; l++)
        {
            for (k = 0; k < sbr->n[sbr->f[0][l]]; k++)
            {
                printf("%f\n", sbr->E_orig[0][k][l]);
                //printf("%f\n", sbr->E_orig[0][k][l] * 1024.  / (float)(1 << REAL_BITS));
            }
        }
    }
// end TEMP
#endif

    if (sbr->bs_coupling)
        unmap_envelope_noise(sbr);

#if 0
// TEMP
    if (sbr->bs_coupling)
    {
        int l, k;

        printf("\n");
        for (l = 0; l < sbr->L_Q[0]; l++)
        {
            for (k = 0; k < sbr->N_Q; k++)
            {
                printf("%f\n", sbr->Q_orig[0][k][l]);
            }
        }
    }
// end TEMP
#endif

    sbr->bs_extended_data = faad_get1bit(ld
        DEBUGVAR(1,233,"sbr_channel_pair_element(): bs_extended_data[0]"));
    if (sbr->bs_extended_data)
    {
        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); */
            sbr->bs_extension_data = faad_getbits(ld, 6
                DEBUGVAR(1,280,"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;
    uint16_t bs_num_env;

    sbr->bs_frame_class[ch] = faad_getbits(ld, 2
        DEBUGVAR(1,248,"sbr_grid(): bs_frame_class"));

#if 0
    if (sbr->bs_frame_class[ch] != FIXFIX)
        printf("%d", sbr->bs_frame_class[ch]);
#endif

    switch (sbr->bs_frame_class[ch])
    {
    case FIXFIX:
        i = faad_getbits(ld, 2
            DEBUGVAR(1,249,"sbr_grid(): bs_num_env_raw"));

        bs_num_env = min(1 << i, 5);

        i = faad_get1bit(ld
            DEBUGVAR(1,250,"sbr_grid(): bs_freq_res_flag"));
        for (env = 0; env < bs_num_env; env++)
            sbr->f[ch][env] = i;

        sbr->abs_bord_lead[ch] = 0;
        sbr->abs_bord_trail[ch] = NO_TIME_SLOTS;
        sbr->n_rel_lead[ch] = bs_num_env - 1;
        sbr->n_rel_trail[ch] = 0;
        break;

    case FIXVAR:
        bs_abs_bord = faad_getbits(ld, 2
            DEBUGVAR(1,251,"sbr_grid(): bs_abs_bord")) + NO_TIME_SLOTS;
        bs_num_env = faad_getbits(ld, 2
            DEBUGVAR(1,252,"sbr_grid(): bs_num_env")) + 1;

        for (rel = 0; rel < bs_num_env-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((int32_t)(bs_num_env + 1));
        sbr->bs_pointer[ch] = faad_getbits(ld, i
            DEBUGVAR(1,254,"sbr_grid(): bs_pointer"));

        for (env = 0; env < bs_num_env; env++)
        {
            sbr->f[ch][bs_num_env - 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;
        sbr->n_rel_lead[ch] = 0;
        sbr->n_rel_trail[ch] = bs_num_env - 1;
        break;

    case VARFIX:
        bs_abs_bord = faad_getbits(ld, 2
            DEBUGVAR(1,256,"sbr_grid(): bs_abs_bord"));
        bs_num_env = faad_getbits(ld, 2
            DEBUGVAR(1,257,"sbr_grid(): bs_num_env")) + 1;

        for (rel = 0; rel < bs_num_env-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((int32_t)(bs_num_env + 1));
        sbr->bs_pointer[ch] = faad_getbits(ld, i
            DEBUGVAR(1,259,"sbr_grid(): bs_pointer"));

        for (env = 0; env < bs_num_env; env++)
        {
            sbr->f[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;
        sbr->n_rel_lead[ch] = bs_num_env - 1;
        sbr->n_rel_trail[ch] = 0;
        break;

    case VARVAR:
        bs_abs_bord = faad_getbits(ld, 2
            DEBUGVAR(1,261,"sbr_grid(): bs_abs_bord_0"));
        bs_abs_bord_1 = faad_getbits(ld, 2
            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"));

        bs_num_env = min(5, 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((int32_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 < bs_num_env; env++)
        {
            sbr->f[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;
        sbr->n_rel_lead[ch] = sbr->bs_num_rel_0[ch];
        sbr->n_rel_trail[ch] = sbr->bs_num_rel_1[ch];
        break;
    }

    if (sbr->bs_frame_class[ch] == VARVAR)
        sbr->L_E[ch] = min(bs_num_env, 5);
    else
        sbr->L_E[ch] = min(bs_num_env, 4);

    if (sbr->L_E[ch] > 1)
        sbr->L_Q[ch] = 2;
    else
        sbr->L_Q[ch] = 1;

    /* TODO: this code can probably be integrated into the code above! */
    envelope_time_border_vector(sbr, ch);
    noise_floor_time_border_vector(sbr, ch);
}

/* table 8 */
static void sbr_dtdf(bitfile *ld, sbr_info *sbr, uint8_t ch)
{
    uint8_t i;

    for (i = 0; i < sbr->L_E[ch]; i++)
    {
        sbr->bs_df_env[ch][i] = faad_get1bit(ld
            DEBUGVAR(1,269,"sbr_dtdf(): bs_df_env"));
    }

    for (i = 0; i < sbr->L_Q[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->N_Q; n++)
    {
        sbr->bs_invf_mode[ch][n] = faad_getbits(ld, 2
            DEBUGVAR(1,271,"invf_mode(): bs_invf_mode"));
    }
}

/* table 10 */
static void sbr_envelope(bitfile *ld, sbr_info *sbr, uint8_t ch)
{
    uint8_t env, band;
    int8_t delta = 0;
    sbr_huff_tab t_huff, f_huff;

    if ((sbr->L_E[ch] == 1) && (sbr->bs_frame_class[ch] == FIXFIX))
        sbr->amp_res[ch] = 0;
    else
        sbr->amp_res[ch] = sbr->bs_amp_res;

    if ((sbr->bs_coupling) && (ch == 1))
    {
        delta = 1;
        if (sbr->amp_res[ch])
        {
            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 {
        delta = 0;
        if (sbr->amp_res[ch])
        {
            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->L_E[ch]; env++)
    {
        if (sbr->bs_df_env[ch][env] == 0)
        {
            if ((sbr->bs_coupling == 1) && (ch == 1))
            {
                if (sbr->amp_res[ch])
                {
                    sbr->E[ch][0][env] = (faad_getbits(ld, 5
                        DEBUGVAR(1,272,"sbr_envelope(): bs_data_env")) << delta);
                } else {
                    sbr->E[ch][0][env] = (faad_getbits(ld, 6
                        DEBUGVAR(1,273,"sbr_envelope(): bs_data_env")) << delta);
                }
            } else {
                if (sbr->amp_res[ch])
                {
                    sbr->E[ch][0][env] = (faad_getbits(ld, 6
                        DEBUGVAR(1,274,"sbr_envelope(): bs_data_env")) << delta);
                } else {
                    sbr->E[ch][0][env] = (faad_getbits(ld, 7
                        DEBUGVAR(1,275,"sbr_envelope(): bs_data_env")) << delta);
                }
            }

            for (band = 1; band < sbr->n[sbr->f[ch][env]]; band++)
            {
                sbr->E[ch][band][env] = (sbr_huff_dec(ld, f_huff) << delta);
            }

        } else {
            for (band = 0; band < sbr->n[sbr->f[ch][env]]; band++)
            {
                sbr->E[ch][band][env] = (sbr_huff_dec(ld, t_huff) << delta);
            }
        }
    }

#if 0
// TEMP
    if (sbr->frame == 19)
    {
        int l, k;

        printf("\n");
        for (l = 0; l < sbr->L_E[ch]; l++)
        {
            for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++)
            {
                printf("l:%d k:%d E:%d\n",l, k, sbr->E[ch][k][l]);
            }
        }
    }
// end TEMP
#endif

    extract_envelope_data(sbr, ch);

#if 0
// TEMP
    if (sbr->frame == 21)
    {
        int l, k;

        printf("\n");
        for (l = 0; l < sbr->L_E[ch]; l++)
        {
            for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++)
            {
                //printf("l:%d k:%d E:%d\n",l,k, sbr->E[ch][k][l]);
                printf("%d\n", sbr->E[ch][k][l]);
            }
        }
    }
// end TEMP
#endif
}

/* table 11 */
static void sbr_noise(bitfile *ld, sbr_info *sbr, uint8_t ch)
{
    uint8_t noise, band;
    int8_t delta = 0;
    sbr_huff_tab t_huff, f_huff;

    if ((sbr->bs_coupling == 1) && (ch == 1))
    {
        delta = 1;
        t_huff = t_huffman_noise_bal_3_0dB;
        f_huff = f_huffman_env_bal_3_0dB;
    } else {
        delta = 0;
        t_huff = t_huffman_noise_3_0dB;
        f_huff = f_huffman_env_3_0dB;
    }

    for (noise = 0; noise < sbr->L_Q[ch]; noise++)
    {
        if(sbr->bs_df_noise[ch][noise] == 0)
        {
            if ((sbr->bs_coupling == 1) && (ch == 1))
            {
                sbr->Q[ch][0][noise] = (faad_getbits(ld, 5
                    DEBUGVAR(1,276,"sbr_noise(): bs_data_noise")) << delta);
            } else {
                sbr->Q[ch][0][noise] = (faad_getbits(ld, 5
                    DEBUGVAR(1,277,"sbr_noise(): bs_data_noise")) << delta);
            }
            for (band = 1; band < sbr->N_Q; band++)
            {
                sbr->Q[ch][band][noise] = (sbr_huff_dec(ld, f_huff) << delta);
            }
        } else {
            for (band = 0; band < sbr->N_Q; band++)
            {
                sbr->Q[ch][band][noise] = (sbr_huff_dec(ld, t_huff) << delta);
            }
        }
    }

    extract_noise_floor_data(sbr, ch);
}

/* table 12 */
static void sinusoidal_coding(bitfile *ld, sbr_info *sbr, uint8_t ch)
{
    uint8_t n;

    for (n = 0; n < sbr->N_high; n++)
    {
        sbr->bs_add_harmonic[ch][n] = faad_get1bit(ld
            DEBUGVAR(1,278,"sinusoidal_coding(): bs_add_harmonic"));
    }
}


#endif /* SBR_DEC */
--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_syntax.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_SYNTAX_H__
#define __SBR_SYNTAX_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "bits.h"

#define tHFGen 8
#define tHFAdj 2

#define EXT_SBR_DATA     13
#define EXT_SBR_DATA_CRC 14

#define FIXFIX 0
#define FIXVAR 1
#define VARFIX 2
#define VARVAR 3

#define LO_RES 0
#define HI_RES 1

#define NO_TIME_SLOTS 16
#define NOISE_FLOOR_OFFSET 6.0


uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint8_t id_aac);
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__ */


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_tf_grid.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

/* Time/Frequency grid */

#include "common.h"
#include "structs.h"

#ifdef SBR_DEC

#include <stdlib.h>

#include "sbr_syntax.h"
#include "sbr_tf_grid.h"

void envelope_time_border_vector(sbr_info *sbr, uint8_t ch)
{
    uint8_t l, border;

    for (l = 0; l <= sbr->L_E[ch]; l++)
    {
        sbr->t_E[ch][l] = 0;
    }

    sbr->t_E[ch][0] = sbr->rate * sbr->abs_bord_lead[ch];
    sbr->t_E[ch][sbr->L_E[ch]] = sbr->rate * sbr->abs_bord_trail[ch];

    switch (sbr->bs_frame_class[ch])
    {
    case FIXFIX:
        switch (sbr->L_E[ch])
        {
        case 4:
            sbr->t_E[ch][3] = sbr->rate * 12;
            sbr->t_E[ch][2] = sbr->rate * 8;
            sbr->t_E[ch][1] = sbr->rate * 4;
            break;
        case 2:
            sbr->t_E[ch][1] = sbr->rate * 8;
            break;
        default:
            break;
        }
        break;

    case FIXVAR:
        if (sbr->L_E[ch] > 1)
        {
            int8_t i = sbr->L_E[ch];
            border = sbr->abs_bord_trail[ch];

            for (l = 0; l < (sbr->L_E[ch] - 1); l++)
            {
                border -= sbr->bs_rel_bord[ch][l];
                sbr->t_E[ch][--i] = sbr->rate * border;
            }
        }
        break;

    case VARFIX:
        if (sbr->L_E[ch] > 1)
        {
            int8_t i = 1;
            border = sbr->abs_bord_lead[ch];

            for (l = 0; l < (sbr->L_E[ch] - 1); l++)
            {
                border += sbr->bs_rel_bord[ch][l];
                sbr->t_E[ch][i++] = sbr->rate * border;
            }
        }
        break;

    case VARVAR:
        if (sbr->bs_num_rel_0[ch])
        {
            int8_t i = 1;
            border = sbr->abs_bord_lead[ch];

            for (l = 0; l < sbr->bs_num_rel_0[ch]; l++)
            {
                border += sbr->bs_rel_bord_0[ch][l];
                sbr->t_E[ch][i++] = sbr->rate * border;
            }
        }

        if (sbr->bs_num_rel_1[ch])
        {
            int8_t i = sbr->L_E[ch];
            border = sbr->abs_bord_trail[ch];

            for (l = 0; l < sbr->bs_num_rel_1[ch]; l++)
            {
                border -= sbr->bs_rel_bord_1[ch][l];
                sbr->t_E[ch][--i] = sbr->rate * border;
            }
        }
        break;
    }
}

void noise_floor_time_border_vector(sbr_info *sbr, uint8_t ch)
{
    sbr->t_Q[ch][0] = sbr->t_E[ch][0];

    if (sbr->L_E[ch] == 1)
    {
        sbr->t_Q[ch][1] = sbr->t_E[ch][1];
        sbr->t_Q[ch][2] = 0;
    } else {
        uint8_t index = middleBorder(sbr, ch);
        sbr->t_Q[ch][1] = sbr->t_E[ch][index];
        sbr->t_Q[ch][2] = sbr->t_E[ch][sbr->L_E[ch]];
    }
}

static int16_t rel_bord_lead(sbr_info *sbr, uint8_t ch, uint8_t l)
{
    uint8_t i;
    int16_t acc = 0;

    switch (sbr->bs_frame_class[ch])
    {
    case FIXFIX:
        return NO_TIME_SLOTS/sbr->L_E[ch];
    case FIXVAR:
        return 0;
    case VARFIX:
        for (i = 0; i < l; i++)
        {
            acc += sbr->bs_rel_bord[ch][i];
        }
        return acc;
    case VARVAR:
        for (i = 0; i < l; i++)
        {
            acc += sbr->bs_rel_bord_0[ch][i];
        }
        return acc;
    }

    return 0;
}

static int16_t rel_bord_trail(sbr_info *sbr, uint8_t ch, uint8_t l)
{
    uint8_t i;
    int16_t acc = 0;

    switch (sbr->bs_frame_class[ch])
    {
    case FIXFIX:
    case VARFIX:
        return 0;
    case FIXVAR:
        for (i = 0; i < l; i++)
        {
            acc += sbr->bs_rel_bord[ch][i];
        }
        return acc;
    case VARVAR:
        for (i = 0; i < l; i++)
        {
            acc += sbr->bs_rel_bord_1[ch][i];
        }
        return acc;
    }

    return 0;
}

static uint8_t middleBorder(sbr_info *sbr, uint8_t ch)
{
    int8_t retval;

    switch (sbr->bs_frame_class[ch])
    {
    case FIXFIX:
        retval = sbr->L_E[ch]/2;
        break;
    case VARFIX:
        if (sbr->bs_pointer[ch] == 0)
            retval = 1;
        else if (sbr->bs_pointer[ch] == 1)
            retval = sbr->L_E[ch] - 1;
        else
            retval = sbr->bs_pointer[ch] - 1;
        break;
    case FIXVAR:
    case VARVAR:
        if (sbr->bs_pointer[ch] > 1)
            retval = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch];
        else
            retval = sbr->L_E[ch] - 1;
        break;
    }

    return (retval > 0) ? retval : 0;
}


#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: sbr_tf_grid.h,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

#ifndef __SBR_TF_GRID_H__
#define __SBR_TF_GRID_H__

#ifdef __cplusplus
extern "C" {
#endif


void envelope_time_border_vector(sbr_info *sbr, uint8_t ch);
void noise_floor_time_border_vector(sbr_info *sbr, uint8_t ch);

static int16_t rel_bord_lead(sbr_info *sbr, uint8_t ch, uint8_t l);
static int16_t rel_bord_trail(sbr_info *sbr, uint8_t ch, uint8_t l);
static uint8_t middleBorder(sbr_info *sbr, uint8_t ch);


#ifdef __cplusplus
}
#endif
#endif


--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
[...8509 lines suppressed...]
    0x10000000,
    0x10000000,
    0x10000000,
    0x10000000,
    0x10000000,
    0x10000000,
    0x10000000,
    0x10000000,
    0x10000000,
    0x10000000,
    0x10000000
};
#endif

#endif

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: specrec.c,v 1.1 2003/08/30 22:30:22 arpi Exp $
**/

/*
  Spectral reconstruction:
   - grouping/sectioning
   - inverse quantization
   - applying scalefactors
*/

#include "common.h"
#include "structs.h"

#include <string.h>
#include "specrec.h"
#include "syntax.h"
#include "iq_table.h"

#ifdef LD_DEC
static uint8_t num_swb_512_window[] =
{
    0, 0, 0, 36, 36, 37, 31, 31, 0, 0, 0, 0
};
static uint8_t num_swb_480_window[] =
{
    0, 0, 0, 35, 35, 37, 30, 30, 0, 0, 0, 0
};
#endif

static uint8_t num_swb_960_window[] =
{
    40, 40, 45, 49, 49, 49, 46, 46, 42, 42, 42, 40
};

static uint8_t num_swb_1024_window[] =
{
    41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40
};

static 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
};

static uint16_t swb_offset_480_48[] =
{
    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, 272, 304, 336, 368, 400,
    432, 480
};
#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
};

static uint16_t swb_offset_480_32[] =
{
    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80,
    88, 96, 104, 112, 124, 136, 148, 164, 180, 200, 224, 256, 288, 320, 352,
    384, 416, 448, 480
};
#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
};

static uint16_t swb_offset_480_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
};
#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
};

static 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
static 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  */
};

static uint16_t *swb_offset_480_window[] =
{
    0,                       /* 96000 */
    0,                       /* 88200 */
    0,                       /* 64000 */
    swb_offset_480_48,       /* 48000 */
    swb_offset_480_48,       /* 44100 */
    swb_offset_480_32,       /* 32000 */
    swb_offset_480_24,       /* 24000 */
    swb_offset_480_24,       /* 22050 */
    0,                       /* 16000 */
    0,                       /* 12000 */
    0,                       /* 11025 */
    0                        /* 8000  */
};
#endif

static 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  */
};

#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(faacDecHandle hDecoder, ic_stream *ics)
{
    uint8_t i, g;

    uint8_t sf_index = hDecoder->sf_index;

    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 (hDecoder->object_type == LD)
        {
            if (hDecoder->frameLength == 512)
                ics->num_swb = num_swb_512_window[sf_index];
            else /* if (hDecoder->frameLength == 480) */
                ics->num_swb = num_swb_480_window[sf_index];
        } else {
#endif
            if (hDecoder->frameLength == 1024)
                ics->num_swb = num_swb_1024_window[sf_index];
            else /* if (hDecoder->frameLength == 960) */
                ics->num_swb = num_swb_960_window[sf_index];
#ifdef LD_DEC
        }
#endif

        /* preparation of sect_sfb_offset for long blocks */
        /* also copy the last value! */
#ifdef LD_DEC
        if (hDecoder->object_type == LD)
        {
            if (hDecoder->frameLength == 512)
            {
                for (i = 0; i < ics->num_swb; i++)
                {
                    ics->sect_sfb_offset[0][i] = swb_offset_512_window[sf_index][i];
                    ics->swb_offset[i] = swb_offset_512_window[sf_index][i];
                }
            } else /* if (hDecoder->frameLength == 480) */ {
                for (i = 0; i < ics->num_swb; i++)
                {
                    ics->sect_sfb_offset[0][i] = swb_offset_480_window[sf_index][i];
                    ics->swb_offset[i] = swb_offset_480_window[sf_index][i];
                }
            }
            ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength;
            ics->swb_offset[ics->num_swb] = hDecoder->frameLength;
        } else {
#endif
            for (i = 0; i < ics->num_swb; i++)
            {
                ics->sect_sfb_offset[0][i] = swb_offset_1024_window[sf_index][i];
                ics->swb_offset[i] = swb_offset_1024_window[sf_index][i];
            }
            ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength;
            ics->swb_offset[ics->num_swb] = hDecoder->frameLength;
#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[sf_index];

        for (i = 0; i < ics->num_swb; i++)
            ics->swb_offset[i] = swb_offset_128_window[sf_index][i];
        ics->swb_offset[ics->num_swb] = hDecoder->frameLength/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 = (hDecoder->frameLength/8) - swb_offset_128_window[sf_index][i];
                } else {
                    width = swb_offset_128_window[sf_index][i+1] -
                        swb_offset_128_window[sf_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)
{
    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;
    memset(tmp_spec_ptr, 0, frame_len*sizeof(real_t));

    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[0] = spec_ptr[0];
                    tmp_spec_ptr[1] = spec_ptr[1];
                    tmp_spec_ptr[2] = spec_ptr[2];
                    tmp_spec_ptr[3] = spec_ptr[3];
                    tmp_spec_ptr += 4;
                    spec_ptr += 4;
                }

                win_ptr += win_inc;
            }
            j += width;
        }
        start_win_ptr += (spec_ptr - start_inptr);
    }

    spec_ptr = spec_data;
    tmp_spec_ptr = tmp_spec;

    memcpy(spec_ptr, tmp_spec_ptr, frame_len*sizeof(real_t));
}

#ifndef FIXED_POINT
void build_tables(real_t *pow2_table)
{
    uint16_t i;

    /* build pow(2, 0.25*x) table for scalefactors */
    for(i = 0; i < POW_TABLE_SIZE; i++)
    {
        pow2_table[i] = REAL_CONST(pow(2.0, 0.25 * (i-100)));
    }
}
#endif

static INLINE real_t iquant(int16_t q, real_t *tab)
{
    int16_t sgn = 1;

    if (q == 0) return 0;

    if (q < 0)
    {
        q = -q;
        sgn = -1;
    }

    if (q >= IQ_TABLE_SIZE)
        return sgn * tab[q>>3] * 16;

    return sgn * tab[q];
}

void inverse_quantization(real_t *x_invquant, int16_t *x_quant, uint16_t frame_len)
{
    int16_t i;
    int16_t *in_ptr = x_quant;
    real_t *out_ptr = x_invquant;
    real_t *tab = iq_table;

    for(i = frame_len/4-1; i >= 0; --i)
    {
        out_ptr[0] = iquant(in_ptr[0], tab);
        out_ptr[1] = iquant(in_ptr[1], tab);
        out_ptr[2] = iquant(in_ptr[2], tab);
        out_ptr[3] = iquant(in_ptr[3], tab);
        out_ptr += 4;
        in_ptr += 4;
    }
}

#ifndef FIXED_POINT
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_CONST(pow(2.0, 0.25 * (scale_factor - 100)));
}
#else
static real_t pow2_table[] =
{
    COEF_CONST(0.59460355750136),
    COEF_CONST(0.70710678118655),
    COEF_CONST(0.84089641525371),
    COEF_CONST(1.0),
    COEF_CONST(1.18920711500272),
    COEF_CONST(1.41421356237310),
    COEF_CONST(1.68179283050743)
};
#endif

#ifdef FIXED_POINT
void apply_scalefactors(faacDecHandle hDecoder, ic_stream *ics, real_t *x_invquant,
                        uint16_t frame_len)
#else
void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table,
                        uint16_t frame_len)
#endif
{
    uint8_t g, sfb;
    uint16_t top;
    real_t *fp;
#ifndef FIXED_POINT
    real_t scale;
#else
    int32_t exp, frac;
#endif
    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];

#ifndef FIXED_POINT
            scale = get_scale_factor_gain(ics->scale_factors[g][sfb], pow2_table);
#else
            exp = (ics->scale_factors[g][sfb] - 100) / 4;
            frac = (ics->scale_factors[g][sfb] - 100) % 4;

            if (hDecoder->object_type == LD)
            {
                exp -= 6 /*9*/;
            } else {
                if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
                    exp -= 4 /*7*/;
                else
                    exp -= 7 /*10*/;
            }
#endif

            /* minimum size of a sf band is 4 and always a multiple of 4 */
            for ( ; k < top; k += 4)
            {
#ifndef FIXED_POINT
                fp[0] = fp[0] * scale;
                fp[1] = fp[1] * scale;
                fp[2] = fp[2] * scale;
                fp[3] = fp[3] * scale;
#else
                if (exp < 0)
                {
                    fp[0] >>= -exp;
                    fp[1] >>= -exp;
                    fp[2] >>= -exp;
                    fp[3] >>= -exp;
                } else {
                    fp[0] <<= exp;
                    fp[1] <<= exp;
                    fp[2] <<= exp;
                    fp[3] <<= exp;
                }

                if (frac)
                {
                    fp[0] = MUL_R_C(fp[0],pow2_table[frac + 3]);
                    fp[1] = MUL_R_C(fp[1],pow2_table[frac + 3]);
                    fp[2] = MUL_R_C(fp[2],pow2_table[frac + 3]);
                    fp[3] = MUL_R_C(fp[3],pow2_table[frac + 3]);
                }
#endif
                fp += 4;
            }
        }
        groups += ics->window_group_length[g];
    }
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: specrec.h,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#ifndef __SPECREC_H__
#define __SPECREC_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "syntax.h"

uint8_t window_grouping_info(faacDecHandle hDecoder, ic_stream *ics);
void quant_to_spec(ic_stream *ics, real_t *spec_data, uint16_t frame_len);
void inverse_quantization(real_t *x_invquant, int16_t *x_quant, uint16_t frame_len);
#ifdef FIXED_POINT
void apply_scalefactors(faacDecHandle hDecoder, ic_stream *ics, real_t *x_invquant,
                        uint16_t frame_len);
#else
void build_tables(real_t *pow2_table);
void apply_scalefactors(ic_stream *ics, real_t *x_invquant, real_t *pow2_table,
                        uint16_t frame_len);
#endif

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ssr.c,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#ifdef SSR_DEC

#include "syntax.h"
#include "filtbank.h"
#include "ssr.h"
#include "ssr_fb.h"

void ssr_decode(ssr_info *ssr, fb_info *fb, uint8_t window_sequence,
                uint8_t window_shape, uint8_t window_shape_prev,
                real_t *freq_in, real_t *time_out, real_t *overlap,
                real_t ipqf_buffer[SSR_BANDS][96/4],
                real_t *prev_fmd, uint16_t frame_len)
{
    uint8_t band;
    uint16_t ssr_frame_len = frame_len/SSR_BANDS;
    real_t time_tmp[2048];
    real_t output[1024];

    memset(output, 0, 1024*sizeof(real_t));
    memset(time_tmp, 0, 2048*sizeof(real_t));

    for (band = 0; band < SSR_BANDS; band++)
    {
        int16_t j;

        /* uneven bands have inverted frequency scale */
        if (band == 1 || band == 3)
        {
            for (j = 0; j < ssr_frame_len/2; j++)
            {
                real_t tmp;
                tmp = freq_in[j + ssr_frame_len*band];
                freq_in[j + ssr_frame_len*band] =
                    freq_in[ssr_frame_len - j - 1 + ssr_frame_len*band];
                freq_in[ssr_frame_len - j - 1 + ssr_frame_len*band] = tmp;
            }
        }

        /* non-overlapping inverse filterbank for SSR */
        ssr_ifilter_bank(fb, window_sequence, window_shape, window_shape_prev,
            freq_in + band*ssr_frame_len, time_tmp + band*ssr_frame_len,
            ssr_frame_len);

        /* gain control */
        ssr_gain_control(ssr, time_tmp, output, overlap, prev_fmd,
            band, window_sequence, ssr_frame_len);
    }

    /* inverse pqf to bring subbands together again */
    ssr_ipqf(ssr, output, time_out, ipqf_buffer, frame_len, SSR_BANDS);
}

static void ssr_gain_control(ssr_info *ssr, real_t *data, real_t *output,
                             real_t *overlap, real_t *prev_fmd, uint8_t band,
                             uint8_t window_sequence, uint16_t frame_len)
{
    uint16_t i;
    real_t gc_function[2*1024/SSR_BANDS];

    if (window_sequence != EIGHT_SHORT_SEQUENCE)
    {
        ssr_gc_function(ssr, &prev_fmd[band * frame_len*2],
            gc_function, window_sequence, frame_len);

        for (i = 0; i < frame_len*2; i++)
            data[band * frame_len*2 + i] *= gc_function[i];
        for (i = 0; i < frame_len; i++)
        {
            output[band*frame_len + i] = overlap[band*frame_len + i] +
                data[band*frame_len*2 + i];
        }
        for (i = 0; i < frame_len; i++)
        {
            overlap[band*frame_len + i] =
                data[band*frame_len*2 + frame_len + i];
        }
    } else {
        uint8_t w;
        for (w = 0; w < 8; w++)
        {
            uint16_t frame_len8 = frame_len/8;
            uint16_t frame_len16 = frame_len/16;

            ssr_gc_function(ssr, &prev_fmd[band*frame_len*2 + w*frame_len*2/8],
                gc_function, window_sequence, frame_len);

            for (i = 0; i < frame_len8*2; i++)
                data[band*frame_len*2 + w*frame_len8*2+i] *= gc_function[i];
            for (i = 0; i < frame_len8; i++)
            {
                overlap[band*frame_len + i + 7*frame_len16 + w*frame_len8] +=
                    data[band*frame_len*2 + 2*w*frame_len8 + i];
            }
            for (i = 0; i < frame_len8; i++)
            {
                overlap[band*frame_len + i + 7*frame_len16 + (w+1)*frame_len8] =
                    data[band*frame_len*2 + 2*w*frame_len8 + frame_len8 + i];
            }
        }
        for (i = 0; i < frame_len; i++)
            output[band*frame_len + i] = overlap[band*frame_len + i];
        for (i = 0; i < frame_len; i++)
            overlap[band*frame_len + i] = overlap[band*frame_len + i + frame_len];
    }
}

static void ssr_gc_function(ssr_info *ssr, real_t *prev_fmd,
                            real_t *gc_function, uint8_t window_sequence,
                            uint16_t frame_len)
{
    uint16_t i;
    uint16_t len_area1, len_area2;
    int32_t aloc[10];
    real_t alev[10];

    switch (window_sequence)
    {
    case ONLY_LONG_SEQUENCE:
        len_area1 = frame_len/SSR_BANDS;
        len_area2 = 0;
        break;
    case LONG_START_SEQUENCE:
        len_area1 = (frame_len/SSR_BANDS)*7/32;
        len_area2 = (frame_len/SSR_BANDS)/16;
        break;
    case EIGHT_SHORT_SEQUENCE:
        len_area1 = (frame_len/8)/SSR_BANDS;
        len_area2 = 0;
        break;
    case LONG_STOP_SEQUENCE:
        len_area1 = (frame_len/SSR_BANDS);
        len_area2 = 0;
        break;
    }

    /* decode bitstream information */

    /* build array M */


    for (i = 0; i < frame_len*2; i++)
        gc_function[i] = 1;
}

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ssr.h,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#ifndef __SSR_H__
#define __SSR_H__

#ifdef __cplusplus
extern "C" {
#endif

#define SSR_BANDS 4
#define PQFTAPS 96

void ssr_decode(ssr_info *ssr, fb_info *fb, uint8_t window_sequence,
                uint8_t window_shape, uint8_t window_shape_prev,
                real_t *freq_in, real_t *time_out, real_t *overlap,
                real_t ipqf_buffer[SSR_BANDS][96/4],
                real_t *prev_fmd, uint16_t frame_len);


static void ssr_gain_control(ssr_info *ssr, real_t *data, real_t *output,
                             real_t *overlap, real_t *prev_fmd, uint8_t band,
                             uint8_t window_sequence, uint16_t frame_len);
static void ssr_gc_function(ssr_info *ssr, real_t *prev_fmd,
                            real_t *gc_function, uint8_t window_sequence,
                            uint16_t frame_len);


#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ssr_fb.c,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#ifdef SSR_DEC

#include <string.h>
#include <stdlib.h>
#include "syntax.h"
#include "filtbank.h"
#include "mdct.h"
#include "ssr_fb.h"
#include "ssr_win.h"

fb_info *ssr_filter_bank_init(uint16_t frame_len)
{
    uint16_t nshort = frame_len/8;

    fb_info *fb = (fb_info*)malloc(sizeof(fb_info));
    memset(fb, 0, sizeof(fb_info));

    /* normal */
    fb->mdct256 = faad_mdct_init(2*nshort);
    fb->mdct2048 = faad_mdct_init(2*frame_len);

    fb->long_window[0]  = sine_long_256;
    fb->short_window[0] = sine_short_32;
    fb->long_window[1]  = kbd_long_256;
    fb->short_window[1] = kbd_short_32;

    return fb;
}

void ssr_filter_bank_end(fb_info *fb)
{
    faad_mdct_end(fb->mdct256);
    faad_mdct_end(fb->mdct2048);

    if (fb) free(fb);
}

static INLINE void imdct_ssr(fb_info *fb, real_t *in_data,
                             real_t *out_data, uint16_t len)
{
    mdct_info *mdct;

    switch (len)
    {
    case 512:
        mdct = fb->mdct2048;
        break;
    case 64:
        mdct = fb->mdct256;
        break;
    }

    faad_imdct(mdct, in_data, out_data);
}

/* NON-overlapping inverse filterbank for use with SSR */
void ssr_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_out, uint16_t frame_len)
{
    int16_t i;
    real_t *transf_buf;

    real_t *window_long;
    real_t *window_long_prev;
    real_t *window_short;
    real_t *window_short_prev;

    uint16_t nlong = frame_len;
    uint16_t nshort = frame_len/8;
    uint16_t trans = nshort/2;

    uint16_t nflat_ls = (nlong-nshort)/2;

    transf_buf = (real_t*)malloc(2*nlong*sizeof(real_t));

    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];

    switch (window_sequence)
    {
    case ONLY_LONG_SEQUENCE:
        imdct_ssr(fb, freq_in, transf_buf, 2*nlong);
        for (i = nlong-1; i >= 0; i--)
        {
            time_out[i] = MUL_R_C(transf_buf[i],window_long_prev[i]);
            time_out[nlong+i] = MUL_R_C(transf_buf[nlong+i],window_long[nlong-1-i]);
        }
        break;

    case LONG_START_SEQUENCE:
        imdct_ssr(fb, freq_in, transf_buf, 2*nlong);
        for (i = 0; i < nlong; i++)
            time_out[i] = MUL_R_C(transf_buf[i],window_long_prev[i]);
        for (i = 0; i < nflat_ls; i++)
            time_out[nlong+i] = transf_buf[nlong+i];
        for (i = 0; i < nshort; i++)
            time_out[nlong+nflat_ls+i] = MUL_R_C(transf_buf[nlong+nflat_ls+i],window_short[nshort-i-1]);
        for (i = 0; i < nflat_ls; i++)
            time_out[nlong+nflat_ls+nshort+i] = 0;
        break;

    case EIGHT_SHORT_SEQUENCE:
        imdct_ssr(fb, freq_in+0*nshort, transf_buf+2*nshort*0, 2*nshort);
        imdct_ssr(fb, freq_in+1*nshort, transf_buf+2*nshort*1, 2*nshort);
        imdct_ssr(fb, freq_in+2*nshort, transf_buf+2*nshort*2, 2*nshort);
        imdct_ssr(fb, freq_in+3*nshort, transf_buf+2*nshort*3, 2*nshort);
        imdct_ssr(fb, freq_in+4*nshort, transf_buf+2*nshort*4, 2*nshort);
        imdct_ssr(fb, freq_in+5*nshort, transf_buf+2*nshort*5, 2*nshort);
        imdct_ssr(fb, freq_in+6*nshort, transf_buf+2*nshort*6, 2*nshort);
        imdct_ssr(fb, freq_in+7*nshort, transf_buf+2*nshort*7, 2*nshort);
        for(i = nshort-1; i >= 0; i--)
        {
            time_out[i+0*nshort] = MUL_R_C(transf_buf[nshort*0+i],window_short_prev[i]);
            time_out[i+1*nshort] = MUL_R_C(transf_buf[nshort*1+i],window_short[i]);
            time_out[i+2*nshort] = MUL_R_C(transf_buf[nshort*2+i],window_short_prev[i]);
            time_out[i+3*nshort] = MUL_R_C(transf_buf[nshort*3+i],window_short[i]);
            time_out[i+4*nshort] = MUL_R_C(transf_buf[nshort*4+i],window_short_prev[i]);
            time_out[i+5*nshort] = MUL_R_C(transf_buf[nshort*5+i],window_short[i]);
            time_out[i+6*nshort] = MUL_R_C(transf_buf[nshort*6+i],window_short_prev[i]);
            time_out[i+7*nshort] = MUL_R_C(transf_buf[nshort*7+i],window_short[i]);
            time_out[i+8*nshort] = MUL_R_C(transf_buf[nshort*8+i],window_short_prev[i]);
            time_out[i+9*nshort] = MUL_R_C(transf_buf[nshort*9+i],window_short[i]);
            time_out[i+10*nshort] = MUL_R_C(transf_buf[nshort*10+i],window_short_prev[i]);
            time_out[i+11*nshort] = MUL_R_C(transf_buf[nshort*11+i],window_short[i]);
            time_out[i+12*nshort] = MUL_R_C(transf_buf[nshort*12+i],window_short_prev[i]);
            time_out[i+13*nshort] = MUL_R_C(transf_buf[nshort*13+i],window_short[i]);
            time_out[i+14*nshort] = MUL_R_C(transf_buf[nshort*14+i],window_short_prev[i]);
            time_out[i+15*nshort] = MUL_R_C(transf_buf[nshort*15+i],window_short[i]);
        }
        break;

    case LONG_STOP_SEQUENCE:
        imdct_ssr(fb, freq_in, transf_buf, 2*nlong);
        for (i = 0; i < nflat_ls; i++)
            time_out[i] = 0;
        for (i = 0; i < nshort; i++)
            time_out[nflat_ls+i] = MUL_R_C(transf_buf[nflat_ls+i],window_short_prev[i]);
        for (i = 0; i < nflat_ls; i++)
            time_out[nflat_ls+nshort+i] = transf_buf[nflat_ls+nshort+i];
        for (i = 0; i < nlong; i++)
            time_out[nlong+i] = MUL_R_C(transf_buf[nlong+i],window_long[nlong-1-i]);
		break;
    }

    free(transf_buf);
}


#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ssr_fb.h,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#ifndef __SSR_FB_H__
#define __SSR_FB_H__

#ifdef __cplusplus
extern "C" {
#endif

fb_info *ssr_filter_bank_init(uint16_t frame_len);
void ssr_filter_bank_end(fb_info *fb);

/*non overlapping inverse filterbank */
void ssr_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_out,
                      uint16_t frame_len);

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ssr_ipqf.c,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#ifdef SSR_DEC

#include "ssr.h"
#include "ssr_ipqf.h"

static real_t **app_pqfbuf;
static real_t **pp_q0, **pp_t0, **pp_t1;

void gc_set_protopqf(real_t *p_proto)
{
    int	j;
    static real_t a_half[48] =
    {
        1.2206911375946939E-05,  1.7261986723798209E-05,  1.2300093657077942E-05,
        -1.0833943097791965E-05, -5.7772498639901686E-05, -1.2764767618947719E-04,
        -2.0965186675013334E-04, -2.8166673689263850E-04, -3.1234860429017460E-04,
        -2.6738519958452353E-04, -1.1949424681824722E-04,  1.3965139412648678E-04,
        4.8864136409185725E-04,  8.7044629275148344E-04,  1.1949430269934793E-03,
        1.3519708175026700E-03,  1.2346314373964412E-03,  7.6953209114159191E-04,
        -5.2242432579537141E-05, -1.1516092887213454E-03, -2.3538469841711277E-03,
        -3.4033123072127277E-03, -4.0028551071986133E-03, -3.8745415659693259E-03,
        -2.8321073426874310E-03, -8.5038892323704195E-04,  1.8856751185350931E-03,
        4.9688741735340923E-03,  7.8056704536795926E-03,  9.7027909685901654E-03,
        9.9960423120166159E-03,  8.2019366335594487E-03,  4.1642072876103365E-03,
        -1.8364453822737758E-03, -9.0384863094167686E-03, -1.6241528177129844E-02,
        -2.1939551286300665E-02, -2.4533179947088161E-02, -2.2591663337768787E-02,
        -1.5122066420044672E-02, -1.7971713448186293E-03,  1.6903413428575379E-02,
        3.9672315874127042E-02,  6.4487527248102796E-02,  8.8850025474701726E-02,
        0.1101132906105560    ,  0.1258540205143761    ,  0.1342239368467012    
    };

    for (j = 0; j < 48; ++j)
    {
        p_proto[j] = p_proto[95-j] = a_half[j];
    }
}

void gc_setcoef_eff_pqfsyn(int mm,
                           int kk,
                           real_t *p_proto,
                           real_t ***ppp_q0,
                           real_t ***ppp_t0,
                           real_t ***ppp_t1)
{
    int	i, k, n;
    real_t	w;

    /* Set 1st Mul&Acc Coef's */
    *ppp_q0 = (real_t **) calloc(mm, sizeof(real_t *));
    for (n = 0; n < mm; ++n)
    {
        (*ppp_q0)[n] = (real_t *) calloc(mm, sizeof(real_t));
    }
    for (n = 0; n < mm/2; ++n)
    {
        for (i = 0; i < mm; ++i)
        {
            w = (2*i+1)*(2*n+1-mm)*M_PI/(4*mm);
            (*ppp_q0)[n][i] = 2.0 * cos((real_t) w);

            w = (2*i+1)*(2*(mm+n)+1-mm)*M_PI/(4*mm);
            (*ppp_q0)[n + mm/2][i] = 2.0 * cos((real_t) w);
        }
    }

    /* Set 2nd Mul&Acc Coef's */
    *ppp_t0 = (real_t **) calloc(mm, sizeof(real_t *));
    *ppp_t1 = (real_t **) calloc(mm, sizeof(real_t *));
    for (n = 0; n < mm; ++n)
    {
        (*ppp_t0)[n] = (real_t *) calloc(kk, sizeof(real_t));
        (*ppp_t1)[n] = (real_t *) calloc(kk, sizeof(real_t));
    }
    for (n = 0; n < mm; ++n)
    {
        for (k = 0; k < kk; ++k)
        {
            (*ppp_t0)[n][k] = mm * p_proto[2*k    *mm + n];
            (*ppp_t1)[n][k] = mm * p_proto[(2*k+1)*mm + n];

            if (k%2 != 0)
            {
                (*ppp_t0)[n][k] = -(*ppp_t0)[n][k];
                (*ppp_t1)[n][k] = -(*ppp_t1)[n][k];
            }
        }
    }
}

void ssr_ipqf(ssr_info *ssr, real_t *in_data, real_t *out_data,
              real_t buffer[SSR_BANDS][96/4],
              uint16_t frame_len, uint8_t bands)
{
    static int initFlag = 0;
    real_t a_pqfproto[PQFTAPS];

    int	i;

    if (initFlag == 0)
    {
        gc_set_protopqf(a_pqfproto);
        gc_setcoef_eff_pqfsyn(SSR_BANDS, PQFTAPS/(2*SSR_BANDS), a_pqfproto,
            &pp_q0, &pp_t0, &pp_t1);
        initFlag = 1;
    }

    for (i = 0; i < frame_len / SSR_BANDS; i++)
    {
        int l, n, k;
        int mm = SSR_BANDS;
        int kk = PQFTAPS/(2*SSR_BANDS);

        for (n = 0; n < mm; n++)
        {
            for (k = 0; k < 2*kk-1; k++)
            {
                buffer[n][k] = buffer[n][k+1];
            }
        }

        for (n = 0; n < mm; n++)
        {
            real_t acc = 0.0;
            for (l = 0; l < mm; l++)
            {
                acc += pp_q0[n][l] * in_data[l*frame_len/SSR_BANDS + i];
            }
            buffer[n][2*kk-1] = acc;
        }

        for (n = 0; n < mm/2; n++)
        {
            real_t acc = 0.0;
            for (k = 0; k < kk; k++)
            {
                acc += pp_t0[n][k] * buffer[n][2*kk-1-2*k];
            }
            for (k = 0; k < kk; ++k)
            {
                acc += pp_t1[n][k] * buffer[n + mm/2][2*kk-2-2*k];
            }
            out_data[i*SSR_BANDS + n] = acc;

            acc = 0.0;
            for (k = 0; k < kk; k++)
            {
                acc += pp_t0[mm-1-n][k] * buffer[n][2*kk-1-2*k];
            }
            for (k = 0; k < kk; k++)
            {
                acc -= pp_t1[mm-1-n][k] * buffer[n + mm/2][2*kk-2-2*k];
            }
            out_data[i*SSR_BANDS + mm-1-n] = acc;
        }
    }
}

#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ssr_ipqf.h,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#ifndef __SSR_IPQF_H__
#define __SSR_IPQF_H__

#ifdef __cplusplus
extern "C" {
#endif

void ssr_ipqf(ssr_info *ssr, real_t *in_data, real_t *out_data,
              real_t buffer[SSR_BANDS][96/4],
              uint16_t frame_len, uint8_t bands);


#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: ssr_win.h,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#ifndef __SSR_WIN_H__
#define __SSR_WIN_H__

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _MSC_VER
#pragma warning(disable:4305)
#pragma warning(disable:4244)
#endif

static real_t sine_short_32[] = {
    0.0245412290,
    0.0735645667,
    0.1224106774,
    0.1709618866,
    0.2191012502,
    0.2667127550,
    0.3136817515,
    0.3598950505,
    0.4052413106,
    0.4496113360,
    0.4928981960,
    0.5349976420,
    0.5758082271,
    0.6152316332,
    0.6531728506,
    0.6895405650,
    0.7242470980,
    0.7572088838,
    0.7883464694,
    0.8175848126,
    0.8448535800,
    0.8700870275,
    0.8932242990,
    0.9142097831,
    0.9329928160,
    0.9495282173,
    0.9637760520,
    0.9757021666,
    0.9852776527,
    0.9924795628,
    0.9972904325,
    0.9996988177
};

static real_t sine_long_256[] = {
    0.0030679568,
    0.0092037553,
    0.0153392069,
    0.0214740802,
    0.0276081469,
    0.0337411724,
    0.0398729295,
    0.0460031852,
    0.0521317050,
    0.0582582653,
    0.0643826351,
    0.0705045760,
    0.0766238645,
    0.0827402696,
    0.0888535529,
    0.0949634984,
    0.1010698676,
    0.1071724296,
    0.1132709533,
    0.1193652153,
    0.1254549921,
    0.1315400302,
    0.1376201212,
    0.1436950415,
    0.1497645378,
    0.1558284014,
    0.1618863940,
    0.1679383069,
    0.1739838719,
    0.1800229102,
    0.1860551536,
    0.1920804083,
    0.1980984211,
    0.2041089684,
    0.2101118416,
    0.2161068022,
    0.2220936269,
    0.2280720919,
    0.2340419590,
    0.2400030345,
    0.2459550500,
    0.2518978119,
    0.2578310966,
    0.2637546957,
    0.2696683407,
    0.2755718231,
    0.2814649343,
    0.2873474658,
    0.2932191789,
    0.2990798354,
    0.3049292266,
    0.3107671738,
    0.3165933788,
    0.3224076927,
    0.3282098472,
    0.3339996636,
    0.3397769034,
    0.3455413282,
    0.3512927592,
    0.3570309579,
    0.3627557456,
    0.3684668541,
    0.3741640747,
    0.3798472285,
    0.3855160773,
    0.3911703825,
    0.3968099952,
    0.4024346471,
    0.4080441594,
    0.4136383235,
    0.4192169011,
    0.4247796834,
    0.4303264916,
    0.4358570874,
    0.4413712919,
    0.4468688369,
    0.4523496032,
    0.4578133225,
    0.4632597864,
    0.4686888456,
    0.4741002321,
    0.4794937670,
    0.4848692715,
    0.4902265072,
    0.4955652654,
    0.5008853674,
    0.5061866641,
    0.5114688873,
    0.5167317986,
    0.5219752789,
    0.5271991491,
    0.5324031115,
    0.5375871062,
    0.5427507758,
    0.5478940606,
    0.5530167222,
    0.5581185222,
    0.5631993413,
    0.5682589412,
    0.5732972026,
    0.5783138275,
    0.5833086967,
    0.5882815719,
    0.5932323337,
    0.5981607437,
    0.6030666232,
    0.6079497933,
    0.6128100753,
    0.6176473498,
    0.6224613190,
    0.6272518039,
    0.6320187449,
    0.6367619038,
    0.6414810419,
    0.6461760402,
    0.6508467197,
    0.6554928422,
    0.6601143479,
    0.6647109985,
    0.6692826152,
    0.6738290191,
    0.6783500314,
    0.6828455329,
    0.6873153448,
    0.6917592883,
    0.6961771250,
    0.7005687952,
    0.7049341202,
    0.7092728615,
    0.7135848999,
    0.7178700566,
    0.7221282125,
    0.7263591886,
    0.7305628061,
    0.7347388864,
    0.7388873696,
    0.7430079579,
    0.7471006513,
    0.7511651516,
    0.7552013993,
    0.7592092156,
    0.7631884217,
    0.7671388984,
    0.7710605264,
    0.7749531269,
    0.7788165212,
    0.7826505899,
    0.7864552140,
    0.7902302146,
    0.7939754725,
    0.7976908684,
    0.8013761640,
    0.8050313592,
    0.8086562157,
    0.8122506142,
    0.8158144355,
    0.8193475604,
    0.8228498101,
    0.8263210654,
    0.8297612667,
    0.8331701756,
    0.8365477324,
    0.8398938179,
    0.8432082534,
    0.8464909792,
    0.8497417569,
    0.8529606462,
    0.8561473489,
    0.8593018055,
    0.8624239564,
    0.8655136228,
    0.8685707450,
    0.8715950847,
    0.8745866418,
    0.8775452971,
    0.8804709315,
    0.8833633661,
    0.8862225413,
    0.8890483975,
    0.8918406963,
    0.8945994973,
    0.8973246217,
    0.9000158906,
    0.9026733041,
    0.9052967429,
    0.9078861475,
    0.9104412794,
    0.9129621983,
    0.9154487252,
    0.9179008007,
    0.9203183055,
    0.9227011204,
    0.9250492454,
    0.9273625612,
    0.9296408892,
    0.9318842888,
    0.9340925813,
    0.9362657070,
    0.9384035468,
    0.9405061007,
    0.9425731897,
    0.9446048737,
    0.9466009140,
    0.9485613704,
    0.9504860640,
    0.9523749948,
    0.9542281032,
    0.9560452700,
    0.9578264356,
    0.9595715404,
    0.9612805247,
    0.9629532695,
    0.9645897746,
    0.9661900401,
    0.9677538276,
    0.9692812562,
    0.9707721472,
    0.9722265005,
    0.9736442566,
    0.9750253558,
    0.9763697386,
    0.9776773453,
    0.9789481759,
    0.9801821709,
    0.9813792109,
    0.9825392962,
    0.9836624265,
    0.9847484827,
    0.9857975245,
    0.9868094325,
    0.9877841473,
    0.9887216687,
    0.9896219969,
    0.9904850721,
    0.9913108945,
    0.9920993447,
    0.9928504229,
    0.9935641289,
    0.9942404628,
    0.9948793054,
    0.9954807758,
    0.9960446954,
    0.9965711236,
    0.9970600605,
    0.9975114465,
    0.9979252815,
    0.9983015656,
    0.9986402392,
    0.9989413023,
    0.9992047548,
    0.9994305968,
    0.9996188283,
    0.9997693896,
    0.9998823404,
    0.9999576211,
    0.9999952912
};

static real_t kbd_short_32[] = {
    0.0000875914060105,
    0.0009321760265333,
    0.0032114611466596,
    0.0081009893216786,
    0.0171240286619181,
    0.0320720743527833,
    0.0548307856028528,
    0.0871361822564870,
    0.1302923415174603,
    0.1848955425508276,
    0.2506163195331889,
    0.3260874142923209,
    0.4089316830907141,
    0.4959414909423747,
    0.5833939894958904,
    0.6674601983218376,
    0.7446454751465113,
    0.8121892962974020,
    0.8683559394406505,
    0.9125649996381605,
    0.9453396205809574,
    0.9680864942677585,
    0.9827581789763112,
    0.9914756203467121,
    0.9961964092194694,
    0.9984956609571091,
    0.9994855586984285,
    0.9998533730714648,
    0.9999671864476404,
    0.9999948432453556,
    0.9999995655238333,
    0.9999999961638728
};


static real_t kbd_long_256[] = {
    0.0005851230124487,
    0.0009642149851497,
    0.0013558207534965,
    0.0017771849644394,
    0.0022352533849672,
    0.0027342299070304,
    0.0032773001022195,
    0.0038671998069216,
    0.0045064443384152,
    0.0051974336885144,
    0.0059425050016407,
    0.0067439602523141,
    0.0076040812644888,
    0.0085251378135895,
    0.0095093917383048,
    0.0105590986429280,
    0.0116765080854300,
    0.0128638627792770,
    0.0141233971318631,
    0.0154573353235409,
    0.0168678890600951,
    0.0183572550877256,
    0.0199276125319803,
    0.0215811201042484,
    0.0233199132076965,
    0.0251461009666641,
    0.0270617631981826,
    0.0290689473405856,
    0.0311696653515848,
    0.0333658905863535,
    0.0356595546648444,
    0.0380525443366107,
    0.0405466983507029,
    0.0431438043376910,
    0.0458455957104702,
    0.0486537485902075,
    0.0515698787635492,
    0.0545955386770205,
    0.0577322144743916,
    0.0609813230826460,
    0.0643442093520723,
    0.0678221432558827,
    0.0714163171546603,
    0.0751278431308314,
    0.0789577503982528,
    0.0829069827918993,
    0.0869763963425241,
    0.0911667569410503,
    0.0954787380973307,
    0.0999129187977865,
    0.1044697814663005,
    0.1091497100326053,
    0.1139529881122542,
    0.1188797973021148,
    0.1239302155951605,
    0.1291042159181728,
    0.1344016647957880,
    0.1398223211441467,
    0.1453658351972151,
    0.1510317475686540,
    0.1568194884519144,
    0.1627283769610327,
    0.1687576206143887,
    0.1749063149634756,
    0.1811734433685097,
    0.1875578769224857,
    0.1940583745250518,
    0.2006735831073503,
    0.2074020380087318,
    0.2142421635060113,
    0.2211922734956977,
    0.2282505723293797,
    0.2354151558022098,
    0.2426840122941792,
    0.2500550240636293,
    0.2575259686921987,
    0.2650945206801527,
    0.2727582531907993,
    0.2805146399424422,
    0.2883610572460804,
    0.2962947861868143,
    0.3043130149466800,
    0.3124128412663888,
    0.3205912750432127,
    0.3288452410620226,
    0.3371715818562547,
    0.3455670606953511,
    0.3540283646950029,
    0.3625521080463003,
    0.3711348353596863,
    0.3797730251194006,
    0.3884630932439016,
    0.3972013967475546,
    0.4059842374986933,
    0.4148078660689724,
    0.4236684856687616,
    0.4325622561631607,
    0.4414852981630577,
    0.4504336971855032,
    0.4594035078775303,
    0.4683907582974173,
    0.4773914542472655,
    0.4864015836506502,
    0.4954171209689973,
    0.5044340316502417,
    0.5134482766032377,
    0.5224558166913167,
    0.5314526172383208,
    0.5404346525403849,
    0.5493979103766972,
    0.5583383965124314,
    0.5672521391870222,
    0.5761351935809411,
    0.5849836462541291,
    0.5937936195492526,
    0.6025612759529649,
    0.6112828224083939,
    0.6199545145721097,
    0.6285726610088878,
    0.6371336273176413,
    0.6456338401819751,
    0.6540697913388968,
    0.6624380414593221,
    0.6707352239341151,
    0.6789580485595255,
    0.6871033051160131,
    0.6951678668345944,
    0.7031486937449871,
    0.7110428359000029,
    0.7188474364707993,
    0.7265597347077880,
    0.7341770687621900,
    0.7416968783634273,
    0.7491167073477523,
    0.7564342060337386,
    0.7636471334404891,
    0.7707533593446514,
    0.7777508661725849,
    0.7846377507242818,
    0.7914122257259034,
    0.7980726212080798,
    0.8046173857073919,
    0.8110450872887550,
    0.8173544143867162,
    0.8235441764639875,
    0.8296133044858474,
    0.8355608512093652,
    0.8413859912867303,
    0.8470880211822968,
    0.8526663589032990,
    0.8581205435445334,
    0.8634502346476508,
    0.8686552113760616,
    0.8737353715068081,
    0.8786907302411250,
    0.8835214188357692,
    0.8882276830575707,
    0.8928098814640207,
    0.8972684835130879,
    0.9016040675058185,
    0.9058173183656508,
    0.9099090252587376,
    0.9138800790599416,
    0.9177314696695282,
    0.9214642831859411,
    0.9250796989403991,
    0.9285789863994010,
    0.9319635019415643,
    0.9352346855155568,
    0.9383940571861993,
    0.9414432135761304,
    0.9443838242107182,
    0.9472176277741918,
    0.9499464282852282,
    0.9525720912004834,
    0.9550965394547873,
    0.9575217494469370,
    0.9598497469802043,
    0.9620826031668507,
    0.9642224303060783,
    0.9662713777449607,
    0.9682316277319895,
    0.9701053912729269,
    0.9718949039986892,
    0.9736024220549734,
    0.9752302180233160,
    0.9767805768831932,
    0.9782557920246753,
    0.9796581613210076,
    0.9809899832703159,
    0.9822535532154261,
    0.9834511596505429,
    0.9845850806232530,
    0.9856575802399989,
    0.9866709052828243,
    0.9876272819448033,
    0.9885289126911557,
    0.9893779732525968,
    0.9901766097569984,
    0.9909269360049311,
    0.9916310308941294,
    0.9922909359973702,
    0.9929086532976777,
    0.9934861430841844,
    0.9940253220113651,
    0.9945280613237534,
    0.9949961852476154,
    0.9954314695504363,
    0.9958356402684387,
    0.9962103726017252,
    0.9965572899760172,
    0.9968779632693499,
    0.9971739102014799,
    0.9974465948831872,
    0.9976974275220812,
    0.9979277642809907,
    0.9981389072844972,
    0.9983321047686901,
    0.9985085513687731,
    0.9986693885387259,
    0.9988157050968516,
    0.9989485378906924,
    0.9990688725744943,
    0.9991776444921379,
    0.9992757396582338,
    0.9993639958299003,
    0.9994432036616085,
    0.9995141079353859,
    0.9995774088586188,
    0.9996337634216871,
    0.9996837868076957,
    0.9997280538466377,
    0.9997671005064359,
    0.9998014254134544,
    0.9998314913952471,
    0.9998577270385304,
    0.9998805282555989,
    0.9999002598526793,
    0.9999172570940037,
    0.9999318272557038,
    0.9999442511639580,
    0.9999547847121726,
    0.9999636603523446,
    0.9999710885561258,
    0.9999772592414866,
    0.9999823431612708,
    0.9999864932503106,
    0.9999898459281599,
    0.9999925223548691,
    0.9999946296375997,
    0.9999962619864214,
    0.9999975018180320,
    0.9999984208055542,
    0.9999990808746198,
    0.9999995351446231,
    0.9999998288155155
};

#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: structs.h,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#ifndef __STRUCTS_H__
#define __STRUCTS_H__

#ifdef __cplusplus
extern "C" {
#endif

#ifdef SBR_DEC
#include "sbr_dec.h"
#endif

#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

/* used to save the prediction state */
typedef struct {
    real_t r[2];
    real_t KOR[2];
    real_t VAR[2];
} pred_state;

typedef struct
{
    uint16_t n;
    uint16_t ifac[15];
    complex_t *work;
    complex_t *tab;
} cfft_info;

typedef struct {
    uint16_t N;
    cfft_info *cfft;
    complex_t *sincos;
    complex_t *Z1;
} mdct_info;

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;

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 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];

    /* extra added values */
    uint8_t num_front_channels;
    uint8_t num_side_channels;
    uint8_t num_back_channels;
    uint8_t num_lfe_channels;
    uint8_t sce_channel[16];
    uint8_t cpe_channel[16];
} 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;

    /* maximum of 16 PCEs */
    program_config pce[16];
} 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[MAX_SFB];
    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[MAX_SFB];
} 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;

#ifdef SSR_DEC
typedef struct
{
    uint8_t max_band;

    uint8_t adjust_num[4][8];
    uint8_t alevcode[4][8][8];
    uint8_t aloccode[4][8][8];
} ssr_info;
#endif

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[52];

    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;
    int16_t scale_factors[8][51];

    uint8_t ms_mask_present;
    uint8_t ms_used[MAX_WINDOW_GROUPS][MAX_SFB];

    uint8_t noise_used;

    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 SSR_DEC
    ssr_info ssr;
#endif

#ifdef ERROR_RESILIENCE
    /* ER HCR data */
    uint16_t length_of_reordered_spectral_data;
    uint8_t length_of_longest_codeword;
    /* ER RLVC data */
    uint8_t sf_concealment;
    uint8_t rev_global_gain;
    uint16_t length_of_rvlc_sf;
    uint16_t dpcm_noise_nrg;
    uint8_t sf_escapes_present;
    uint8_t length_of_rvlc_escapes;
    uint16_t dpcm_noise_last_position;
#endif
} ic_stream; /* individual channel stream */

typedef struct
{
    uint8_t ele_id;

    uint8_t channel;
    int16_t paired_channel;

    uint8_t element_instance_tag;
    uint8_t common_window;

    ic_stream ics1;
    ic_stream ics2;
} element; /* syntax element (SCE, CPE, LFE) */

typedef struct mp4AudioSpecificConfig
{
    /* Audio Specific Info */
    uint8_t objectTypeIndex;
    uint8_t samplingFrequencyIndex;
    uint32_t samplingFrequency;
    uint8_t channelsConfiguration;

    /* GA Specific Info */
    uint8_t frameLengthFlag;
    uint8_t dependsOnCoreCoder;
    uint16_t coreCoderDelay;
    uint8_t extensionFlag;
    uint8_t aacSectionDataResilienceFlag;
    uint8_t aacScalefactorDataResilienceFlag;
    uint8_t aacSpectralDataResilienceFlag;
    uint8_t epConfig;

    int8_t sbr_present_flag;
} mp4AudioSpecificConfig;

typedef struct faacDecConfiguration
{
    uint8_t defObjectType;
    uint32_t defSampleRate;
    uint8_t outputFormat;
    uint8_t downMatrix;
} faacDecConfiguration, *faacDecConfigurationPtr;

typedef struct faacDecFrameInfo
{
    uint32_t bytesconsumed;
    uint32_t samples;
    uint8_t channels;
    uint8_t error;
    uint32_t samplerate;

    /* multichannel configuration */
    uint8_t num_front_channels;
    uint8_t num_side_channels;
    uint8_t num_back_channels;
    uint8_t num_lfe_channels;
    uint8_t channel_position[MAX_CHANNELS];
} faacDecFrameInfo;

typedef struct
{
    uint8_t adts_header_present;
    uint8_t adif_header_present;
    uint8_t sf_index;
    uint8_t object_type;
    uint8_t channelConfiguration;
#ifdef ERROR_RESILIENCE
    uint8_t aacSectionDataResilienceFlag;
    uint8_t aacScalefactorDataResilienceFlag;
    uint8_t aacSpectralDataResilienceFlag;
#endif
    uint16_t frameLength;
    uint16_t samplesLeft;
    uint8_t postSeekResetFlag;

    uint32_t frame;

    uint8_t downMatrix;
    uint8_t first_syn_ele;
    uint8_t last_syn_ele;
    uint8_t has_lfe;
    uint8_t fr_channels;
    uint8_t fr_ch_ele;

    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_out[MAX_CHANNELS];

#ifdef SBR_DEC
    int8_t sbr_present_flag;

    real_t *time_out2[MAX_CHANNELS];

    uint8_t sbr_used[32];

    sbr_info *sbr[32];
#endif

#ifdef SSR_DEC
    real_t *ssr_overlap[MAX_CHANNELS];
    real_t *prev_fmd[MAX_CHANNELS];
    real_t ipqf_buffer[MAX_CHANNELS][4][96/4];
#endif

#ifdef MAIN_DEC
    pred_state *pred_stat[MAX_CHANNELS];
#endif
#ifdef LTP_DEC
    real_t *lt_pred_stat[MAX_CHANNELS];
#endif

#ifndef FIXED_POINT
#if POW_TABLE_SIZE
    real_t *pow2_table;
#endif
#endif

    /* Program Config Element */
    uint8_t pce_set;
    program_config pce;
    uint8_t channel_element[MAX_CHANNELS];
    uint8_t internal_channel[MAX_CHANNELS];

    /* Configuration data */
    faacDecConfiguration config;
} faacDecStruct, *faacDecHandle;



#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
[...1921 lines suppressed...]
        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"));
    }
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: syntax.h,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#ifndef __SYNTAX_H__
#define __SYNTAX_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "decoder.h"
#include "drc.h"
#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_FIL            0
#define EXT_FILL_DATA      1
#define EXT_DATA_ELEMENT   2
#define EXT_DYNAMIC_RANGE 11
#define ANC_DATA           0

/* 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 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 NOISE_HCB      13
#define INTENSITY_HCB2 14
#define INTENSITY_HCB  15

static uint32_t sample_rates[] =
{
    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000,
    12000, 11025, 8000
};

int8_t GASpecificConfig(bitfile *ld, mp4AudioSpecificConfig *mp4ASC,
                        program_config *pce);

uint8_t adts_frame(adts_header *adts, bitfile *ld);
void get_adif_header(adif_header *adif, bitfile *ld);


/* static functions */
static uint8_t single_lfe_channel_element(faacDecHandle hDecoder,
                                          element *sce, bitfile *ld,
                                          int16_t *spec_data);
static uint8_t channel_pair_element(faacDecHandle hDecoder, element *cpe,
                                    bitfile *ld, int16_t *spec_data1,
                                    int16_t *spec_data2);
static uint8_t coupling_channel_element(faacDecHandle hDecoder, bitfile *ld);
static uint16_t data_stream_element(faacDecHandle hDecoder, bitfile *ld);
static uint8_t program_config_element(program_config *pce, bitfile *ld);
static uint8_t fill_element(faacDecHandle hDecoder, bitfile *ld, drc_info *drc
#ifdef SBR_DEC
                            ,uint8_t sbr_ele
#endif
                            );
static uint8_t individual_channel_stream(faacDecHandle hDecoder, element *ele,
                                         bitfile *ld, ic_stream *ics, uint8_t scal_flag,
                                         int16_t *spec_data);
static uint8_t ics_info(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld,
                        uint8_t common_window);
static uint8_t section_data(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld);
static uint8_t scale_factor_data(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld);
static void gain_control_data(bitfile *ld, ic_stream *ics);
static uint8_t spectral_data(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld,
                             int16_t *spectral_data);
static uint16_t extension_payload(bitfile *ld, drc_info *drc, uint16_t count);
#ifdef ERROR_RESILIENCE
uint8_t reordered_spectral_data(faacDecHandle hDecoder, ic_stream *ics,
                                bitfile *ld, int16_t *spectral_data);
#endif
static uint8_t pulse_data(ic_stream *ics, pulse_info *pul, bitfile *ld);
static void tns_data(ic_stream *ics, tns_info *tns, bitfile *ld);
static void ltp_data(faacDecHandle hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld);
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

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: tns.c,v 1.1 2003/08/30 22:30:23 arpi Exp $
**/

#include "common.h"
#include "structs.h"

#include "syntax.h"
#include "tns.h"

#ifdef FIXED_POINT
static real_t tns_coef_0_3[] =
{
    0x0, 0x6F13013, 0xC8261BA, 0xF994E02,
    0xF03E3A3A, 0xF224C28C, 0xF5B72457, 0xFA8715E3,
    0xF90ECFED, 0xF37D9E46, 0xF066B1FE, 0xF066B1FE,
    0xF03E3A3A, 0xF224C28C, 0xF5B72457, 0xFA8715E3
};
static real_t tns_coef_0_4[] =
{
    0x0, 0x3539B35, 0x681FE48, 0x9679182,
    0xBE3EBD4, 0xDDB3D74, 0xF378709, 0xFE98FCA,
    0xF011790B, 0xF09C5CB7, 0xF1AD6942, 0xF33B524A,
    0xF5388AEB, 0xF793BBDF, 0xFA385AA9, 0xFD0F5CAB
};
static real_t tns_coef_1_3[] =
{
    0x0, 0x6F13013, 0xF5B72457, 0xFA8715E3,
    0xF994E02, 0xC8261BA, 0xF5B72457, 0xFA8715E3,
    0xF90ECFED, 0xF37D9E46, 0xF5B72457, 0xFA8715E3,
    0xF37D9E46, 0xF90ECFED, 0xF5B72457, 0xFA8715E3
};
static real_t tns_coef_1_4[] =
{
    0x0, 0x3539B35, 0x681FE48, 0x9679182,
    0xF5388AEB, 0xF793BBDF, 0xFA385AA9, 0xFD0F5CAB,
    0xFE98FCA, 0xF378709, 0xDDB3D74, 0xBE3EBD4,
    0xF5388AEB, 0xF793BBDF, 0xFA385AA9, 0xFD0F5CAB
};
#else
#ifdef _MSC_VER
#pragma warning(disable:4305)
#pragma warning(disable:4244)
#endif
static real_t tns_coef_0_3[] =
{
    0.0, 0.4338837391, 0.7818314825, 0.9749279122,
    -0.9848077530, -0.8660254038, -0.6427876097, -0.3420201433,
    -0.4338837391, -0.7818314825, -0.9749279122, -0.9749279122,
    -0.9848077530, -0.8660254038, -0.6427876097, -0.3420201433
};
static real_t tns_coef_0_4[] =
{
    0.0, 0.2079116908, 0.4067366431, 0.5877852523,
    0.7431448255, 0.8660254038, 0.9510565163, 0.9945218954,
    -0.9957341763, -0.9618256432, -0.8951632914, -0.7980172273,
    -0.6736956436, -0.5264321629, -0.3612416662, -0.1837495178
};
static real_t tns_coef_1_3[] =
{
    0.0, 0.4338837391, -0.6427876097, -0.3420201433,
    0.9749279122, 0.7818314825, -0.6427876097, -0.3420201433,
    -0.4338837391, -0.7818314825, -0.6427876097, -0.3420201433,
    -0.7818314825, -0.4338837391, -0.6427876097, -0.3420201433
};
static real_t tns_coef_1_4[] =
{
    0.0, 0.2079116908, 0.4067366431, 0.5877852523,
    -0.6736956436, -0.5264321629, -0.3612416662, -0.1837495178,
    0.9945218954, 0.9510565163, 0.8660254038, 0.7431448255,
    -0.6736956436, -0.5264321629, -0.3612416662, -0.1837495178
};
#endif


/* 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);
            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, ics->max_sfb)];
            end = ics->swb_offset[min(top, 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);
            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, ics->max_sfb)];
            end = ics->swb_offset[min(top, 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;
    real_t tmp2[TNS_MAX_ORDER+1], b[TNS_MAX_ORDER+1];

    /* Conversion to signed integer */
    for (i = 0; i < order; i++)
    {
        if (coef_compress == 0)
        {
            if (coef_res_bits == 3)
            {
                tmp2[i] = tns_coef_0_3[coef[i]];
            } else {
                tmp2[i] = tns_coef_0_4[coef[i]];
            }
        } else {
            if (coef_res_bits == 3)
            {
                tmp2[i] = tns_coef_1_3[coef[i]];
            } else {
                tmp2[i] = tns_coef_1_4[coef[i]];
            }
        }
    }

    /* Conversion to LPC coefficients */
    a[0] = COEF_CONST(1.0);
    for (m = 1; m <= order; m++)
    {
        for (i = 1; i < m; i++) /* loop only while i<m */
            b[i] = a[i] + MUL_C_C(tmp2[m-1], a[m-i]);

        for (i = 1; i < m; i++) /* loop only while i<m */
            a[i] = b[i];

        a[m] = tmp2[m-1]; /* changed */
    }
}

static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc,
                          uint8_t order)
{
    /*
     - Simple all-pole filter of order "order" defined by
       y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order)
     - The state variables of the filter are initialized to zero every time
     - The output data is written over the input data ("in-place operation")
     - An input vector of "size" samples is processed and the index increment
       to the next data sample is given by "inc"
    */

    uint8_t j;
    uint16_t i;
    real_t y, state[TNS_MAX_ORDER];

    for (i = 0; i < order; i++)
        state[i] = 0;

    for (i = 0; i < size; i++)
    {
        y = *spectrum;

        for (j = 0; j < order; j++)
            y -= MUL_R_C(state[j], lpc[j+1]);

        for (j = order-1; j > 0; j--)
            state[j] = state[j-1];

        state[0] = y;
        *spectrum = y;
        spectrum += inc;
    }
}

static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc,
                          uint8_t order)
{
    /*
     - Simple all-zero filter of order "order" defined by
       y(n) =  x(n) + a(2)*x(n-1) + ... + a(order+1)*x(n-order)
     - The state variables of the filter are initialized to zero every time
     - The output data is written over the input data ("in-place operation")
     - An input vector of "size" samples is processed and the index increment
       to the next data sample is given by "inc"
    */

    uint8_t j;
    uint16_t i;
    real_t y, state[TNS_MAX_ORDER];

    for (i = 0; i < order; i++)
        state[i] = REAL_CONST(0.0);

    for (i = 0; i < size; i++)
    {
        y = *spectrum;

        for (j = 0; j < order; j++)
            y += MUL_R_C(state[j], lpc[j+1]);

        for (j = order-1; j > 0; j--)
            state[j] = state[j-1];

        state[0] = *spectrum;
        *spectrum = y;
        spectrum += inc;
    }
}

--- NEW FILE ---
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
**  
** 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.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense at nero.com.
**
** $Id: tns.h,v 1.1 2003/08/30 22:30:23 arpi 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);


#ifdef __cplusplus
}
#endif
#endif



More information about the MPlayer-cvslog mailing list