/*****************************************************************************/
/* This software module was originally developed by                          */
/*   Akio Jin      (NTT),                                                    */
/*   Takeshi Norimatsu,                                                      */
/*   Mineo Tsushima,                                                         */
/*   and Tomokazu Ishikawa (Matsushita Electric Industrial Co Ltd.)          */
/* and edited by                                                             */
/*   Naoki Iwakami (NTT) on 1997-07-17,                                      */
/*   Akio Jin (NTT),                                                         */
/*   Mineo Tsushima, (Matsushita Electric Industrial Co Ltd.)                */
/*   and Tomokazu Ishikawa (Matsushita Electric Industrial Co Ltd.)          */
/*   on 1997-10-23,                                                          */
/* 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.                                                        */
/*****************************************************************************/



#include <stdio.h>

#include "ntt_conf.h"
#include "ntt_scale_conf.h"
#include "ntt_scale_enc_para.h"
#include "ntt_encode.h"
#include "ntt_scale_encode.h"
#include "ntt_tools.h"
#include "mat_def_ntt.h"


void ntt_scale_enc_lpc_spectrum
  (/* Parameters */
   int    nfr,
   int    nsf,
   int    n_ch,
   int    n_pr,
   double *lsp_code,
   double *lsp_fgcode,
   double prev_buf[ntt_N_SUP_MAX][ntt_MA_NP][ntt_N_PR_MAX+1],
   int    ma_np,
   /* Input */
   double spectrum[],
   int    w_type,
   int    current_block,
   /* Output */
   int    index_lsp[ntt_N_SUP_MAX][ntt_LSP_NIDX_MAX],
   double lpc_spectrum[],
   /* Scalable layer ID */
   int iscl,
   double band_lower[],
   double band_upper[]
   )
{
  /*--- Variables ---*/
  double resid, alf[ntt_N_SUP_MAX][ntt_N_PR_MAX+1],
  lsp[ntt_N_PR_MAX+1], lspq[ntt_N_SUP_MAX*(ntt_N_PR_MAX+1)];
  double spectrum_wide[ntt_T_FR_MAX],
         lpc_spectrum_re[ntt_T_FR_MAX];
  int    i_sup, top, subtop, w_type_t, isf, lsptop, ismp;
  int    block_size, nfr_l, nfr_u, nfr_lu;
  block_size = nfr * nsf;

  /*--- encode LSP coefficients ---*/
  if (current_block == ntt_BLOCK_LONG) w_type_t = w_type;
  else                                 w_type_t = ONLY_LONG_WINDOW;
  for ( i_sup=0; i_sup<n_ch; i_sup++ ){
       nfr_u  = (int)(nfr*band_upper[i_sup]);
       nfr_l  =(int) (nfr*band_lower[i_sup]);
       nfr_lu = (int)(nfr*(band_upper[i_sup]-band_lower[i_sup]));
       top    = i_sup*block_size;
       ntt_zerod(block_size, spectrum_wide+top);
       ntt_setd(block_size,1.e5, lpc_spectrum+top);

       /*--- band extension for nallow band lpc (by A.Jin 1997.6.9) ---*/
       for(isf=0; isf<nsf; isf++){
	    subtop = top + isf*nfr;
	    for(ismp=nfr_l; ismp<nfr_u; ismp++){
		 spectrum_wide[(int)((ismp-nfr_l)/
		   (band_upper[i_sup]-band_lower[i_sup])+subtop)] 
		   = spectrum[ismp+subtop];
	    }
       }

       /* calculate LSP coefficients */
       ntt_scale_fgetalf(nfr, nsf, spectrum_wide+top,alf[i_sup],&resid,
			 ntt_N_PR_SCL[iscl], ntt_BAND_EXP_SCL[iscl]);
       ntt_alflsp(ntt_N_PR_SCL[iscl], alf[i_sup], lsp);
       /* quantize LSP coefficients */
       ntt_lsp_encw(ntt_N_PR_SCL[iscl], (double (*)[ntt_N_PR_MAX])lsp_code,
		    (double (*)[ntt_MA_NP][ntt_N_PR_MAX])lsp_fgcode,
		    ntt_lsp_csize_scl[iscl],
		    prev_buf[i_sup], ma_np,
		    lsp, lspq+i_sup*ntt_N_PR_SCL[iscl],
		    index_lsp[i_sup], ntt_LSP_SPLIT_SCL[iscl]);
  }

  /*--- reconstruct LPC spectrum ---*/
  for (i_sup=0; i_sup<n_ch; i_sup++){
       nfr_u  = (int)(nfr*band_upper[i_sup]);
       nfr_l  =(int) (nfr*band_lower[i_sup]);
       nfr_lu = (int)(nfr*(band_upper[i_sup]-band_lower[i_sup]));
       top = i_sup * block_size;
       lsptop = i_sup * n_pr;
       ntt_lsptowt(nfr, n_pr, lspq+lsptop, lpc_spectrum+top);

       /*--- band re-extension for nallow band lpc (by A.Jin 1997.6.9) ---*/
       for(ismp=0; ismp<nfr_lu; ismp++){
	    lpc_spectrum_re[ismp+top+nfr_l]
		 = lpc_spectrum[(int)(ismp/
			     (band_upper[i_sup]-band_lower[i_sup]))+top];
       }
       ntt_movdd(nfr_lu,lpc_spectrum_re+top+nfr_l, lpc_spectrum+top+nfr_l);
       ntt_setd(nfr_l, 999., lpc_spectrum+top);
       ntt_setd(nfr- nfr_u, 999., lpc_spectrum+top+nfr_u);

       for (isf=1; isf<nsf; isf++){
	    subtop = top + isf*nfr;
	    ntt_movdd(nfr, lpc_spectrum+top, lpc_spectrum+subtop);
       }
  }
}


#define ntt_GAMMA  0.95 

