00001
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <sent/stddefs.h>
00041 #include <sent/mfcc.h>
00042
00056 int Wav2MFCC(SP16 *wave, float **mfcc, Value para, int nSamples, float *ssbuf, int ssbuflen)
00057 {
00058 float *bf;
00059 double *fbank;
00060 int i, k, t;
00061 int end = 0, start = 1;
00062 int frame_num;
00063 int bflen;
00064
00065
00066 WMP_init(para, &bf, ssbuf, ssbuflen);
00067
00068 frame_num = (int)((nSamples - para.framesize) / para.frameshift) + 1;
00069
00070 for(t = 0; t < frame_num; t++){
00071 if(end != 0) start = end - (para.framesize - para.frameshift) - 1;
00072
00073 k = 1;
00074 for(i = start; i <= start + para.framesize; i++){
00075 bf[k] = (float)wave[i - 1]; k++;
00076 }
00077 end = i;
00078
00079
00080 WMP_calc(mfcc[t], bf, para, ssbuf);
00081 }
00082
00083
00084 if (para.energy && para.enormal) NormaliseLogE(mfcc, frame_num, para);
00085
00086
00087 if (para.delta) Delta(mfcc, frame_num, para);
00088
00089
00090 if (para.acc) Accel(mfcc, frame_num, para);
00091
00092
00093 if(para.cmn) CMN(mfcc, frame_num, para.mfcc_dim);
00094
00095
00096 WMP_calc_fin(bf);
00097
00098 return(frame_num);
00099 }
00100
00108 void NormaliseLogE(float **mfcc, int frame_num, Value para)
00109 {
00110 float max, min, f;
00111 int t;
00112 int l;
00113
00114 l = para.mfcc_dim;
00115 if (para.c0) l++;
00116
00117
00118 max = mfcc[0][l];
00119 for(t = 0; t < frame_num; t++)
00120 if(mfcc[t][l] > max) max = mfcc[t][l];
00121
00122
00123 min = max - (para.silFloor * LOG_TEN) / 10.0;
00124
00125
00126 for(t = 0; t < frame_num; t++){
00127 f = mfcc[t][l];
00128 if (f < min) f = min;
00129 mfcc[t][l] = 1.0 - (max - f) * para.escale;
00130 }
00131 }
00132
00140 void Delta(float **c, int frame, Value para)
00141 {
00142 int theta, t, n, B = 0;
00143 float A1, A2, sum;
00144 float *ed;
00145
00146 for(theta = 1; theta <= para.delWin; theta++)
00147 B += theta * theta;
00148
00149 if (para.absesup) ed = (float *)mymalloc(sizeof(float) * frame);
00150
00151 for(t = 0; t < frame; t++){
00152 for(n = 0; n < para.baselen; n++){
00153 sum = 0;
00154 for(theta = 1; theta <= para.delWin; theta++){
00155
00156
00157 if (t - theta < 0) A1 = c[0][n];
00158 else A1 = c[t - theta][n];
00159 if (t + theta >= frame) A2 = c[frame - 1][n];
00160 else A2 = c[t + theta][n];
00161 sum += theta * (A2 - A1);
00162 }
00163 if (para.absesup && n == para.baselen-1) {
00164 ed[t] = sum / (2 * B);
00165 } else {
00166 c[t][para.baselen + n] = sum / (2 * B);
00167 }
00168 }
00169 }
00170
00171 if (para.absesup) {
00172 for (t=0;t<frame;t++) {
00173 memmove(&(c[t][para.baselen-1]), &(c[t][para.baselen]), sizeof(float) * (para.baselen - 1));
00174 c[t][para.baselen * 2 - 2] = ed[t];
00175 }
00176 free(ed);
00177 }
00178 }
00179
00180
00188 void Accel(float **c, int frame, Value para)
00189 {
00190 int theta, t, n, B = 0;
00191 int src, dst;
00192 float A1, A2, sum;
00193
00194 for(theta = 1; theta <= para.accWin; theta++)
00195 B += theta * theta;
00196
00197 for(t = 0; t < frame; t++){
00198 src = para.baselen * 2 - 1;
00199 if (para.absesup) src--;
00200 dst = src + para.baselen;
00201 for(n = 0; n < para.baselen; n++){
00202 sum = 0;
00203 for(theta = 1; theta <= para.accWin; theta++){
00204
00205
00206 if (t - theta < 0) A1 = c[0][src];
00207 else A1 = c[t - theta][src];
00208 if (t + theta >= frame) A2 = c[frame - 1][src];
00209 else A2 = c[t + theta][src];
00210 sum += theta * (A2 - A1);
00211 }
00212 c[t][dst] = sum / (2 * B);
00213 src--;
00214 dst--;
00215 }
00216 }
00217 }
00218
00227 void CMN(float **mfcc, int frame_num, int dim)
00228 {
00229 int i, t;
00230 float *mfcc_ave, *sum;
00231
00232 mfcc_ave = (float *)mycalloc(dim, sizeof(float));
00233 sum = (float *)mycalloc(dim, sizeof(float));
00234
00235 for(i = 0; i < dim; i++){
00236 sum[i] = 0.0;
00237 for(t = 0; t < frame_num; t++)
00238 sum[i] += mfcc[t][i];
00239 mfcc_ave[i] = sum[i] / frame_num;
00240 }
00241 for(t = 0; t < frame_num; t++){
00242 for(i = 0; i < dim; i++)
00243 mfcc[t][i] = mfcc[t][i] - mfcc_ave[i];
00244 }
00245 free(sum);
00246 free(mfcc_ave);
00247 }