/*****************************************************************************/
/* 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,
   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[],
   /* 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 yylpc[ntt_T_WDW_MAX], spectrum_wide[ntt_T_FR_MAX],
         lpc_spectrum_re[ntt_T_FR_MAX];
  int    i_sup, ii,jj, top, subtop, w_type_t, isf, lsptop, ismp;
  int    block_size, nfr_l, nfr_u, nfr_lu;
  block_size = nfr * nsf;
  nfr_u = nfr*band_upper;
  nfr_l = nfr*band_lower;
  nfr_lu = 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,
                      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], ntt_lsp_cdim_scl[iscl],
                 prev_buf[i_sup], ma_np,
                 i_sup, 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++){
    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);
  }
}
}


#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], xi[ntt_N_FR_MAX*2];
    int    ismp, isf, ex;

    /*--- 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 ---*/
    xr[0] = powspec[0];
    xi[0] = 0.;
    xr[nfr] = xi[nfr] = 0.;
    for (ismp=1; ismp<nfr; ismp++){
      xr[ismp] = xr[nfr*2-ismp] = powspec[ismp];
      xi[ismp] = xi[nfr*2-ismp] = 0.;
    }
    ex = (int)(log(nfr)/log(2.)+0.1) + 1;
    ntt_fft(xr, xi, ex);
    ntt_movdd(n_pr+1, xr, cor);
    for (ip=1; ip<=n_pr; ip++){
      cor[ip] /= cor[0] + 1.e-5;
    }
    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 */
				   /* Input */
				   ntt_PARAM *param_ntt,  /* encoding parameters */
				   double lpc_spectrum_org[]) /* not used */
{
    /*--- 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, param_ntt);
            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, param_ntt);
	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 */
                                ntt_PARAM param_ntt,
                                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, i_nsp;
  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:
  case LONG_MEDIUM_WINDOW: case MEDIUM_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_MEDIUM_WINDOW: case MEDIUM_SHORT_WINDOW: case SHORT_MEDIUM_WINDOW:
    /* subframe */
    nfr = ntt_N_FR_M;
    nsf = ntt_N_MID;
    n_ch = ntt_N_SUP;
    /* Bark-scale table (Bark-scale envelope) */
    n_crb    = ntt_N_CRB_M_SCL[iscl];
    bark_tbl = ntt_crb_tbl_m_scl[iscl];
    /* quantization (Bark-scale envelope) */
    fw_ndiv = ntt_FW_N_DIV_M_SCL[iscl];
    fw_cb_size = ntt_FW_CB_SIZE_M_SCL[iscl];
    fw_length  = ntt_FW_CB_LEN_M_SCL[iscl];
    fw_len_max = ntt_FW_CB_LEN_M_SCL[iscl];
    fw_codev = (double *)ntt_fwcodevm_scl[iscl];
    fw_prcpt = 0.5;
    fw_env_memory = fw_env_memory_medium[iscl];
    /* envelope calculation (Bark-scale envelope) */
    fw_pdot = fw_pdot_medium[iscl];
    current_block = ntt_BLOCK_MEDIUM;
    fw_nbit = ntt_FW_N_BIT_M_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;
}
  /* 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];

  /*--- 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 */
  ntt_scale_enc_lpc_spectrum(nfr, nsf, n_ch, n_pr, lsp_code, lsp_fgcode,
                             lsp_csize, lsp_cdim, prev_buf[iscl], ma_np[iscl],
                             spectrum, index->w_type, current_block,
                             index->lsp, lpc_spectrum, iscl,
                             band_lower, band_upper);
  /* pre process (bandwidth setting) */
  ntt_freq_domain_pre_process(nfr, nsf, band_lower, band_upper,
                              spectrum, lpc_spectrum_org, param_ntt,
                              spectrum, lpc_spectrum_mod);
  ntt_freq_domain_pre_process(nfr, nsf, band_lower, band_upper,
                              spectrum, lpc_spectrum, param_ntt,
                              spectrum, lpc_spectrum);

  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_lower);

}
  /* 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_tf_quantize_spectrum(double spectrum[],
                                    double lpc_spectrum[],
                                    double bark_env[],
                                    double pitch_sequence[],
                                    double gain[],
                                    double perceptual_weight[],
                                    ntt_INDEX *index,
                                    ntt_PARAM *param_ntt,
                                    int       iscl)
{
  /*--- Variables ---*/
  int    ismp, nfr, nsf, bits_side_info, n_can, vq_bits, cb_len_max,
         subtop, isf, ii;
  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];
  double spectrum_buf[ntt_T_FR_MAX];

  /*--- Parameter settings ---*/
  switch (index->w_type){
  case ONLY_LONG_WINDOW:
  case LONG_SHORT_WINDOW:
  case SHORT_LONG_WINDOW:
  case LONG_MEDIUM_WINDOW:
  case MEDIUM_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_MEDIUM_WINDOW:
 case MEDIUM_SHORT_WINDOW:
 case SHORT_MEDIUM_WINDOW:
    /* available bits */
    vq_bits = ntt_VQTOOL_BITS_M_SCL[iscl];
    /* codebooks */
    sp_cv0 = (double *)ntt_codev0m_scl[iscl];
    sp_cv1 = (double *)ntt_codev1m_scl[iscl];
    cb_len_max = ntt_CB_LEN_READ_M_SCL[iscl] + ntt_CB_LEN_MGN;
    /* number of pre-selection candidates */
    n_can = ntt_N_CAN_M_SCL[iscl];
    /* number of subframes in a frame */
    nfr = ntt_N_FR_M;
    nsf = ntt_N_SUP * ntt_N_MID;
    /* additional signal */
    ntt_zerod(ntt_N_FR*ntt_N_SUP, add_signal);
    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 ---*/

      ntt_movdd(ntt_N_FR, spectrum, spectrum_buf);

  if(iscl >= 2){
    ntt_zerod(ntt_N_FR,spec_buf);
    ntt_setd(ntt_N_FR,1.e5,lpc_buf);
    ntt_setd(ntt_N_FR,1.e-1,bark_buf);
    ntt_setd(ntt_N_FR,2.e3,wei_buf);

    switch(iscl){
    case 2:
      for(isf=0;isf<nsf;isf++){
        subtop= isf*nfr;
        /*
        ntt_movdd(nfr/3,spectrum+nfr/6+subtop,spec_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,lpc_spectrum+nfr/6+subtop,lpc_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,bark_env+nfr/6+subtop,bark_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,perceptual_weight+nfr/6+subtop,wei_buf+nfr/6+subtop);
        */
        ntt_movdd(nfr/3,spectrum+subtop,spec_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,lpc_spectrum+subtop,lpc_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,bark_env+subtop,bark_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,perceptual_weight+subtop,wei_buf+nfr/6+subtop);
      /*MORIYA*/}
      ntt_movdd(ntt_N_FR,spec_buf,spectrum_buf);
      ntt_movdd(ntt_N_FR,lpc_buf,lpc_spectrum);
      ntt_movdd(ntt_N_FR,bark_buf,bark_env);
      ntt_movdd(ntt_N_FR,wei_buf,perceptual_weight);
      break;
  case 3:
      for(isf=0;isf<nsf;isf++){
        subtop= isf*nfr;
        ntt_movdd(nfr/3,spectrum+nfr/3+subtop,spec_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,lpc_spectrum+nfr/3+subtop,lpc_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,bark_env+nfr/3+subtop,bark_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,perceptual_weight+nfr/3+subtop,wei_buf+nfr/6+subtop);
    }
      ntt_movdd(ntt_N_FR,spec_buf,spectrum_buf);
      ntt_movdd(ntt_N_FR,lpc_buf,lpc_spectrum);
      ntt_movdd(ntt_N_FR,bark_buf,bark_env);
      ntt_movdd(ntt_N_FR,wei_buf,perceptual_weight);
      break;
  case 4:
      for(isf=0;isf<nsf;isf++){
        subtop= isf*nfr;
        ntt_movdd(nfr/3,spectrum+nfr/3+subtop,spec_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,lpc_spectrum+nfr/3+subtop,lpc_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,bark_env+nfr/3+subtop,bark_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,perceptual_weight+nfr/3+subtop,wei_buf+nfr/6+subtop);
    }
      ntt_movdd(ntt_N_FR,spec_buf,spectrum_buf);
      ntt_movdd(ntt_N_FR,lpc_buf,lpc_spectrum);
      ntt_movdd(ntt_N_FR,bark_buf,bark_env);
      ntt_movdd(ntt_N_FR,wei_buf,perceptual_weight);
      break;
  case 5:
      for(isf=0;isf<nsf;isf++){
        subtop= isf*nfr;
        ntt_movdd(nfr/3,spectrum+nfr*2/3+subtop,spec_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,lpc_spectrum+nfr*2/3+subtop,lpc_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,bark_env+nfr*2/3+subtop,bark_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,perceptual_weight+nfr*2/3+subtop,wei_buf+nfr/6+subtop);
    }
      ntt_movdd(ntt_N_FR,spec_buf,spectrum_buf);
      ntt_movdd(ntt_N_FR,lpc_buf,lpc_spectrum);
      ntt_movdd(ntt_N_FR,bark_buf,bark_env);
      ntt_movdd(ntt_N_FR,wei_buf,perceptual_weight);
      break;
  case 6:
      for(isf=0;isf<nsf;isf++){
        subtop= isf*nfr;
        ntt_movdd(nfr/3,spectrum+subtop,spec_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,lpc_spectrum+subtop,lpc_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,bark_env+subtop,bark_buf+nfr/6+subtop);
        ntt_movdd(nfr/3,perceptual_weight+subtop,wei_buf+nfr/6+subtop);
    }
      ntt_movdd(ntt_N_FR,spec_buf,spectrum_buf);
      ntt_movdd(ntt_N_FR,lpc_buf,lpc_spectrum);
      ntt_movdd(ntt_N_FR,bark_buf,bark_env);
      ntt_movdd(ntt_N_FR,wei_buf,perceptual_weight);
      break;
  }
}

  ntt_vq_pn(nfr, nsf, vq_bits, n_can,
            sp_cv0, sp_cv1, cb_len_max,
            spectrum_buf, lpc_spectrum, bark_env, add_signal, gain,
            perceptual_weight,
            index->wvq);
}


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);
      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= 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.0e-5;
  }
    for(ismp=bark_tbl[n_crb-1];ismp<nfr;ismp++){
      pred[ismp]=1.0e-5;
  }

    for(ib=0, ismp=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 norm, pwr;
  double sub_pwr_tmp, sub_pwr[ntt_N_SHRT_MAX];
  double g_gain, g_norm;

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



#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

int mat_scale_lay_shift(double spectrum[],
			double spectrum_org[],
			double lpc[],
			double bark[],
			int iscl,
			ntt_INDEX *index,
			ntt_PARAM *para)
{
        int ii,jj,top;
        double err_max,err[4];
        static int mat_shift_max[5],mat_shift_min[5];
        double tmp_spect[ntt_N_FR_MAX];
        static int short_flag,init_flag;
        static int pre_win;
        static int frame_count;
        static int speech_count;

        double time_diff[ntt_T_FR_MAX*3],time_org[ntt_T_FR_MAX*3];
        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];
        ntt_PARAM param_tmp;
        ntt_PARAM param_org;
        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 band_lower,band_upper;
        double tmp;

        ntt_zerod(ntt_T_FR_MAX*3,time_diff);
        ntt_zerod(ntt_T_FR_MAX*3,time_org);
        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);

