/* $Id: dec_tf.c,v 1.45 1998/05/08 16:05:37 purnhage Exp $ */

/************************* MPEG-2 NBC Audio Decoder **************************
 *                                                                           *
 "This software module was originally developed by 
 Fraunhofer Gesellschaft IIS / University of Erlangen (UER) in the course of 
 development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 
 14496-1,2 and 3. This software module is an implementation of a part of one or more 
 MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 
 Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio 
 standards free license to this software module or modifications thereof for use in 
 hardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4
 Audio standards. Those intending to use this software module in hardware or 
 software products are advised that this use may infringe existing patents. 
 The original developer of this software module and his/her company, the subsequent 
 editors and their companies, and ISO/IEC have no liability for use of this software 
 module or modifications thereof in an implementation. Copyright is not released for 
 non MPEG-2 NBC/MPEG-4 Audio conforming products.The original developer
 retains full right to use the code for his/her  own purpose, assign or donate the 
 code to a third party and to inhibit third party from using the code for non 
 MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must
 be included in all copies or derivative works." 
 Copyright(c)1996.
 *                                                                           *
 ****************************************************************************/

/* CREATED BY :  Bernhard Grill -- June-96  */

/* fixed bit stream handling: Heiko Purnhagen, Uni Hannover, 960705 */
/* 21-aug-96   HP    added DecTfInfo(), DecTfFree() */
/*                   renamed to dec_tf.c, adapted to new dec.h */
/* 26-aug-96   HP   updated to vm0_tf_02a */
/* 28-aug-96   NI   integrated NTT's VQ coder. */
/* 09-feb-97   TK   integrated NBC compliant post processing module. */
/* 18-apr-97   NI   integrated scalable coder. */
/* 28-may-97   HP   -nttDecLyr help */
/* 25-aug-97   NI   bugfix */
/* 23-oct-97   HP   merged Nokia's predictor 971013 & 971020 */
/* 08-apr-98   HP   removed LDFB */

/*******************************************************************************************
 *
 * Master module for T/F based codecs
 *
 ******************************************************************************************/
#include <memory.h>
#include <math.h>
#include <string.h>

#include "bitstream.h"
#include "dec.h"
#include "tf_main.h"
#include "common.h"
#include "block.h"

/* son_NBCpp */
#include "sony_local.h"

/* NTT VQ */ 
#include "ntt_conf.h"
#include "ntt_scale_conf.h"
#include "mat_def_ntt.h"

/* Long term predictor */
#include "all.h"
#include "nok_lt_prediction.h"
#include "ntt_nok_lt_predict_dec.h"
#include "ntt_nok_pred.h"

/* ---  AAC --- */
#include "aac.h"
#include "dec.h"
#include "huffdec2.h"
#include "resilience.h"
#include "buffers.h"
#include "concealment.h"

/* SAM BSAC */
#include "sam_dec.h"    /* YB : 970825 */

/* currently the psych module contains the sfb-width info 
   this should be moved into a separate file */
#include "psych.h"
CH_PSYCH_OUTPUT chpo_long[MAX_TIME_CHANNELS];
CH_PSYCH_OUTPUT chpo_short[MAX_TIME_CHANNELS][MAX_SHORT_WINDOWS];


static int     block_size_samples;      /* nr of samples per block in one! audio channel */
static int     med_win_in_long    = 2;  /* for NTT */
static int     short_win_in_long  = 8;

static int     max_ch;    /* no of of audio channels */

static double *spectral_line_vector[MAX_TF_LAYER][MAX_TIME_CHANNELS];
static double *time_sample_vector[MAX_TIME_CHANNELS];
static double *overlap_buffer[MAX_TIME_CHANNELS];

/* son_NBCpp */
static int    max_band[MAX_TIME_CHANNELS];
static double *spectral_line_vector_for_gc[MAX_TIME_CHANNELS];
static double *imdctBufForGC[MAX_TIME_CHANNELS];
static double **DBandSigBufForOverlapping[MAX_TIME_CHANNELS];
static double **DBandSigBuf[MAX_TIME_CHANNELS];
static GAINC  **gainInfo[MAX_TIME_CHANNELS];
static int    ssr_decoder_band = NBANDS;

static int frame_bits, frameNumBit;

static enum CH_CONFIG  channel_configuration = CHC_MONO; /* later f(encPara) */
static enum PP_MOD_SELECT pp_select = NONE;              /* later f(encPara) */
static QC_MOD_SELECT qc_select = MDCT_VALUES_16BIT; /* later f(encPara) */
static enum TF_MOD_SELECT tf_select = MDCT_UER;          /* later f(encPara) */
static enum TRANSPORT_STREAM transport_stream =  LENINFO_TSTREAM;  /* later f(encPara) */
static int scalOutSelect = 100;
static int lopLong = 0, lopShort = 0;
static float normBw=0.0F;
/* Variable bit switch for the NTT_VQ coder */
static enum NTT_VARBIT ntt_varbit = NTT_VARBIT_OFF;
/* Number of scalable layers to be decoded */
static int ntt_NSclLayDec;

/* BSAC scalable decode bitrate */
static int sam_DecBr;  /* YB : 970825 */

/* AAC shorter windows 960-480-120 */
static int useShortWindows=0;

/* Predictor type */
static PRED_TYPE pred_type = MONOPRED;

/* Nokia LTP for TwinVQ */
static Info ntt_info;
NOK_LT_PRED_STATUS *ntt_nok_lt_status[MAX_TIME_CHANNELS];


/********************************************************/
/* functions DecTfInfo() and DecTfFree()   HP 21-aug-96 */
/********************************************************/