void ntt_scale_fgetalf(/* Parameters */
		 int    nfr,    /* subframe size */
		 int    nsf,    /* number of subframes */
		 /* Input */
		 double *spectrum,  /* MDCT spectrum */
		 /* Output */
		 double *alf,   /* LPC coefficients */
		 double *resid, /* residual power */
		 /* Input */
		 int n_pr,  
		 double band_exp) 
{
    double wlag[ntt_N_PR_MAX + 1];
    double powspec[ntt_N_FR_MAX];
    int    unstable;
    int    ip;
    double ref[ntt_N_PR_MAX+1];         
    double cep[(ntt_N_PR_MAX+1)*2];        
    double refb[ntt_N_PR_MAX+1];      
    double alfb[ntt_N_PR_MAX+1];     
    double gamma; 			   
    double          
	cor[ntt_N_PR_MAX+1],
        pow_counter;
    double 
      xr[ntt_N_FR_MAX*2];
    int    ismp, isf;

    /*--- Initialization ---*/
    /*--- set lag window ---*/
    ntt_lagwdw( wlag, n_pr, band_exp / ntt_SAMPF );

    /*--- Calculate power spectrum ---*/
    pow_counter = 0.;
    for (ismp=0; ismp<nfr; ismp++) powspec[ismp] = 0.;
    for (isf=0; isf<nsf; isf++){
      for (ismp=0; ismp<nfr; ismp++){
	powspec[ismp] += spectrum[ismp+isf*nfr]*spectrum[ismp+isf*nfr];
	pow_counter   += powspec[ismp]*1.e-6;
      }
    }
    /*--- convert low power signals to zero(for certain LPC) ---*/
    if(pow_counter<1.e-2){
      ntt_zerod(nfr, powspec);
    }
    /*--- Calculate auto correlation coefficients ---*/
 {
 double tmp, theta;
 int jsmp, pointer, pointer0;
     for(jsmp=0; jsmp<n_pr+1; jsmp++){
       tmp=0.0;
       pointer =0; pointer0=0; theta=1.0;
       for(ismp=0; ismp<nfr; ismp++){
        tmp += powspec[ismp]*theta;
        pointer += jsmp*ntt_N_FR*4/nfr;
        if(pointer >= ntt_N_FR*8) pointer -= ntt_N_FR*8;
        if(0<= pointer && pointer <ntt_N_FR*2 ) {
          pointer0 = pointer;
          theta = ntt_cos_TT[pointer0];
        }
        else if(ntt_N_FR*2 <= pointer && pointer <ntt_N_FR*4 ){
            pointer0 = ntt_N_FR*4-pointer;
            theta = -ntt_cos_TT[pointer0];
        }
        else if(ntt_N_FR*4<= pointer && pointer <ntt_N_FR*6 ){
            pointer0 = pointer-ntt_N_FR*4;
            theta = -ntt_cos_TT[pointer0];
        }
        else if(ntt_N_FR*6<= pointer && pointer <ntt_N_FR*8 ){
            pointer0 = ntt_N_FR*8-pointer;
            theta = ntt_cos_TT[pointer0];
        }
       }
        xr[jsmp]= tmp;
     }
 }
    ntt_movdd(n_pr+1, xr, cor);
    for (ip=1; ip<=n_pr; ip++){
      cor[ip] /= (cor[0] + 1.e-5)*1.02;
    }
    cor[0] = 1.0;

    /*--- LPC analysis --*/
    ntt_mulddd(n_pr + 1, cor, wlag, cor);
    ntt_corref(n_pr, cor, alfb ,refb, resid); alfb[0] = 1.;

    /*--- LPC parameters to cepstrum parameters ---*/
    ntt_alfcep(n_pr, alfb, cep, (n_pr)*2);
   
    /*--- Divide cepstrum parameters by 2 (sqrt in the spectrum domain) ---*/
    ntt_mulcdd((n_pr)*2, 0.5, cep+1, cep+1);

    /*--- Cepstrum parameters to LPC alpha parameters ---*/
    ntt_cep2alf((n_pr)*2, n_pr, cep, alf);

    /*--- Stability check ---*/
    alf[0]=1.0;
    do{
       ntt_alfref(n_pr, alf, ref, resid);
       unstable =0;
       for(ip=1; ip<=n_pr; ip++){
          if(ref[ip] > 0.999 || ref[ip] < -0.999) unstable =1;
          if(ref[ip] > 0.999 || ref[ip] < -0.999)
	       fprintf(stderr,
		       "ntt_scale_fgetalf(): unstable ref. pram. order:%5d, value: %7.4f\n",
		       ip, ref[ip]);
       }
       if(unstable) {
         gamma= ntt_GAMMA;
         for(ip=1; ip<=n_pr; ip++){
           alf[ip] *= gamma;
           gamma *= ntt_GAMMA;
         }
       }
    }while(unstable);

}

void ntt_scale_tf_perceptual_model(/* Input */
				   double lpc_spectrum[], /* LPC spectrum */
				   double bark_env[],     /* Bark-scale envelope */
				   double gain[],         /* gain factor */
				   int       w_type,      /* block type */
				   double spectrum[],     /* specturm */
				   double pitch_sequence[], /* pitch peak components */
				   /* Output */
				   double perceptual_weight[]) /* perceptual weight */
{
    /*--- Variables ---*/
    int    ismp, i_sup, top, isf, subtop;
    double ratio;
    double ratio0;

    switch(w_type){
    case ONLY_LONG_WINDOW:
    case LONG_SHORT_WINDOW:
    case SHORT_LONG_WINDOW:
    case LONG_MEDIUM_WINDOW:
    case MEDIUM_LONG_WINDOW:
	for (i_sup=0; i_sup<ntt_N_SUP; i_sup++){
	    top = i_sup * ntt_N_FR;
	    for (ismp=0; ismp<ntt_N_FR; ismp++){
		perceptual_weight[ismp+top] = (1./lpc_spectrum[ismp+top]);
	    }
            ntt_prcptw(perceptual_weight+top, bark_env+top);
            for (ismp=0; ismp<ntt_N_FR; ismp++){
		perceptual_weight[ismp+top] *=
		    lpc_spectrum[ismp+top]/bark_env[ismp+top];
	    }

	    for (ismp=0; ismp<ntt_N_FR; ismp++){
		ratio0= (spectrum[ismp+top]/lpc_spectrum[ismp+top]);
		  ratio = ((ratio0-pitch_sequence[ismp+top])*
		           (ratio0-pitch_sequence[ismp+top])+10.001)
		           /((ratio0*ratio0)+10.001);
		if(ratio<1.0) perceptual_weight[ismp+top] *= ratio;
	     }
	}
	break;
    case ONLY_MEDIUM_WINDOW:
    case MEDIUM_SHORT_WINDOW:
    case SHORT_MEDIUM_WINDOW:
	for (i_sup=0; i_sup<ntt_N_SUP; i_sup++){
	    top = i_sup * ntt_N_FR;
	    for (isf=0; isf<ntt_N_MID; isf++){
		subtop = top + isf * ntt_N_FR_M;
		for (ismp=0; ismp<ntt_N_FR_M; ismp++){
		    perceptual_weight[ismp+subtop] = 
			(bark_env[ismp+subtop] / lpc_spectrum[ismp+subtop]);
		}
	    }
	}
        ntt_prcptw_m(perceptual_weight, gain, perceptual_weight);
	for (i_sup=0; i_sup<ntt_N_SUP; i_sup++){
	    top = i_sup * ntt_N_FR;
	    for (isf=0; isf<ntt_N_MID; isf++){
		subtop = top + isf * ntt_N_FR_M;
		for (ismp=0; ismp<ntt_N_FR_M; ismp++){
		    perceptual_weight[ismp+subtop] *=
			lpc_spectrum[ismp+subtop] / bark_env[ismp+subtop];
		}
	    }
	}
	break;
    case ONLY_SHORT_WINDOW:
	for (i_sup=0; i_sup<ntt_N_SUP; i_sup++){
	    top = i_sup * ntt_N_FR;
	    for (isf=0; isf<ntt_N_SHRT; isf++){
		subtop = top + isf * ntt_N_FR_S;
		for (ismp=0; ismp<ntt_N_FR_S; ismp++){
		    perceptual_weight[ismp+subtop] =
		      (bark_env[ismp+subtop] / lpc_spectrum[ismp+subtop]);
		}
	    }
	}
        ntt_prcptw_s(perceptual_weight, gain, perceptual_weight);
	for (i_sup=0; i_sup<ntt_N_SUP; i_sup++){
	    top = i_sup * ntt_N_FR;
	    for (isf=0; isf<ntt_N_SHRT; isf++){
		subtop = top + isf * ntt_N_FR_S;
		for (ismp=0; ismp<ntt_N_FR_S; ismp++){
		    perceptual_weight[ismp+subtop] *=
			lpc_spectrum[ismp+subtop] / bark_env[ismp+subtop];
		}
	    }
	}
	break;
    }
}