#if 1
        switch(para->speech_sw)
	{

	case 1:
                        if(iscl==2)
			{
                                        speech_count++;
				    }
                        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_max[0]=1;
                        mat_shift_max[1]=2;
                        mat_shift_max[2]=2;
                        mat_shift_max[3]=2;
                        mat_shift_max[4]=2;

                        break;
		    case 0:
                        if((pre_win==ONLY_SHORT_WINDOW)&&(index->w_type==SHORT_LONG_WINDOW)&&(iscl==2))
			{
                                        frame_count=0;
                                        short_flag=1;
                                        init_flag=1;
                                        /*fprintf(stderr,"frame_count %d\n",frame_count);*/
				    }
                        if(iscl==2)
			{
                                        frame_count++;
				    }

                        if((iscl==2)&&(frame_count>=mat_SHORT_DELAY))
			{
                                        short_flag=0;
                                        init_flag=0;
                                        frame_count=0;
                                        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;
				    }

                        if(short_flag==1)
			{
                                        mat_shift_min[0]=1;
                                        mat_shift_min[1]=1;
                                        mat_shift_min[2]=1;
                                        mat_shift_min[3]=1;
                                        mat_shift_min[4]=1;
                                        init_flag=1;
				    }
                        mat_shift_max[0]=1;
                        mat_shift_max[1]=2;
                        mat_shift_max[2]=2;
                        mat_shift_max[3]=3;
                        mat_shift_max[4]=3;
                        break;
		    default:
                        fprintf(stderr,"speech-sw error in mat_scale_lay_shift\n");
                        exit(1);
		    }
        if(speech_count>mat_SPEECH)
	{
                        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_max[0]=1;
                        mat_shift_max[1]=2;
                        mat_shift_max[2]=2;
                        mat_shift_max[3]=2;
                        mat_shift_max[4]=2;
		    }
/*      if(iscl==2)
        fprintf(stderr,"mat_shift_min %d\n",mat_shift_min[0]);*/
#endif

