/** * @file strip_mfcc.c * * * @brief MFCC列からゼロサンプル列を取り除く * * エネルギー項の値からゼロサンプルのフレームを検出します. * * * @brief Strip zero frames from MFCC data * * Zero sample frames will be detected by the energy coefficient of MFCC. * * * The detection is done by setting valid range of log energy. * * However, since HTK parameter file has no information for framesize or * frequency, defining precise upper bound of power is impossible. * * Guess the power that is in log scale as described below, * * framesize : 1 100 400 1000 10000(can't be!) * upper bound: 20.794 25.400 26.786 27.702 30.005 * * Thus it can be said that the range of [0..30] will work. * * When energy normalization was on, the parameters are normalized to: * * 1.0 - (Emax - value) * ESCALE * * So the range becomes [1.0-Emax*ESCALE..1.0]. But * the engine cannot know whether the ENORMALIZE was on for given parameters. * * As a conclusion, the safe bit is to set the range of log energy to * [-30..30] * hoping that escale is less than 1.0 (the HTK's default is 0.1). * * But remember, there are no guarantee that valid segments is not * misdetected. When the misdetection frequently occurs on your MFCC file, * please try "-nostrip" option to turn off the stripping. * * @author Akinobu LEE * @date Tue Feb 15 00:38:57 2005 * * $Revision: 1.5 $ * */ /* * Copyright (c) 1991-2012 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2012 Julius project team, Nagoya Institute of Technology * All rights reserved */ #include #include #include /// Invalid log value range to detect zero sample frame. #define IS_INVALID_FRAME_MFCC(A) ((A) < -30.0 || (A) > 30.0) /** * Guess where the absolute energy coefficient is. * * @param param [in] parameter data * * @return the guessed dimension number of energy coefficient, -1 on failure. */ static int guess_abs_e_location(HTK_Param *param) { short qualtype; int basenum, abs_e_num; qualtype = param->header.samptype & ~(F_COMPRESS | F_CHECKSUM); qualtype &= ~(F_BASEMASK); basenum = guess_basenum(param, qualtype); if (qualtype & F_ENERGY) { if (qualtype & F_ZEROTH) { abs_e_num = basenum + 1; } else { abs_e_num = basenum; } } else { /* absolute energy not included */ jlog("Stat: strip_mfcc: absolute energy coef. not exist, stripping disabled\n"); abs_e_num = -1; } return abs_e_num; } /** * Strip zero frames from MFCC data. * * @param param [in] parameter data * * @return TRUE on success, FALSE on failure. */ boolean param_strip_zero(HTK_Param *param) { unsigned int src,dst; int eloc; /* guess where the absolute energy coefficient is */ eloc = guess_abs_e_location(param); if ((eloc = guess_abs_e_location(param)) < 0) return FALSE; /* guess the invalid range... */ dst = 0; for(src=0;srcsamplenum;src++) { if (IS_INVALID_FRAME_MFCC(param->parvec[src][eloc])) { jlog("Warning: strip_mfcc: frame %d has invalid energy, stripped\n", src); continue; } if (src != dst) { memcpy(param->parvec[dst], param->parvec[src], sizeof(VECT) * param->veclen); } dst++; } if (dst != param->samplenum) { jlog("Warning: strip_mfcc: input shrinked from %d to %d frames\n", param->samplenum, dst); param->header.samplenum = param->samplenum = dst; } return TRUE; }