void ntt_scale_tf_proc_spectrum(/* In/Out */
                                double spectrum[],
                                /* In/Out */
                                ntt_INDEX  *index,
                                /* Output */
                                double lpc_spectrum[],
                                double bark_env[],
                                double pitch_sequence[],
                                double gain[],
                                /* In/Out */
                                int iscl,
                                double lpc_spectrum_org[],
                                double lpc_spectrum_mod[])
{
  double tc[ntt_T_FR_MAX], pwt[ntt_T_FR_MAX];
  int    current_block, i_ch, i_ma, ii;
  double band_l[ntt_N_SUP_MAX], band_u[ntt_N_SUP_MAX];
  static int InitFlag = 1;

  /*--- Parameters ---*/
  double band_lower, band_upper;
  int    nfr, nsf, n_ch;
  int    n_crb, *bark_tbl;
  int    fw_ndiv, fw_length, fw_len_max, fw_cb_size;
  double fw_prcpt;
  double *fw_codev;
  double *fw_env_memory, *fw_pdot;
  int    n_pr;
  double *lsp_code;
  double *lsp_fgcode;
  int    *lsp_csize, *lsp_cdim;
  /*--- Memories ---*/
  /* Bark-scale envelope */
  static double fw_pdot_long[ntt_NSclLay_MAX][ntt_T_FR_MAX];
  static double fw_pdot_medium[ntt_NSclLay_MAX][ntt_T_FR_M_MAX];
  static double fw_pdot_short[ntt_NSclLay_MAX][ntt_T_FR_S_MAX];
  static double
    fw_env_memory_long[ntt_NSclLay_MAX][ntt_N_CRB_MAX*ntt_N_SUP_MAX];
  static double
    fw_env_memory_medium[ntt_NSclLay_MAX][ntt_N_CRB_M_MAX*ntt_N_SUP_MAX];
  static double
    fw_env_memory_short[ntt_NSclLay_MAX][ntt_N_CRB_S_MAX*ntt_N_SUP_MAX];
  static int    p_w_type[ntt_NSclLay_MAX];
  /* LPC spectrum */
  static double
    prev_buf[ntt_NSclLay_MAX][ntt_N_SUP_MAX][ntt_MA_NP][ntt_N_PR_MAX+1];
  static int ma_np[ntt_NSclLay_MAX];
  int fw_nbit;
  int ifr;
  int isf, top, subtop, ismp, block_size;

  /*--- Set parameters ---*/
  switch(index->w_type){
  case ONLY_LONG_WINDOW: case LONG_SHORT_WINDOW: case SHORT_LONG_WINDOW:
    /* subframe */
    nfr = ntt_N_FR;
    nsf = 1;
    n_ch = ntt_N_SUP;
    /* Bark-scale table (Bark-scale envelope) */
    n_crb    = ntt_N_CRB_SCL[iscl];
    bark_tbl = ntt_crb_tbl_scl[iscl];
    /* quantization (Bark-scale envelope) */
    fw_ndiv = ntt_FW_N_DIV_SCL[iscl];
    fw_cb_size = ntt_FW_CB_SIZE_SCL[iscl];
    fw_length  = ntt_FW_CB_LEN_SCL[iscl];
    fw_len_max = ntt_FW_CB_LEN_SCL[iscl];
    fw_codev = (double *)ntt_fwcodev_scl[iscl];
    fw_prcpt = 0.4;
    fw_env_memory = fw_env_memory_long[iscl];
    /* envelope calculation (Bark-scale envelope) */
    fw_pdot = fw_pdot_long[iscl];
    current_block = ntt_BLOCK_LONG;
    fw_nbit = ntt_FW_N_BIT_SCL[iscl];
    break;
 case ONLY_SHORT_WINDOW:
    /* subframe */
    nfr = ntt_N_FR_S;
    nsf = ntt_N_SHRT;
    n_ch = ntt_N_SUP;
    /* Bark-scale table (Bark-scale envelope) */
    n_crb    = ntt_N_CRB_S_SCL[iscl];
    bark_tbl = ntt_crb_tbl_s_scl[iscl];
    /* quantization (Bark-scale envelope) */
    fw_ndiv = ntt_FW_N_DIV_S_SCL[iscl];
    fw_cb_size = ntt_FW_CB_SIZE_S_SCL[iscl];
    fw_length  = ntt_FW_CB_LEN_S_SCL[iscl];
    fw_len_max = ntt_FW_CB_LEN_S_SCL[iscl];
    fw_codev = (double *)ntt_fwcodevs_scl[iscl];
    fw_prcpt = 0.5;
    fw_env_memory = fw_env_memory_short[iscl];
    /* envelope calculation (Bark-scale envelope) */
    fw_pdot = fw_pdot_short[iscl];
    current_block = ntt_BLOCK_SHORT;
    fw_nbit = ntt_FW_N_BIT_S_SCL[iscl];
    break;
 default:
        fprintf( stderr,"Fatal error! %d: no such window type.\n", index->w_type );
        exit(1);
}
  /* pre process (bandwidth setting) */
/*
  band_lower = ntt_BAND_LOWER_SCL[iscl];
  band_upper = ntt_BAND_UPPER_SCL[iscl];
*/
  /* LPC spectrum */
  n_pr = ntt_N_PR_SCL[iscl];
  lsp_code   = (double *)lsp_code_scl[iscl];
  lsp_fgcode = (double *)lsp_fgcode_scl[iscl];
  lsp_csize      = ntt_lsp_csize_scl[iscl];
  lsp_cdim       = ntt_lsp_cdim_scl[iscl];

  block_size = nfr*nsf ; /* tsushima add */

  /*--- Initialize ---*/
  if (InitFlag){
    for (ii=0; ii<ntt_NSclLay; ii++){
      /* Bark-scale envelope */
      ntt_setd(ntt_N_FR  *ntt_N_SUP, 0.1, fw_pdot_long[ii]);
      ntt_setd(ntt_N_FR_M*ntt_N_SUP, 0.1, fw_pdot_medium[ii]);
      ntt_setd(ntt_N_FR_S*ntt_N_SUP, 0.1, fw_pdot_short[ii]);

      ntt_zerod(ntt_N_CRB_SCL[ii]  *ntt_N_SUP, fw_env_memory_long[ii]);
      ntt_zerod(ntt_N_CRB_M_SCL[ii]*ntt_N_SUP, fw_env_memory_medium[ii]);
      ntt_zerod(ntt_N_CRB_S_SCL[ii]*ntt_N_SUP, fw_env_memory_short[ii]);

      p_w_type[ii] = ntt_BLOCK_LONG;

      /* LPC spectrum */
      for ( i_ch=0; i_ch<n_ch; i_ch++ ){
        for ( i_ma=0; i_ma<ntt_MA_NP; i_ma++ ){
          ntt_zerod( n_pr+1, prev_buf[ii][i_ch][i_ma] );
	}
      }
      ma_np[ii] = 0;
    }
  }
  InitFlag=0;

  /*--- Encoding tools ---*/
  /* LPC spectrum encoding */
  { 
    for (i_ch=0;i_ch<n_ch;i_ch++){ 
      band_l[i_ch] = ntt_AC_BTM[iscl][i_ch][mat_shift[iscl][i_ch]]; 
      band_u[i_ch] = ntt_AC_TOP[iscl][i_ch][mat_shift[iscl][i_ch]]; 
    }
    ntt_scale_enc_lpc_spectrum(nfr, nsf, n_ch, n_pr, lsp_code, lsp_fgcode,
                             prev_buf[iscl], ma_np[iscl],
                             spectrum, index->w_type, current_block,
                             index->lsp, lpc_spectrum, iscl,
                             band_l, band_u);
  }
  /* pre process (bandwidth setting) */
  for (i_ch=0;i_ch<n_ch;i_ch++){ /* corrected by TSUSHIMA */
    top=i_ch*ntt_N_FR;
    ntt_freq_domain_pre_process(nfr, nsf, band_l[i_ch], band_u[i_ch],
				spectrum+top, lpc_spectrum_org+top,
				spectrum+top, lpc_spectrum_mod+top); /* correct*/
    ntt_freq_domain_pre_process(nfr, nsf, band_l[i_ch], band_u[i_ch],
				spectrum+top, lpc_spectrum+top,
				spectrum+top, lpc_spectrum+top); /*correct*/
  }

  ntt_zerod(ntt_N_FR*ntt_N_SUP, pitch_sequence);

  /* Bark-scale envelope encoding */

  if(fw_nbit == 0){
       for(ifr=0; ifr<nfr*nsf*n_ch; ifr++){
	    bark_env[ifr]=1.0;
       }
       for (i_ch=0; i_ch<n_ch; i_ch++){
	    top = i_ch * block_size;
	    for(isf=0; isf<nsf; isf++){
		 subtop = top + isf*nfr;
		 /* make input data */
		 for (ismp=0; ismp<nfr; ismp++){
		      tc[ismp+subtop] =
			   spectrum[ismp+subtop] * lpc_spectrum[ismp+subtop]
				- pitch_sequence[ismp+subtop];
		 }
	    }
       }
  }else{
       ntt_scale_enc_bark_env(nfr, nsf, n_ch, n_crb, bark_tbl,
			      fw_ndiv, fw_cb_size, fw_length,
			      fw_codev, fw_len_max, fw_prcpt,
			      fw_env_memory, fw_pdot, &(p_w_type[iscl]),
			      spectrum, lpc_spectrum, pitch_sequence, current_block,
			      tc, pwt, index->fw, index->fw_alf, bark_env, band_l);
  }
  /* gain encoding */
  ntt_scale_enc_gain_t(nfr, nsf, n_ch, iscl, bark_env, tc, index->pow, gain);

 /*--- Memory operation ---*/
  ma_np[iscl] ++;
  if(ma_np[iscl] > ntt_MA_NP) ma_np[iscl] = ntt_MA_NP;
}