#if 1 /* Long only  Shift Global optimization by Bark-scale spectrum */

        switch(index->w_type)
	{
	case ONLY_LONG_WINDOW:
	case LONG_SHORT_WINDOW:
	case SHORT_LONG_WINDOW:
	case LONG_MEDIUM_WINDOW:
	case MEDIUM_LONG_WINDOW:
                        ntt_tf_freq2time(spectrum,index->w_type,time_diff);
                        ntt_tf_freq2time(spectrum_org,index->w_type,time_org);
                        /* Copy */
                        band_lower=ntt_BAND_LOWER;
                        band_upper=ntt_BAND_UPPER;

                        /* Set */
                        ntt_BAND_LOWER=0.0;
                        ntt_BAND_UPPER=1.0;

                        mat_tf_proc_spectrum(time_org,spectrum_org,index,lpc_spect_org,bark_env_org,pitch_sequence_org,gain_org,param_org);
                        mat_tf_proc_spectrum(time_diff,spectrum,index,lpc_spect_tmp,bark_env_tmp,pitch_sequence_tmp,gain_tmp,param_tmp);

                        /* Copy again */
                        ntt_BAND_LOWER=band_lower;
                        ntt_BAND_UPPER=band_upper;

                        for(ii=0;ii<2048;ii++)
			{
                                        tmp=bark_env_org[ii]/lpc_spect_org[ii]-bark_env_tmp[ii]/lpc_spect_tmp[ii];
                                        if(tmp != 0.0)
					{
/*                                                      tmp_spect[ii] = fabs(tmp);*/
                                                        tmp_spect[ii] = mat_PERCEPT_POW*log(fabs(tmp));
/*                                                      tmp_spect[ii] = 1./pow(fabs(tmp),(double)mat_PERCEPT_POW);*/
/*                                                      tmp_spect[ii] = pow(fabs(tmp),(double)mat_PERCEPT_POW);*/
						    }
                                        else
					{
                                                        tmp_spect[ii] = 0.0;
						    }
				    }
                        err[0]=0.0;
                        for(ii=0;ii<(int)(2048./3.);ii++)
			{
                                        err[0]+= tmp_spect[ii]*mat_ERR_WEI_0;
				    }
                        err[1]=0.0;
                        for(ii=(int)(2048./6.);ii<(int)(2048./2.);ii++)
			{
                                        err[1]+= tmp_spect[ii]*mat_ERR_WEI_1;
				    }
                        err[2]=0.0;
                        for(ii=(int)(2048./3.);ii<(int)(2048.*2./3.);ii++)
			{
                                        err[2]+= tmp_spect[ii]*mat_ERR_WEI_2;
				    }
                        err[3]=0.0;
                        for(ii=(int)(2048.*2./3.);ii<2048;ii++)
			{
                                        err[3]+= tmp_spect[ii]*mat_ERR_WEI_3;
				    }

                        err_max=0.0;

                        for(ii=mat_shift_min[iscl-2];ii<mat_shift_max[iscl-2];ii++)
			{
                                        if(err_max<err[ii])
					{
                                                        err_max=err[ii];
                                                        mat_shift[iscl]=ii;
						    }
				    }

                        /*fprintf(stderr,"err_max %lf\n",err_max);*/
                        break;

		    case ONLY_MEDIUM_WINDOW:
		    case MEDIUM_SHORT_WINDOW:
		    case SHORT_MEDIUM_WINDOW:

#if 1
                        for(ii=0;ii<2048;ii++)
			{
                                        tmp_spect[ii] = ((spectrum_org[ii]-spectrum[ii])*(spectrum_org[ii]-spectrum[ii]))/(spectrum_org[ii]*spectrum_org[ii]);
				    }
                        err[0]=0.0;
                        err[1]=0.0;
                        err[2]=0.0;
                        err[3]=0.0;
                        for(jj=0;jj<ntt_N_MID;jj++)
			{
                                        top=(int)(jj*ntt_N_FR_M);
                                        for(ii=top;ii<(int)(ntt_N_FR_M/3.)+top;ii++)
					{
                                                        err[0]+= tmp_spect[ii]*mat_ERR_WEI_0;
						    }
                                        for(ii=(int)(ntt_N_FR_M/6.)+top;ii<(int)(ntt_N_FR_M/2.)+top;ii++)
					{
                                                        err[1]+= tmp_spect[ii]*mat_ERR_WEI_1;
						    }
                                        for(ii=(int)(ntt_N_FR_M/3.)+top;ii<(int)(ntt_N_FR_M*2./3.)+top;ii++)
					{
                                                        err[2]+= tmp_spect[ii]*mat_ERR_WEI_2;
						    }
                                        for(ii=(int)(ntt_N_FR_M*2./3.)+top;ii<ntt_N_FR_M+top;ii++)
					{
                                                        err[3]+= tmp_spect[ii]*mat_ERR_WEI_3;
						    }
				    }

                        err_max=0.0;

                        for(ii=mat_shift_min[iscl-2];ii<mat_shift_max[iscl-2];ii++)
			{
                                        if(err_max<err[ii])
					{
                                                        err_max=err[ii];
                                                        mat_shift[iscl]=ii;
						    }
				    }
#endif
                        break;

		    case ONLY_SHORT_WINDOW:

                        switch(iscl) /* Original Position */
			{
			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;
				    }
                        break;
		    }
#endif
        if(iscl==2)
	{
                        pre_win=index->w_type;
                        /*fprintf(stderr,"pre_win %d\n",pre_win);*/
		    }

/*
        if(mat_shift[iscl]!=0)
        fprintf(stderr,"mat_scale_lay_shift[%d] %d\n",iscl,mat_shift[iscl]);
*/
        return(0);
    }



#if 0
int mat_scale_set_shift_para(int iscl)
{
        int ii;

        switch(mat_shift[iscl])
	{
	case 0: /* 0 to 8kHz */
                        ntt_BAND_UPPER_SCL[iscl]=1./3.;
                        ntt_BAND_LOWER_SCL[iscl]=0.0;
                        /*fprintf(stderr," 0 to 8kHz \n");*/
                        break;
		    case 1: /* 4kHz to 12kHz */
                        ntt_BAND_UPPER_SCL[iscl]=0.5;
                        ntt_BAND_LOWER_SCL[iscl]=1./6.;
                        /*fprintf(stderr," 4 to 12kHz \n");*/
                        break;
		    case 2: /* 8kHz to 16kHz */
                        ntt_BAND_UPPER_SCL[iscl]=2./3.;
                        ntt_BAND_LOWER_SCL[iscl]=1./3.;
                        /*fprintf(stderr," 8 to 16kHz \n");*/
                        break;
		    case 3: /* 16kHz to 24kHz */
                        ntt_BAND_UPPER_SCL[iscl]=1.0;
                        ntt_BAND_LOWER_SCL[iscl]=2./3.;
                        /*fprintf(stderr," 16 to 24kHz \n");*/
                        break;
		    default:
                        fprintf(stderr,"SHIFT Error !! in mat_scale_set_para \n");
                        exit(1);
                        break;
		    }

        /* Long */
        for(ii=0;ii<ntt_N_CRB_48_2048_3rd;ii++){
                ntt_crb_tbl_scl[iscl][ii] = (int)(((ntt_BAND_LOWER_SCL[iscl] - ntt_BAND_LOWER_SCL[1])*ntt_N_FR ) + ntt_crb_tbl_48_2048_3rd[ii]);
	    }

        /* Short */
        ntt_N_CRB_S_SCL[iscl]=ntt_N_CRB_S_48_128_3rd;

        for(ii=0;ii<ntt_N_CRB_S_SCL[iscl];ii++){
                ntt_crb_tbl_s_scl[iscl][ii] = (int)(((ntt_BAND_LOWER_SCL[iscl] - ntt_BAND_LOWER_SCL[1])*ntt_N_FR/ntt_N_SHRT ) + ntt_crb_tbl_s_48_128_3rd[ii]);
	    }

        /* Mid */
        ntt_N_CRB_M_SCL[iscl]=ntt_N_CRB_48_512_3rd;
        for(ii=0;ii<ntt_N_CRB_M_SCL[iscl];ii++){
                ntt_crb_tbl_m_scl[iscl][ii] = (int)(((ntt_BAND_LOWER_SCL[iscl] - ntt_BAND_LOWER_SCL[1])*ntt_N_FR/ntt_N_MID ) + ntt_crb_tbl_48_512_3rd[ii]);
	    }

        return(0);
    }

