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))
92static const unsigned char fe_logadd_table[] = {
93177, 177, 176, 176, 175, 175, 174, 174, 173, 173,
94172, 172, 172, 171, 171, 170, 170, 169, 169, 168,
95168, 167, 167, 166, 166, 165, 165, 164, 164, 163,
96163, 162, 162, 161, 161, 161, 160, 160, 159, 159,
97158, 158, 157, 157, 156, 156, 155, 155, 155, 154,
98154, 153, 153, 152, 152, 151, 151, 151, 150, 150,
99149, 149, 148, 148, 147, 147, 147, 146, 146, 145,
100145, 144, 144, 144, 143, 143, 142, 142, 141, 141,
101141, 140, 140, 139, 139, 138, 138, 138, 137, 137,
102136, 136, 136, 135, 135, 134, 134, 134, 133, 133,
103132, 132, 131, 131, 131, 130, 130, 129, 129, 129,
104128, 128, 128, 127, 127, 126, 126, 126, 125, 125,
105124, 124, 124, 123, 123, 123, 122, 122, 121, 121,
106121, 120, 120, 119, 119, 119, 118, 118, 118, 117,
107117, 117, 116, 116, 115, 115, 115, 114, 114, 114,
108113, 113, 113, 112, 112, 112, 111, 111, 110, 110,
109110, 109, 109, 109, 108, 108, 108, 107, 107, 107,
110106, 106, 106, 105, 105, 105, 104, 104, 104, 103,
111103, 103, 102, 102, 102, 101, 101, 101, 100, 100,
112100, 99, 99, 99, 98, 98, 98, 97, 97, 97,
11396, 96, 96, 96, 95, 95, 95, 94, 94, 94,
11493, 93, 93, 92, 92, 92, 92, 91, 91, 91,
11590, 90, 90, 89, 89, 89, 89, 88, 88, 88,
11687, 87, 87, 87, 86, 86, 86, 85, 85, 85,
11785, 84, 84, 84, 83, 83, 83, 83, 82, 82,
11882, 82, 81, 81, 81, 80, 80, 80, 80, 79,
11979, 79, 79, 78, 78, 78, 78, 77, 77, 77,
12077, 76, 76, 76, 75, 75, 75, 75, 74, 74,
12174, 74, 73, 73, 73, 73, 72, 72, 72, 72,
12271, 71, 71, 71, 71, 70, 70, 70, 70, 69,
12369, 69, 69, 68, 68, 68, 68, 67, 67, 67,
12467, 67, 66, 66, 66, 66, 65, 65, 65, 65,
12564, 64, 64, 64, 64, 63, 63, 63, 63, 63,
12662, 62, 62, 62, 61, 61, 61, 61, 61, 60,
12760, 60, 60, 60, 59, 59, 59, 59, 59, 58,
12858, 58, 58, 58, 57, 57, 57, 57, 57, 56,
12956, 56, 56, 56, 55, 55, 55, 55, 55, 54,
13054, 54, 54, 54, 53, 53, 53, 53, 53, 52,
13152, 52, 52, 52, 52, 51, 51, 51, 51, 51,
13250, 50, 50, 50, 50, 50, 49, 49, 49, 49,
13349, 49, 48, 48, 48, 48, 48, 48, 47, 47,
13447, 47, 47, 47, 46, 46, 46, 46, 46, 46,
13545, 45, 45, 45, 45, 45, 44, 44, 44, 44,
13644, 44, 43, 43, 43, 43, 43, 43, 43, 42,
13742, 42, 42, 42, 42, 41, 41, 41, 41, 41,
13841, 41, 40, 40, 40, 40, 40, 40, 40, 39,
13939, 39, 39, 39, 39, 39, 38, 38, 38, 38,
14038, 38, 38, 37, 37, 37, 37, 37, 37, 37,
14137, 36, 36, 36, 36, 36, 36, 36, 35, 35,
14235, 35, 35, 35, 35, 35, 34, 34, 34, 34,
14334, 34, 34, 34, 33, 33, 33, 33, 33, 33,
14433, 33, 32, 32, 32, 32, 32, 32, 32, 32,
14532, 31, 31, 31, 31, 31, 31, 31, 31, 31,
14630, 30, 30, 30, 30, 30, 30, 30, 30, 29,
14729, 29, 29, 29, 29, 29, 29, 29, 28, 28,
14828, 28, 28, 28, 28, 28, 28, 28, 27, 27,
14927, 27, 27, 27, 27, 27, 27, 27, 26, 26,
15026, 26, 26, 26, 26, 26, 26, 26, 25, 25,
15125, 25, 25, 25, 25, 25, 25, 25, 25, 24,
15224, 24, 24, 24, 24, 24, 24, 24, 24, 24,
15323, 23, 23, 23, 23, 23, 23, 23, 23, 23,
15423, 23, 22, 22, 22, 22, 22, 22, 22, 22,
15522, 22, 22, 22, 21, 21, 21, 21, 21, 21,
15621, 21, 21, 21, 21, 21, 21, 20, 20, 20,
15720, 20, 20, 20, 20, 20, 20, 20, 20, 20,
15819, 19, 19, 19, 19, 19, 19, 19, 19, 19,
15919, 19, 19, 19, 18, 18, 18, 18, 18, 18,
16018, 18, 18, 18, 18, 18, 18, 18, 18, 17,
16117, 17, 17, 17, 17, 17, 17, 17, 17, 17,
16217, 17, 17, 17, 16, 16, 16, 16, 16, 16,
16316, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16416, 15, 15, 15, 15, 15, 15, 15, 15, 15,
16515, 15, 15, 15, 15, 15, 15, 15, 14, 14,
16614, 14, 14, 14, 14, 14, 14, 14, 14, 14,
16714, 14, 14, 14, 14, 14, 14, 13, 13, 13,
16813, 13, 13, 13, 13, 13, 13, 13, 13, 13,
16913, 13, 13, 13, 13, 13, 13, 12, 12, 12,
17012, 12, 12, 12, 12, 12, 12, 12, 12, 12,
17112, 12, 12, 12, 12, 12, 12, 12, 12, 11,
17211, 11, 11, 11, 11, 11, 11, 11, 11, 11,
17311, 11, 11, 11, 11, 11, 11, 11, 11, 11,
17411, 11, 11, 10, 10, 10, 10, 10, 10, 10,
17510, 10, 10, 10, 10, 10, 10, 10, 10, 10,
17610, 10, 10, 10, 10, 10, 10, 10, 10, 9,
1779, 9, 9, 9, 9, 9, 9, 9, 9, 9,
1789, 9, 9, 9, 9, 9, 9, 9, 9, 9,
1799, 9, 9, 9, 9, 9, 9, 9, 8, 8,
1808, 8, 8, 8, 8, 8, 8, 8, 8, 8,
1818, 8, 8, 8, 8, 8, 8, 8, 8, 8,
1828, 8, 8, 8, 8, 8, 8, 8, 8, 8,
1837, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1847, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1857, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1867, 7, 7, 7, 7, 7, 7, 7, 6, 6,
1876, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1886, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1896, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1906, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1916, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1925, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1935, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1945, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1955, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1965, 5, 5, 4, 4, 4, 4, 4, 4, 4,
1974, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1984, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1994, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2004, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2014, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2024, 4, 4, 4, 4, 4, 4, 4, 3, 3,
2033, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2043, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2053, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2063, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2073, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2083, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2093, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2103, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2113, 3, 3, 3, 2, 2, 2, 2, 2, 2,
2122, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2132, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2142, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2152, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2162, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2172, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2182, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2192, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2202, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2212, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2222, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2232, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2242, 2, 2, 2, 2, 2, 1, 1, 1, 1,
2251, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2261, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2271, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2281, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2291, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2301, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2311, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2321, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2331, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2341, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2351, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2361, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2371, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2381, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2391, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2401, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2411, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2421, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2431, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2441, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2451, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2461, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2471, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2481, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2491, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2501, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2511, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2521, 1, 1, 1, 1, 1, 1, 0
254static const int fe_logadd_table_size =
sizeof(fe_logadd_table) /
sizeof(fe_logadd_table[0]);
257fe_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));
297 float32 warped = fe_warp_unwarped_to_warped(mel, x);
299 return (float32) (2595.0 * log10(1.0 + warped / 700.0));
303fe_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);
310fe_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;
437fe_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));
477fe_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;
508fe_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];
524fe_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);
542fe_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]);
578fe_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,
604fe_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);
625fe_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);
653fe_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));
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;
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);
899fe_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];
944fe_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];
976fe_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);
1023fe_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;
1052fe_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);
1077fe_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]);
1090fe_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);
1105fe_write_frame(
fe_t * fe, mfcc_t * fea)
1107 fe_spec_magnitude(fe);
1109 fe_mel_cep(fe, fea);
1116fe_create_2d(int32 d1, int32 d2, int32 elem_size)
1122fe_free_2d(
void *arr)
Sphinx's memory allocation/deallocation routines.
SPHINXBASE_EXPORT void ckd_free_2d(void *ptr)
Free a 2-D array (ptr) previously allocated by ckd_calloc_2d.
#define ckd_malloc(sz)
Macro for ckd_malloc
#define ckd_calloc_2d(d1, d2, sz)
Macro for ckd_calloc_2d
Implementation of logging routines.
#define E_FATAL
Exit with non-zero status after error message.
#define E_WARN
Print warning information to standard error stream.
High performance prortable random generator created by Takuji Nishimura and Makoto Matsumoto.
Basic type definitions used in Sphinx.
Structure for the front-end computation.
Base Struct to hold all structure for MFCC computation.