49 #pragma warning (disable: 4244)
56 #define M_PI 3.14159265358979323846
61 #include "sphinxbase/byteorder.h"
62 #include "sphinxbase/fixpoint.h"
63 #include "sphinxbase/fe.h"
67 #include "fe_internal.h"
73 #define FLOAT2COS(x) FLOAT2FIX_ANY(x,30)
74 #define COSMUL(x,y) FIXMUL_ANY(x,y,30)
76 #define FLOAT2COS(x) (x)
77 #define COSMUL(x,y) ((x)*(y))
92 static const unsigned char fe_logadd_table[] = {
93 177, 177, 176, 176, 175, 175, 174, 174, 173, 173,
94 172, 172, 172, 171, 171, 170, 170, 169, 169, 168,
95 168, 167, 167, 166, 166, 165, 165, 164, 164, 163,
96 163, 162, 162, 161, 161, 161, 160, 160, 159, 159,
97 158, 158, 157, 157, 156, 156, 155, 155, 155, 154,
98 154, 153, 153, 152, 152, 151, 151, 151, 150, 150,
99 149, 149, 148, 148, 147, 147, 147, 146, 146, 145,
100 145, 144, 144, 144, 143, 143, 142, 142, 141, 141,
101 141, 140, 140, 139, 139, 138, 138, 138, 137, 137,
102 136, 136, 136, 135, 135, 134, 134, 134, 133, 133,
103 132, 132, 131, 131, 131, 130, 130, 129, 129, 129,
104 128, 128, 128, 127, 127, 126, 126, 126, 125, 125,
105 124, 124, 124, 123, 123, 123, 122, 122, 121, 121,
106 121, 120, 120, 119, 119, 119, 118, 118, 118, 117,
107 117, 117, 116, 116, 115, 115, 115, 114, 114, 114,
108 113, 113, 113, 112, 112, 112, 111, 111, 110, 110,
109 110, 109, 109, 109, 108, 108, 108, 107, 107, 107,
110 106, 106, 106, 105, 105, 105, 104, 104, 104, 103,
111 103, 103, 102, 102, 102, 101, 101, 101, 100, 100,
112 100, 99, 99, 99, 98, 98, 98, 97, 97, 97,
113 96, 96, 96, 96, 95, 95, 95, 94, 94, 94,
114 93, 93, 93, 92, 92, 92, 92, 91, 91, 91,
115 90, 90, 90, 89, 89, 89, 89, 88, 88, 88,
116 87, 87, 87, 87, 86, 86, 86, 85, 85, 85,
117 85, 84, 84, 84, 83, 83, 83, 83, 82, 82,
118 82, 82, 81, 81, 81, 80, 80, 80, 80, 79,
119 79, 79, 79, 78, 78, 78, 78, 77, 77, 77,
120 77, 76, 76, 76, 75, 75, 75, 75, 74, 74,
121 74, 74, 73, 73, 73, 73, 72, 72, 72, 72,
122 71, 71, 71, 71, 71, 70, 70, 70, 70, 69,
123 69, 69, 69, 68, 68, 68, 68, 67, 67, 67,
124 67, 67, 66, 66, 66, 66, 65, 65, 65, 65,
125 64, 64, 64, 64, 64, 63, 63, 63, 63, 63,
126 62, 62, 62, 62, 61, 61, 61, 61, 61, 60,
127 60, 60, 60, 60, 59, 59, 59, 59, 59, 58,
128 58, 58, 58, 58, 57, 57, 57, 57, 57, 56,
129 56, 56, 56, 56, 55, 55, 55, 55, 55, 54,
130 54, 54, 54, 54, 53, 53, 53, 53, 53, 52,
131 52, 52, 52, 52, 52, 51, 51, 51, 51, 51,
132 50, 50, 50, 50, 50, 50, 49, 49, 49, 49,
133 49, 49, 48, 48, 48, 48, 48, 48, 47, 47,
134 47, 47, 47, 47, 46, 46, 46, 46, 46, 46,
135 45, 45, 45, 45, 45, 45, 44, 44, 44, 44,
136 44, 44, 43, 43, 43, 43, 43, 43, 43, 42,
137 42, 42, 42, 42, 42, 41, 41, 41, 41, 41,
138 41, 41, 40, 40, 40, 40, 40, 40, 40, 39,
139 39, 39, 39, 39, 39, 39, 38, 38, 38, 38,
140 38, 38, 38, 37, 37, 37, 37, 37, 37, 37,
141 37, 36, 36, 36, 36, 36, 36, 36, 35, 35,
142 35, 35, 35, 35, 35, 35, 34, 34, 34, 34,
143 34, 34, 34, 34, 33, 33, 33, 33, 33, 33,
144 33, 33, 32, 32, 32, 32, 32, 32, 32, 32,
145 32, 31, 31, 31, 31, 31, 31, 31, 31, 31,
146 30, 30, 30, 30, 30, 30, 30, 30, 30, 29,
147 29, 29, 29, 29, 29, 29, 29, 29, 28, 28,
148 28, 28, 28, 28, 28, 28, 28, 28, 27, 27,
149 27, 27, 27, 27, 27, 27, 27, 27, 26, 26,
150 26, 26, 26, 26, 26, 26, 26, 26, 25, 25,
151 25, 25, 25, 25, 25, 25, 25, 25, 25, 24,
152 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
153 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
154 23, 23, 22, 22, 22, 22, 22, 22, 22, 22,
155 22, 22, 22, 22, 21, 21, 21, 21, 21, 21,
156 21, 21, 21, 21, 21, 21, 21, 20, 20, 20,
157 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
158 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
159 19, 19, 19, 19, 18, 18, 18, 18, 18, 18,
160 18, 18, 18, 18, 18, 18, 18, 18, 18, 17,
161 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
162 17, 17, 17, 17, 16, 16, 16, 16, 16, 16,
163 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
164 16, 15, 15, 15, 15, 15, 15, 15, 15, 15,
165 15, 15, 15, 15, 15, 15, 15, 15, 14, 14,
166 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
167 14, 14, 14, 14, 14, 14, 14, 13, 13, 13,
168 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
169 13, 13, 13, 13, 13, 13, 13, 12, 12, 12,
170 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
171 12, 12, 12, 12, 12, 12, 12, 12, 12, 11,
172 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
173 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
174 11, 11, 11, 10, 10, 10, 10, 10, 10, 10,
175 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
176 10, 10, 10, 10, 10, 10, 10, 10, 10, 9,
177 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
178 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
179 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
180 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
181 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
182 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
183 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
184 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
185 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
186 7, 7, 7, 7, 7, 7, 7, 7, 6, 6,
187 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
188 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
189 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
190 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
191 6, 5, 5, 5, 5, 5, 5, 5, 5, 5,
192 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
193 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
194 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
195 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
196 5, 5, 5, 4, 4, 4, 4, 4, 4, 4,
197 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
198 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
199 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
200 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
201 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
202 4, 4, 4, 4, 4, 4, 4, 4, 3, 3,
203 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
204 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
205 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
206 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
207 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
208 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
209 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
210 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
211 3, 3, 3, 3, 2, 2, 2, 2, 2, 2,
212 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
213 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
214 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
215 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
216 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
217 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
218 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
219 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
220 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
221 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
222 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
223 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
224 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
225 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
226 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
227 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
228 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
229 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
230 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
231 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
232 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
233 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
234 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
235 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
236 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
237 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
238 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
239 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
240 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
241 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
242 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
243 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
244 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
245 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
246 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
247 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
248 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
249 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
250 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
251 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
252 1, 1, 1, 1, 1, 1, 1, 0
254 static const int fe_logadd_table_size =
sizeof(fe_logadd_table) /
sizeof(fe_logadd_table[0]);
257 fe_log_add(fixed32 x, fixed32 y)
262 d = (x - y) >> (DEFAULT_RADIX - 8);
266 d = (y - x) >> (DEFAULT_RADIX - 8);
269 if (d > fe_logadd_table_size - 1)
272 r += ((fixed32)fe_logadd_table[d] << (DEFAULT_RADIX - 8));
289 return FLOAT2FIX(log(x));
295 fe_mel(
melfb_t *mel, float32 x)
297 float32 warped = fe_warp_unwarped_to_warped(mel, x);
299 return (float32) (2595.0 * log10(1.0 + warped / 700.0));
303 fe_melinv(
melfb_t *mel, float32 x)
305 float32 warped = (float32) (700.0 * (pow(10.0, x / 2595.0) - 1.0));
306 return fe_warp_warped_to_unwarped(mel, warped);
310 fe_build_melfilters(
melfb_t *mel_fb)
312 float32 melmin, melmax, melbw, fftfreq;
316 mel_fb->spec_start =
ckd_malloc(mel_fb->num_filters *
sizeof(*mel_fb->spec_start));
317 mel_fb->filt_start =
ckd_malloc(mel_fb->num_filters *
sizeof(*mel_fb->filt_start));
318 mel_fb->filt_width =
ckd_malloc(mel_fb->num_filters *
sizeof(*mel_fb->filt_width));
322 melmin = fe_mel(mel_fb, mel_fb->lower_filt_freq);
323 melmax = fe_mel(mel_fb, mel_fb->upper_filt_freq);
326 melbw = (melmax - melmin) / (mel_fb->num_filters + 1);
327 if (mel_fb->doublewide) {
330 if ((fe_melinv(mel_fb, melmin) < 0) ||
331 (fe_melinv(mel_fb, melmax) > mel_fb->sampling_rate / 2)) {
333 (
"Out of Range: low filter edge = %f (%f)\n",
334 fe_melinv(mel_fb, melmin), 0.0);
336 (
" high filter edge = %f (%f)\n",
337 fe_melinv(mel_fb, melmax), mel_fb->sampling_rate / 2);
338 return FE_INVALID_PARAM_ERROR;
343 fftfreq = mel_fb->sampling_rate / (float32) mel_fb->fft_size;
347 for (i = 0; i < mel_fb->num_filters; ++i) {
351 for (j = 0; j < 3; ++j) {
352 if (mel_fb->doublewide)
353 freqs[j] = fe_melinv(mel_fb, (i + j * 2) * melbw + melmin);
355 freqs[j] = fe_melinv(mel_fb, (i + j) * melbw + melmin);
357 if (mel_fb->round_filters)
358 freqs[j] = ((int)(freqs[j] / fftfreq + 0.5)) * fftfreq;
362 mel_fb->spec_start[i] = -1;
364 for (j = 0; j < mel_fb->fft_size/2+1; ++j) {
365 float32 hz = j * fftfreq;
368 else if (hz > freqs[2] || j == mel_fb->fft_size/2) {
370 mel_fb->filt_width[i] = j - mel_fb->spec_start[i];
372 mel_fb->filt_start[i] = n_coeffs;
373 n_coeffs += mel_fb->filt_width[i];
376 if (mel_fb->spec_start[i] == -1)
377 mel_fb->spec_start[i] = j;
382 mel_fb->filt_coeffs =
ckd_malloc(n_coeffs *
sizeof(*mel_fb->filt_coeffs));
386 for (i = 0; i < mel_fb->num_filters; ++i) {
390 for (j = 0; j < 3; ++j) {
391 if (mel_fb->doublewide)
392 freqs[j] = fe_melinv(mel_fb, (i + j * 2) * melbw + melmin);
394 freqs[j] = fe_melinv(mel_fb, (i + j) * melbw + melmin);
396 if (mel_fb->round_filters)
397 freqs[j] = ((int)(freqs[j] / fftfreq + 0.5)) * fftfreq;
400 for (j = 0; j < mel_fb->filt_width[i]; ++j) {
401 float32 hz, loslope, hislope;
403 hz = (mel_fb->spec_start[i] + j) * fftfreq;
404 if (hz < freqs[0] || hz > freqs[2]) {
405 E_FATAL(
"Failed to create filterbank, frequency range does not match. "
406 "Sample rate %f, FFT size %d, lowerf %f < freq %f > upperf %f.\n", mel_fb->sampling_rate, mel_fb->fft_size, freqs[2], hz, freqs[0]);
408 loslope = (hz - freqs[0]) / (freqs[1] - freqs[0]);
409 hislope = (freqs[2] - hz) / (freqs[2] - freqs[1]);
410 if (mel_fb->unit_area) {
411 loslope *= 2 / (freqs[2] - freqs[0]);
412 hislope *= 2 / (freqs[2] - freqs[0]);
414 if (loslope < hislope) {
416 mel_fb->filt_coeffs[n_coeffs] = fe_log(loslope);
418 mel_fb->filt_coeffs[n_coeffs] = loslope;
423 mel_fb->filt_coeffs[n_coeffs] = fe_log(hislope);
425 mel_fb->filt_coeffs[n_coeffs] = hislope;
437 fe_compute_melcosine(
melfb_t * mel_fb)
448 freqstep = M_PI / mel_fb->num_filters;
451 for (i = 0; i < mel_fb->num_cepstra; i++) {
452 for (j = 0; j < mel_fb->num_filters; j++) {
455 cosine = cos(freqstep * i * (j + 0.5));
456 mel_fb->mel_cosine[i][j] = FLOAT2COS(cosine);
461 mel_fb->sqrt_inv_n = FLOAT2COS(sqrt(1.0 / mel_fb->num_filters));
462 mel_fb->sqrt_inv_2n = FLOAT2COS(sqrt(2.0 / mel_fb->num_filters));
465 if (mel_fb->lifter_val) {
466 mel_fb->lifter = calloc(mel_fb->num_cepstra,
sizeof(*mel_fb->lifter));
467 for (i = 0; i < mel_fb->num_cepstra; ++i) {
468 mel_fb->lifter[i] = FLOAT2MFCC(1 + mel_fb->lifter_val / 2
469 * sin(i * M_PI / mel_fb->lifter_val));
477 fe_pre_emphasis(int16
const *in, frame_t * out, int32 len,
478 float32 factor, int16 prior)
483 int16 fxd_alpha = (int16)(factor * 0x8000);
486 tmp1 = (int32)in[0] << 15;
487 tmp2 = (int32)prior * fxd_alpha;
488 out[0] = (int16)((tmp1 - tmp2) >> 15);
489 for (i = 1; i < len; ++i) {
490 tmp1 = (int32)in[i] << 15;
491 tmp2 = (int32)in[i-1] * fxd_alpha;
492 out[i] = (int16)((tmp1 - tmp2) >> 15);
494 #elif defined(FIXED_POINT)
495 fixed32 fxd_alpha = FLOAT2FIX(factor);
496 out[0] = ((fixed32)in[0] << DEFAULT_RADIX) - (prior * fxd_alpha);
497 for (i = 1; i < len; ++i)
498 out[i] = ((fixed32)in[i] << DEFAULT_RADIX)
499 - (fixed32)in[i-1] * fxd_alpha;
501 out[0] = (frame_t) in[0] - (frame_t) prior * factor;
502 for (i = 1; i < len; i++)
503 out[i] = (frame_t) in[i] - (frame_t) in[i-1] * factor;
508 fe_short_to_frame(int16
const *in, frame_t * out, int32 len)
513 memcpy(out, in, len *
sizeof(*out));
514 #elif defined(FIXED_POINT)
515 for (i = 0; i < len; i++)
516 out[i] = (int32) in[i] << DEFAULT_RADIX;
518 for (i = 0; i < len; i++)
519 out[i] = (frame_t) in[i];
524 fe_create_hamming(window_t * in, int32 in_len)
529 for (i = 0; i < in_len / 2; i++) {
531 hamm = (0.54 - 0.46 * cos(2 * M_PI * i /
532 ((float64) in_len - 1.0)));
534 in[i] = (int16)(hamm * 0x8000);
536 in[i] = FLOAT2COS(hamm);
542 fe_hamming_window(frame_t * in, window_t * window, int32 in_len, int32 remove_dc)
553 for (i = 0; i < in_len; i++)
556 for (i = 0; i < in_len; i++)
557 in[i] -= (frame_t)mean;
561 for (i = 0; i < in_len/2; i++) {
564 tmp1 = (int32)in[i] * window[i];
565 tmp2 = (int32)in[in_len-1-i] * window[i];
566 in[i] = (int16)(tmp1 >> 15);
567 in[in_len-1-i] = (int16)(tmp2 >> 15);
570 for (i = 0; i < in_len/2; i++) {
571 in[i] = COSMUL(in[i], window[i]);
572 in[in_len-1-i] = COSMUL(in[in_len-1-i], window[i]);
578 fe_spch_to_frame(
fe_t *fe,
int len)
581 if (fe->pre_emphasis_alpha != 0.0) {
582 fe_pre_emphasis(fe->spch, fe->frame, len,
583 fe->pre_emphasis_alpha, fe->prior);
584 if (len >= fe->frame_shift)
585 fe->prior = fe->spch[fe->frame_shift - 1];
587 fe->prior = fe->spch[len - 1];
590 fe_short_to_frame(fe->spch, fe->frame, len);
593 memset(fe->frame + len, 0,
594 (fe->fft_size - len) *
sizeof(*fe->frame));
597 fe_hamming_window(fe->frame, fe->hamming_window, fe->frame_size,
604 fe_read_frame(
fe_t *fe, int16
const *in, int32 len)
608 if (len > fe->frame_size)
609 len = fe->frame_size;
612 memcpy(fe->spch, in, len *
sizeof(*in));
615 for (i = 0; i < len; ++i)
616 SWAP_INT16(&fe->spch[i]);
618 for (i = 0; i < len; ++i)
619 fe->spch[i] += (int16) ((!(s3_rand_int31() % 4)) ? 1 : 0);
621 return fe_spch_to_frame(fe, len);
625 fe_shift_frame(
fe_t *fe, int16
const *in, int32 len)
629 if (len > fe->frame_shift)
630 len = fe->frame_shift;
631 offset = fe->frame_size - fe->frame_shift;
634 memmove(fe->spch, fe->spch + fe->frame_shift,
635 offset *
sizeof(*fe->spch));
636 memcpy(fe->spch + offset, in, len *
sizeof(*fe->spch));
639 for (i = 0; i < len; ++i)
640 SWAP_INT16(&fe->spch[offset + i]);
642 for (i = 0; i < len; ++i)
644 += (int16) ((!(s3_rand_int31() % 4)) ? 1 : 0);
646 return fe_spch_to_frame(fe, offset + len);
653 fe_create_twiddle(
fe_t *fe)
657 for (i = 0; i < fe->fft_size / 4; ++i) {
658 float64 a = 2 * M_PI * i / fe->fft_size;
660 fe->ccc[i] = (int16)(cos(a) * 0x8000);
661 fe->sss[i] = (int16)(sin(a) * 0x8000);
662 #elif defined(FIXED_POINT)
663 fe->ccc[i] = FLOAT2COS(cos(a));
664 fe->sss[i] = FLOAT2COS(sin(a));
680 fe_fft_real(
fe_t *fe)
682 int i, j, k, m, n, lz;
691 for (i = 0; i < n - 1; ++i) {
706 for (i = 0; i < n; ++i)
712 for (lz = 0; lz < m; ++lz)
713 if (max & (1 << (15-lz)))
723 for (i = 0; i < n; i += 2) {
724 int atten = (lz == 0);
726 x[i] = xt + (x[i + 1] >> atten);
727 x[i + 1] = xt - (x[i + 1] >> atten);
731 for (k = 1; k < m; ++k) {
734 int atten = (k >= lz);
740 for (i = 0; i < n; i += (1 << n1)) {
746 x[i] = xt + (x[i + (1 << n2)] >> atten);
747 x[i + (1 << n2)] = xt - (x[i + (1 << n2)] >> atten);
755 x[i + (1 << n2) + (1 << n4)] = -x[i + (1 << n2) + (1 << n4)] >> atten;
756 x[i + (1 << n4)] = x[i + (1 << n4)] >> atten;
761 for (j = 1; j < (1 << n4); ++j) {
762 frame_t cc, ss, t1, t2;
766 i2 = i + (1 << n2) - j;
767 i3 = i + (1 << n2) + j;
768 i4 = i + (1 << n2) + (1 << n2) - j;
774 cc = fe->ccc[j << (m - n1)];
775 ss = fe->sss[j << (m - n1)];
781 tmp1 = (int32)x[i3] * cc + (int32)x[i4] * ss;
782 tmp2 = (int32)x[i3] * ss - (int32)x[i4] * cc;
783 t1 = (int16)(tmp1 >> 15) >> atten;
784 t2 = (int16)(tmp2 >> 15) >> atten;
787 x[i4] = (x[i2] >> atten) - t2;
788 x[i3] = (-x[i2] >> atten) - t2;
789 x[i2] = (x[i1] >> atten) - t1;
790 x[i1] = (x[i1] >> atten) + t1;
800 fe_fft_real(
fe_t *fe)
811 for (i = 0; i < n - 1; ++i) {
829 for (i = 0; i < n; i += 2) {
831 x[i] = (xt + x[i + 1]);
832 x[i + 1] = (xt - x[i + 1]);
836 for (k = 1; k < m; ++k) {
843 for (i = 0; i < n; i += (1 << n1)) {
849 x[i] = (xt + x[i + (1 << n2)]);
850 x[i + (1 << n2)] = (xt - x[i + (1 << n2)]);
858 x[i + (1 << n2) + (1 << n4)] = -x[i + (1 << n2) + (1 << n4)];
859 x[i + (1 << n4)] = x[i + (1 << n4)];
864 for (j = 1; j < (1 << n4); ++j) {
865 frame_t cc, ss, t1, t2;
869 i2 = i + (1 << n2) - j;
870 i3 = i + (1 << n2) + j;
871 i4 = i + (1 << n2) + (1 << n2) - j;
877 cc = fe->ccc[j << (m - n1)];
878 ss = fe->sss[j << (m - n1)];
882 t1 = COSMUL(x[i3], cc) + COSMUL(x[i4], ss);
883 t2 = COSMUL(x[i3], ss) - COSMUL(x[i4], cc);
885 x[i4] = (x[i2] - t2);
886 x[i3] = (-x[i2] - t2);
887 x[i2] = (x[i1] - t1);
888 x[i1] = (x[i1] + t1);
899 fe_spec_magnitude(
fe_t *fe)
903 int32 j, scale, fftsize;
907 scale = fe_fft_real(fe);
912 fftsize = fe->fft_size;
915 scale = fe->fft_order - scale;
920 spec[0] = fixlog(abs(fft[0]) << scale) * 2;
921 #elif defined(FIXED_POINT)
922 spec[0] = FIXLN(abs(fft[0]) << scale) * 2;
924 spec[0] = fft[0] * fft[0];
928 for (j = 1; j <= fftsize / 2; j++) {
930 int32 rr = fixlog(abs(fft[j]) << scale) * 2;
931 int32 ii = fixlog(abs(fft[fftsize - j]) << scale) * 2;
932 spec[j] = fe_log_add(rr, ii);
933 #elif defined(FIXED_POINT)
934 int32 rr = FIXLN(abs(fft[j]) << scale) * 2;
935 int32 ii = FIXLN(abs(fft[fftsize - j]) << scale) * 2;
936 spec[j] = fe_log_add(rr, ii);
938 spec[j] = fft[j] * fft[j] + fft[fftsize - j] * fft[fftsize - j];
944 fe_mel_spec(
fe_t * fe)
947 powspec_t *spec, *mfspec;
953 for (whichfilt = 0; whichfilt < fe->mel_fb->num_filters; whichfilt++) {
954 int spec_start, filt_start, i;
956 spec_start = fe->mel_fb->spec_start[whichfilt];
957 filt_start = fe->mel_fb->filt_start[whichfilt];
960 mfspec[whichfilt] = spec[spec_start] + fe->mel_fb->filt_coeffs[filt_start];
961 for (i = 1; i < fe->mel_fb->filt_width[whichfilt]; i++) {
962 mfspec[whichfilt] = fe_log_add(mfspec[whichfilt],
963 spec[spec_start + i] +
964 fe->mel_fb->filt_coeffs[filt_start + i]);
967 mfspec[whichfilt] = 0;
968 for (i = 0; i < fe->mel_fb->filt_width[whichfilt]; i++)
970 spec[spec_start + i] * fe->mel_fb->filt_coeffs[filt_start + i];
976 fe_mel_cep(
fe_t * fe, mfcc_t *mfcep)
984 for (i = 0; i < fe->mel_fb->num_filters; ++i) {
987 mfspec[i] = log(mfspec[i]);
998 if (fe->log_spec == RAW_LOG_SPEC) {
999 for (i = 0; i < fe->feature_dimension; i++) {
1000 mfcep[i] = (mfcc_t) mfspec[i];
1004 else if (fe->log_spec == SMOOTH_LOG_SPEC) {
1006 fe_dct2(fe, mfspec, mfcep, 0);
1007 fe_dct3(fe, mfcep, mfspec);
1008 for (i = 0; i < fe->feature_dimension; i++) {
1009 mfcep[i] = (mfcc_t) mfspec[i];
1012 else if (fe->transform == DCT_II)
1013 fe_dct2(fe, mfspec, mfcep, FALSE);
1014 else if (fe->transform == DCT_HTK)
1015 fe_dct2(fe, mfspec, mfcep, TRUE);
1017 fe_spec2cep(fe, mfspec, mfcep);
1023 fe_spec2cep(
fe_t * fe,
const powspec_t * mflogspec, mfcc_t * mfcep)
1029 mfcep[0] = mflogspec[0] / 2;
1030 for (j = 1; j < fe->mel_fb->num_filters; j++)
1031 mfcep[0] += mflogspec[j];
1032 mfcep[0] /= (frame_t) fe->mel_fb->num_filters;
1034 for (i = 1; i < fe->num_cepstra; ++i) {
1036 for (j = 0; j < fe->mel_fb->num_filters; j++) {
1041 mfcep[i] += COSMUL(mflogspec[j],
1042 fe->mel_fb->mel_cosine[i][j]) * beta;
1047 mfcep[i] /= (frame_t) fe->mel_fb->num_filters * 2;
1052 fe_dct2(
fe_t * fe,
const powspec_t * mflogspec, mfcc_t * mfcep,
int htk)
1058 mfcep[0] = mflogspec[0];
1059 for (j = 1; j < fe->mel_fb->num_filters; j++)
1060 mfcep[0] += mflogspec[j];
1062 mfcep[0] = COSMUL(mfcep[0], fe->mel_fb->sqrt_inv_2n);
1064 mfcep[0] = COSMUL(mfcep[0], fe->mel_fb->sqrt_inv_n);
1066 for (i = 1; i < fe->num_cepstra; ++i) {
1068 for (j = 0; j < fe->mel_fb->num_filters; j++) {
1069 mfcep[i] += COSMUL(mflogspec[j],
1070 fe->mel_fb->mel_cosine[i][j]);
1072 mfcep[i] = COSMUL(mfcep[i], fe->mel_fb->sqrt_inv_2n);
1077 fe_lifter(
fe_t *fe, mfcc_t *mfcep)
1081 if (fe->mel_fb->lifter_val == 0)
1084 for (i = 0; i < fe->num_cepstra; ++i) {
1085 mfcep[i] = MFCCMUL(mfcep[i], fe->mel_fb->lifter[i]);
1090 fe_dct3(
fe_t * fe,
const mfcc_t * mfcep, powspec_t * mflogspec)
1094 for (i = 0; i < fe->mel_fb->num_filters; ++i) {
1095 mflogspec[i] = COSMUL(mfcep[0], SQRT_HALF);
1096 for (j = 1; j < fe->num_cepstra; j++) {
1097 mflogspec[i] += COSMUL(mfcep[j],
1098 fe->mel_fb->mel_cosine[j][i]);
1100 mflogspec[i] = COSMUL(mflogspec[i], fe->mel_fb->sqrt_inv_2n);
1105 fe_write_frame(
fe_t * fe, mfcc_t * fea)
1107 fe_spec_magnitude(fe);
1109 fe_mel_cep(fe, fea);
1116 fe_create_2d(int32 d1, int32 d2, int32 elem_size)
1122 fe_free_2d(
void *arr)
#define ckd_calloc_2d(d1, d2, sz)
Macro for ckd_calloc_2d
Base Struct to hold all structure for MFCC computation.
Sphinx's memory allocation/deallocation routines.
Basic type definitions used in Sphinx.
#define E_WARN
Print warning information to standard error stream.
Implementation of logging routines.
High performance prortable random generator created by Takuji Nishimura and Makoto Matsumoto...
#define ckd_malloc(sz)
Macro for ckd_malloc
#define E_FATAL
Exit with non-zero status after error message.
SPHINXBASE_EXPORT void ckd_free_2d(void *ptr)
Free a 2-D array (ptr) previously allocated by ckd_calloc_2d.
Structure for the front-end computation.