#endif


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,
                                    ntt_PARAM *param_ntt,
                                    int       iscl)
{
  /*--- Variables ---*/
  int    ismp, nfr, nsf, bits_side_info, n_can, vq_bits, cb_len_max,
         subtop, isf, ii;
  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];

  /*--- Parameter settings ---*/
  switch (index->w_type){
  case ONLY_LONG_WINDOW:
  case LONG_SHORT_WINDOW:
  case SHORT_LONG_WINDOW:
  case LONG_MEDIUM_WINDOW:
  case MEDIUM_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_MEDIUM_WINDOW:
 case MEDIUM_SHORT_WINDOW:
 case SHORT_MEDIUM_WINDOW:
    /* available bits */
    vq_bits = ntt_VQTOOL_BITS_M_SCL[iscl];
    /* codebooks */
    sp_cv0 = (double *)ntt_codev0m_scl[iscl];
    sp_cv1 = (double *)ntt_codev1m_scl[iscl];
    cb_len_max = ntt_CB_LEN_READ_M_SCL[iscl] + ntt_CB_LEN_MGN;
    /* number of pre-selection candidates */
    n_can = ntt_N_CAN_M_SCL[iscl];
    /* number of subframes in a frame */
    nfr = ntt_N_FR_M;
    nsf = ntt_N_SUP * ntt_N_MID;
    /* additional signal */
    ntt_zerod(ntt_N_FR*ntt_N_SUP, add_signal);
    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 ---*/

  if(iscl >= 2){
    ntt_zerod(ntt_N_FR,spec_buf);
    ntt_setd(ntt_N_FR,1.e5,lpc_buf);
    ntt_setd(ntt_N_FR,1.e-1,bark_buf);
    ntt_setd(ntt_N_FR,2.e3,wei_buf);

        switch(mat_shift[iscl])
	{
	case 0: /* 0 to 8kHz */
                        for(isf=0;isf<nsf;isf++){
                                subtop= isf*nfr;
                                ntt_movdd(nfr/3,spectrum+subtop,spec_buf+nfr/6+subtop);
                                ntt_movdd(nfr/3,lpc_spectrum+subtop,lpc_buf+nfr/6+subtop);
                                ntt_movdd(nfr/3,bark_env+subtop,bark_buf+nfr/6+subtop);
                                ntt_movdd(nfr/3,perceptual_weight+subtop,wei_buf+nfr/6+subtop);
			    }
                        ntt_movdd(ntt_N_FR,spec_buf,spectrum);
                        ntt_movdd(ntt_N_FR,lpc_buf,lpc_spectrum);
                        ntt_movdd(ntt_N_FR,bark_buf,bark_env);
                        ntt_movdd(ntt_N_FR,wei_buf,perceptual_weight);
                        break;

		    case 1: /* 4 to 12kHz */
                        /* Shift don't need */
                        break;
		    case 2: /* 8 to 16kHz */
                        for(isf=0;isf<nsf;isf++){
                                subtop= isf*nfr;
                                ntt_movdd(nfr/3,spectrum+nfr/3+subtop,spec_buf+nfr/6+subtop);
                                ntt_movdd(nfr/3,lpc_spectrum+nfr/3+subtop,lpc_buf+nfr/6+subtop);
                                ntt_movdd(nfr/3,bark_env+nfr/3+subtop,bark_buf+nfr/6+subtop);
                                ntt_movdd(nfr/3,perceptual_weight+nfr/3+subtop,wei_buf+nfr/6+subtop);
			    }
                        ntt_movdd(ntt_N_FR,spec_buf,spectrum);
                        ntt_movdd(ntt_N_FR,lpc_buf,lpc_spectrum);
                        ntt_movdd(ntt_N_FR,bark_buf,bark_env);
                        ntt_movdd(ntt_N_FR,wei_buf,perceptual_weight);
                        break;

		    case 3: /* 16 to 24kHz */
                        for(isf=0;isf<nsf;isf++){
                                subtop= isf*nfr;
                                ntt_movdd(nfr/3,spectrum+nfr*2/3+subtop,spec_buf+nfr/6+subtop);
                                ntt_movdd(nfr/3,lpc_spectrum+nfr*2/3+subtop,lpc_buf+nfr/6+subtop);
                                ntt_movdd(nfr/3,bark_env+nfr*2/3+subtop,bark_buf+nfr/6+subtop);
                                ntt_movdd(nfr/3,perceptual_weight+nfr*2/3+subtop,wei_buf+nfr/6+subtop);
			    }
                        ntt_movdd(ntt_N_FR,spec_buf,spectrum);
                        ntt_movdd(ntt_N_FR,lpc_buf,lpc_spectrum);
                        ntt_movdd(ntt_N_FR,bark_buf,bark_env);
                        ntt_movdd(ntt_N_FR,wei_buf,perceptual_weight);
                        break;
		    default:
                        fprintf(stderr,"shift error !! in mat_scale_tf_quantize_spectrum\n");
                        break;
		    }
}

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



void mat_tf_proc_spectrum(/* Input */
                          double sig[],
                          double spectrum[],
                          /* In/Out */
                          ntt_INDEX  *index,
                          /* Output */
                          double lpc_spectrum[],
                          double bark_env[],
                          double pitch_sequence[],
                          double gain[],
                          /* In/Out */
                          ntt_PARAM param_ntt)
{
  double tc[ntt_T_FR_MAX], pwt[ntt_T_FR_MAX];
  int    current_block, i_ch, i_ma;
  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_T_FR_MAX];
  static double fw_pdot_medium[ntt_T_FR_M_MAX];
  static double fw_pdot_short[ntt_T_FR_S_MAX];
  static double fw_env_memory_long[ntt_N_CRB_MAX*ntt_N_SUP_MAX];
  static double fw_env_memory_medium[ntt_N_CRB_M_MAX*ntt_N_SUP_MAX];
  static double fw_env_memory_short[ntt_N_CRB_S_MAX*ntt_N_SUP_MAX];
  static int    p_w_type;
  int ifr;
  int isf, top, subtop, ismp, block_size;
  /* LPC spectrum */
  static double prev_buf[ntt_N_SUP_MAX][ntt_MA_NP][ntt_N_PR_MAX+1];
  static int ma_np;

  InitFlag=1;

  /*--- Set parameters ---*/
  switch(index->w_type){
  case ONLY_LONG_WINDOW: case LONG_SHORT_WINDOW: case SHORT_LONG_WINDOW:
  case LONG_MEDIUM_WINDOW: case MEDIUM_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;
    bark_tbl = ntt_crb_tbl;
    /* quantization (Bark-scale envelope) */
    fw_ndiv = ntt_FW_N_DIV;
    fw_cb_size = ntt_FW_CB_SIZE;
    fw_length = ntt_FW_CB_LEN;
    fw_codev = (double *)ntt_fwcodev;
    fw_len_max = ntt_FW_CB_LEN;
    fw_prcpt = 0.4;
    fw_env_memory = fw_env_memory_long;
    /* envelope calculation (Bark-scale envelope) */
    fw_pdot = fw_pdot_long;
    current_block = ntt_BLOCK_LONG;
    break;
 case ONLY_MEDIUM_WINDOW: case MEDIUM_SHORT_WINDOW: case SHORT_MEDIUM_WINDOW:
    /* subframe */
    nfr = ntt_N_FR_M;
    nsf = ntt_N_MID;
    n_ch = ntt_N_SUP;
    /* Bark-scale table (Bark-scale envelope) */
    n_crb    = ntt_N_CRB_M;
    bark_tbl = ntt_crb_tbl_m;
    /* quantization (Bark-scale envelope) */
    fw_ndiv = ntt_FW_N_DIV_M;
    fw_cb_size = ntt_FW_CB_SIZE_M;
    fw_length = ntt_FW_CB_LEN_M;
    fw_codev = (double *)ntt_fwcodevm;
    fw_len_max = ntt_FW_CB_LEN_M;
    fw_prcpt = 0.5;
    fw_env_memory = fw_env_memory_medium;
    /* envelope calculation (Bark-scale envelope) */
    fw_pdot = fw_pdot_medium;
    current_block = ntt_BLOCK_MEDIUM;
    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;
    bark_tbl = ntt_crb_tbl_s;
    /* quantization (Bark-scale envelope) */
    fw_ndiv = ntt_FW_N_DIV_S;
    fw_cb_size = ntt_FW_CB_SIZE_S;
    fw_length = ntt_FW_CB_LEN_S;
    fw_codev = (double *)ntt_fwcodevs;
    fw_len_max = ntt_FW_CB_LEN_S;
    fw_prcpt = 0.5;
    fw_env_memory = fw_env_memory_short;
    /* envelope calculation (Bark-scale envelope) */
    fw_pdot = fw_pdot_short;
    current_block = ntt_BLOCK_SHORT;
    break;
}
  /* pre process (bandwidth setting) */
  band_lower = ntt_BAND_LOWER;
  band_upper = ntt_BAND_UPPER;
  /* LPC spectrum */
  n_pr = ntt_N_PR;
  lsp_code   = (double *)lsp_code_base;
  lsp_fgcode = (double *)lsp_fgcode_base;
  lsp_csize      = ntt_lsp_csize_base;
  lsp_cdim       = ntt_lsp_cdim_base;

  block_size = nfr*nsf;

  /*--- Initialize ---*/
  if (InitFlag){
    /* Bark-scale envelope */
    ntt_setd(ntt_N_FR  *ntt_N_SUP, 0.1, fw_pdot_long);
    ntt_setd(ntt_N_FR_M*ntt_N_SUP, 0.1, fw_pdot_medium);
    ntt_setd(ntt_N_FR_S*ntt_N_SUP, 0.1, fw_pdot_short);

    ntt_zerod(ntt_N_CRB  *ntt_N_SUP, fw_env_memory_long);
    ntt_zerod(ntt_N_CRB_M*ntt_N_SUP, fw_env_memory_medium);
    ntt_zerod(ntt_N_CRB_S*ntt_N_SUP, fw_env_memory_short);

    p_w_type = 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[i_ch][i_ma] );
    }
  }
    ma_np = 0;
}
  InitFlag=0;


  /*--- Encoding tools ---*/
  /* LPC spectrum encoding */
  ntt_enc_lpc_spectrum(nfr, nsf, n_ch, n_pr, lsp_code, lsp_fgcode,
                       lsp_csize, lsp_cdim, prev_buf, ma_np,
                       sig, index->w_type, current_block,
                       index->lsp, lpc_spectrum);

  /* pre process (bandwidth setting) */
  ntt_freq_domain_pre_process(nfr, nsf, /*n_ch,*/ band_lower, band_upper,
                              spectrum, lpc_spectrum, param_ntt,
                              spectrum, lpc_spectrum);
  /* periodic peak components encoding */
  if(ntt_TBIT_P > 0){
    ntt_enc_pitch(spectrum, lpc_spectrum, index->w_type,
                  index->pit, index->pls, index->pgain, pitch_sequence);
}
  else{
    ntt_zerod(ntt_N_FR*ntt_N_SUP, pitch_sequence);
}
  /* Bark-scale envelope encoding */

  if(fw_cb_size==1){
    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,
                   spectrum, lpc_spectrum, pitch_sequence, current_block,
                   tc, pwt, index->fw, index->fw_alf, bark_env, band_lower);
}
   /* gain encoding */
  ntt_enc_gain_t(nfr, nsf, n_ch, bark_env, tc, index->pow, gain);

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



