/*****************************************************************************/
/* This software module was originally developed by                          */
/*   Naoki Iwakami (NTT)                                                     */
/* and edited by                                                             */
/*   Naoki Iwakami and Satoshi Miki (NTT) on 1996-05-01,                     */
/*   Naoki Iwakami (NTT) on 1996-08-27,                                      */
/*   Naoki Iwakami (NTT) on 1997-04-18,                                      */
/*   Naoki Iwakami (NTT) on 1997-08-25,                                      */
/*   Akio Jin (NTT) 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.                                                        */
/*****************************************************************************/

/* 18-apr-97  NI   merged long, medium, & short procedure into single module */
/* 25-aug-97  NI   added bandwidth control */

#include "ntt_conf.h"

void ntt_tf_proc_spectrum_d(/* Input */
			    ntt_INDEX  *indexp,
			    double flat_spectrum[],
			    /* Output */
			    double spectrum[])
{
  /*--- Variables ---*/
  double inv_lpc_spec[ntt_T_FR_MAX];
  double bark_env[ntt_T_FR_MAX];
  double gain[ntt_T_SHRT_MAX];
  double pit_seq[ntt_T_FR_MAX];
  double pgain[ntt_T_SHRT_MAX];
  static int InitFlag = 1;
  int    i_ch, ii, top;

  /*--- Parameters ---*/
  int    nfr, nsf;
  double *fw_codebook;
  int    fw_ndiv, fw_cv_len, fw_cv_len_max;
  int    *fw_bark_tbl, fw_n_crb;
  int    fw_nbit;
  double fw_alf_step, *fw_penv_tmp;
  double *lsp_code;
  double *lsp_fgcode;
  int    n_pr, *lsp_csize, *lsp_cdim;
  double band_lower, band_upper;
  int    ifr;
  int    isf;

  /*--- Memories ---*/
  /* Bark-scale envelope quantization */
  static double env_memory_long[ntt_N_CRB_MAX*ntt_N_SUP_MAX];
  static double env_memory_medium[ntt_N_CRB_M_MAX*ntt_N_SUP_MAX];
  static double env_memory_short[ntt_N_CRB_S_MAX*ntt_N_SUP_MAX];
  /* LSP quantization */
  static double prev_buf[ntt_N_SUP_MAX][ntt_MA_NP][ntt_N_PR_MAX+1];
  static int    ma_np;

  /*--- Initialization ---*/
  if (InitFlag==1){
    /* Bark-scale envelope */
    ntt_zerod(ntt_N_CRB  *ntt_N_SUP, env_memory_long);
    ntt_zerod(ntt_N_CRB_M*ntt_N_SUP, env_memory_medium);
    ntt_zerod(ntt_N_CRB_S*ntt_N_SUP, env_memory_short);

    /* LPC spectrum */
    for (i_ch=0; i_ch<ntt_N_SUP; i_ch++){
      for (ii=0; ii<ntt_MA_NP; ii++){
	ntt_zerod(ntt_N_PR+1, prev_buf[i_ch][ii]);
      }
    }
    ma_np = 0;
  }
  InitFlag = 0;
  
  /*--- Parameter settings ---*/
  switch (indexp->w_type){
  case ONLY_LONG_WINDOW:  /* long */
  case LONG_SHORT_WINDOW:
  case SHORT_LONG_WINDOW:
  case LONG_MEDIUM_WINDOW:
  case MEDIUM_LONG_WINDOW:
    /* subframes */
    nfr = ntt_N_FR;
    nsf = 1;
    /* quantization (Bark-scale envelope) */
    fw_codebook = (double *)ntt_fwcodev;
    fw_ndiv       = ntt_FW_N_DIV;
    fw_cv_len     = ntt_FW_CB_LEN;
    fw_cv_len_max = ntt_FW_CB_LEN;
    /* Bark-scale table (Bark-scale envelope) */
    fw_bark_tbl = ntt_crb_tbl;
    fw_n_crb    = ntt_N_CRB;
    /* Reconstruction (Bark-scale envelope) */
    fw_alf_step = ntt_FW_ALF_STEP;
    fw_penv_tmp = env_memory_long;
    fw_nbit = ntt_FW_N_BIT;
    break;
  case ONLY_MEDIUM_WINDOW:
  case MEDIUM_SHORT_WINDOW:
  case SHORT_MEDIUM_WINDOW:
    /* subframes */
    nfr = ntt_N_FR_M;
    nsf = ntt_N_MID;
    /* quantization (Bark-scale envelope) */
    fw_codebook = (double *)ntt_fwcodevm;
    fw_ndiv       = ntt_FW_N_DIV_M;
    fw_cv_len     = ntt_FW_CB_LEN_M;
    fw_cv_len_max = ntt_FW_CB_LEN_M;
    /* Bark-scale table (Bark-scale envelope) */
    fw_bark_tbl = ntt_crb_tbl_m;
    fw_n_crb    = ntt_N_CRB_M;
    /* Reconstruction (Bark-scale envelope) */
    fw_alf_step = ntt_FW_ALF_STEP;
    fw_penv_tmp = env_memory_medium;
    fw_nbit = ntt_FW_N_BIT_M;
    break;
  case ONLY_SHORT_WINDOW:
    /* subframes */
    nfr = ntt_N_FR_S;
    nsf = ntt_N_SHRT;
    /* quantization (Bark-scale envelope) */
    fw_codebook = (double *)ntt_fwcodevs;
    fw_ndiv       = ntt_FW_N_DIV_S;
    fw_cv_len     = ntt_FW_CB_LEN_S;
    fw_cv_len_max = ntt_FW_CB_LEN_S;
    /* Bark-scale table (Bark-scale envelope) */
    fw_bark_tbl = ntt_crb_tbl_s;
    fw_n_crb    = ntt_N_CRB_S;
    /* Reconstruction (Bark-scale envelope) */
    fw_alf_step = ntt_FW_ALF_STEP;
    fw_penv_tmp = env_memory_short;
    fw_nbit = ntt_FW_N_BIT_S;
    break;
  default:
    CommonExit(1,"window type not handled");
  }
  /* LSP quantization */
  n_pr       = ntt_N_PR;                  /* prediction order */
  lsp_code   = (double *)lsp_code_base;   /* code tables */
  lsp_fgcode = (double *)lsp_fgcode_base;
  lsp_csize  = ntt_lsp_csize_base;        /* codebook size */
  lsp_cdim   = ntt_lsp_cdim_base;         /* codevector length */

  /*--- Decoding tools ---*/
  
  /* Periodic pitch components */
  if( ntt_TBIT_P > 0){
    ntt_dec_pitch(indexp->pit, indexp->pls, indexp->pgain, indexp->w_type, 
		  pit_seq, pgain);
  }
  else{
    ntt_zerod(ntt_N_FR*ntt_N_SUP, pit_seq); 
    ntt_zerod(ntt_N_SHRT*ntt_N_SUP, pgain);
  }
  /* Bark-scale envelope */
/*--- A.Jin 1997.10.19---*/
/*
  ntt_dec_bark_env(nfr, nsf, ntt_N_SUP,
		   fw_codebook, fw_ndiv, fw_cv_len, fw_cv_len_max,
		   fw_bark_tbl, fw_n_crb, fw_alf_step, fw_penv_tmp,
		   indexp->fw, indexp->fw_alf, indexp->pf, bark_env);
*/
  if(fw_nbit>0){
    ntt_dec_bark_env(nfr, nsf, ntt_N_SUP,
                   fw_codebook, fw_ndiv, fw_cv_len, fw_cv_len_max,
                   fw_bark_tbl, fw_n_crb, fw_alf_step, fw_penv_tmp,
                   indexp->fw, indexp->fw_alf, indexp->pf, bark_env);
}
  else{
    for(ifr=0; ifr<nfr*nsf*ntt_N_SUP; ifr++ ){
      bark_env[ifr]=1.0;
  }
}
  /* Gain */
/*--- A.Jin 1997.10.19--*/

  ntt_dec_gain(nsf, indexp->pow, gain);

/*
  if(nsf==1) {
     for(i_sup=0; i_sup<ntt_N_SUP; i_sup++)
         ntt_dec_sq_gain(indexp->pow[i_sup],
                 ntt_AMP_MAX, ntt_MU, ntt_STEP, ntt_AMP_NM, &gain[i_sup]);
 }
  else{
     for(i_sup=0; i_sup<ntt_N_SUP; i_sup++){
         iptop = i_sup * (nsf + 1);
         ntt_dec_sq_gain(indexp->pow[iptop],
                 ntt_AMP_MAX, ntt_MU, ntt_STEP, ntt_AMP_NM, &g_gain);
         for(isf=0; isf<nsf; isf++){
             ntt_dec_sq_gain(indexp->pow[iptop+1+isf],
                   ntt_SUB_AMP_MAX, ntt_MU, ntt_SUB_STEP,
                   ntt_SUB_AMP_NM, &gain[isf+i_sup*nsf]);
             gain[isf+i_sup*nsf] *=g_gain;
         }
     }
 }
*/
  /* LPC spectrum */
  ntt_dec_lpc_spectrum_inv(nfr, ntt_N_SUP, ntt_N_PR, ntt_LSP_SPLIT,
                           lsp_code, lsp_fgcode,
                           lsp_csize, prev_buf, ma_np,
                           indexp->lsp, inv_lpc_spec);

  /** Moriya informed **/
  {
       int nfr_l, nfr_lu, subtop, ismp;
       double inv_lpc_spec_nall[ntt_T_FR_MAX]; /* Tsushima add routine (This line)**/
	    nfr_l  = (int) ( nfr * ntt_BAND_LOWER );
	    nfr_lu = (int) ( nfr * ( ntt_BAND_UPPER - ntt_BAND_LOWER ) );
  
	    for( i_ch=0; i_ch<ntt_N_SUP; i_ch++ ){
		 top    = i_ch*nfr*nsf;
		 ntt_zerod(nfr*nsf, inv_lpc_spec_nall+top);
  
		 for(isf=0; isf<nsf; isf++){
		      subtop = top + isf*nfr;
		      for(ismp=0; ismp<nfr_lu; ismp++){
			   inv_lpc_spec_nall[ismp+subtop+nfr_l] =
				inv_lpc_spec[(int)(ismp/(ntt_BAND_UPPER-ntt_BAND_LOWER))+top];
/*				inv_lpc_spec[(int)(ismp/(band_upper-band_lower))+subtop]; */
		      }
		      for(ismp=0; ismp<nfr; ismp++){
			   inv_lpc_spec[ismp+subtop] = inv_lpc_spec_nall[ismp+subtop];
		      }
		}
       }
  }
  /** end moriya informed **/

  /* De-normalization */
  ntt_denormalizer_spectrum(nfr, nsf, ntt_N_SUP,
			    flat_spectrum, gain, 
			    pit_seq, pgain, bark_env, inv_lpc_spec,
			    spectrum);
  /*--- Bandwidth control ---*/
  for (i_ch=0; i_ch<ntt_N_SUP; i_ch++){
    top = i_ch * ntt_N_FR;
    if (ntt_BLIM_BITS_H > 0){
      band_upper = 
	ntt_BAND_UPPER * 
	  (1. - (1.-ntt_CUT_M_H) * 
	   (double)indexp->blim_h[i_ch]/(double)ntt_BLIM_STEP_H);
    }
    else{
      band_upper = ntt_BAND_UPPER;
    }
    if (ntt_BLIM_BITS_L > 0){
      band_lower = ntt_BAND_LOWER + ntt_CUT_M_L * indexp->blim_l[i_ch];
    }
    else{
      band_lower = ntt_BAND_LOWER;
    }
    ntt_post_process(nfr, nsf, band_lower, band_upper,
		     spectrum+top, spectrum+top);
  }

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

}