#define PROGVER "t/f-based decoder core V5.0 20-nov-97"



/* DecTfInfo() */
/* Get info about t/f-based decoder core. */
char *DecTfInfo (FILE *helpStream)      /* in: print decPara help text to helpStream */
                                /*     if helpStream not NULL */
                                /* returns: core version string */
{
  if (helpStream != NULL) {
    fprintf(helpStream,
            PROGVER "\n"
            "decoder parameter string format:\n"
            "possible options:\n"
            "-qc_mdct16\n"
            "-qc_mdct16_960\n"
            "-qc_ntt\n"
            "-qc_aac_960\n"        
            "-qc_aac\n"
            "-aac_raw\n"
#ifdef VERSION2
            "     -lcw length_of_longest_codeword within bitstream\n"
            "     -hcr HCR within spectral data, length_of_longest_codeword and\n"
            "                                    length_of_spectral_data within bitstream\n"
            "     -tab error protection predefinition file\n"
#endif /*VERSION2*/
            "-aac_sca\n"
            "     -out <n>  select output layer for -aac_sca (n=0 :  base layer)\n"
            "     -lop <n long> <n short> <bandwidth> set lowpass line limits\n"
	    "-aac_bsac\n"
	    "-aac_ssr\n"
	    "-aac_core_bsac\n"
	    "-pred_ltp\n"
	    "-pred_nok_bwp\n"
	    "-nttDecLyr <n> (scalable, n=0: base layer)\n"
		"-bsacDecBr <n> (scalable, n=0: core codec if it is present, 16 <= n <= 64)\n"
	    "\n");
  }
	ConcealmentHelp(helpStream);
  return PROGVER;
}


/* DecTfFree() */
/* Free memory allocated by t/f-based decoder core. */

void DecTfFree ()
{
}


/*****************************************************************************************
 ***
 *** Function: DecTfInit
 ***
 *** Purpose:  Initialize the T/F-part and the macro blocks of the T/F part of the VM
 ***
 *** Description:
 *** 
 ***
 *** Parameters:
 ***
 ***
 *** Return Value:
 ***
 *** **** MPEG-4 VM ****
 ***
 ****************************************************************************************/
static Info** sfbInfo;
static char*  aacDebugString;
static long   sampling_rate_decoded;