void ntt_tf_freq2time(/* Input */
                  double spectrum[],
                  int    w_type,
                  /* Output */
                  double audio_sample[])
{
    /*--- Variables ---*/
    static int InitFlag = 1;
    static int InitFlagL = 1;
    static int InitFlagM = 1;
    static int InitFlagS = 1;
    static double prev[ntt_T_FR_MAX];
    double out2[ntt_N_WDW_MAX], prev_m[ntt_N_FR_M_MAX], prev_s[ntt_N_FR_S_MAX];
    double theta, dt;
    int    ii, i_sup, top, isf, subtop, w_type_t;

    /*--- Initialization ---*/
    if (InitFlag){
        ntt_zerod( ntt_N_FR*ntt_N_SUP, prev );
    }

    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;
            ntt_imdct_l(spectrum+top, out2);
            ntt_imdctwd( out2, audio_sample+top, prev+top, w_type );
        }
        InitFlagL = 0;
        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;

            /*--- IMDCT ---*/
            ntt_movdd(ntt_N_FR/2-ntt_N_FR_M/2, prev+top, audio_sample+top);
            ntt_movdd(ntt_N_FR_M, prev+top+ntt_N_FR/2-ntt_N_FR_M/2, prev_m);
            for (isf=0; isf<ntt_N_MID; isf++ ){
                subtop = isf*ntt_N_FR_M;
                ntt_imdct_m(spectrum+top+subtop, out2);
                w_type_t = ONLY_MEDIUM_WINDOW;
                if (w_type == SHORT_MEDIUM_WINDOW && isf == 0)
                    w_type_t = SHORT_MEDIUM_WINDOW;
                if (w_type == MEDIUM_SHORT_WINDOW && isf == ntt_N_MID-1)
                    w_type_t = MEDIUM_SHORT_WINDOW;
                ntt_imdctwd(out2, audio_sample+top+ntt_N_FR/2-ntt_N_FR_M/2+subtop,
                        prev_m, w_type_t);
            }
            ntt_movdd(ntt_N_FR/2-ntt_N_FR_M/2, audio_sample+top+ntt_N_FR, prev+top);
            ntt_movdd(ntt_N_FR_M, prev_m, prev+top+ntt_N_FR/2-ntt_N_FR_M/2);
            ntt_zerod(ntt_N_FR/2-ntt_N_FR_M/2, prev+top+ntt_N_FR/2+ntt_N_FR_M/2);
        }
        InitFlagM = 0;
        break;
    case ONLY_SHORT_WINDOW:
        for ( i_sup=0; i_sup<ntt_N_SUP; i_sup++ ){
            top = i_sup*ntt_N_FR;
            /*--- IMDCT ---*/
            ntt_movdd(ntt_N_FR/2-ntt_N_FR_S/2, prev+top, audio_sample+top);
            ntt_movdd(ntt_N_FR_S, prev+top+ntt_N_FR/2-ntt_N_FR_S/2, prev_s);
            for (isf=0; isf<ntt_N_SHRT; isf++ ){
                subtop = isf*ntt_N_FR_S;
                ntt_imdct_s(spectrum+top+subtop, out2);
                ntt_imdctwd( out2, audio_sample+top+ntt_N_FR/2-ntt_N_FR_S/2+subtop,
                        prev_s, ONLY_SHORT_WINDOW);
            }
            ntt_movdd(ntt_N_FR/2-ntt_N_FR_S/2, audio_sample+top+ntt_N_FR, prev+top);
            ntt_movdd(ntt_N_FR_S, prev_s, prev+top+ntt_N_FR/2-ntt_N_FR_S/2);
            ntt_zerod(ntt_N_FR/2-ntt_N_FR_S/2, prev+top+ntt_N_FR/2+ntt_N_FR_S/2);
        }
        InitFlagS = 0;
        break;
    }

    InitFlag = 0;
}