void ntt_scale_enc_bark_env(/* Parameters */
                      int    nfr,
                      int    nsf,
                      int    n_ch,
                      int    n_crb,
                      int    *bark_tbl,
                      int    ndiv,
                      int    cb_size,
                      int    length,
                      double *codev,
                      int    len_max,
                      double prcpt,
                      double *env_memory,
                      double *pdot,
                      int    *p_w_type,
                      /* Input */
                      double spectrum[],
                      double lpc_spectrum[],
                      double pitch_sequence[],
                      int    current_block,
                      /* Output */
                      double tc[ntt_T_FR_MAX],
                      double pwt[ntt_T_FR_MAX],
                      int    index_fw[],
                      int    ind_fw_alf[],
                      double bark_env[],
                      double band_lower[])
{
  /*--- Variables ---*/
  int    ismp, i_ch, top, isf, subtop, pred_sw, block_size;

  /*--- Initialization ---*/
  block_size = nfr * nsf;
  if ((*p_w_type != current_block)){
    ntt_zerod(nfr*n_ch, pdot);
}

  /*--- Encoding process ---*/
  for (i_ch=0; i_ch<n_ch; i_ch++){
    top = i_ch * block_size;
    /* make weight */
    for (ismp=0; ismp<block_size; ismp++){
      /*pwt[ismp+top] = 1./lpc_spectrum[ismp+top];*/
      pwt[ismp+top] = 1. / pow(lpc_spectrum[ismp+top], 0.5);
  }

    /* set MA prediction switch */
    if (*p_w_type == current_block) pred_sw = 1;
    else                           pred_sw = 0;

    for(isf=0; isf<nsf; isf++){
      subtop = top + isf*nfr;
      /* make input data */
      for (ismp=0; ismp<nfr; ismp++){
        tc[ismp+subtop] =
          spectrum[ismp+subtop] * lpc_spectrum[ismp+subtop]
            - pitch_sequence[ismp+subtop];
    }
      /* envelope coding */
      ntt_scale_fwpred(nfr, n_crb, bark_tbl, ndiv,
                 cb_size, length, codev, len_max, prcpt,
                 env_memory, pdot,
                 pwt+subtop, bark_env+subtop, tc+subtop,
                 &index_fw[(i_ch*nsf+isf)*ndiv],
                 &ind_fw_alf[isf+i_ch*nsf], i_ch, pred_sw, band_lower[i_ch]);
      pred_sw = 1;
  }
}
  *p_w_type = current_block;
}