void DecTfInit ( int               numChannel,       /* in: num audio channels */
                 float             fSample,          /* in: sampling frequancy [Hz] */
                 float             bitRate,          /* in: bit rate [bit/sec] */
                 char*             decPara,          /* in: decoder parameter string */
                 BsBitBuffer*      bitHeader,        /* in: header from bit stream */
                 int*              frameNumSample,   /* out: num samples per frame */
                 int*              delayNumSample,   /* out: encoder delay (num samples) */
                 char*             aacDebugStr,
                 HANDLE_RESILIENCE hResilience,         /* in: error resilience information handler */
                 HANDLE_BUFFER*    hVm,
                 HANDLE_BUFFER*    hHcrSpecData,
                 HANDLE_HCR*       hHcrInfo,
#ifdef VERSION2
                 char*             infoFileName,
                 char*             predFileName,
#endif
                 FRAME_DATA*       frameData,
                 HANDLE_EP_INFO*   hEPInfo )
{
  unsigned long ultmp;
  long          bit_rate_decoded;
  int           delay_samples_decoded;
  int           x; 
  int           i_ch;
  BsBitStream*  header_stream;
  char * ssrPara;
#if 0
  if (numChannel != 1)
    CommonExit(1,"DecTfInit: audio data has more than one channel (%d)",
               numChannel);
#endif

  header_stream = BsOpenBufferRead(bitHeader);
 

  *hVm          = CreateBuffer(VIRTUELL);
  *hHcrSpecData = CreateBuffer(AAC_MAX_INPUT_BUF_BITS);
#ifdef VERSION2
  *hHcrInfo     = CreateHcrInfo();
#endif /*VERSION2*/
  /* -----  Set qc_select ----- */
  if ( ( strstr(decPara, "-qc_aac")) ||
       ( strstr(decPara, "-qc_aac_960"))) {
    tf_select = MDCT_AAC;
    qc_select = AAC_QC;
  }

#ifdef VERSION2

 /* creates an handler with all the info to decode ep bitstreams */
  if( GetEPFlag ( hResilience ) )  
   *hEPInfo = CreateEPInfo( decPara, infoFileName, predFileName);

#endif 
 
  if (strstr(decPara, "-aac_bsac")) {  /* YB : 970825 */
    tf_select = MDCT_AAC;
    qc_select = AAC_BSAC;
    transport_stream = NO_SYNCWORD;
  }

  if( strstr( decPara, "-aac_raw" ) ) {
    fprintf(stderr," AAC-Main profile decoding\n");
    /* currently fix coded !!! */
    bit_rate_decoded = (long int )bitRate;
    sampling_rate_decoded = (long int)fSample;
    block_size_samples = 1024;
    med_win_in_long = 2;
    short_win_in_long = 8;
    delay_samples_decoded = 2048;
    channel_configuration = CHC_MONO;
    if (numChannel ==2){
      channel_configuration =CHC_DUAL;
    }

    qc_select = AAC_QC;
    tf_select = MDCT_AAC;
    transport_stream = AAC_RAWDATA_TSTREAM;
		ConcealmentParseCmdline(decPara);
  }

  if( ( ssrPara = strstr( decPara, "-aac_ssr" ) ) ) {
/*	sscanf(&ssrPara[8],"%d",&ssr_decoder_band); currently not supported */
	mc_info.profile = SSR_Profile;
	fprintf(stderr," AAC-SSR  %d band decoding\n",ssr_decoder_band);
  }
  else {
	mc_info.profile = Main_Profile;
  }



  if( strstr( decPara, "-aac_sca" )  ) {
    char * outLayNr;
    char * lopPara;
    /* currently fix coded !!! */
    fprintf(stderr," TF scaleable decoding OLD bitstream syntyx\n");
    bit_rate_decoded = (long int)bitRate;
    sampling_rate_decoded = (long int)fSample;
    block_size_samples = 960;
    med_win_in_long = 2;
    short_win_in_long = 8;
    delay_samples_decoded = 2048;
    channel_configuration = CHC_MONO;
    if (numChannel ==2){
      channel_configuration =CHC_DUAL;
    }
    qc_select = AAC_SCALEABLE;
    tf_select = MDCT_AAC;
    transport_stream = AAC_RAWDATA_TSTREAM;

    if ( ( lopPara = strstr ( decPara, "-lop"))) {
      sscanf(&lopPara[4],"%d%d%f",&lopLong,&lopShort,&normBw);
      if ((lopLong < 0 ) || (lopLong > 950)) {
        CommonExit(-1,"\n lopLong parameter out of range: %d", lopLong);
      }
      if ((lopShort < 0 ) || (lopShort > 110)) {
        CommonExit(-1,"\n lopShort parameter out of range: %d", lopShort);
      }
      if ((normBw < 0.0F) || (normBw > 1.0F)) {
        CommonExit(-1,"\n normalized bandwidth out of range: %f", lopShort);
      }
      fprintf(stderr,"lopLong=%d, lopShort=%d, normalized bandwidth=%3.2f\n", lopLong, lopShort, normBw);
    }
    if ( ( outLayNr = strstr( decPara, "-out") ) ){
      sscanf(&outLayNr[4],"%d",&scalOutSelect);
      if ( (scalOutSelect < 0 ) || ( scalOutSelect > 7 ) ){
        CommonExit(-1,"\n errorn in output layer select %d  ",scalOutSelect);
      } 
      fprintf(stderr,"\n for output layer nr. %d is selected ",scalOutSelect);
    }
    aacScaleableDecodeInit();
  }
  if( strstr( decPara, "-aac_sys" ) || strstr( decPara, "-aac_sys_bsac")) {
    unsigned int x;
    char * outLayNr;
    char * lopPara;
    /* currently fix coded !!! */
    fprintf(stderr," TF scaleable decoding NEW flexmux  bitstream syntyx\n");
    bit_rate_decoded = (long int)bitRate;
    sampling_rate_decoded = (long int)fSample;
    block_size_samples = ( frameData->od->ESDescriptor[0]->DecConfigDescr.audioSpecificConfig.specConf.TFSpecificConfig.frameLength.value ? 960:1024) ;
    med_win_in_long = 2;
    short_win_in_long = 8;
    delay_samples_decoded = 2048;
    channel_configuration = CHC_MONO;
    if (numChannel ==2){
      channel_configuration =CHC_DUAL;
    }
    qc_select = AAC_SCALEABLE;
    if(strstr( decPara, "-aac_sys_bsac"))
      qc_select = AAC_SCA_BSAC;
    tf_select = MDCT_AAC;
    transport_stream = AAC_RAWDATA_TSTREAM;

    if ( ( lopPara = strstr ( decPara, "-lop"))) {
      sscanf(&lopPara[4],"%d%d%f",&lopLong,&lopShort,&normBw);
      if ((lopLong < 0 ) || (lopLong > 950)) {
        CommonExit(-1,"\n lopLong parameter out of range: %d", lopLong);
      }
      if ((lopShort < 0 ) || (lopShort > 110)) {
        CommonExit(-1,"\n lopShort parameter out of range: %d", lopShort);
      }
      if ((normBw < 0.0F) || (normBw > 1.0F)) {
        CommonExit(-1,"\n normalized bandwidth out of range: %f", lopShort);
      }
      fprintf(stderr,"lopLong=%d, lopShort=%d, normalized bandwidth=%3.2f\n", lopLong, lopShort, normBw);
    }
    if ( ( outLayNr = strstr( decPara, "-out") ) ){
      sscanf(&outLayNr[4],"%d",&scalOutSelect);
      if ( (scalOutSelect < 0 ) || ( scalOutSelect > 7 ) ){
        CommonExit(-1,"\n errorn in output layer select %d  ",scalOutSelect);
      } 
      fprintf(stderr,"\n for output layer nr. %d is selected ",scalOutSelect);
    }
    aacScaleableDecodeInit();
    for ( x = 0; x < frameData->od->streamCount.value; x++ ){
      frameData->layer[x].bitBuf = BsAllocBuffer(6000);
    }
    frameData->tnsBevCore=0;     
    if( strstr( decPara, "-tnsBevCor" ) ) {
      fprintf(stderr,"\n DON'T calc tns on core spectrum");
      frameData->tnsBevCore=1;      
    }
  }
  
  if( strstr( decPara, "-aac_core_bsac" ) ) { /* SH : 971121 */
    char *lopPara;
    /* currently fix coded !!! */
    bit_rate_decoded = (long int)bitRate;
    sampling_rate_decoded = (long int)fSample;
    block_size_samples = 960;
    med_win_in_long = 2;
    short_win_in_long = 8;
    delay_samples_decoded = 2048;
    channel_configuration = CHC_MONO;
    if (numChannel ==2){
      channel_configuration =CHC_DUAL;
    }
    qc_select = AAC_SCA_BSAC;
    tf_select = MDCT_AAC;
    transport_stream = AAC_RAWDATA_TSTREAM;
    scalOutSelect = 1;
    aacScaleableDecodeInit();

    if ( ( lopPara = strstr ( decPara, "-lop") ) ) {
      sscanf(&lopPara[4],"%d%d%f",&lopLong,&lopShort,&normBw);
      if ((lopLong < 0 ) || (lopLong > 950)) {
        CommonExit(-1,"\n lopLong parameter out of range: %d", lopLong);
      }
      if ((lopShort < 0 ) || (lopShort > 110)) {
        CommonExit(-1,"\n lopShort parameter out of range: %d", lopShort);
      }
      if ((normBw < 0.0F) || (normBw > 1.0F)) {
        CommonExit(-1,"\n normalized bandwidth out of range: %f", lopShort);
      }
      fprintf(stderr,"lopLong=%d, lopShort=%d, normalized bandwidth=%3.2f\n", lopLong, lopShort, normBw);
    }
  }

  if( strstr( decPara, "-qc_ntt" ) ) {
    qc_select = NTT_VQ;
  }
  
  if( strstr( decPara, "-qc_mdct16" ) ) {
    qc_select = MDCT_VALUES_16BIT;
  }
  
  if( strstr( decPara, "-pred_ltp" ) )
    pred_type = NOK_LTP;
  if( strstr( decPara, "-pred_nok_bwp" ) )
    pred_type = NOK_BWP;

  /* ----- if no AAC_RAWDATA, get some header information -----*/
  if (transport_stream != AAC_RAWDATA_TSTREAM){
    BsGetBit( header_stream, &ultmp, 16 );
    if( ultmp != 0x1234 ) {
      CommonExit( 1,"Wrong Stream Header" );
    }
    BsGetBit( header_stream, &ultmp, 24 );
    bit_rate_decoded = ultmp;
    BsGetBit( header_stream, &ultmp, 24 );
    sampling_rate_decoded = ultmp;
    BsGetBit( header_stream, &ultmp, 16 );
    block_size_samples = ultmp;
    BsGetBit( header_stream, &ultmp, 16 );
    med_win_in_long = ultmp;
    BsGetBit( header_stream, &ultmp, 16 );
    short_win_in_long = ultmp;
    BsGetBit( header_stream, &ultmp, 16 );
    delay_samples_decoded = ultmp;
    BsGetBit( header_stream, &ultmp, 8 );
    channel_configuration = (enum CH_CONFIG)ultmp;
    BsGetBit( header_stream, &ultmp, 32 );
    tf_select = (enum TF_MOD_SELECT)ultmp;
    BsGetBit( header_stream, &ultmp, 32 );
    qc_select = (QC_MOD_SELECT)ultmp;
  }

  if(qc_select == AAC_BSAC) {   /* YB : 971115 */
    if (numChannel ==2){
      channel_configuration =CHC_DUAL;
    }
  }

  if (qc_select != NTT_VQ){
    if (numChannel > 2)
      CommonExit(1,"DecTfInit: audio data has more than one channel (%d)",
                 numChannel);
  }
  
  /* If short blocks, set blocksizeSample manually, 
     if encoder is up to date for 960s this should be 
     written/read to/from bitstreamheader */
  if (strstr(decPara, "-qc_aac_960")){
    useShortWindows=1;
    block_size_samples=960;
  }
  else
    useShortWindows=0;
  
  /* -- if AAC_RAWDATA, get "aacraw. "
     Note: you must have set -c -aac_raw for decoding  --- */
  /*
    if( transport_stream == AAC_RAWDATA_TSTREAM ) {
    BsGetBit( header_stream, &ultmp, 8 );
    BsGetBit( header_stream, &ultmp, 8 );
    BsGetBit( header_stream, &ultmp, 8 );
    BsGetBit( header_stream, &ultmp, 8 );
    BsGetBit( header_stream, &ultmp, 8 );
    BsGetBit( header_stream, &ultmp, 8 );
    }
  */

  if (qc_select == NTT_VQ){
    int iscl;
    /* NTT_VQ supports both LENINFO_STREAM and NO_SYNCWORD. */
    BsGetBit(header_stream, &ultmp, 2);
    transport_stream = (enum TRANSPORT_STREAM)ultmp;
    /* If the ntt_varbit is off, number of bits
       per frame should be in the header. */
    BsGetBit(header_stream, &ultmp, 1);
    ntt_varbit = (enum NTT_VARBIT)ultmp;
    if (ntt_varbit == NTT_VARBIT_OFF){
      BsGetBit(header_stream, &ultmp, 32);
      frameNumBit = ultmp;
    }
    /* long term predictor */
    BsGetBit(header_stream, &ultmp, 1);
    ntt_LTP_SW = ultmp;
    /* header for scalable coder */
    BsGetBit(header_stream, &ultmp, ntt_NSclLay_BITS);
    ntt_NSclLay = (int)ultmp;
    for (iscl=0; iscl<ntt_NSclLay; iscl++){
      BsGetBit(header_stream, &ultmp, ntt_IBPS_BITS_SCL);
      ntt_IBPS_SCL[iscl] = (int)ultmp;
      BsGetBit(header_stream, &ultmp, ntt_BLIM_BITS);
      ntt_BAND_UPPER_ID_SCL[iscl] = (int)ultmp;
      BsGetBit(header_stream, &ultmp, ntt_BLIM_BITS);
      ntt_BAND_LOWER_ID_SCL[iscl] = (int)ultmp;
    }
  }

  BsClose(header_stream);

  /* currently initializes the scale factor band table; should be moved to a separate module */
  if( qc_select != NTT_VQ ){
    double *p_tmp[8];
   
    EncTf_psycho_acoustic( sampling_rate_decoded , 1, p_tmp, 0, qc_select,block_size_samples, chpo_long, chpo_short );
  }
 
  /* set the return values */
  *frameNumSample = block_size_samples;
  *delayNumSample = delay_samples_decoded;

  /* calc. no of audio channels */
  if (qc_select != NTT_VQ){
    /* table to get the no. of audio channels depending on the value of channel_configuration */
    static int  chc_2_chan_nr[CHC_MODES] = { 1, 2, 2, 5 };

    max_ch  = chc_2_chan_nr[channel_configuration];
  }
  else{
    max_ch = numChannel;
  }

  for (x=0;x<MAX_TF_LAYER;x++){
    for (i_ch=0; i_ch<max_ch; i_ch++){
      spectral_line_vector[x][i_ch] = (double*)calloc(block_size_samples,
                                                      sizeof(double));
    }
  }
  for (i_ch=0; i_ch<max_ch; i_ch++){
    time_sample_vector[i_ch] = (double*)calloc(block_size_samples,
                                               sizeof(double));
  }

  frame_bits = (int)((double)bit_rate_decoded*(double)block_size_samples*(double)max_ch/(double)sampling_rate_decoded);
  
  /* son_NBCpp */
  {
    int i_ch; /* added 971010 YT*/
    int band;
    for (i_ch=0; i_ch<max_ch; i_ch++){ /* added 971010 YT*/
      
      spectral_line_vector_for_gc[i_ch] = (double *)calloc(block_size_samples, sizeof(double));
      imdctBufForGC[i_ch] = (double *)calloc(block_size_samples*2, sizeof(double));
      DBandSigBufForOverlapping[i_ch] = (double **)calloc(NBANDS, sizeof(double *));
      DBandSigBuf[i_ch] = (double **)calloc(NBANDS, sizeof(double *));
      gainInfo[i_ch] = (GAINC **)calloc(NBANDS, sizeof(GAINC *));
      for (band = 0; band < NBANDS; band++) {
        DBandSigBufForOverlapping[i_ch][band] =
          (double *)calloc(block_size_samples/NBANDS*2, sizeof(double));
        DBandSigBuf[i_ch][band] =
          (double *)calloc(block_size_samples/NBANDS, sizeof(double));
        gainInfo[i_ch][band] = (GAINC *)calloc(short_win_in_long, sizeof(GAINC));
      }
    } /* end of for(i_ch...)*/
  }
  
  /* initialize inverse Q&C */
  switch(qc_select){
  case NTT_VQ:
    {
      int med_win_in_long_dmy, short_win_in_long_dmy;
      int frameNumSample_dmy, delayNumSample_dmy;
      int iscl;
      float t_bit_rate_scl;
      char *p_ctmp;

      /* bitrate control */
      t_bit_rate_scl = 0.;
      for (iscl=0; iscl<ntt_NSclLay; iscl++){
        t_bit_rate_scl += (float)ntt_IBPS_SCL[iscl]*1000.;
      }
      /* initalization of base decoder */
      ntt_TfInit((float)fSample, (float)bitRate, t_bit_rate_scl, max_ch,
                 &frameNumSample_dmy, &delayNumSample_dmy,
                 &med_win_in_long_dmy, &short_win_in_long_dmy);

      ntt_nok_lt_pred_dec_init(&ntt_info);
    
      /* initialization of scalable coders */
      ntt_TBITS_FR_SCL = 0;
      /* set number of scalable layers to be decoded */
      ntt_NSclLayDec = ntt_NSclLay;
      if( ( p_ctmp=strstr( decPara, "-nttDecLyr " ) ) ) {
        if(sscanf(p_ctmp+11, "%d", &ntt_NSclLayDec) == 0){
          CommonExit(1, "Encode: parameter of -nttDecLyr switch not found");
        }
      }
      if (ntt_NSclLayDec > ntt_NSclLay) ntt_NSclLayDec = ntt_NSclLay;
      for (iscl=0; iscl<ntt_NSclLay; iscl++){
        ntt_scale_init(iscl, ntt_NSclLayDec);
        ntt_TBITS_FR_SCL += ntt_NBITS_FR_SCL[iscl];
        if( strstr( decPara, "-nttSclMsg" ) ) {
          ntt_scale_message(iscl);
        }
      }
      if (ntt_NSclLay > 0){
        fprintf(stderr, "<<>><<>> NUMBER OF LAYERS TO BE DECODED: %d\n",
                ntt_NSclLayDec);
      }
      break;
    }

  case AAC_QC:
    {
      aacDebugString = aacDebugStr;
      aac_decode_init ( sampling_rate_decoded,
                        aacDebugStr,
                        block_size_samples,
                        &sfbInfo,
                        pred_type );
      break;    /* HP 970407 */
    }

  case AAC_SCALEABLE:
    {
      int med_win_in_long_dmy, short_win_in_long_dmy;
      int frameNumSample_dmy, delayNumSample_dmy;

      aacDebugString = aacDebugStr;
      aac_decode_init ( sampling_rate_decoded,
                        aacDebugStr, 
                        block_size_samples, 
                        &sfbInfo,
                        pred_type );
      if (frameData && 
          (frameData->od->ESDescriptor[0]->DecConfigDescr.audioSpecificConfig.specConf.TFSpecificConfig.TFCodingType.value==2)){
        ntt_TfInit((float)fSample, (float)(frameData->od->ESDescriptor[0]->DecConfigDescr.avgBitrate.value), 0.0, 1,
                   &frameNumSample_dmy, &delayNumSample_dmy,
                   &med_win_in_long_dmy, &short_win_in_long_dmy);
      }
      break;
    }

  case AAC_BSAC:  /* YB : 970825 */
  case AAC_SCA_BSAC: /* SH : 971121 */
    {
	  int med_win_in_long_dmy, short_win_in_long_dmy;
	  int frameNumSample_dmy, delayNumSample_dmy;
      char *p_ctmp;

      sam_DecBr = bit_rate_decoded/1000/numChannel;     /* YB : 971115 */
      if( (p_ctmp=strstr( decPara, "-bsacDecBr " )) ) {
        if(sscanf(p_ctmp+11, "%d", &sam_DecBr) == 0){
          CommonExit(1, "Encode: parameter of -bsacDecBr switch not found");
        }
      }
      if(qc_select == AAC_SCA_BSAC && sam_DecBr < 16) {
        fprintf(stderr, "core codec used\n");
        scalOutSelect = 0;
      } else {
        if(sam_DecBr > bit_rate_decoded/1000/numChannel) {
          fprintf(stderr, ">> BSAC Warning : inappropriated bsacDecBr value\n");
          fprintf(stderr, ">> BSAC Warning : using encoded bit rate\n");
          sam_DecBr = bit_rate_decoded/1000/numChannel;
        }
        fprintf(stderr, ">> BSAC Decoding BitRate: %d kbits/s/ch\n", sam_DecBr);
      }

      sam_decode_init(sampling_rate_decoded, block_size_samples);       /* HP 971105 */

      if(qc_select == AAC_SCA_BSAC) {
        aacDebugString = aacDebugStr;
        aac_decode_init(sampling_rate_decoded,aacDebugStr, block_size_samples, &sfbInfo, pred_type);
        if (frameData->od->ESDescriptor[0]->DecConfigDescr.audioSpecificConfig.specConf.TFSpecificConfig.TFCodingType.value==2){
        ntt_TfInit((float)fSample, (float)(frameData->od->ESDescriptor[0]->DecConfigDescr.avgBitrate.value), 0.0, 1,
                   &frameNumSample_dmy, &delayNumSample_dmy,
                   &med_win_in_long_dmy, &short_win_in_long_dmy);
        }
      }
      break;
    }

  default:
    CommonExit(-1,"\nerror in switch");
  }
  for (i_ch=0; i_ch<max_ch; i_ch++){
    overlap_buffer[i_ch] = (double*)calloc(block_size_samples,
                                           sizeof(double));
  }
  
}