void ntt_imdctwd(double sig[],
             double out[],
             double prev[],
             int w_type)
{
    /*--- Variables ---*/
    int         mm, nn, kk, ll, oo, pp;

    nn = ntt_N_FR/2;
    mm = ntt_N_FR_S/2;
    oo = ntt_N_FR_M/2;
    kk = ntt_N_FR_WDW/2;
    ll = ntt_N_FR_S_WDW/2;
    pp = ntt_N_FR_M_WDW/2;

    switch( w_type ){
    case ONLY_LONG_WINDOW:      /* Normal */
        ntt_zerod( nn-kk, out );
        ntt_sinwinl( &sig[nn-kk], &out[nn-kk] ,0 );
        ntt_movdd( nn-kk, &sig[nn+kk], &out[nn+kk] );
        ntt_addddd( ntt_N_FR, out, prev, out );
        ntt_movdd( nn-kk, &sig[ntt_N_FR], prev );
        ntt_sinwinl( &sig[nn*3-kk], &prev[nn-kk] , 1 /*stop*/);
        ntt_zerod( nn-kk, &prev[nn+kk] );
        break;
    case LONG_SHORT_WINDOW:             /* Start */
        ntt_zerod( nn-kk, out );
        ntt_sinwinl( &sig[nn-kk], &out[nn-kk] ,0 );
        ntt_movdd( nn-kk, &sig[nn+kk], &out[nn+kk] );
        ntt_addddd( ntt_N_FR, out, prev, out );
        ntt_movdd( nn-ll, &sig[ntt_N_FR], prev );
        ntt_sinwins( &sig[nn*3-ll], &prev[nn-ll] , 1 /*stop*/);
        ntt_zerod( nn-ll, &prev[nn+ll] );
        break;
    case LONG_MEDIUM_WINDOW:            /* Long-medium */
        ntt_zerod( nn-kk, out );
        ntt_sinwinl( &sig[nn-kk], &out[nn-kk] ,0 );
        ntt_movdd( nn-kk, &sig[nn+kk], &out[nn+kk] );
        ntt_addddd( ntt_N_FR, out, prev, out );
        ntt_movdd( nn-pp, &sig[ntt_N_FR], prev );
        ntt_sinwinm( &sig[nn*3-pp], &prev[nn-pp] , 1 /*stop*/);
        ntt_zerod( nn-pp, &prev[nn+pp] );
        break;
    case SHORT_LONG_WINDOW:             /* Stop */
        ntt_zerod( nn-ll, out );
        ntt_sinwins( &sig[nn-ll], &out[nn-ll] ,0 );
        ntt_movdd( nn-ll, &sig[nn+ll], &out[nn+ll] );
        ntt_addddd( ntt_N_FR, out, prev, out );
        ntt_movdd( nn-kk, &sig[ntt_N_FR], prev );
        ntt_sinwinl( &sig[nn*3-kk], &prev[nn-kk] , 1 /*stop*/);
        ntt_zerod( nn-kk, &prev[nn+kk] );
        break;
    case MEDIUM_LONG_WINDOW:            /* Medium -> long */
        ntt_zerod( nn-pp, out );
        ntt_sinwinm( &sig[nn-pp], &out[nn-pp] ,0 );
        ntt_movdd( nn-pp, &sig[nn+pp], &out[nn+pp] );
        ntt_addddd( ntt_N_FR, out, prev, out );
        ntt_movdd( nn-kk, &sig[ntt_N_FR], prev );
        ntt_sinwinl( &sig[nn*3-kk], &prev[nn-kk] , 1 /*stop*/);
        ntt_zerod( nn-kk, &prev[nn+kk] );
        break;
    case ONLY_SHORT_WINDOW:             /* Short */
        ntt_zerod( mm-ll, out );
        ntt_sinwins( &sig[mm-ll], &out[mm-ll] ,0 );
        ntt_movdd( mm-ll, &sig[mm+ll], &out[mm+ll] );
        ntt_addddd( ntt_N_FR_S, out, prev, out );
        ntt_movdd( mm-ll, &sig[ntt_N_FR_S], prev );
        ntt_sinwins( &sig[mm*3-ll], &prev[mm-ll] , 1 /*stop*/);
        ntt_zerod( mm-ll, &prev[mm+ll] );
        break;
    case ONLY_MEDIUM_WINDOW:            /* Medium */
        ntt_zerod( oo-pp, out );
        ntt_sinwinm( &sig[oo-pp], &out[oo-pp] ,0 );
        ntt_movdd( oo-pp, &sig[oo+pp], &out[oo+pp] );
        ntt_addddd( ntt_N_FR_M, out, prev, out );
        ntt_movdd( oo-pp, &sig[ntt_N_FR_M], prev );
        ntt_sinwinm( &sig[oo*3-pp], &prev[oo-pp] , 1 /*stop*/);
        ntt_zerod( oo-pp, &prev[oo+pp] );
        break;
    case MEDIUM_SHORT_WINDOW:           /* Medium -> Short */
        ntt_zerod( oo-pp, out );
        ntt_sinwinm( &sig[oo-pp], &out[oo-pp] ,0 );
        ntt_movdd( oo-pp, &sig[oo+pp], &out[oo+pp] );
        ntt_addddd( ntt_N_FR_M, out, prev, out );
        ntt_movdd( oo-ll, &sig[ntt_N_FR_M], prev );
        ntt_sinwins( &sig[oo*3-ll], &prev[oo-ll] , 1 /*stop*/);
        ntt_zerod( oo-ll, &prev[oo+ll] );
        break;
    case SHORT_MEDIUM_WINDOW:           /* Short -> Medium */
        ntt_zerod( oo-ll, out );
        ntt_sinwins( &sig[oo-ll], &out[oo-ll] ,0 );
        ntt_movdd( oo-ll, &sig[oo+ll], &out[oo+ll] );
        ntt_addddd( ntt_N_FR_M, out, prev, out );
        ntt_movdd( oo-pp, &sig[ntt_N_FR_M], prev );
        ntt_sinwinm( &sig[oo*3-pp], &prev[oo-pp] , 1 /*stop*/);
        ntt_zerod( oo-pp, &prev[oo+pp] );
        break;
    default:
        fprintf( stderr, "IMDCT: Fatal error! %d: Unknown window type\n", w_type );
        exit(1);
    }
}




