SphinxBase 0.6
|
00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */ 00002 /* ==================================================================== 00003 * Copyright (c) 1996-2004 Carnegie Mellon University. All rights 00004 * reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in 00015 * the documentation and/or other materials provided with the 00016 * distribution. 00017 * 00018 * This work was supported in part by funding from the Defense Advanced 00019 * Research Projects Agency and the National Science Foundation of the 00020 * United States of America, and the CMU Sphinx Speech Consortium. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 00023 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 00024 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00025 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY 00026 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00027 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00028 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00029 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00030 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00032 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 * 00034 * ==================================================================== 00035 * 00036 */ 00037 #include <stdio.h> 00038 #include <string.h> 00039 #include <math.h> 00040 #include <stdlib.h> 00041 #include <assert.h> 00042 #ifdef _WIN32_WCE 00043 #include <windows.h> 00044 #else 00045 #include <time.h> 00046 #endif 00047 00048 #ifdef HAVE_CONFIG_H 00049 #include <config.h> 00050 #endif 00051 00052 #include "sphinxbase/prim_type.h" 00053 #include "sphinxbase/byteorder.h" 00054 #include "sphinxbase/fixpoint.h" 00055 #include "sphinxbase/genrand.h" 00056 #include "sphinxbase/err.h" 00057 #include "sphinxbase/cmd_ln.h" 00058 #include "sphinxbase/ckd_alloc.h" 00059 00060 #include "fe_internal.h" 00061 #include "fe_warp.h" 00062 00063 static const arg_t fe_args[] = { 00064 waveform_to_cepstral_command_line_macro(), 00065 { NULL, 0, NULL, NULL } 00066 }; 00067 00068 int 00069 fe_parse_general_params(cmd_ln_t *config, fe_t * fe) 00070 { 00071 int j; 00072 00073 fe->config = config; 00074 fe->sampling_rate = cmd_ln_float32_r(config, "-samprate"); 00075 fe->frame_rate = (int16)cmd_ln_int32_r(config, "-frate"); 00076 if (cmd_ln_boolean_r(config, "-dither")) { 00077 fe->dither = 1; 00078 fe->seed = cmd_ln_int32_r(config, "-seed"); 00079 } 00080 #ifdef WORDS_BIGENDIAN 00081 fe->swap = strcmp("big", cmd_ln_str_r(config, "-input_endian")) == 0 ? 0 : 1; 00082 #else 00083 fe->swap = strcmp("little", cmd_ln_str_r(config, "-input_endian")) == 0 ? 0 : 1; 00084 #endif 00085 fe->window_length = cmd_ln_float32_r(config, "-wlen"); 00086 fe->pre_emphasis_alpha = cmd_ln_float32_r(config, "-alpha"); 00087 00088 fe->num_cepstra = (uint8)cmd_ln_int32_r(config, "-ncep"); 00089 fe->fft_size = (int16)cmd_ln_int32_r(config, "-nfft"); 00090 00091 /* Check FFT size, compute FFT order (log_2(n)) */ 00092 for (j = fe->fft_size, fe->fft_order = 0; j > 1; j >>= 1, fe->fft_order++) { 00093 if (((j % 2) != 0) || (fe->fft_size <= 0)) { 00094 E_ERROR("fft: number of points must be a power of 2 (is %d)\n", 00095 fe->fft_size); 00096 return -1; 00097 } 00098 } 00099 /* Verify that FFT size is greater or equal to window length. */ 00100 if (fe->fft_size < (int)(fe->window_length * fe->sampling_rate)) { 00101 E_ERROR("FFT: Number of points must be greater or equal to frame size (%d samples)\n", 00102 (int)(fe->window_length * fe->sampling_rate)); 00103 return -1; 00104 } 00105 00106 fe->remove_dc = cmd_ln_boolean_r(config, "-remove_dc"); 00107 00108 if (0 == strcmp(cmd_ln_str_r(config, "-transform"), "dct")) 00109 fe->transform = DCT_II; 00110 else if (0 == strcmp(cmd_ln_str_r(config, "-transform"), "legacy")) 00111 fe->transform = LEGACY_DCT; 00112 else if (0 == strcmp(cmd_ln_str_r(config, "-transform"), "htk")) 00113 fe->transform = DCT_HTK; 00114 else { 00115 E_ERROR("Invalid transform type (values are 'dct', 'legacy', 'htk')\n"); 00116 return -1; 00117 } 00118 00119 if (cmd_ln_boolean_r(config, "-logspec")) 00120 fe->log_spec = RAW_LOG_SPEC; 00121 if (cmd_ln_boolean_r(config, "-smoothspec")) 00122 fe->log_spec = SMOOTH_LOG_SPEC; 00123 00124 return 0; 00125 } 00126 00127 static int 00128 fe_parse_melfb_params(cmd_ln_t *config, fe_t *fe, melfb_t * mel) 00129 { 00130 mel->sampling_rate = fe->sampling_rate; 00131 mel->fft_size = fe->fft_size; 00132 mel->num_cepstra = fe->num_cepstra; 00133 mel->num_filters = cmd_ln_int32_r(config, "-nfilt"); 00134 00135 if (fe->log_spec) 00136 fe->feature_dimension = mel->num_filters; 00137 else 00138 fe->feature_dimension = fe->num_cepstra; 00139 00140 mel->upper_filt_freq = cmd_ln_float32_r(config, "-upperf"); 00141 mel->lower_filt_freq = cmd_ln_float32_r(config, "-lowerf"); 00142 00143 mel->doublewide = cmd_ln_boolean_r(config, "-doublebw"); 00144 00145 mel->warp_type = cmd_ln_str_r(config, "-warp_type"); 00146 mel->warp_params = cmd_ln_str_r(config, "-warp_params"); 00147 mel->lifter_val = cmd_ln_int32_r(config, "-lifter"); 00148 00149 mel->unit_area = cmd_ln_boolean_r(config, "-unit_area"); 00150 mel->round_filters = cmd_ln_boolean_r(config, "-round_filters"); 00151 00152 if (fe_warp_set(mel, mel->warp_type) != FE_SUCCESS) { 00153 E_ERROR("Failed to initialize the warping function.\n"); 00154 return -1; 00155 } 00156 fe_warp_set_parameters(mel, mel->warp_params, mel->sampling_rate); 00157 return 0; 00158 } 00159 00160 void 00161 fe_print_current(fe_t const *fe) 00162 { 00163 E_INFO("Current FE Parameters:\n"); 00164 E_INFO("\tSampling Rate: %f\n", fe->sampling_rate); 00165 E_INFO("\tFrame Size: %d\n", fe->frame_size); 00166 E_INFO("\tFrame Shift: %d\n", fe->frame_shift); 00167 E_INFO("\tFFT Size: %d\n", fe->fft_size); 00168 E_INFO("\tLower Frequency: %g\n", 00169 fe->mel_fb->lower_filt_freq); 00170 E_INFO("\tUpper Frequency: %g\n", 00171 fe->mel_fb->upper_filt_freq); 00172 E_INFO("\tNumber of filters: %d\n", fe->mel_fb->num_filters); 00173 E_INFO("\tNumber of Overflow Samps: %d\n", fe->num_overflow_samps); 00174 E_INFO("\tStart Utt Status: %d\n", fe->start_flag); 00175 E_INFO("Will %sremove DC offset at frame level\n", 00176 fe->remove_dc ? "" : "not "); 00177 if (fe->dither) { 00178 E_INFO("Will add dither to audio\n"); 00179 E_INFO("Dither seeded with %d\n", fe->seed); 00180 } 00181 else { 00182 E_INFO("Will not add dither to audio\n"); 00183 } 00184 if (fe->mel_fb->lifter_val) { 00185 E_INFO("Will apply sine-curve liftering, period %d\n", 00186 fe->mel_fb->lifter_val); 00187 } 00188 E_INFO("Will %snormalize filters to unit area\n", 00189 fe->mel_fb->unit_area ? "" : "not "); 00190 E_INFO("Will %sround filter frequencies to DFT points\n", 00191 fe->mel_fb->round_filters ? "" : "not "); 00192 E_INFO("Will %suse double bandwidth in mel filter\n", 00193 fe->mel_fb->doublewide ? "" : "not "); 00194 } 00195 00196 fe_t * 00197 fe_init_auto() 00198 { 00199 return fe_init_auto_r(cmd_ln_retain(cmd_ln_get())); 00200 } 00201 00202 fe_t * 00203 fe_init_auto_r(cmd_ln_t *config) 00204 { 00205 fe_t *fe; 00206 00207 fe = ckd_calloc(1, sizeof(*fe)); 00208 fe->refcount = 1; 00209 00210 /* transfer params to front end */ 00211 if (fe_parse_general_params(config, fe) < 0) { 00212 fe_free(fe); 00213 return NULL; 00214 } 00215 00216 /* compute remaining fe parameters */ 00217 /* We add 0.5 so approximate the float with the closest 00218 * integer. E.g., 2.3 is truncate to 2, whereas 3.7 becomes 4 00219 */ 00220 fe->frame_shift = (int32) (fe->sampling_rate / fe->frame_rate + 0.5); 00221 fe->frame_size = (int32) (fe->window_length * fe->sampling_rate + 0.5); 00222 fe->prior = 0; 00223 fe->frame_counter = 0; 00224 00225 if (fe->frame_size > (fe->fft_size)) { 00226 E_WARN 00227 ("Number of FFT points has to be a power of 2 higher than %d\n", 00228 (fe->frame_size)); 00229 fe_free(fe); 00230 return (NULL); 00231 } 00232 00233 if (fe->dither) 00234 fe_init_dither(fe->seed); 00235 00236 /* establish buffers for overflow samps and hamming window */ 00237 fe->overflow_samps = ckd_calloc(fe->frame_size, sizeof(int16)); 00238 fe->hamming_window = ckd_calloc(fe->frame_size/2, sizeof(window_t)); 00239 00240 /* create hamming window */ 00241 fe_create_hamming(fe->hamming_window, fe->frame_size); 00242 00243 /* init and fill appropriate filter structure */ 00244 fe->mel_fb = ckd_calloc(1, sizeof(*fe->mel_fb)); 00245 00246 /* transfer params to mel fb */ 00247 fe_parse_melfb_params(config, fe, fe->mel_fb); 00248 fe_build_melfilters(fe->mel_fb); 00249 fe_compute_melcosine(fe->mel_fb); 00250 00251 /* Create temporary FFT, spectrum and mel-spectrum buffers. */ 00252 /* FIXME: Gosh there are a lot of these. */ 00253 fe->spch = ckd_calloc(fe->frame_size, sizeof(*fe->spch)); 00254 fe->frame = ckd_calloc(fe->fft_size, sizeof(*fe->frame)); 00255 fe->spec = ckd_calloc(fe->fft_size, sizeof(*fe->spec)); 00256 fe->mfspec = ckd_calloc(fe->mel_fb->num_filters, sizeof(*fe->mfspec)); 00257 00258 /* create twiddle factors */ 00259 fe->ccc = ckd_calloc(fe->fft_size / 4, sizeof(*fe->ccc)); 00260 fe->sss = ckd_calloc(fe->fft_size / 4, sizeof(*fe->sss)); 00261 fe_create_twiddle(fe); 00262 00263 if (cmd_ln_boolean_r(config, "-verbose")) { 00264 fe_print_current(fe); 00265 } 00266 00267 /*** Z.A.B. ***/ 00268 /*** Initialize the overflow buffers ***/ 00269 fe_start_utt(fe); 00270 return fe; 00271 } 00272 00273 arg_t const * 00274 fe_get_args(void) 00275 { 00276 return fe_args; 00277 } 00278 00279 cmd_ln_t * 00280 fe_get_config(fe_t *fe) 00281 { 00282 return fe->config; 00283 } 00284 00285 void 00286 fe_init_dither(int32 seed) 00287 { 00288 if (seed < 0) { 00289 E_INFO("You are using the internal mechanism to generate the seed.\n"); 00290 #ifdef _WIN32_WCE 00291 s3_rand_seed(GetTickCount()); 00292 #else 00293 s3_rand_seed((long) time(0)); 00294 #endif 00295 } 00296 else { 00297 E_INFO("You are using %d as the seed.\n", seed); 00298 s3_rand_seed(seed); 00299 } 00300 } 00301 00302 int32 00303 fe_start_utt(fe_t * fe) 00304 { 00305 fe->num_overflow_samps = 0; 00306 memset(fe->overflow_samps, 0, fe->frame_size * sizeof(int16)); 00307 fe->start_flag = 1; 00308 fe->prior = 0; 00309 return 0; 00310 } 00311 00312 int 00313 fe_get_output_size(fe_t *fe) 00314 { 00315 return (int)fe->feature_dimension; 00316 } 00317 00318 void 00319 fe_get_input_size(fe_t *fe, int *out_frame_shift, 00320 int *out_frame_size) 00321 { 00322 if (out_frame_shift) 00323 *out_frame_shift = fe->frame_shift; 00324 if (out_frame_size) 00325 *out_frame_size = fe->frame_size; 00326 } 00327 00328 int32 00329 fe_process_frame(fe_t * fe, int16 const *spch, int32 nsamps, mfcc_t * fr_cep) 00330 { 00331 fe_read_frame(fe, spch, nsamps); 00332 return fe_write_frame(fe, fr_cep); 00333 } 00334 00335 int 00336 fe_process_frames(fe_t *fe, 00337 int16 const **inout_spch, 00338 size_t *inout_nsamps, 00339 mfcc_t **buf_cep, 00340 int32 *inout_nframes) 00341 { 00342 int32 frame_count; 00343 int outidx, i, n, n_overflow, orig_n_overflow; 00344 int16 const *orig_spch; 00345 00346 /* In the special case where there is no output buffer, return the 00347 * maximum number of frames which would be generated. */ 00348 if (buf_cep == NULL) { 00349 if (*inout_nsamps + fe->num_overflow_samps < (size_t)fe->frame_size) 00350 *inout_nframes = 0; 00351 else 00352 *inout_nframes = 1 00353 + ((*inout_nsamps + fe->num_overflow_samps - fe->frame_size) 00354 / fe->frame_shift); 00355 return *inout_nframes; 00356 } 00357 00358 /* Are there not enough samples to make at least 1 frame? */ 00359 if (*inout_nsamps + fe->num_overflow_samps < (size_t)fe->frame_size) { 00360 if (*inout_nsamps > 0) { 00361 /* Append them to the overflow buffer. */ 00362 memcpy(fe->overflow_samps + fe->num_overflow_samps, 00363 *inout_spch, *inout_nsamps * (sizeof(int16))); 00364 fe->num_overflow_samps += *inout_nsamps; 00365 /* Update input-output pointers and counters. */ 00366 *inout_spch += *inout_nsamps; 00367 *inout_nsamps = 0; 00368 } 00369 /* We produced no frames of output, sorry! */ 00370 *inout_nframes = 0; 00371 return 0; 00372 } 00373 00374 /* Can't write a frame? Then do nothing! */ 00375 if (*inout_nframes < 1) { 00376 *inout_nframes = 0; 00377 return 0; 00378 } 00379 00380 /* Keep track of the original start of the buffer. */ 00381 orig_spch = *inout_spch; 00382 orig_n_overflow = fe->num_overflow_samps; 00383 /* How many frames will we be able to get? */ 00384 frame_count = 1 00385 + ((*inout_nsamps + fe->num_overflow_samps - fe->frame_size) 00386 / fe->frame_shift); 00387 /* Limit it to the number of output frames available. */ 00388 if (frame_count > *inout_nframes) 00389 frame_count = *inout_nframes; 00390 /* Index of output frame. */ 00391 outidx = 0; 00392 00393 /* Start processing, taking care of any incoming overflow. */ 00394 if (fe->num_overflow_samps) { 00395 int offset = fe->frame_size - fe->num_overflow_samps; 00396 00397 /* Append start of spch to overflow samples to make a full frame. */ 00398 memcpy(fe->overflow_samps + fe->num_overflow_samps, 00399 *inout_spch, offset * sizeof(**inout_spch)); 00400 fe_read_frame(fe, fe->overflow_samps, fe->frame_size); 00401 assert(outidx < frame_count); 00402 if ((n = fe_write_frame(fe, buf_cep[outidx])) < 0) 00403 return -1; 00404 outidx += n; 00405 /* Update input-output pointers and counters. */ 00406 *inout_spch += offset; 00407 *inout_nsamps -= offset; 00408 fe->num_overflow_samps -= fe->frame_shift; 00409 } 00410 else { 00411 fe_read_frame(fe, *inout_spch, fe->frame_size); 00412 assert(outidx < frame_count); 00413 if ((n = fe_write_frame(fe, buf_cep[outidx])) < 0) 00414 return -1; 00415 outidx += n; 00416 /* Update input-output pointers and counters. */ 00417 *inout_spch += fe->frame_size; 00418 *inout_nsamps -= fe->frame_size; 00419 } 00420 00421 /* Process all remaining frames. */ 00422 for (i = 1; i < frame_count; ++i) { 00423 assert(*inout_nsamps >= (size_t)fe->frame_shift); 00424 00425 fe_shift_frame(fe, *inout_spch, fe->frame_shift); 00426 assert(outidx < frame_count); 00427 if ((n = fe_write_frame(fe, buf_cep[outidx])) < 0) 00428 return -1; 00429 outidx += n; 00430 /* Update input-output pointers and counters. */ 00431 *inout_spch += fe->frame_shift; 00432 *inout_nsamps -= fe->frame_shift; 00433 /* Amount of data behind the original input which is still needed. */ 00434 if (fe->num_overflow_samps > 0) 00435 fe->num_overflow_samps -= fe->frame_shift; 00436 } 00437 00438 /* How many relevant overflow samples are there left? */ 00439 if (fe->num_overflow_samps <= 0) { 00440 /* Maximum number of overflow samples past *inout_spch to save. */ 00441 n_overflow = *inout_nsamps; 00442 if (n_overflow > fe->frame_shift) 00443 n_overflow = fe->frame_shift; 00444 fe->num_overflow_samps = fe->frame_size - fe->frame_shift; 00445 /* Make sure this isn't an illegal read! */ 00446 if (fe->num_overflow_samps > *inout_spch - orig_spch) 00447 fe->num_overflow_samps = *inout_spch - orig_spch; 00448 fe->num_overflow_samps += n_overflow; 00449 if (fe->num_overflow_samps > 0) { 00450 memcpy(fe->overflow_samps, 00451 *inout_spch - (fe->frame_size - fe->frame_shift), 00452 fe->num_overflow_samps * sizeof(**inout_spch)); 00453 /* Update the input pointer to cover this stuff. */ 00454 *inout_spch += n_overflow; 00455 *inout_nsamps -= n_overflow; 00456 } 00457 } 00458 else { 00459 /* There is still some relevant data left in the overflow buffer. */ 00460 /* Shift existing data to the beginning. */ 00461 memmove(fe->overflow_samps, 00462 fe->overflow_samps + orig_n_overflow - fe->num_overflow_samps, 00463 fe->num_overflow_samps * sizeof(*fe->overflow_samps)); 00464 /* Copy in whatever we had in the original speech buffer. */ 00465 n_overflow = *inout_spch - orig_spch + *inout_nsamps; 00466 if (n_overflow > fe->frame_size - fe->num_overflow_samps) 00467 n_overflow = fe->frame_size - fe->num_overflow_samps; 00468 memcpy(fe->overflow_samps + fe->num_overflow_samps, 00469 orig_spch, n_overflow * sizeof(*orig_spch)); 00470 fe->num_overflow_samps += n_overflow; 00471 /* Advance the input pointers. */ 00472 if (n_overflow > *inout_spch - orig_spch) { 00473 n_overflow -= (*inout_spch - orig_spch); 00474 *inout_spch += n_overflow; 00475 *inout_nsamps -= n_overflow; 00476 } 00477 } 00478 00479 /* Finally update the frame counter with the number of frames we procesed. */ 00480 *inout_nframes = outidx; /* FIXME: Not sure why I wrote it this way... */ 00481 return 0; 00482 } 00483 00484 int 00485 fe_process_utt(fe_t * fe, int16 const * spch, size_t nsamps, 00486 mfcc_t *** cep_block, int32 * nframes) 00487 { 00488 mfcc_t **cep; 00489 int rv; 00490 00491 /* Figure out how many frames we will need. */ 00492 fe_process_frames(fe, NULL, &nsamps, NULL, nframes); 00493 /* Create the output buffer (it has to exist, even if there are no output frames). */ 00494 if (*nframes) 00495 cep = (mfcc_t **)ckd_calloc_2d(*nframes, fe->feature_dimension, sizeof(**cep)); 00496 else 00497 cep = (mfcc_t **)ckd_calloc_2d(1, fe->feature_dimension, sizeof(**cep)); 00498 /* Now just call fe_process_frames() with the allocated buffer. */ 00499 rv = fe_process_frames(fe, &spch, &nsamps, cep, nframes); 00500 *cep_block = cep; 00501 00502 return rv; 00503 } 00504 00505 00506 int32 00507 fe_end_utt(fe_t * fe, mfcc_t * cepvector, int32 * nframes) 00508 { 00509 /* Process any remaining data. */ 00510 if (fe->num_overflow_samps > 0) { 00511 fe_read_frame(fe, fe->overflow_samps, fe->num_overflow_samps); 00512 *nframes = fe_write_frame(fe, cepvector); 00513 } 00514 else { 00515 *nframes = 0; 00516 } 00517 00518 /* reset overflow buffers... */ 00519 fe->num_overflow_samps = 0; 00520 fe->start_flag = 0; 00521 00522 return 0; 00523 } 00524 00525 fe_t * 00526 fe_retain(fe_t *fe) 00527 { 00528 ++fe->refcount; 00529 return fe; 00530 } 00531 00532 int 00533 fe_free(fe_t * fe) 00534 { 00535 if (fe == NULL) 00536 return 0; 00537 if (--fe->refcount > 0) 00538 return fe->refcount; 00539 00540 /* kill FE instance - free everything... */ 00541 if (fe->mel_fb) { 00542 if (fe->mel_fb->mel_cosine) 00543 fe_free_2d((void *) fe->mel_fb->mel_cosine); 00544 ckd_free(fe->mel_fb->lifter); 00545 ckd_free(fe->mel_fb->spec_start); 00546 ckd_free(fe->mel_fb->filt_start); 00547 ckd_free(fe->mel_fb->filt_width); 00548 ckd_free(fe->mel_fb->filt_coeffs); 00549 ckd_free(fe->mel_fb); 00550 } 00551 ckd_free(fe->spch); 00552 ckd_free(fe->frame); 00553 ckd_free(fe->ccc); 00554 ckd_free(fe->sss); 00555 ckd_free(fe->spec); 00556 ckd_free(fe->mfspec); 00557 ckd_free(fe->overflow_samps); 00558 ckd_free(fe->hamming_window); 00559 cmd_ln_free_r(fe->config); 00560 ckd_free(fe); 00561 00562 return 0; 00563 } 00564 00568 int32 00569 fe_mfcc_to_float(fe_t * fe, 00570 mfcc_t ** input, float32 ** output, int32 nframes) 00571 { 00572 int32 i; 00573 00574 #ifndef FIXED_POINT 00575 if ((void *) input == (void *) output) 00576 return nframes * fe->feature_dimension; 00577 #endif 00578 for (i = 0; i < nframes * fe->feature_dimension; ++i) 00579 output[0][i] = MFCC2FLOAT(input[0][i]); 00580 00581 return i; 00582 } 00583 00587 int32 00588 fe_float_to_mfcc(fe_t * fe, 00589 float32 ** input, mfcc_t ** output, int32 nframes) 00590 { 00591 int32 i; 00592 00593 #ifndef FIXED_POINT 00594 if ((void *) input == (void *) output) 00595 return nframes * fe->feature_dimension; 00596 #endif 00597 for (i = 0; i < nframes * fe->feature_dimension; ++i) 00598 output[0][i] = FLOAT2MFCC(input[0][i]); 00599 00600 return i; 00601 } 00602 00603 int32 00604 fe_logspec_to_mfcc(fe_t * fe, const mfcc_t * fr_spec, mfcc_t * fr_cep) 00605 { 00606 #ifdef FIXED_POINT 00607 fe_spec2cep(fe, fr_spec, fr_cep); 00608 #else /* ! FIXED_POINT */ 00609 powspec_t *powspec; 00610 int32 i; 00611 00612 powspec = ckd_malloc(fe->mel_fb->num_filters * sizeof(powspec_t)); 00613 for (i = 0; i < fe->mel_fb->num_filters; ++i) 00614 powspec[i] = (powspec_t) fr_spec[i]; 00615 fe_spec2cep(fe, powspec, fr_cep); 00616 ckd_free(powspec); 00617 #endif /* ! FIXED_POINT */ 00618 return 0; 00619 } 00620 00621 int32 00622 fe_logspec_dct2(fe_t * fe, const mfcc_t * fr_spec, mfcc_t * fr_cep) 00623 { 00624 #ifdef FIXED_POINT 00625 fe_dct2(fe, fr_spec, fr_cep, 0); 00626 #else /* ! FIXED_POINT */ 00627 powspec_t *powspec; 00628 int32 i; 00629 00630 powspec = ckd_malloc(fe->mel_fb->num_filters * sizeof(powspec_t)); 00631 for (i = 0; i < fe->mel_fb->num_filters; ++i) 00632 powspec[i] = (powspec_t) fr_spec[i]; 00633 fe_dct2(fe, powspec, fr_cep, 0); 00634 ckd_free(powspec); 00635 #endif /* ! FIXED_POINT */ 00636 return 0; 00637 } 00638 00639 int32 00640 fe_mfcc_dct3(fe_t * fe, const mfcc_t * fr_cep, mfcc_t * fr_spec) 00641 { 00642 #ifdef FIXED_POINT 00643 fe_dct3(fe, fr_cep, fr_spec); 00644 #else /* ! FIXED_POINT */ 00645 powspec_t *powspec; 00646 int32 i; 00647 00648 powspec = ckd_malloc(fe->mel_fb->num_filters * sizeof(powspec_t)); 00649 fe_dct3(fe, fr_cep, powspec); 00650 for (i = 0; i < fe->mel_fb->num_filters; ++i) 00651 fr_spec[i] = (mfcc_t) powspec[i]; 00652 ckd_free(powspec); 00653 #endif /* ! FIXED_POINT */ 00654 return 0; 00655 }