void ntt_scale_fwpred(int    nfr,  /* Param:  block size */
                int    n_crb,       /* Param:  number of Bark-scale band */
                int    *bark_tbl,   /* Param:  Bark-scale table */
                int    ndiv,        /* Param:  number of interleave division */
                int    cb_size,     /* Param:  codebook size */
                int    length,      /* Param:  codevector length */
                double *codev,      /* Param:  codebook */
                int    len_max,     /* Param:  codevector memory length */
                double prcpt,
                double *penv_tmp,   /* Param:  memory for Bark-scale envelope*/
                double *pdot_tmp,   /* Param:  memory for env. calculation */
                double iwt[],       /* Input:  LPC envelope */
                double pred[],      /* In/Out: Prediction factor */
                double tc[],        /* Input:  Residual signal */
                int    index_fw[],  /* Output: Envelope VQ indices */
                int    *ind_fw_alf, /* Output: AR prediction coefficient index */
                int    i_sup,       /* Input:  Channel number */
                int    pred_sw,     /* Input:  prediction switch */
                double band_lower)
{
    /*--- Variables ---*/
    double        bwt[ntt_N_CRB_MAX], env[ntt_N_CRB_MAX];
    double        *pdot, fwgain, alf, alfq;
    double        *penv;
    register double acc, cdot, acc2, col0, col1, dtmp;
    int           top, top2, ismp, iblow, ibhigh, ib;

    /*--- Initialization ---*/
    top  = i_sup*nfr;
    top2 = i_sup*n_crb;
    pdot = pdot_tmp + top;
    penv = penv_tmp + top2;

    /*--- Calculate envelope ---*/
    iblow= (int)(nfr*band_lower); /*iblow=0;*/ fwgain=0.; ib=0;
    for (ib=0; ib<n_crb; ib++){
        ibhigh = bark_tbl[ib];
        /* reset the accumulations */
        acc  = 0.0;
        acc2 = 0.0;
        /* bandle the input coefficient lines into the bark-scale band */
        for(ismp=iblow; ismp<ibhigh; ismp++){
            cdot =  tc[ismp]*tc[ismp];/* calc. power */
            acc += pdot[ismp] + cdot; /* acc. the current and previous power */
            acc2 = acc2 + iwt[ismp];  /* accumulate the weighting factor */
            pdot[ismp] = cdot;        /* store the power */
        }
        env[ib] = sqrt(acc/(double)(ibhigh-iblow)) + 0.1; /* envelope in bark*/
        bwt[ib] = acc2;         /* weighting factor in bark scale */
        fwgain += env[ib];      /* accumulate the envelope power */

        iblow = ibhigh;
    }
    /* gain to normalize the bark-scale envelope */
    fwgain = (double) n_crb / fwgain;

    /*--- Normalize the envelope, and remove the offset ---*/
    for (ib=0; ib<n_crb; ib++){
        env[ib] = env[ib]*fwgain - 1.0;
    }

    /*--- Calculate the AR prediction coefficient and quantize it ---*/
    col0 = 0.1;
    col1 = 0.;
    if (pred_sw == 1){
      /* calculate auto correlation and cross correlation */
      for (ib=0; ib<n_crb; ib++){
        col0 += penv[ib]*penv[ib];
        col1 += penv[ib]*env[ib];
    }
      alf = col1/col0;   /* normalize the cross correlation coefficient */
      ntt_fwalfenc( alf, &alfq, ind_fw_alf ); /* quantize the cor. coefficient */
      /* AR prediction (cancellation using cor. coeff.) */
      for ( ib=0; ib<n_crb; ib++ ){
        env[ib] -= alfq*penv[ib];
    }
  }
    else{ /* in stop frame */
      alf = 0.;
      ntt_fwalfenc( alf, &alfq, ind_fw_alf );
  }

    /*--- Quantization of the envelope ---*/
    ntt_fwvq(ndiv, cb_size, length, codev, len_max, prcpt,
             env, bwt, index_fw);
    /*--- Local decoding ---*/
    ntt_fwex( index_fw, ndiv, length, codev, len_max, env );
    for(ib=ndiv*length; ib<n_crb; ib++) env[ib] = 0.;

    for(ismp=0;ismp<nfr*band_lower;ismp++){
      pred[ismp]=1.0;
  }
    for(ismp=bark_tbl[n_crb-1];ismp<nfr;ismp++){
      pred[ismp]=1.0;
  }

    for(ib=0, ismp=(int)(nfr*band_lower)/*0*/; ib<n_crb; ib++){
        ibhigh = bark_tbl[ib];
        dtmp = ntt_max(env[ib]+alfq*penv[ib]+1., ntt_FW_LLIM);
        while(ismp<ibhigh){
            pred[ismp] = dtmp;
            ismp++;
        }
    }
    /*--- Store the current envelope ---*/
    ntt_movdd(n_crb, env, penv);
}