#define N_MAX (ntt_N_FR_MAX*2)
#define Nh_MAX (N_MAX/2)
#define Nq_MAX  (Nh_MAX/2)
#define Nqh_MAX (Nq_MAX/2)
#define Nqq_MAX (Nqh_MAX/2)

void ntt_imdct_l(double sig[],  /* Input  --- input signal */
             double out[])  /* Output --- output signal */
{
    int j;
    static double       isqm;
    double          *yr, *yi, *ptr, yy[N_MAX];
    double          wr, wi, rtmp, itmp;
    static int      N, Nh, Nq, Nqh, Nqq, ex;
    static int InitFlag = 1;
    double *p1, *p2;
    if (InitFlag){
        N   = (ntt_N_FR*2);
        Nh  = (N/2);
        Nq  = (Nh/2);
        Nqh = (Nq/2);
        Nqq = (Nqh/2);
        ex  = (ntt_N_FR_EX+1);
        isqm = 2.0 / (2.*sqrt( (double) N ));
    }
    InitFlag = 0;
    yr = yy; yi = yy+Nq;
    p1= ntt_cos_TT+1;
    p2 =ntt_cos_TT+N-1;
    for ( j=0; j<Nq; j++ ){
        wr = *p1 *isqm;
        wi = *p2 *isqm;
        rtmp = sig[j];  itmp = sig[Nh-j-1];
        yr[j] = wr*rtmp + wi*itmp;
        yi[j] = wi*rtmp - wr*itmp;
     p1 +=2;
     p2 -=2;
    }
    ntt_roifft_m( yy, ex );

#    if (RIFFT_REORD)
    yr=zz;
#    else
    yr=yy;
#    endif
    /* rearranging */

#if (RIFFT_REORD)
    ptr=out-Nq;
    for ( j=Nqq; j<Nq; j++ ){
        k=j*2; i=k*2;
        ptr[i  ] = yr[k];
        ptr[i+1] = yr[N-1-k];
        ptr[i+2] = yr[k+1];
        ptr[i+3] = yr[N-2-k];
    }
    ptr=out+N-Nq;
    for ( j=0; j<Nqq; j++ ){
        k=j*2; i=k*2;
        ptr[i  ] = -yr[k];
        ptr[i+1] = -yr[N-1-k];
        ptr[i+2] = -yr[k+1];
        ptr[i+3] = -yr[N-2-k];
    }
#else
    ptr=out;
    for ( j=Nqq; j<Nq; j++ ){
        *(ptr++) = yr[j];
        *(ptr++) = yr[N-1-j];
        *(ptr++) = yr[j+Nh];
        *(ptr++) = yr[Nh-1-j];
    }
    ptr=out+N-Nq;
    for ( j=0; j<Nqq; j++ ){
        *(ptr++) = -yr[j];
        *(ptr++) = -yr[N-1-j];
        *(ptr++) = -yr[j+Nh];
        *(ptr++) = -yr[Nh-1-j];
    }
#endif
}


void ntt_imdct_m(double sig[],  /* Input  --- input signal */
             double out[])  /* Output --- output signal */
{
    int j;
    static double       isqm;
    double          *yr, *yi, *ptr, yy[N_MAX];
    double          wr, wi, rtmp, itmp;
    static int      N, Nh, Nq, Nqh, Nqq, ex;
    static int InitFlag = 1;
    int  mag2;
    double  *p1, *p2;

    if (InitFlag){
        N   = (ntt_N_FR_M*2);
        Nh  = (N/2);
        Nq  = (Nh/2);
        Nqh = (Nq/2);
        Nqq = (Nqh/2);
        ex  = (ntt_N_FR_M_EX+1);
        isqm = 2.0 / (2.*sqrt( (double) N ));
    }
    InitFlag = 0;

#if (IMDCT_TYPE == FFT_REAL )
    yr = yy; yi = yy+Nq;
        mag2 = ntt_N_MID*2;
        p1=ntt_cos_TT+ntt_N_MID;
        p2=ntt_cos_TT+(ntt_N_FR*2)-ntt_N_MID;
   for ( j=0; j<Nq; j++ ){
        wr = *p1 *isqm;
        wi = *p2 *isqm;
        rtmp = sig[j];  itmp = sig[Nh-j-1];
        yr[j]=  wr*rtmp + wi*itmp;
        yi[j] = wi*rtmp - wr*itmp;
        p1 += mag2;
        p2 -= mag2;
    }
    ntt_roifft_m( yy, ex );

#    if (RIFFT_REORD)
    yr=zz;
#    else
    yr=yy;
#    endif
#endif

    /* rearranging */

#if (RIFFT_REORD)
    ptr=out-Nq;
    for ( j=Nqq; j<Nq; j++ ){
        k=j*2; i=k*2;
        ptr[i  ] = yr[k];
        ptr[i+1] = yr[N-1-k];
        ptr[i+2] = yr[k+1];
        ptr[i+3] = yr[N-2-k];
    }
    ptr=out+N-Nq;
    for ( j=0; j<Nqq; j++ ){
        k=j*2; i=k*2;
        ptr[i  ] = -yr[k];
        ptr[i+1] = -yr[N-1-k];
        ptr[i+2] = -yr[k+1];
        ptr[i+3] = -yr[N-2-k];
    }
#else
    ptr=out;
    for ( j=Nqq; j<Nq; j++ ){
        *(ptr++) = yr[j];
        *(ptr++) = yr[N-1-j];
        *(ptr++) = yr[j+Nh];
        *(ptr++) = yr[Nh-1-j];
    }
    ptr=out+N-Nq;
    for ( j=0; j<Nqq; j++ ){
        *(ptr++) = -yr[j];
        *(ptr++) = -yr[N-1-j];
        *(ptr++) = -yr[j+Nh];
        *(ptr++) = -yr[Nh-1-j];
    }
#endif
}



