libsent/src/wav2mfcc/wav2mfcc-buffer.c

Go to the documentation of this file.
00001 
00031 /************************************************************************/
00032 /*    wav2mfcc.c   Convert Speech file to MFCC_E_D_(Z) file             */
00033 /*----------------------------------------------------------------------*/
00034 /*    Author    : Yuichiro Nakano                                       */
00035 /*                                                                      */
00036 /*    Copyright(C) Yuichiro Nakano 1996-1998                            */
00037 /*----------------------------------------------------------------------*/
00038 /************************************************************************/
00039 
00040 
00041 #include <sent/stddefs.h>
00042 #include <sent/mfcc.h>
00043 
00056 int
00057 Wav2MFCC(SP16 *wave, float **mfcc, Value *para, int nSamples, MFCCWork *w)
00058 {
00059   int i, k, t;
00060   int end = 0, start = 1;
00061   int frame_num;                    /* Number of samples in output file */
00062 
00063   /* set noise spectrum if any */
00064   if (w->ssbuf != NULL) {
00065     /* check ssbuf length */
00066     if (w->ssbuflen != w->bflen) {
00067       jlog("Error: mfcc-core: noise spectrum length not match\n");
00068       return FALSE;
00069     }
00070   }
00071 
00072   frame_num = (int)((nSamples - para->framesize) / para->frameshift) + 1;
00073   
00074   for(t = 0; t < frame_num; t++){
00075     if(end != 0) start = end - (para->framesize - para->frameshift) - 1;
00076 
00077     k = 1;
00078     for(i = start; i <= start + para->framesize; i++){
00079       w->bf[k] = (float)wave[i - 1];  k++;
00080     }
00081     end = i;
00082     
00083     /* Calculate base MFCC coefficients */
00084     WMP_calc(w, mfcc[t], para);
00085   }
00086   
00087   /* Normalise Log Energy */
00088   if (para->energy && para->enormal) NormaliseLogE(mfcc, frame_num, para);
00089   
00090   /* Delta (consider energy suppress) */
00091   if (para->delta) Delta(mfcc, frame_num, para);
00092 
00093   /* Acceleration */
00094   if (para->acc) Accel(mfcc, frame_num, para);
00095 
00096   /* Cepstrum Mean Normalization */
00097   if(para->cmn) CMN(mfcc, frame_num, para->mfcc_dim);
00098 
00099   return(frame_num);
00100 }
00101 
00109 void NormaliseLogE(float **mfcc, int frame_num, Value *para)
00110 {  
00111   float max, min, f;
00112   int t;
00113   int l;
00114 
00115   l = para->mfcc_dim;
00116   if (para->c0) l++;
00117 
00118   /* find max log energy */
00119   max = mfcc[0][l];
00120   for(t = 0; t < frame_num; t++)
00121     if(mfcc[t][l] > max) max = mfcc[t][l];
00122 
00123   /* set the silence floor */
00124   min = max - (para->silFloor * LOG_TEN) / 10.0;  
00125 
00126   /* normalise */
00127   for(t = 0; t < frame_num; t++){
00128     f = mfcc[t][l];
00129     if (f < min) f = min;
00130     mfcc[t][l] = 1.0 - (max - f) * para->escale;
00131   }
00132 }
00133 
00141 void Delta(float **c, int frame, Value *para)
00142 {
00143   int theta, t, n, B = 0;
00144   float A1, A2, sum;
00145 
00146   for(theta = 1; theta <= para->delWin; theta++)
00147     B += theta * theta;
00148 
00149   for(n = para->baselen - 1; n >=0; n--){
00150     for(t = 0; t < frame; t++){
00151       sum = 0;
00152       for(theta = 1; theta <= para->delWin; theta++){
00153         /* Replicate the first or last vector */
00154         /* at the beginning and end of speech */
00155         if (t - theta < 0) A1 = c[0][n];
00156         else A1 = c[t - theta][n];
00157         if (t + theta >= frame) A2 = c[frame - 1][n];
00158         else A2 = c[t + theta][n];
00159         sum += theta * (A2 - A1);
00160       }
00161       sum /= (2.0 * B);
00162       if (para->absesup) {
00163         c[t][para->baselen + n - 1] = sum;
00164       } else {
00165         c[t][para->baselen + n] = sum;
00166       }
00167     }
00168   }
00169 }
00170 
00171 
00179 void Accel(float **c, int frame, Value *para)
00180 {
00181   int theta, t, n, B = 0;
00182   int src, dst;
00183   float A1, A2, sum;
00184 
00185   for(theta = 1; theta <= para->accWin; theta++)
00186     B += theta * theta;
00187 
00188   for(t = 0; t < frame; t++){
00189     src = para->baselen * 2 - 1;
00190     if (para->absesup) src--;
00191     dst = src + para->baselen;
00192     for(n = 0; n < para->baselen; n++){
00193       sum = 0;
00194       for(theta = 1; theta <= para->accWin; theta++){
00195         /* Replicate the first or last vector */
00196         /* at the beginning and end of speech */
00197         if (t - theta < 0) A1 = c[0][src];
00198         else A1 = c[t - theta][src];
00199         if (t + theta >= frame) A2 = c[frame - 1][src];
00200         else A2 = c[t + theta][src];
00201         sum += theta * (A2 - A1);
00202       }
00203       c[t][dst] = sum / (2 * B);
00204       src--;
00205       dst--;
00206     }
00207   }
00208 }
00209 
00218 void CMN(float **mfcc, int frame_num, int dim)
00219 {
00220   int i, t;
00221   float *mfcc_ave, *sum;
00222 
00223   mfcc_ave = (float *)mycalloc(dim, sizeof(float));
00224   sum = (float *)mycalloc(dim, sizeof(float));
00225 
00226   for(i = 0; i < dim; i++){
00227     sum[i] = 0.0;
00228     for(t = 0; t < frame_num; t++)
00229       sum[i] += mfcc[t][i];
00230     mfcc_ave[i] = sum[i] / frame_num;
00231   }
00232   for(t = 0; t < frame_num; t++){
00233     for(i = 0; i < dim; i++)
00234       mfcc[t][i] = mfcc[t][i] - mfcc_ave[i];
00235   }
00236   free(sum);
00237   free(mfcc_ave);
00238 }

Generated on Tue Dec 18 15:59:57 2007 for Julius by  doxygen 1.5.4