/* $Id: dec_tf.c,v 1.35 1997/11/20 22:02:00 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 */


/*******************************************************************************************
 *
 * 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"

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

int LDFB=0;  /* Low Delay Filter Bank, 0: disabled 1: enabled*/


/********************************************************/
/* 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"
	    "-aac_sca\n"
	    "-out <n>  select output layer for -aac_sca (n=0 :  base layer)\n"
	    "-aac_bsac\n"
	    "-pred ltp\n"
	    "-pred nok_bwp\n"
	    "-nttDecLyr <n> (scalable, n=0: base layer)\n"
		"-bsacDecBr <n> (scalable, 16 <= n <= 64)\n"
            "-ldfb (Low Delay Filter Bank enabled)\n"
	    "\n");
  }
  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 int 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     
)
{
  unsigned long ultmp;
  long bit_rate_decoded;
  int  delay_samples_decoded;
  int x, i_ch;
  BsBitStream *header_stream;

#if 0
  if (numChannel != 1)
    CommonExit(1,"DecTfInit: audio data has more than one channel (%d)",
	       numChannel);
#endif

  header_stream = BsOpenBufferRead(bitHeader);
 

  if( strstr( decPara, "-ldfb" ) ) {
    LDFB = 1;
  }

  /* -----  Set qc_select ----- */
  if ( ( strstr(decPara, "-qc_aac")) ||
       ( strstr(decPara, "-qc_aac_960"))) {
    tf_select = MDCT_AAC;
    qc_select = AAC_QC;
  }

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

  if( strstr( decPara, "-aac_raw" ) ) {
    /* 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;
  }
  if( strstr( decPara, "-aac_sca" ) ) {
    char * outLayNr;
    /* 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_SCALEABLE;
    tf_select = MDCT_AAC;
    transport_stream = AAC_RAWDATA_TSTREAM;
    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, "-qc_ntt" ) ) {
    qc_select = NTT_VQ;
  }
  
  if( strstr( decPara, "-qc_mdct16" ) ) {
    qc_select = MDCT_VALUES_16BIT;
  }
  
  if( strstr( decPara, "-pred " ) ) {
    if( strstr( decPara, "ltp" ) )
      pred_type = NOK_LTP;
    else if( strstr( decPara, "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 */
  {
   double *p_tmp[8];
   
   EncTf_psycho_acoustic( 48000, 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 tmp;
    aacDebugString = aacDebugStr;


    aac_decode_init(sampling_rate_decoded,aacDebugStr, block_size_samples, &sfbInfo,
		    pred_type);
    break;
   }

   case AAC_BSAC:  /* YB : 970825 */
   {
    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(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();	/* HP 971105 */
    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)
{
  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,i;  
  static Window_shape prev_windowShape[2]={WS_FHG, WS_FHG}; /* YB : 971113 */
  
  /* VQ: Variables for NTT_VQ decoder */
  ntt_INDEX  index, index_scl;
  static int InitFlag = 1;

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

      decoded_bits += aac_decode_frame(fixed_stream,
				       gc_WRstream,
				       spectral_line_vector[0], 
				       (int*)&(block_type[MONO_CHAN]), 
				       &windowShape,
				       NOT_SCALEABLE,max_sfb,numChannels,0,sfbInfo); 
    }	
  break;
  case AAC_SCALEABLE:
    {
      aacScaleableDecode( fixed_stream, 
                          gc_WRstream,
                          &block_type[MONO_CHAN], 
                          &decoded_bits, 
                          spectral_line_vector, 
                          block_size_samples, 
                          scalOutSelect ,
                          sfbInfo,
                          numChannels ,sampling_rate_decoded);
    }	
  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, InitFlag);
    /* 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, 0,
		     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>=2){ 
			mat_scale_set_shift_para(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)
    {
      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 < NBANDS; 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]
			);

      /* 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)) {
      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...*/

}


