

/************************************************************************/
/*    mfcc.h                                                            */
/*                                                                      */
/*    Author    : Yuichiro Nakano                                       */
/************************************************************************/


/* $Id: mfcc.h,v 1.4 2002/08/23 11:44:06 ri Exp $ */

#if !defined (MFCC_H)
#define MFCC_H


#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

/* Define pi */ 
#if !defined(PI)
#define PI 3.14159265358979
#endif

/* Define 2*pi */
#if !defined(TPI)
#define TPI 6.28318530717959 
#endif



/* define default values (MFCC_E_D) */
#define DEF_FRAMESIZE   400
#define DEF_FFTNUM      512
#define DEF_FRAMESHIFT  160
#define DEF_PREENPH     0.97
#define DEF_MFCCDIM     12
#define DEF_CEPLIF      22
#define DEF_DELWIN      2
#define DEF_SILFLOOR    50.0
#define DEF_ESCALE      0.1
#define DEF_FBANK       24
#define DEF_SMPPERIOD   625
#define DEF_SSALPHA     2.0
#define DEF_SSFLOOR     0.5

#define MAXLEN          200
#if !defined(FALSE)
#define FALSE           0
#endif
#if !defined(TRUE)
#define TRUE            1
#endif

typedef struct value{
  char inFile[MAXLEN];  /* Input file */
  char outFile[MAXLEN]; /* Output fle */
  long smp_period;      /* sample period in 100ns units (16KHz) */
  int framesize;        /* Window size */
  int frameshift;       /* Frame shift */
  float preEmph;        /* Pre-emphasis coefficient */
  int mfcc_dim;         /* Number of MFCC dimensions */
  int lifter;           /* Cepstral liftering coefficient */
  int delWin;           /* Delta window size */
  float silFloor;       /* Energy silence floor in dBs */
  float escale;         /* Scale log energy */
  int vec_num;          /* Number of dimensions */
  int fbank_num;        /* Number of filterbank channels */
  int hipass;		/* hi pass frequency */
  int lopass;		/* lo pass frequency */
  int cmn;              /* Cepstrum Mean Normalization */
  int enormal;          /* Normalise Energy */
  int raw_e;            /* Raw Energy */
  int c0;		/* 0'th cepstral parameter */
  float ss_alpha;	/* alpha coef. for spectral subtraction */
  float ss_floor;	/* spectral floor in spectral subtraction */
}Value;

typedef struct{
   int fftN;            /* fft size */
   int n;               /* log2(fftN) */
   int klo,khi;         /* lopass to hipass cut-off fft indices */
   float fres;          /* scaled fft resolution */
   float *cf;           /* array[1..pOrder+1] of centre freqs */
   short *loChan;       /* array[1..fftN/2] of loChan index */
   float *loWt;         /* array[1..fftN/2] of loChan weighting */
   float *Re;           /* array[1..fftN] of fftchans (real part) */
   float *Im;           /* array[1..fftN] of fftchans (imag part) */
}FBankInfo;


/* Apply hamming window */
void Hamming (float *wave, int framesize);

/* Apply pre-emphasis filter */
void PreEmphasise (float *wave, Value para);

/* Return mel-frequency */
float Mel(int k, float fres);

/* Get filterbank information */
FBankInfo InitFBank(Value para);
void FreeFBank(FBankInfo fb);

/* Apply FFT */
void FFT(float *xRe, float *xIm, int p);

/* Convert wave -> mel-frequency filterbank */
void MakeFBank(float *wave, double *fbank, FBankInfo info, Value para, float *ssbuf);

/* Apply the DCT to filterbank */ 
void MakeMFCC(double *fbank, float *mfcc, Value para);

/* Calculate 0'th Cepstral parameter*/
float CalcC0(double *fbank, Value para);

/* Calculate Log Raw Energy */
float CalcLogRawE(float *wave, int framesize);

/* Re-scale cepstral coefficients */
void WeightCepstrum (float *mfcc, Value para);

/* Calculate delta coefficients */
void Delta(float **c, int frame, Value para);

/* Normalise log energy */
void NormaliseLogE(float **c, float *energy, int frame_num, Value para);

/* Convert wave -> MFCC_E_D_(Z) */
int Wav2MFCC_E_D(SP16 *wave, float **mfcc, Value para, int nSamples, float *ssbuf, int ssbuflen);

/* Cepstrum Mean Normalization */
void CMN(float **mfcc, int frame_num, int dim);

/* for wav2mfcc-pipe.c */
void WMP_init(Value para, float **bf, float *ssbuf, int ssbuflen);
void WMP_calc(float *mfcc, float *bf, Value para, float *ssbuf);
void WMP_Delta(float **c, int t, int frame, Value para);
void CMN_realtime_update();
void CMN_realtime(float *mfcc, int dim);
boolean CMN_load_from_file(char *filename, int dim);
boolean CMN_save_to_file(char *filename);

/* spectral subtraction */
float *new_SS_load_from_file(char *filename, int *slen);
float *new_SS_calculate(SP16 *wave, int wavelen, Value para, int *slen);

#endif