void ntt_scale_enc_gain_t(/* Parameters */
                    int    nfr,
                    int    nsf,
                    int    n_ch,
                    int    iscl,
                    /* Input */
                    double bark_env[],
                    double tc[],
                    /* Output */
                    int    index_pow[],
                    double gain[])
{
  int    ismp, top, subtop, isf, iptop, gtop, i_ch, block_size;
  double pwr;
  double sub_pwr_tmp, sub_pwr[ntt_N_SHRT_MAX];
  double g_gain;

  block_size = nfr * nsf;

  /*--- Encoding process ---*/
  for (i_ch=0; i_ch<n_ch; i_ch++){
    top = i_ch * block_size;
    /*--- Gain calculation ---*/
    pwr = 0.1;
    for(isf=0; isf<nsf; isf++){
      subtop = top + isf*nfr;
      for ( ismp=0; ismp<nfr; ismp++ ){
        tc[ismp+subtop] /= bark_env[ismp+subtop];
    }
      sub_pwr_tmp
        =(ntt_dotdd(nfr, tc+subtop, tc+subtop)+0.1)/(double)nfr;
      pwr += sub_pwr_tmp;
      sub_pwr[isf] =sqrt( sub_pwr_tmp );
  }
    pwr = sqrt(pwr/(double)nsf);

    /*--- Quantization ---*/
    if (isf == 1){
      /* global gain */
      ntt_enc_sq_gain(pwr, ntt_AMP_MAX_SCL[iscl], ntt_MU_SCL[iscl],
                      ntt_STEP_SCL[iscl], ntt_AMP_NM,
                      &index_pow[i_ch],&gain[i_ch]);
  }
    else{
      /* global gain */
      iptop = (nsf+1)*i_ch;
      gtop  = nsf*i_ch;
      ntt_enc_sq_gain(pwr, ntt_AMP_MAX_SCL[iscl], ntt_MU_SCL[iscl],
                      ntt_STEP_SCL[iscl], ntt_AMP_NM,
                      &index_pow[iptop],&g_gain);

      /*
      gain[gtop] = g_gain;
      */
      /* subband gain */
      for(isf=0; isf<nsf; isf++){
        subtop = top + isf*nfr;
        ntt_enc_sq_gain(sub_pwr[isf]/(g_gain+0.0000001),
                      ntt_SUB_AMP_MAX_SCL[iscl], ntt_MU_SCL[iscl],
                      ntt_SUB_STEP_SCL[iscl], ntt_SUB_AMP_NM,
                     &index_pow[iptop+isf+1],&gain[gtop+isf]);
                gain[gtop+isf] *= g_gain;
    }
  }
}
}


void ntt_enc_sq_gain(
              double power,      /* Input  --- Power to be encoded */
              double  amp_max,
              double  mu,
              double  step,
              double  amp_nm,
              int    *index_pow, /* Output --- Power code index */
              double *gain)      /* Output --- Gain */
{
    /*--- Variables --*/
    double mu_power, dmu_power, dec_power;

    mu_power = ntt_mulaw(power, amp_max, mu);         /* mu-Law power */
    *index_pow = (int)(mu_power/ step);               /* quantization */
    dmu_power = *index_pow * step + step/2.;        /* decoded mu-Law power */
    dec_power = ntt_mulawinv(dmu_power, amp_max, mu); /* decoded power */
    *gain= dec_power / amp_nm;                        /* calculate gain */
}



/** revised from here by M.Tsushima , original by tomo ishikawa **/
#define mat_ERR_WEI_0 0.6
#define mat_ERR_WEI_1 0.9
#define mat_ERR_WEI_2 1.8
#define mat_ERR_WEI_3 2.0
#define mat_PERCEPT_POW 0.45

#define mat_SHORT_DELAY 14
#define mat_SPEECH 20