/*****************************************************************************************
 ***
 *** Function:    DecTfFrame
 ***
 *** Purpose:     processes a block of time signal input samples into a bitstream
 ***              based on T/F encoding 
 ***
 *** Description:
 *** 
 ***
 *** Parameters:
 ***
 ***
 *** Return Value:  returns the number of used bits
 ***
 *** **** MPEG-4 VM ****
 ***
 ****************************************************************************************/

void DecTfFrame ( BsBitBuffer*      bitBuf,           /* in: bit stream frame */
                  float**           sampleBuf,        /* out: frameNumSample audio samples */
                  int*              usedNumBit,       /* out: num bits used for this frame */
                  int               numChannels,
                  HANDLE_RESILIENCE hResilience,        /* in: handler for error resilience info */
                  HANDLE_BUFFER     hVm,
                  HANDLE_BUFFER     hHcrSpecData,
                  HANDLE_HCR        hHcrInfo ,
                  FRAME_DATA*       frameData,
                  HANDLE_EP_INFO    hEPInfo )
     
{
  WINDOW_TYPE         block_type[MAX_TIME_CHANNELS];
  unsigned long       ultmp;
  int                 decoded_bits = 0;
  int                 i_ch;  /* added 971010 YT */
  BsBitStream*        fixed_stream;
  /* son_NBCpp */
  BsBitStream*        gc_stream[MAX_TIME_CHANNELS];
  BsBitStream*        gc_WRstream[MAX_TIME_CHANNELS];
  BsBitBuffer*        gcBitBuf[MAX_TIME_CHANNELS];     /* bit buffer for gain_control_data() */
  static Window_shape windowShape =  WS_FHG;
  int                 curBitPos;
  int                 i;  
  static Window_shape prev_windowShape[2]={WS_FHG, WS_FHG}; /* YB : 971113 */
  
  /* VQ: Variables for NTT_VQ decoder */
  ntt_INDEX           index;
  ntt_INDEX           index_scl;
  static int          InitFlag = 1;

  ResetReadBitCnt ( hVm );
  fixed_stream = BsOpenBufferRead(bitBuf);
  /* son_NBCpp */
  for(i_ch=0;i_ch<MAX_TIME_CHANNELS;i_ch++){
    gcBitBuf[i_ch] = BsAllocBuffer(4096);
    gc_WRstream[i_ch] = BsOpenBufferWrite(gcBitBuf[i_ch]);
    gc_stream[i_ch] = BsOpenBufferRead(gcBitBuf[i_ch]);
  } /* for i_ch...*/
  
  /* get sync word */
  /* a 7 bit alternative to the strange MPEG-1 audio syncword */
  /* === KEMAL: syncword makes problems with qc_aac, because it
     needs byte_alignment, which would be done in aac_decode_frame() === */
  if (qc_select!=AAC_SCALEABLE) { 
    if( (transport_stream != AAC_RAWDATA_TSTREAM) &&
        (transport_stream != NO_TSTREAM) &&
        (transport_stream != NO_SYNCWORD) ) {
      BsGetBit( fixed_stream, &ultmp, 7 );     
      decoded_bits += 7;
      if( ultmp != 0x6e ) {
        CommonExit( 1," Wrong Syncword %d ", ultmp);
      }
    }
  }

  /* inverse Q&C */
  switch(qc_select) {

  case MDCT_VALUES_16BIT: /* debug option unpack MDCT output values */
    {
      double scal;
      unsigned long iscal;
      int i;

      /* get window type */
      BsGetBit( fixed_stream, &ultmp, 4 );
      decoded_bits += 4;
      block_type[MONO_CHAN] = (WINDOW_TYPE)ultmp;
      fprintf(stderr,"\nblocktype %ld",ultmp);
      /* get block scaling factor */
      BsGetBit( fixed_stream, &iscal, 12 );
      decoded_bits += 12;

      scal = pow( 2.0, -(((int)iscal)-2048) );
      for( i=0; i<block_size_samples; i++ ) {
        BsGetBit( fixed_stream, &ultmp, 16 );
        decoded_bits += 16;
        spectral_line_vector[0][MONO_CHAN][i] = (double)(((int)ultmp)-32768) * scal;
      }
    }
    break;
   
  case AAC_QC:
    {
      byte max_sfb[Winds];
      byte dummy[2][MAXBANDS]; /* needed for PNS in scalaeble case ! */

      decoded_bits += aac_decode_frame ( fixed_stream,
                                         gc_WRstream,
                                         spectral_line_vector[0], 
                                         &(block_type[MONO_CHAN]), 
                                         &windowShape,
                                         NOT_SCALEABLE,max_sfb,numChannels,0,sfbInfo,dummy,
                                         hResilience,
                                         hVm,
                                         hHcrSpecData,
                                         hHcrInfo, hEPInfo ); 
    }   
    break;

  case AAC_SCA_BSAC: /* SH : 971121 */
  case AAC_SCALEABLE:
    {
      if  (frameData==NULL){
        aacScaleableDecode( fixed_stream, 
                            gc_WRstream,
                            &block_type[MONO_CHAN], 
                            &decoded_bits, 
                            spectral_line_vector, 
                            block_size_samples, 
                            scalOutSelect ,
                            sfbInfo,
                            numChannels,
                            sampling_rate_decoded,
                            lopLong, 
                            lopShort, 
                            normBw,
                            &windowShape,
                            qc_select, 
                            sam_DecBr,
                            hResilience,
                            hVm,
                            hHcrSpecData,
                            hHcrInfo ,
                            frameData, hEPInfo);
      } else {
        aacScaleableFlexMuxDecode( fixed_stream, 
                            gc_WRstream,
                            &block_type[MONO_CHAN], 
                            &decoded_bits, 
                            spectral_line_vector, 
                            block_size_samples, 
                            scalOutSelect ,
                            sfbInfo,
                            numChannels,
                            sampling_rate_decoded,
                            lopLong, 
                            lopShort, 
                            normBw,
                            &windowShape,
                            qc_select, 
                            sam_DecBr,
                            hResilience,
                            hVm,
                            hHcrSpecData,
                            hHcrInfo ,
                            frameData, hEPInfo);
      }
    }
      break;
      
    case AAC_BSAC:  /* YB : 970825 */
        {
          decoded_bits += sam_decode_frame ( fixed_stream,
                                             gc_WRstream,     /* YB : 971106 */
                                             sam_DecBr,
                                             spectral_line_vector[0], 
                                             (int*)&(block_type[MONO_CHAN]), 
                                             &windowShape );
    }
    break;
  
  case NTT_VQ:
    {
      int ntt_available_bits;

      /* get block type */
      BsGetBit( fixed_stream, &ultmp, 4);
      block_type[MONO_CHAN] = (WINDOW_TYPE)ultmp;
      decoded_bits += 4;
      if (block_type[MONO_CHAN] >= 9) block_type[MONO_CHAN] = ONLY_LONG_WINDOW;
    
      /* if ntt_varbit is on, get the available bits */
      if (ntt_varbit == NTT_VARBIT_ON){
        BsGetBit(fixed_stream, &ultmp, 12);
        ntt_available_bits = ultmp;
        decoded_bits += 12;
      }
      else{
        ntt_available_bits = frameNumBit - decoded_bits;
      }
      ntt_available_bits -= ntt_TBITS_FR_SCL;
    
      /*--- base decoder ---*/
      {
        float current_frame[ntt_T_FR_MAX];
        int itmp;
        /* bit unpacking */
        decoded_bits += ntt_BitUnPack ( fixed_stream, 
                                        ntt_available_bits,
                                        block_type[MONO_CHAN], 
                                        &index, 
                                        hResilience,
                                        hVm, 
                                        hEPInfo );
        /* decoding tools*/
        ntt_vq_decoder(&index, spectral_line_vector[0]);

        if (ntt_LTP_SW == 1){
          if (index.w_type == ONLY_LONG_WINDOW ||
              index.w_type == LONG_MEDIUM_WINDOW ||
              index.w_type == MEDIUM_LONG_WINDOW ||
              index.w_type == LONG_SHORT_WINDOW ||
              index.w_type == SHORT_LONG_WINDOW){
            for (itmp=0; itmp<ntt_N_FR; itmp++){
              current_frame[itmp] = (float)spectral_line_vector[0][0][itmp];
            }
            nok_lt_predict ( 0, 
                             &ntt_info, 
                             index.w_type, 
                             WS_FHG,
                             ntt_nok_lt_status[0]->sbk_prediction_used,
                             ntt_nok_lt_status[0]->sfb_prediction_used,
                             ntt_nok_lt_status[0], ntt_nok_lt_status[0]->weight,
                             ntt_nok_lt_status[0]->delay,
                             current_frame,
                             ntt_N_FR, 
                             ntt_N_FR_M, 
                             ntt_N_FR_S );
            for (itmp=0; itmp<ntt_N_FR; itmp++){
              spectral_line_vector[0][0][itmp] = (double)current_frame[itmp];
            }
          }
        }
      }

      /*--- scalable decoders ---*/
      {
        int iscl;
        for (iscl=0; iscl<ntt_NSclLay; iscl++){ 
          /* bit unpacking */
          decoded_bits += ntt_SclBitUnPack(fixed_stream, &index_scl, iscl);
              
          /* decoding tools */
          if (iscl < ntt_NSclLayDec){ 
                  
            if(iscl>=1){ 
              mat_scale_set_shift_para2(iscl);
            } 
            ntt_scale_vq_decoder(&index_scl, spectral_line_vector[0], iscl);
          }
        }
      }
      InitFlag = 0;
    }
    break;
  default:
    CommonExit(-1,"\nerror in switch");  
  } /* switch( qc_select ) */

  /* son_NBCpp */
  /* unpack gain_control_data() */
  for(i_ch=0;i_ch<max_ch;i_ch++){

    if (gcBitBuf[i_ch]->numBit > 0) {
      pp_select = AAC_PP;
      /* decoded_bits = */
      son_gc_unpack(gc_stream[i_ch], block_type[MONO_CHAN],
                    &max_band[i_ch], gainInfo[i_ch]);
    }
    else {
      pp_select = NONE;
    }
  } /* for(i_ch... */
  
  /* F -> T */
  /*if (pp_select == AAC_PP)  fixed 980211 YT*/
  if (mc_info.profile  == SSR_Profile) 

    {
      int band;
      int i_ch; /* 971010 YT*/
      for(i_ch=0;i_ch<max_ch;i_ch++){
      
        son_gc_arrangeSpecDec(
                              spectral_line_vector[0][i_ch],
                              block_size_samples,
                              block_type[MONO_CHAN],
                              spectral_line_vector_for_gc[i_ch]
                              );

        for (band = 0; band < ssr_decoder_band; band++) {
          freq2buffer(
                      &spectral_line_vector_for_gc[i_ch][block_size_samples/NBANDS*band],
                      &imdctBufForGC[i_ch][block_size_samples/NBANDS*2*band],
                      &overlap_buffer[i_ch][block_size_samples/NBANDS*band],
                      block_type[MONO_CHAN],
                      block_size_samples/NBANDS,
                      block_size_samples/NBANDS/med_win_in_long,
                      block_size_samples/NBANDS/short_win_in_long, 
                      windowShape,
                      prev_windowShape[i_ch], /* YB : 971113 */
                      NON_OVERLAPPED,
                      short_win_in_long 
                      );
        }

        /* gain compensator */
        son_gc_compensate(
                          imdctBufForGC[i_ch],
                          gainInfo[i_ch],
                          block_size_samples,
                          block_type[MONO_CHAN],
                          i_ch,
                          DBandSigBufForOverlapping[i_ch],
                          DBandSigBuf[i_ch],
                          ssr_decoder_band
                          );
        /* ipqf */
        son_ipqf_main(
                      DBandSigBuf[i_ch],
                      block_size_samples,
                      i_ch,
                      time_sample_vector[i_ch]
                      );
        prev_windowShape[i_ch] = windowShape;
      } /* for i_ch ...*/
    }
  else {
    int i_ch;
    for (i_ch=0; i_ch<max_ch; i_ch++){
      freq2buffer(
                  spectral_line_vector[0][i_ch],
                  time_sample_vector[i_ch],
                  overlap_buffer[i_ch],
                  block_type[MONO_CHAN],
                  block_size_samples, /* changed to variables (NI) */
                  block_size_samples/med_win_in_long,
                  block_size_samples/short_win_in_long,
                  windowShape,
                  prev_windowShape[i_ch],   /* YB : 971113 */
                  OVERLAPPED,
                  short_win_in_long             /* HP 971023 */
                  );
      prev_windowShape[i_ch] = windowShape;
    }
  }
  /* Write accumulation_buffer[0..block_size_samples-1] to pcm output */
  {
    int i, i_ch;
    for (i_ch=0; i_ch<max_ch; i_ch++){
      for( i=0; i<block_size_samples; i++ ) {
        sampleBuf[i_ch][i] = (float)time_sample_vector[i_ch][i];
      }
    }
  }    
  
  if (qc_select==AAC_QC || qc_select==AAC_BSAC){ /* read align bits */
   
      curBitPos=BsCurrentBit(fixed_stream);
      while (curBitPos & ((1<<3)-1)) {
#ifdef VERSION2
        if ( GetEPFlag ( hResilience ) ) {
          BsGetBitEP(ALIGN_BITS, hEPInfo,fixed_stream, &ultmp, 1 );
        }
        else
#endif
          BsGetBit(fixed_stream,&ultmp,1);
        curBitPos=BsCurrentBit(fixed_stream);    
        i += 1;
        decoded_bits++;
      }
  }
  *usedNumBit = decoded_bits;

  BsClose(fixed_stream);
  for (i_ch=0; i_ch<max_ch; i_ch++){
    BsClose(gc_stream[i_ch]);
    BsClose(gc_WRstream[i_ch]);
    BsFreeBuffer(gcBitBuf[i_ch]);
  }/* for(i_ch...*/
}