void ntt_imdct_s(double sig[],  /* Input  --- input signal */
             double out[])  /* Output --- output signal */
{
    int j;
    static double       isqm;
    double          *yr, *yi, *ptr, yy[N_MAX];
    double          wr, wi, rtmp, itmp;
    static int      N, Nh, Nq, Nqh, Nqq, ex;
    static int InitFlag = 1;
    int mag2;
    double  *p1, *p2;

    if (InitFlag){
        N   = (ntt_N_FR_S*2);
        Nh  = (N/2);
        Nq  = (Nh/2);
        Nqh = (Nq/2);
        Nqq = (Nqh/2);
        ex  = (ntt_N_FR_S_EX+1);
        isqm = 2.0 / (2.*sqrt( (double) N ));
    }
    InitFlag = 0;

#if (IMDCT_TYPE == FFT_REAL )
    yr = yy; yi = yy+Nq;
        mag2 = ntt_N_SHRT*2;
        p1=ntt_cos_TT+ntt_N_SHRT;
        p2=ntt_cos_TT+(ntt_N_FR*2)-ntt_N_SHRT;
   for ( j=0; j<Nq; j++ ){
        wr = *p1 *isqm;
        wi = *p2 *isqm;
        rtmp = sig[j];  itmp = sig[Nh-j-1];
        yr[j]=  wr*rtmp + wi*itmp;
        yi[j] = wi*rtmp - wr*itmp;
        p1 += mag2;
        p2 -= mag2;
    }
    ntt_roifft_m( yy, ex );

#    if (RIFFT_REORD)
    yr=zz;
#    else
    yr=yy;
#    endif
#endif

    /* rearranging */

#if (RIFFT_REORD)
    ptr=out-Nq;
    for ( j=Nqq; j<Nq; j++ ){
        k=j*2; i=k*2;
        ptr[i  ] = yr[k];
        ptr[i+1] = yr[N-1-k];
        ptr[i+2] = yr[k+1];
        ptr[i+3] = yr[N-2-k];
    }
    ptr=out+N-Nq;
    for ( j=0; j<Nqq; j++ ){
        k=j*2; i=k*2;
        ptr[i  ] = -yr[k];
        ptr[i+1] = -yr[N-1-k];
        ptr[i+2] = -yr[k+1];
        ptr[i+3] = -yr[N-2-k];
    }
#else
    ptr=out;
    for ( j=Nqq; j<Nq; j++ ){
        *(ptr++) = yr[j];
        *(ptr++) = yr[N-1-j];
        *(ptr++) = yr[j+Nh];
        *(ptr++) = yr[Nh-1-j];
    }
    ptr=out+N-Nq;
    for ( j=0; j<Nqq; j++ ){
        *(ptr++) = -yr[j];
        *(ptr++) = -yr[N-1-j];
        *(ptr++) = -yr[j+Nh];
        *(ptr++) = -yr[Nh-1-j];
    }
#endif
}


/* --- r1ifft ---

******************************************************************
*     LPC / PARCOR / CSM / LSP   subroutine  library     # nn    *
*               coded by N.Osumi & S.Sagayama       3/20/1977    *
******************************************************************
 ( Original C version )

   description:
   * Inverse FFT for real data.
   * Descrete Fourier series caluculation for a set of real data from
     a cos/sin transforms (DFT) of a real data.
   * It is assumed that the cos transform is a symmetric array and
     that the cos transform is an anti-symmetric array:
       c[i] = c[N-i] (cos transform); s[i] = -s[N-i] (sin transform)
   * The input data is given as follows:
       x[i] = c[i] for i=0, ..., N/2; x[N/2+i] = s[i] for i=1, ..., N/2-1.
   * The algorithm was suggested by J.W.Cooley, P.A.W.Lewis, and P.D.Welch.

   synopsis:
          -----------
          r1ifft(x,m)
          -----------

   x[.]    : input/output. double array : dimension=2^m.
             input : DFT frequency sequence of the form:
               r0, r1, r2, ..., rn, i1, i2, ..., in-1   (where n=2^(m-1))
               (   real parts    )  (imaginary parts)
               i.e., first (2^(m-1)+1) data are real (cos) parts;
               and last (2^(m-1)-1) data are imaginary (sin) parts;
             output: real time sequence of dimension (2^l).
   m       : input.        integer.
             exponent.  i.e., dimension = 2^m.  (nonnegative)
             the DFT of "x" is stored in x[0],....,x[2^m+1], as a complex
             array. (2^m+2) points are to be given.

   subroutine call:   ifft
*/

#define M842 1
extern double ntt_cos_TT[]; /* 1024 -- pi/2 */

/* cos table size  */

void ntt_roifft_m( double *x, int m)

{ int h,i,j,q; double d,e,s,t,a,b,wr,wi;
  double *xr, *xi;
  int mag, mag2;
  double *p1, *p2;
  double *xr_h, *xr_q2, *xr_q2_h;
  double *xi_h, *xi_q2, *xi_q2_h;
  int TAB_SIZE2;

  q=1<<(m-2); h=2*q;  /* N=2^m, h=N/2, q=N/4 */
  xr = x;  xi = x+q;
  TAB_SIZE2 = ntt_N_FR*2;
  mag = TAB_SIZE2>>(m-2);
  mag2= mag*2;
  p1=ntt_cos_TT+mag; p2= ntt_cos_TT+mag*(q-1);
  for(i=0, j=q-1;i<q/2;i++,j--,p1+=mag2, p2-=mag2)
  {
      s=xr[i]+xr[j]; d=xr[i]-xr[j]; t=xi[i]+xi[j]; e=xi[i]-xi[j];
      a=*(p1)*t + *(p2)*d; b=*(p1)*d - *(p2)*t;

      xr[i] =  (s-a); xr[j] = (s+a);
      xi[i] = (e+b); xi[j] = -(e-b);
  }
#if M842
      ntt_fft842_m( m-2, xr, xi );
      for(i=0;i<q;i++) xi[i] = -xi[i];
#else
      for(i=0;i<q;i++) xi[i] = -xi[i];
      ntt_fft( xr, xi, m-2 );
#endif
        xr_h = xr+h;
        xi_h = xi+h;
        xr_q2= xr+q/2;
        xi_q2= xi+q/2;
        xr_q2_h= xr_q2+h;
        xi_q2_h= xi_q2+h;

        *xi_h =   *xi;
        *xi   = - *xr;
        *(xr++)   = - *(xi++);
        *(xr_h++) = - *(xi_h++);

        *xi_q2   = - *(xi_q2);
        *xi_q2_h = - *(xr_q2);
        *(xr_q2++)   = - *(xi_q2++);
        *(xr_q2_h++) = - *(xi_q2_h++);

      p1=ntt_cos_TT+mag2; p2= ntt_cos_TT+TAB_SIZE2-mag2;
      for ( i=1 ; i<q/2; i++, p1+=mag2, p2-=mag2 ){
        wr= *p1; wi= *p2;

        *xi_h = - *(xr)*wi + *(xi)*wr;
        *xi   = - *(xr)*wr - *(xi)*wi;
        *(xr++)   = - *(xi++);
        *(xr_h++) = - *(xi_h++);

        *xi_q2_h = - *(xr_q2)*wr - *(xi_q2)*wi;
        *xi_q2   =   *(xr_q2)*wi - *(xi_q2)*wr;
        *(xr_q2++)   = - *(xi_q2++);
        *(xr_q2_h++) = - *(xi_q2_h++);
    }
#if (RIFFT_REORD)
  for ( n=0; n<h; n++ ){
      z[n*2]=x[n];
      z[n*2+1]=x[n+h];
  }
#endif

  return;
}


void ntt_addddd(int n, double xx[], double yy[], double zz[])
{
   double
        *p_xx,
        *p_yy,
        *p_zz;
   register int
         iloop_fr;

   p_xx = xx;
   p_yy = yy;
   p_zz = zz;
   iloop_fr = n;
   do
   {
      *(p_zz++) = *(p_xx++) + *(p_yy++);
  }
   while ((--iloop_fr) > 0);
}

/** 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 yylpc[ntt_T_WDW_MAX], spectrum_wide[ntt_T_FR_MAX],
              lpc_spectrum_re[ntt_T_FR_MAX];
       int    i_sup, ii,jj, top, subtop, w_type_t, isf, lsptop, ismp;
       int    block_size, nfr_l, nfr_u, nfr_lu;
       block_size = nfr * nsf;
       nfr_u = nfr*band_upper;
       nfr_l = nfr*band_lower;
       nfr_lu = 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, lsp_cdim,
                      prev_buf[i_sup], ma_np,
                      i_sup, 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);
      }
    }
  }