/* Added by Tomokazu Ishikawa 980309 */
int mat_scale_lay_shift2(double spectrum[],
			double spectrum_org[],
			int iscl,
			ntt_INDEX *index)
{
	int ii,jj,top, i_ch;
	double err_max,err[4];
	static int mat_shift_max[6], mat_shift_min[6];
	double tmp_spect[ntt_N_FR_MAX];

	double lpc_spect_tmp[ntt_T_FR_MAX],bark_env_tmp[ntt_T_FR_MAX];
	double lpc_spect_org[ntt_T_FR_MAX],bark_env_org[ntt_T_FR_MAX];
	double pitch_sequence_tmp[ntt_T_FR_MAX];
	double pitch_sequence_org[ntt_T_FR_MAX];
	double gain_tmp[ntt_T_SHRT_MAX];
	double gain_org[ntt_T_SHRT_MAX];
        double acc;

	ntt_zerod(ntt_T_FR_MAX,pitch_sequence_tmp);
	ntt_zerod(ntt_T_FR_MAX,pitch_sequence_org);
	ntt_zerod(ntt_T_SHRT_MAX,gain_tmp);
	ntt_zerod(ntt_T_SHRT_MAX,gain_org);
	ntt_zerod(ntt_T_FR_MAX,lpc_spect_tmp);
	ntt_zerod(ntt_T_FR_MAX,lpc_spect_org);
	ntt_zerod(ntt_T_FR_MAX,bark_env_tmp);
	ntt_zerod(ntt_T_FR_MAX,bark_env_org);


	/* Warning!!! mat_shift_min[0] & mat_shift_max[0] ==> Enh-1 */
	mat_shift_min[0]=0;
	mat_shift_min[1]=0;
	mat_shift_min[2]=0;
	mat_shift_min[3]=0;
	mat_shift_min[4]=0;
	mat_shift_min[5]=0;

	mat_shift_max[0]= 3 /*1 test  TM98506 */;
	mat_shift_max[1]= 3 /*2 test          */;
	mat_shift_max[2]= 3 /*2 test          */;
	mat_shift_max[3]=3;
	mat_shift_max[4]=3;
	mat_shift_max[5]=3;
/*	fprintf(stderr,"Low-pass Ver. \n");*/
	
	
	switch(index->w_type){
	case ONLY_LONG_WINDOW:			
	case LONG_SHORT_WINDOW:			
	case SHORT_LONG_WINDOW:			
	for(i_ch=0; i_ch<ntt_N_SUP; i_ch++){
	  if(iscl< 1) mat_shift[iscl][i_ch]=0;
	  else if (iscl >= 1) {
	     for(ii=0;ii<ntt_N_FR-1;ii++){
	     tmp_spect[ii] = fabs(0.5*(spectrum[ii+i_ch*ntt_N_FR]+
				       spectrum[ii+i_ch*ntt_N_FR+1]))/
		 sqrt(sqrt(fabs(0.5*(spectrum_org[ii+i_ch*ntt_N_FR]+
				     spectrum_org[ii+i_ch*ntt_N_FR+1]))+0.001));
	     }
	     tmp_spect[ntt_N_FR-1]=fabs(spectrum[ntt_N_FR-1+i_ch*ntt_N_FR])/
		 sqrt(sqrt(fabs(spectrum_org[ntt_N_FR-1+i_ch*ntt_N_FR])+0.001));
	  
	  if( ntt_ISAMPF == 24){
	   {
	     int ind, bias[4], qsample;
	     qsample = ntt_N_FR* 2./3.;
	     bias[0] = 0;
	     bias[1] = 1./12. *ntt_N_FR;
	     bias[2] = 1./6. *ntt_N_FR;
	     bias[3] = 1./3. *ntt_N_FR;
	     for(ind=0; ind<4; ind++){
	       for(acc=0.0, ii=bias[ind];ii<bias[ind]+qsample;ii++){
		  acc+= (tmp_spect[ii]*tmp_spect[ii]);
	       }
	       if(ind ==0)      err[ind] = acc*mat_ERR_WEI_0;
	       else if(ind ==1) err[ind] = acc*mat_ERR_WEI_1;
	       else if(ind ==2) err[ind] = acc*mat_ERR_WEI_2;
	       else if(ind ==3) err[ind] = acc*mat_ERR_WEI_3;
	    }
	   }
	  }
	  else{
	   {
	   int ind, bias, qsample;
	   for(ind=0; ind<4; ind++){
             qsample=ntt_N_FR*(ntt_AC_TOP[iscl][i_ch][ind] 
                    -   ntt_AC_BTM[iscl][i_ch][ind]);
             bias =  ntt_N_FR*ntt_AC_BTM[iscl][i_ch][ind];
	  
	     for(acc=0.0, ii=bias;ii<bias+qsample;ii++){
		  acc+= (tmp_spect[ii]*tmp_spect[ii]);
	     }
	     if(ind ==0)      err[ind] = acc*mat_ERR_WEI_0;
	     else if(ind ==1) err[ind] = acc*mat_ERR_WEI_1;
	     else if(ind ==2) err[ind] = acc*mat_ERR_WEI_2;
	     else if(ind ==3) err[ind] = acc*mat_ERR_WEI_3;
	    }
	   }
	  }
	     err_max=0.0;
	     for(ii=mat_shift_min[iscl-1];ii<mat_shift_max[iscl-1];ii++){/* Modified by Tomokazu Ishikawa 980304 */
		  if(err_max<err[ii]){
		       err_max=err[ii];
		       mat_shift[iscl][i_ch]=ii;
		  }
	     }
	   }
	}
	     break;
	case ONLY_SHORT_WINDOW:
	   for(i_ch=0; i_ch<ntt_N_SUP; i_ch++){
	       switch(iscl){ /* Original Position */
			 case 1:
			 mat_shift[iscl][i_ch]=0;
			 break;
			 case 2:
			 mat_shift[iscl][i_ch]=0;
			 break;
			 case 3:
			 mat_shift[iscl][i_ch]=2;
			 break;
			 case 4:
			 mat_shift[iscl][i_ch]=2;
			 break;
			 case 5:
			 mat_shift[iscl][i_ch]=3;
			 break;
			 case 6:
			 mat_shift[iscl][i_ch]=0;
			 break;
			 default:
			 break;
	     }
	   }
	     break;
        default:
             fprintf( stderr,"Fatal error! %d: no such window type.\n", index->w_type );
             exit(1);
	}

#if 0 /* For Debugging flexible Tomokazu Ishikawa */
     switch(iscl){ /* Flex Position */
		 case 1:
		 mat_shift[iscl]=3;
		 break;
		 case 2:
		 mat_shift[iscl]=0;
		 break;
		 case 3:
		 mat_shift[iscl]=2;
		 break;
		 case 4:
		 mat_shift[iscl]=2;
		 break;
		 case 5:
		 mat_shift[iscl]=3;
		 break;
		 case 6:
		 mat_shift[iscl]=0;
		 break;
		 default:
		 break;
	     }	
#endif /* for debug */

/*	fprintf(stderr,"   mat_shift[%d] %d",iscl,mat_shift[iscl]);*/

	return(0);

} /** end fix_or_flex **/

void mat_scale_tf_quantize_spectrum(double spectrum[],
                                    double lpc_spectrum[],
                                    double bark_env[],
                                    double pitch_sequence[],
                                    double gain[],
                                    double perceptual_weight[],
                                    ntt_INDEX *index,
                                    int       iscl)
{
  /*--- Variables ---*/
  int    ismp, nfr, nsf, n_can, vq_bits, cb_len_max,
         subtop, isf, i_ch;
  double add_signal[ntt_T_FR_MAX];
  double *sp_cv0, *sp_cv1;
  double spec_buf[ntt_T_FR_MAX],lpc_buf[ntt_T_FR_MAX],bark_buf[ntt_T_FR_MAX],
         wei_buf[ntt_T_FR_MAX];
  int qsample[ntt_N_SUP_MAX], bias[ntt_N_SUP_MAX];

  /*--- Parameter settings ---*/
  switch (index->w_type){
  case ONLY_LONG_WINDOW:
  case LONG_SHORT_WINDOW:
  case SHORT_LONG_WINDOW:
    /* available bits */
    vq_bits = ntt_VQTOOL_BITS_SCL[iscl];
    /* codebooks */
    sp_cv0 = (double *)ntt_codev0_scl[iscl];
    sp_cv1 = (double *)ntt_codev1_scl[iscl];
    cb_len_max = ntt_CB_LEN_READ_SCL[iscl] + ntt_CB_LEN_MGN;
    /* number of pre-selection candidates */
    n_can = ntt_N_CAN_SCL[iscl];
    /* frame size */
    nfr = ntt_N_FR;
    nsf = ntt_N_SUP;
    /* additional signal */
    for (ismp=0; ismp<ntt_N_FR*ntt_N_SUP; ismp++){
      add_signal[ismp] = pitch_sequence[ismp] / lpc_spectrum[ismp];
  }
    break;
 case ONLY_SHORT_WINDOW:
    /* available bits */
    vq_bits = ntt_VQTOOL_BITS_S_SCL[iscl];
    /* codebooks */
    sp_cv0 = (double *)ntt_codev0s_scl[iscl];
    sp_cv1 = (double *)ntt_codev1s_scl[iscl];
    cb_len_max = ntt_CB_LEN_READ_S_SCL[iscl] + ntt_CB_LEN_MGN;
    /* number of pre-selection candidates */
    n_can = ntt_N_CAN_S_SCL[iscl];
    /* number of subframes in a frame */
    nfr = ntt_N_FR_S;
    nsf = ntt_N_SUP * ntt_N_SHRT;
    /* additional signal */
    ntt_zerod(ntt_N_FR*ntt_N_SUP, add_signal);
    break;
 default:
    fprintf(stderr, "ntt_sencode(): %d: Window mode error.\n", index->w_type);
    exit(1);
}

  /*--- Vector quantization process ---*/
/* Base,Enh-1 : fix ,,,, Enh-2... : flex  980302 Tomokazu Ishikawa */
  if(iscl >= 1){
    ntt_zerod(ntt_N_FR*ntt_N_SUP,spec_buf);
    ntt_setd(ntt_N_FR*ntt_N_SUP,1.e5,lpc_buf);
    ntt_setd(ntt_N_FR*ntt_N_SUP,1.e-1,bark_buf);
    ntt_setd(ntt_N_FR*ntt_N_SUP,2.e3,wei_buf);
    for(i_ch = 0; i_ch<ntt_N_SUP; i_ch++){
      qsample[i_ch]=nfr*(ntt_AC_TOP[iscl][i_ch][mat_shift[iscl][i_ch]] 
                    -   ntt_AC_BTM[iscl][i_ch][mat_shift[iscl][i_ch]]);
      bias[i_ch] =  nfr *ntt_AC_BTM[iscl][i_ch][mat_shift[iscl][i_ch]];
    }
    for(isf=0;isf<nsf;isf++){
	subtop= isf*nfr;
        i_ch = subtop/ntt_N_FR;
        ntt_movdd(qsample[i_ch],spectrum+subtop+bias[i_ch],spec_buf+subtop);
        ntt_movdd(qsample[i_ch],lpc_spectrum+subtop+bias[i_ch],lpc_buf+subtop);
        ntt_movdd(qsample[i_ch],bark_env+subtop+bias[i_ch],bark_buf+subtop);
        ntt_movdd(qsample[i_ch],perceptual_weight+subtop+bias[i_ch],wei_buf+subtop);
    }
        ntt_movdd(ntt_N_FR*ntt_N_SUP,spec_buf,spectrum);
        ntt_movdd(ntt_N_FR*ntt_N_SUP,lpc_buf,lpc_spectrum);
        ntt_movdd(ntt_N_FR*ntt_N_SUP,bark_buf,bark_env);
        ntt_movdd(ntt_N_FR*ntt_N_SUP,wei_buf,perceptual_weight);
                                
   }
	   
/* Fix or Flex 980302 Tomokazu Ishikawa*/
  ntt_vq_pn(nfr, nsf, vq_bits, n_can,
            sp_cv0, sp_cv1, cb_len_max,
            spectrum, lpc_spectrum, bark_env, add_signal, gain,
            perceptual_weight,
            index->wvq);
}



/** moriya informed and add **/
void ntt_scalebase_enc_lpc_spectrum  /* Takehiro Moriya*/
       (/* Parameters */
       int    nfr,
       int    nsf,
       int    n_ch,
       int    n_pr,
       double *lsp_code,
       double *lsp_fgcode,
        int    *lsp_csize,
        int    *lsp_cdim,
        double prev_buf[ntt_N_SUP_MAX][ntt_MA_NP][ntt_N_PR_MAX+1],
        int    ma_np,
        /* Input */
        double spectrum[],
        int    w_type,
        int    current_block,
        /* Output */
        int    index_lsp[ntt_N_SUP_MAX][ntt_LSP_NIDX_MAX],
        double lpc_spectrum[],
        double band_lower,
        double band_upper
        )
{
       /*--- Variables ---*/
       double resid, alf[ntt_N_SUP_MAX][ntt_N_PR_MAX+1],
       lsp[ntt_N_PR_MAX+1], lspq[ntt_N_SUP_MAX*(ntt_N_PR_MAX+1)];
       double spectrum_wide[ntt_T_FR_MAX],
              lpc_spectrum_re[ntt_T_FR_MAX];
       int    i_sup, top, subtop, w_type_t, isf, lsptop, ismp;
       int    block_size, nfr_l, nfr_u, nfr_lu;
       block_size = nfr * nsf;
       nfr_u = (int)(nfr*band_upper);
       nfr_l = (int)(nfr*band_lower);
       nfr_lu = (int)(nfr*(band_upper-band_lower));

       /*--- encode LSP coefficients ---*/
       if (current_block == ntt_BLOCK_LONG) w_type_t = w_type;
       else                                 w_type_t = ONLY_LONG_WINDOW;

       for ( i_sup=0; i_sup<n_ch; i_sup++ ){
         top    = i_sup*block_size;
        ntt_zerod(block_size, spectrum_wide+top);
        ntt_setd(block_size,1.e5, lpc_spectrum+top);
  
         /*--- band extension for nallow band lpc (by A.Jin 1997.6.9) ---*/
         for(isf=0; isf<nsf; isf++){
           subtop = top + isf*nfr;
          for(ismp=nfr_l; ismp<nfr_u; ismp++){
           spectrum_wide[(int)((ismp-nfr_l)/
           (band_upper-band_lower)+subtop)]=spectrum[ismp+subtop];
      }
      }
   
         /* calculate LSP coefficients */
         ntt_scale_fgetalf(nfr, nsf, spectrum_wide+top,alf[i_sup],&resid,
                           n_pr, ntt_BAND_EXP);
         ntt_alflsp(n_pr, alf[i_sup], lsp);
         /* quantize LSP coefficients */
           ntt_lsp_encw(n_pr, (double (*)[ntt_N_PR_MAX])lsp_code,
                      (double (*)[ntt_MA_NP][ntt_N_PR_MAX])lsp_fgcode,
                      lsp_csize,
                      prev_buf[i_sup], ma_np,
                      lsp, lspq+i_sup*n_pr,
                      index_lsp[i_sup], ntt_LSP_SPLIT);
    }
   
       /*--- reconstruct LPC spectrum ---*/
       for (i_sup=0; i_sup<n_ch; i_sup++){
         top = i_sup * block_size;
         lsptop = i_sup * n_pr;
         ntt_lsptowt(nfr, n_pr, lspq+lsptop, lpc_spectrum+top);
       /*--- band re-extension for nallow band lpc (by A.Jin 1997.6.9) ---*/
        for(ismp=0; ismp<nfr_lu; ismp++){
            lpc_spectrum_re[ismp+top+nfr_l]
               = lpc_spectrum[(int)(ismp/(band_upper-band_lower))+top];
       }
         ntt_movdd(nfr_lu,lpc_spectrum_re+top+nfr_l, lpc_spectrum+top+nfr_l);
         ntt_setd(nfr_l, 999., lpc_spectrum+top);
         ntt_setd(nfr- nfr_u, 999., lpc_spectrum+top+nfr_u);
   
         for (isf=1; isf<nsf; isf++){
           subtop = top + isf*nfr;
           ntt_movdd(nfr, lpc_spectrum+top, lpc_spectrum+subtop);
      }
    }
  }
