FE_feature.cpp
上传用户:italyroyal
上传日期:2013-05-06
资源大小:473k
文件大小:22k
源码类别:

语音合成与识别

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // This is a part of the Feature program.
  3. // Version: 1.0
  4. // Date: February 22, 2003
  5. // Programmer: Oh-Wook Kwon
  6. // Copyright(c) 2003 Oh-Wook Kwon. All rights reserved. owkwon@ucsd.edu
  7. ///////////////////////////////////////////////////////////////////////////////
  8. /*************************************************************************
  9. * Feature extraction
  10. * sampleN = Number of speech samples
  11. * frameN = Number of output parameter frames
  12. * frameN = int((sampleN-(frameSize-shiftSize))/shiftSize)
  13. *************************************************************************/
  14. #include "StdAfx.h"
  15. #include "FE_feature.h"
  16. /* Feature name must be consistent with the declaration of FeatKind */
  17. const char *FE_featNameA[]={
  18. "LPC", "LPCC", "PLCC", "MFCC", "FTCC", "FBANK", 
  19. "LPC_D", "LPCC_D", "PLCC_D", "MFCC_D", "FTCC_D", "FBANK_D",
  20. "FFT_SPEC", "LPC_SPEC", "LPCC_SPEC", "MFCC_SPEC", "FTCC_SPEC",
  21. "LPCCOV", "LAR", "LSF", "PARCOR", "FORMANT",
  22. "ZCR", "ENERGY", "PITCH", "VUS", "ENDPOINT",
  23. "EPOCH", "GLOFLOW", "GLOPULSE", "LPCRES", "FFTCEP",
  24. "FILE",0
  25. };
  26. #ifdef WIN32
  27. static char* strtok_r(char *s1, const char *s2, char **savept);
  28. #endif
  29. /************************************************************************
  30.  * Analysis Condition (Default)
  31.  *   ---- Don't Change !!
  32.  *************************************************************************/
  33. Fe::Fe()
  34. {
  35. /* set core parameters for adc data */
  36. m_sampleRate = DEFAULT_SAMPLING_RATE;
  37. m_emphFac = (float)FE_PRE_EMPH_FAC;
  38. /* set core parameters for analysis */
  39. m_shiftSizeMs = DEFAULT_SHIFT_SIZE_IN_MS;
  40. m_winSizeMs = DEFAULT_WINDOW_SIZE_IN_MS;
  41. m_lpcOrder = FE_LPC_ORDER;
  42. m_cepOrder = FE_CEP_ORDER;
  43. m_fbOrder = FE_NUM_CHANNELS;
  44. m_fftSize = DEFAULT_FFT_SIZE;
  45. m_deltaSize = FE_DELTA;
  46. m_lifter = LIFT_SIN;
  47. /* set extra parameters */
  48. m_dither = FALSE; // set to TRUE in order to prevent underflow in taking log energy
  49. m_covShiftSizeMs = m_shiftSizeMs/5;
  50. m_covWinSizeMs = m_winSizeMs/6;
  51. m_cepSmooth = FALSE;
  52. if ( little_endian() ) {
  53. m_byteOrder = MY_LITTLE_ENDIAN;
  54. m_swapByte = 0;
  55. }
  56. else{
  57. m_byteOrder = MY_BIG_ENDIAN;
  58. m_swapByte = 1;
  59. }
  60. /* PLP */
  61. init_plp();
  62. /* MFCC */
  63. m_MelFBfftSize=0;
  64. m_logEnergyFloor=FE_MIN_LOG_ENERGY;
  65. m_energyFloor=(float)exp(m_logEnergyFloor);
  66. /* control parameters */
  67. m_pProgress = NULL;
  68. m_pCancel = NULL;
  69. }
  70. Fe::~Fe()
  71. {
  72. }
  73. void Fe::Init(FeatKind fk, CFeature& adcData)
  74. {
  75. if(fk==FE_PLCC) m_winSizeMs = PLP_WINDOW_SIZE_IN_MS;
  76. if(adcData.sampleFreqN>0) m_sampleRate = adcData.sampleFreqN;
  77. else if(m_sampleRate>0)adcData.sampleFreqN=m_sampleRate;
  78. if(m_sampleRate==8000){
  79. m_lpcOrder = FE_LPC_ORDER_1;
  80. }
  81. else if(m_sampleRate==16000){
  82. m_lpcOrder = FE_LPC_ORDER_2;
  83. }
  84. if(adcData.shiftN>0)
  85. m_shiftSizeMs = (int)((adcData.shiftN*1000)/adcData.sampleFreqN+0.5);
  86. else if(m_shiftSizeMs>0)
  87. adcData.shiftN=(int)(m_shiftSizeMs*adcData.sampleFreqN/1000);
  88. m_covShiftSizeMs = m_shiftSizeMs/5;
  89. }
  90. int Fe::FeatureMain(FeatKind fk, const char *infile, const char *outfile, const char *parafile, const char* tag)
  91. {
  92. if(parafile){
  93. ReadParaFile(parafile);
  94. }
  95. if(tag){
  96. m_tag=tag;
  97. }
  98. FILE *fi, *fo;
  99. if( (fi = fopen(infile, "rb")) == NULL)
  100. err_fopen(infile);
  101. if( (fo = fopen(outfile, "wb")) == NULL)
  102. err_fopen(outfile);
  103. fseek(fi,0L,SEEK_END);
  104. int fsize = ftell(fi);
  105. rewind(fi);
  106. CFeature adcData;
  107. adcData.vec.resize(fsize/sizeof(short));
  108. int sampleN = ad_read(fi,&adcData.vec[0],fsize/sizeof(short));
  109. CFeature feature;
  110. int frameN = FeatureMain(fk, adcData, 0, sampleN, feature, -1, -1);
  111. int dimN = GetDim(fk);
  112. vector<int> pTag(dimN);
  113. ReadTag(m_tag.c_str(), &pTag[0], dimN);
  114. string featname = GetFeatName(fk);
  115. switch(fk){
  116. case FE_LPCRES:
  117. case FE_EPOCH:
  118. case FE_GLOFLOW:
  119. ad_write(fo, &feature.vec[0], sampleN);
  120. break;
  121. default:
  122. write_feature_vectors(fo, feature.mat, &pTag[0], featname.c_str());
  123. break;
  124. }
  125. fclose(fi);
  126. fclose(fo);
  127. return 1;
  128. }
  129. int Fe::FeatureMain(FeatKind fk, CFeature& adcData, int beginX, int endX, CFeature& feature, int outBeginX, int outEndX)
  130. {
  131. if(adcData.shiftN != feature.shiftN){
  132. FE_ERROR("FeatureMain: The shift sizes of adaData and feature are different.n");
  133. if(feature.shiftN>0) adcData.shiftN=feature.shiftN;
  134. assert(0);
  135. }
  136. if(adcData.sampleFreqN != feature.sampleFreqN){
  137. FE_ERROR("FeatureMain: The sampling rates of adaData and feature are different.n");
  138. if(feature.sampleFreqN>0) adcData.sampleFreqN=feature.sampleFreqN;
  139. }
  140. Init(fk, adcData);
  141. if(fk==FE_VUS || fk==FE_FORMANT || fk==FE_PITCH || fk==FE_VUS || FE_ENDPOINT){
  142. /* First reduce noise by Wiener filtering */
  143. enhance_basic(&adcData.vec[beginX],(endX-beginX),m_sampleRate,1);
  144. }
  145. int i;
  146. int frameN;
  147. int sampleN=(endX-beginX);
  148. vector<float> pitchA;
  149. switch(fk){
  150. case FE_PITCH:
  151. frameN = vus_basic(&adcData.vec[beginX], sampleN, GetFrameSize(), m_vusA);
  152. frameN = pitch_basic(&adcData.vec[beginX], sampleN, m_sampleRate, GetShiftSize(), m_vusA, pitchA);
  153. feature.frameN = frameN; feature.dimN = 1; feature.byteN = 4;
  154. feature.mat.Resize(frameN,1);
  155. if(outBeginX<0 || outEndX<0){
  156. outBeginX=0;
  157. outEndX=frameN;
  158. }
  159. for(i=0; i<frameN;i++) feature.mat[outBeginX+i][0] = pitchA[i];
  160. break;
  161. case FE_ENDPOINT:
  162. epd_basic(&adcData.vec[beginX], sampleN, m_sampleRate, feature.label);
  163. break;
  164. default:
  165. frameN = FeatureExtract(fk, adcData, beginX, endX, feature, outBeginX, outEndX);
  166. break;
  167. }
  168. return frameN;
  169. }
  170. int Fe::FeatureExtract(FeatKind fk, CFeature& adcData, int beginX, int endX, CFeature& feature, int outBeginX, int outEndX)
  171. {
  172. int n,k;
  173. vector<short> wave1d;
  174. FeMatrix<float> feature2d;
  175. short *sample = &adcData.vec[beginX];
  176. int sampleN = endX-beginX;
  177. int frameN = 0;
  178. int dimN = GetDim(fk);
  179. int frameSize = GetFrameSize();
  180. /* V/U/S classification works for utterance only */
  181. if(fk==FE_VUS){
  182. frameN = vus_basic(sample, sampleN, frameSize, m_vusA);
  183. if(outBeginX<0) outBeginX=0; if(outEndX<0) outEndX=frameN;
  184. feature.frameN = frameN; feature.dimN = dimN; feature.byteN = 4; feature.mat.Resize(outEndX,1);
  185. for(n=0; n<frameN && n+outBeginX<outEndX; n++) feature.mat[outBeginX+n][0] = m_vusA[n];
  186. return frameN;
  187. }
  188. /* formant tracking requires pitch information to remove non-voice parts */
  189. if(fk==FE_FORMANT){
  190. frameN = vus_basic(sample, sampleN, frameSize, m_vusA);
  191. int shiftSize = GetShiftSize();
  192. int n_pitch_frames = pitch_basic(sample, sampleN, m_sampleRate, shiftSize, m_vusA, m_pitchA);
  193. }
  194. vector<float> preprocessedA;
  195. preprocessedA.resize(sampleN);
  196. /* Preprocessing */
  197. if(fk==FE_ZCR || fk==FE_ENERGY || fk==FE_EPOCH || fk==FE_GLOFLOW || fk==FE_GLOPULSE || fk==FE_VUS){
  198. /* just convert to float */
  199. for(int i=0;i<sampleN;i++) preprocessedA[i] = (float)sample[i];
  200. } else {
  201. preprocessing(sample, sampleN, &preprocessedA[0]);
  202. }
  203. /* Feature extraction */
  204. if(fk==FE_LPCRES || fk==FE_EPOCH || fk==FE_GLOFLOW){
  205. /* result is a 1-dim short vector */
  206. frameN = compute_feature_1d(fk,&preprocessedA[0],sampleN,wave1d);
  207. }
  208. else{
  209. /* result is a 2-dim float matrix */
  210. frameN = compute_feature_2d(fk,&preprocessedA[0],sampleN,feature2d);
  211. }
  212. /* Reorder cepstrum coefficients to follow the convention [c1, c2, c3, ..., c12, c0] */
  213. FeatKind bk=GetBaseFeatKind(fk);
  214. if(bk==FE_LPCC || bk==FE_PLCC || bk==FE_MFCC || bk==FE_FTCC){
  215. for(n=0;n<frameN;n++){
  216. float atmp=feature2d[n][0];
  217. for(k=0;k<m_cepOrder;k++) feature2d[n][k]=feature2d[n][k+1];
  218. feature2d[n][m_cepOrder]=atmp;
  219. }
  220. }
  221. /* Compute delta coefficients */
  222. if(HasDeltaFeat(fk)){
  223. FeMatrix<float> tmp2d=feature2d;
  224. delta_compute(tmp2d, m_deltaSize, feature2d);
  225. }
  226. /* Copy the resulting features */
  227. if(outBeginX<0) outBeginX=0; if(outEndX<0 || outEndX>frameN) outEndX=frameN;
  228. if(fk==FE_LPCRES || fk==FE_EPOCH || fk==FE_GLOFLOW){
  229. assert(sampleN==frameN);
  230. feature.frameN = sampleN; feature.dimN = 1; feature.byteN = 2; feature.vec.resize(sampleN);
  231. for(n=0; n<sampleN; n++) feature.vec[n] = wave1d[n];
  232. }
  233. else{
  234. feature.frameN = frameN; feature.dimN = dimN; feature.byteN = 4; feature.mat.Resize(outEndX,dimN);
  235. for(n=0; n<frameN && n+outBeginX<outEndX; n++){
  236. for(k=0; k<dimN; k++) feature.mat[outBeginX+n][k] = feature2d[n][k];
  237. }
  238. }
  239. return frameN;
  240. }
  241. int Fe::compute_feature_1d(FeatKind fk, float *sample, int sampleN, vector<short>& featA)
  242. {
  243. int n;
  244. int shiftSize, frameSize;
  245. if(fk==FE_GLOFLOW){
  246. shiftSize = (int)(m_covShiftSizeMs*m_sampleRate/1000.0+0.5); if(shiftSize%2) shiftSize += 1;
  247. frameSize = (int)(m_covWinSizeMs*m_sampleRate/1000.0+0.5); if(frameSize%2) frameSize += 1;
  248. if(frameSize < 2*m_lpcOrder) frameSize = 2*m_lpcOrder;
  249. }
  250. else{
  251. shiftSize = GetShiftSize();
  252. frameSize = GetFrameSize();
  253. }
  254. int frameN = (int)((float)(sampleN-(frameSize-shiftSize))/shiftSize);
  255. int dimN = 1;
  256. vector<float> frameA(frameSize);
  257. vector<float> acf(m_lpcOrder+1);
  258. vector<float> kcf(m_lpcOrder+1);
  259. featA.resize(sampleN);
  260. if(fk==FE_EPOCH) return calc_epoch(sample, sampleN, featA, NULL);
  261. vector<float> residual_data(frameSize);
  262. FeMatrix<float> cov(m_lpcOrder+1, m_lpcOrder+1);
  263. int remainN;
  264. for (n=0; ; n++){
  265. int i;
  266. int begX=n*shiftSize;
  267. if(!CheckWinMessage()) break;
  268. ShowProgress((int)((n*100)/frameN));
  269. remainN=my_min(sampleN-begX,frameSize);
  270. if(remainN<=0) break;
  271. for(i=0;i<remainN;i++) frameA[i]=sample[begX+i];
  272. for(i=remainN;i<frameSize;i++) frameA[i]=0;
  273. m_window.Windowing(&frameA[0], remainN, WIN_HAMMING);
  274. switch(fk){
  275. case FE_LPCRES:
  276. {
  277. int k;
  278. float G;
  279. if(remainN == frameSize)
  280. _lpc_basic(&frameA[0], frameSize, &acf[0], m_lpcOrder, &G);
  281. _lpc_error_basic(&frameA[0], remainN, &acf[0], m_lpcOrder, &residual_data[0]);
  282. for(k=0; k<shiftSize && begX+k<sampleN;k++) featA[begX+k] = (short)(residual_data[k]);
  283. }
  284. break;
  285. case FE_GLOFLOW:
  286. {
  287. float G;
  288. if(remainN == frameSize)
  289. lpc_cov(&frameA[0], frameSize, cov, &acf[0], m_lpcOrder, &G);
  290. lpc_cov_error(&frameA[0], remainN, &acf[0], m_lpcOrder, &residual_data[0]);
  291. // differentiated glottal flow
  292. Integrate(&residual_data[0], remainN, &featA[begX]);
  293. // glottal flow
  294. //Integrate(&((*featA)[i]), remainN, featA+i);
  295. }
  296. break;
  297. default:
  298. assert(0);
  299. return 0;
  300. break;
  301. }
  302. }
  303. return sampleN;
  304. }
  305. int Fe::compute_feature_2d(FeatKind fk, float *sample, int sampleN, FeMatrix<float>& featA)
  306. {
  307. int n;
  308. int shiftSize = GetShiftSize();
  309. int frameSize = GetFrameSize();
  310. int frameN = (int)((float)(sampleN-(frameSize-shiftSize))/shiftSize);
  311. int dimN = GetDim(fk);
  312. int fft_size; for (fft_size=1; fft_size<frameSize; fft_size*=2) ;
  313. vector<float> frameA(frameSize);
  314. vector<float> acf(m_lpcOrder+1);
  315. vector<float> kcf(m_lpcOrder+1);
  316. featA.Resize(frameN,dimN);
  317. FeMatrix<float> featTmpA;
  318. if(fk==FE_FORMANT) featTmpA.Resize(frameN, m_lpcOrder/2+1);
  319. fk=GetBaseFeatKind(fk);
  320. int dc_bias=0, level=0;
  321. float mean=0;
  322. if(fk==FE_ENERGY || fk==FE_ZCR){
  323. int i;
  324. for(i=0;i<sampleN;i++) mean += sample[i]; mean = mean/sampleN;
  325. dc_bias = (int)((mean >= 0) ? mean+0.5 : mean-0.5);
  326. if(frameN>10){
  327. /* Assume that there are at least 3 frames of silence at the beginning */
  328. float v=0; int m=3*shiftSize;
  329. for (i=0; i<m;i++) v+=(sample[i]-dc_bias)*(sample[i]-dc_bias);
  330. v=(float)sqrt(v/m);
  331. level=(int)(2*v); /* Set ZCR threshold to 2*noiseLevel */
  332. }
  333. }
  334. for (n=0; n<frameN; n++){
  335. float G=0;
  336. int begX=n*shiftSize;
  337. int i, k;
  338. float energy;
  339. if(!CheckWinMessage()) break;
  340. ShowProgress((int)((n*100)/frameN));
  341. if(!(fk==FE_ENERGY || fk==FE_ZCR)){
  342. for(i=0;i<frameSize;i++) frameA[i]=sample[begX+i];
  343. m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
  344. }
  345. switch(fk){
  346. case FE_ENERGY:
  347. energy=compute_energy(sample+begX, frameSize, mean);
  348. featA[n][0] = 10*LOG10((energy>FE_MIN_ENERGY ? energy : FE_MIN_ENERGY));
  349. break;
  350. case FE_ZCR:
  351. featA[n][0] = (float)compute_zero_cross_rate(sample+begX, frameSize, level, dc_bias);
  352. break;
  353. case FE_LAR:
  354. _lpc_parcor_basic(&frameA[0], frameSize, &acf[0], &kcf[0], m_lpcOrder, &G);
  355. featA[n][0] = 0;
  356. for(k=1; k<=m_lpcOrder; k++) featA[n][k] = (float)log((1-kcf[k])/(1+kcf[k]));
  357. break;
  358. case FE_LSF:
  359. {
  360. vector<CComplex> oldRootsP;
  361. vector<CComplex> oldRootsQ;
  362. _lpc_basic(&frameA[0], frameSize, &acf[0], m_lpcOrder, &G);
  363. lpc_to_lsf(&acf[0],m_lpcOrder,&featA[n][0], oldRootsP, oldRootsQ);
  364. }
  365. break;
  366. case FE_PARCOR:
  367. _lpc_parcor_basic(&frameA[0], frameSize, &acf[0], &featA[n][0], m_lpcOrder, &G);
  368. featA[n][0] = 0;
  369. break;
  370. case FE_FORMANT:
  371. {
  372. vector<CComplex> rootsA(m_lpcOrder+1);
  373. for(i=0;i<=m_lpcOrder;i++) rootsA[i] = 0;
  374. _lpc_basic(&frameA[0], frameSize, &acf[0], m_lpcOrder, &G);
  375. /* Note that we compute all formant frequencies for post-processing */
  376. int ntmp=lpc_to_formant(&acf[0],m_lpcOrder,&featTmpA[n][0],m_lpcOrder/2,rootsA);
  377. for(k=0;k<=m_lpcOrder/2;k++) featTmpA[n][k] *= (m_sampleRate/(float)(2*M_PI));
  378. }
  379. break;
  380. case FE_LPC:
  381. _lpc_basic(&frameA[0], frameSize, &featA[n][0], m_lpcOrder, &G);
  382. break;
  383. case FE_FBANK:
  384. _filterbank_basic(&frameA[0], frameSize, &featA[n][0], m_fbOrder, fft_size, m_cepSmooth, (int)(m_sampleRate/MAX_PITCH_FREQ));
  385. break;
  386. case FE_MFCC:
  387. _mel_cepstrum_basic(&frameA[0], frameSize, &featA[n][0], m_fbOrder, m_cepOrder, m_fftSize);
  388. cepstral_window(&featA[n][0],m_cepOrder,m_lifter);
  389. break;
  390. case FE_PLCC:
  391. _plp_basic(&frameA[0], frameSize, &featA[n][0], m_plccOrder, m_plpOrder);
  392. cepstral_window(&featA[n][0],m_plccOrder,m_lifter);
  393. break;
  394. case FE_LPCC:
  395. _lpc_basic(&frameA[0], frameSize, &acf[0], m_lpcOrder, &G);
  396. lpc_to_cepstrum(&acf[0], m_lpcOrder, &featA[n][0], m_cepOrder, G);
  397. cepstral_window(&featA[n][0],m_cepOrder,m_lifter);
  398. break;
  399. case FE_FTCC:
  400. _fft_cepstrum_basic(&frameA[0], frameSize, &featA[n][0], m_cepOrder, fft_size);
  401. cepstral_window(&featA[n][0],m_cepOrder,m_lifter);
  402. break;
  403. default:
  404. assert(0);
  405. return 0;
  406. break;
  407. }
  408. }
  409. if(fk==FE_FORMANT){
  410. /* check formant range, noting that F0 is always zero */
  411. formant_check_range(featTmpA, m_lpcOrder/2, frameN);
  412. /* smooth formant trajectory */
  413. formant_median_filter(featTmpA, m_lpcOrder/2, frameN);
  414. formant_linear_filter(featTmpA, m_lpcOrder/2, frameN);
  415. /* Make formant consistent with pitch information */
  416. assert(m_pitchA.size()>0);
  417. frameN = formant_remove_nonvoice(featTmpA, m_lpcOrder/2, frameN, m_pitchA);
  418. /* Copy to the result variable, skipping F0  */
  419. for(n=0;n<frameN;n++){
  420. for(int k=0;k<dimN && k<m_lpcOrder/2+1;k++){
  421. featA[n][k]=featTmpA[n][k+1];
  422. }
  423. }
  424. }
  425. return frameN;
  426. }
  427. int Fe::ReadParaFile(const char *parafile)
  428. {
  429. FILE *fi = fopen(parafile,"r");
  430. if(!fi) return 0;
  431. char line[1024], arg1[256], arg2[256];
  432. string name;
  433. while(fgets(line,sizeof(line)-1,fi)){
  434. if(line[0]==0) break; // end of file
  435. if(line[0]=='#') continue; // skip comment line
  436. sscanf(line,"%s%s", arg1, arg2);
  437. name=arg1;
  438. if(name=="SAMPLING_RATE"){ m_sampleRate = atoi(arg2); } 
  439. else if(name=="WINDOW_SIZE"){ m_winSizeMs = atoi(arg2); } 
  440. else if(name=="SHIFT_SIZE"){ m_shiftSizeMs = atoi(arg2); } 
  441. else if(name=="PREEMPHASIS_FACTOR"){ m_emphFac = (float)atof(arg2); } 
  442. else if(name=="FFT_SIZE"){ m_fftSize = atoi(arg2); } 
  443. else if(name=="LPC_ORDER"){ m_lpcOrder = atoi(arg2); } 
  444. else if(name=="CEPSTRUM_ORDER"){ m_cepOrder = atoi(arg2); } 
  445. else if(name=="PLP_ORDER"){ m_plpOrder = atoi(arg2); } 
  446. else if(name=="PLP_CEPSTRUM_ORDER"){ m_plccOrder = atoi(arg2); } 
  447. else if(name=="FILTER_BANK_ORDER"){ m_fbOrder = atoi(arg2); } 
  448. else if(name=="CEPSTRAL_SMOOTHING"){ m_cepSmooth = (strcmp(arg2,"ON")==0); } 
  449. else if(name=="DITHERING"){ m_dither = (strcmp(arg2,"ON")==0); } 
  450. else if(name=="TEMPORAL_FILTER_SIZE"){ m_deltaSize = atoi(arg2); }
  451. }
  452. fclose(fi);
  453. return 1;
  454. }
  455. int Fe::ReadTag(const char *tag, int* pTag, int ndim)
  456. {
  457. int i;
  458. for(i=0;i<ndim;i++) pTag[i] = 0;
  459. if(!tag){
  460. for(i=0;i<ndim;i++) pTag[i] = 1;
  461. return 1;
  462. }
  463. vector<char> tmp(strlen(tag)+1);
  464. strcpy(&tmp[0],tag);
  465. char* tmp_save = NULL;
  466. char* p = strtok_r(&tmp[0], " ,", &tmp_save);
  467. if(!p){
  468. for(i=0;i<ndim;i++) pTag[i] = 1;
  469. }
  470. while(p){
  471. int begin = 0, end = 0;
  472. int len = strlen(p);
  473. char* p_save = NULL;
  474. if(*p == '-'){
  475. begin = 0;
  476. if(*(p+1) != '')
  477. end = atoi(p+1);
  478. else
  479. end = -1;
  480. }
  481. else if(*(p+len-1) == '-'){
  482. end = ndim-1;
  483. *(p+len-1) = '';
  484. begin = atoi(p);
  485. }
  486. else{
  487. char* q = strtok_r(p, "-", &p_save);
  488. if(q) begin = end = atoi(q);
  489. q = strtok_r(NULL, "-", &p_save);
  490. if(q) end = atoi(q);
  491. }
  492. for(i=begin; i<=end; i++) pTag[i] = 1;
  493. p = strtok_r(NULL, " ,", &tmp_save);
  494. }
  495. return 1;
  496. }
  497. int Fe::GetShiftSize()
  498. {
  499. int nshift = (int)((m_shiftSizeMs*m_sampleRate)/1000.0+0.5);
  500. if(nshift%2) nshift += 1;
  501. return nshift;
  502. }
  503. int Fe::GetFrameSize()
  504. {
  505. int frameSize = (int)((m_winSizeMs*m_sampleRate)/1000.0+0.5);
  506. if(frameSize%2) frameSize += 1;
  507. return frameSize;
  508. }
  509. const char *GetFeatName(FeatKind fk)
  510. {
  511. assert((int)fk>=0 && (int)fk<(int)FE_NUM_FEAT);
  512. return FE_featNameA[(int)fk];
  513. }
  514. string GetFeatExtension(FeatKind fk)
  515. {
  516. FeatKind bk=GetBaseFeatKind(fk);
  517. string name=GetFeatName(bk);
  518. for(int i=0;i<name.size();i++) name[i]=tolower(name[i]);
  519. if(HasDeltaFeat(fk)) name=name+"_d";
  520. if(HasStftFeat(fk)) {
  521. int k=name.find("_stft");
  522. name=name.substr(0,k);
  523. name=name+"_s";
  524. }
  525. return name;
  526. }
  527. FeatKind GetBaseFeatKind(FeatKind fk)
  528. {
  529. string name=GetFeatName(fk);
  530. int k=name.find("_D");
  531. if(k==string::npos) return fk;
  532. if(name[k+2]==0 || name[k+2]=='_'){
  533. name=name.substr(0,k);
  534. for(int i=0;i<FE_NUM_FEAT-1;i++){
  535. if(strcmp(FE_featNameA[i],name.c_str())==0) return (FeatKind)i;
  536. }
  537. }
  538. return fk;
  539. }
  540. FeatKind FeatName2Kind(const char* name)
  541. {
  542. int i;
  543. for(i=0;i<FE_NUM_FEAT-1;i++){
  544. if(strcmp(FE_featNameA[i],name)==0) return (FeatKind)i;
  545. }
  546. return (FeatKind)i;
  547. }
  548. int HasDeltaFeat(FeatKind fk)
  549. {
  550. const char *name=GetFeatName(fk);
  551. char *i=strstr(name,"_D");
  552. if(i) return 1;
  553. else return 0;
  554. }
  555. int HasStftFeat(FeatKind fk)
  556. {
  557. const char *name=GetFeatName(fk);
  558. char *i=strstr(name,"_SPEC");
  559. if(i) return 1;
  560. else return 0;
  561. }
  562. int Fe::GetDim(FeatKind fk)
  563. {
  564. int ndim = 0;
  565. fk=GetBaseFeatKind(fk);
  566. switch(fk){
  567. case FE_LPC: case FE_LPCCOV:
  568. ndim = m_lpcOrder + 1; break;
  569. case FE_LPCC: case FE_MFCC: case FE_FTCC:
  570. ndim = m_cepOrder + 1; break;
  571. case FE_PLCC:
  572. ndim = m_plccOrder + 1; break;
  573. case FE_FBANK:
  574. ndim = m_fbOrder; break;
  575. case FE_LAR: case FE_LSF: case FE_PARCOR:
  576. ndim = m_lpcOrder + 1; break;
  577. case FE_FORMANT:
  578. /* F1, F2, F3, F4 */
  579. ndim = 4; break;
  580. case FE_FFT_SPEC: case FE_LPC_SPEC: case FE_LPCC_SPEC:
  581. case FE_MFCC_SPEC: case FE_FTCC_SPEC:
  582. ndim = m_fftSize; break;
  583. case FE_FFTCEP:
  584. ndim = m_fftSize; break;
  585. case FE_ZCR: case FE_ENERGY: case FE_PITCH: case FE_VUS: case FE_ENDPOINT:
  586. case FE_EPOCH: case FE_GLOFLOW: case FE_GLOPULSE: case FE_LPCRES:
  587. ndim = 1; break;
  588. default:
  589. ndim = 1; break;
  590. }
  591. return ndim;
  592. }
  593. int GetDefaultDim(enum FeatKind fk)
  594. {
  595. int dim=0;
  596. fk=GetBaseFeatKind(fk);
  597. switch(fk){
  598. case FE_FFT_SPEC: case FE_LPC_SPEC: case FE_LPCC_SPEC: case FE_MFCC_SPEC: case FE_FTCC_SPEC:
  599. dim = DEFAULT_FFT_SIZE/2+1; break;
  600. case FE_FFTCEP:
  601. dim = DEFAULT_FFT_SIZE/2+1; break;
  602. case FE_LPC: case FE_LPCCOV: case FE_LAR: case FE_LSF: case FE_PARCOR:
  603. dim = FE_LPC_ORDER+1; break;
  604. case FE_FBANK:
  605. dim = FE_NUM_CHANNELS+1; break;
  606. case FE_LPCC: case FE_FTCC: case FE_MFCC:
  607. dim = FE_CEP_ORDER+1; break;
  608. case FE_PLCC:
  609. dim = PLP_CEP_ORDER+1; break;
  610. case FE_FORMANT:
  611. dim = 4; break;
  612. default:
  613. dim = 1; break;
  614. }
  615. return dim;
  616. }
  617. int GetDefaultOrder(enum FeatKind fk)
  618. {
  619. int order=1;
  620. fk=GetBaseFeatKind(fk);
  621. switch(fk){
  622. case FE_FFT_SPEC:
  623. order = DEFAULT_FFT_SIZE/2+1; break;
  624. case FE_FFTCEP:
  625. order = DEFAULT_FFT_SIZE/2+1; break;
  626. case FE_LPC_SPEC:
  627. order = FE_LPC_ORDER; break;
  628. case FE_LPCC_SPEC: case FE_MFCC_SPEC: case FE_FTCC_SPEC:
  629. order = FE_CEP_ORDER; break;
  630. case FE_LPC: case FE_LPCCOV: case FE_LAR: case FE_LSF: case FE_PARCOR:
  631. order = FE_LPC_ORDER; break;
  632. case FE_FBANK:
  633. order = FE_NUM_CHANNELS; break;
  634. case FE_LPCC: case FE_FTCC: case FE_MFCC: case FE_PLCC:
  635. order = PLP_CEP_ORDER; break;
  636. case FE_FORMANT:
  637. order = 4; break;
  638. default:
  639. order = 1; break;
  640. }
  641. return order;
  642. }
  643. float Fe::LogE(float x)
  644. {
  645. if(x>m_energyFloor) return log(x);
  646. else return m_logEnergyFloor;
  647. }
  648. int Fe::Integrate(float *a, int n, short *b)
  649. {
  650. float alpha = (float)0.98;
  651. static float prev = 0;
  652. for(int i=0;i<n;i++){
  653. prev = a[i] + alpha*prev;
  654. b[i] = (short)(prev);
  655. }
  656. return 1;
  657. }
  658. int Fe::Integrate(short *a, int n, short *b)
  659. {
  660. float alpha = (float)0.98;
  661. static float prev = 0;
  662. for(int i=0;i<n;i++){
  663. prev = a[i] + alpha*prev;
  664. b[i] = (short)(prev);
  665. }
  666. return 1;
  667. }
  668. float Fe::GetMedian(float* a, int n)
  669. {
  670. int i;
  671. float median = 0;
  672. vector<float> tmp(n);;
  673. for(i=0;i<n;i++)
  674. tmp[i] = a[i];
  675. qsort(&tmp[0],n,sizeof(float),FE_CompareFloat);
  676. median = tmp[(n-1)/2];
  677. return median;
  678. }
  679. int Fe::InitProgress(int* pProgress, int* pCancel)
  680. {
  681. m_pProgress = pProgress;
  682. m_pCancel = pCancel;
  683. return 1;
  684. }
  685. int Fe::CheckWinMessage()
  686. {
  687. #if defined(_WIN32) && defined(ANALYSIS_LIB)
  688. MSG message;
  689. if(PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {
  690. TranslateMessage(&message);
  691. DispatchMessage(&message);
  692. }
  693. #endif
  694. if(m_pCancel && (*m_pCancel)) return 0;
  695. else return 1;
  696. }
  697. int Fe::ShowProgress(int progress)
  698. {
  699. #if defined(_WIN32) && defined(ANALYSIS_LIB)
  700. if(m_pProgress) *m_pProgress = progress;
  701. #endif
  702. return 1;
  703. }
  704. int FE_CompareFloat(const void *a, const void *b)
  705. {
  706. float *aa = (float*)a;
  707. float *bb = (float*)b;
  708. if(*aa > *bb) return 1;
  709. else if(*aa < *bb) return -1;
  710. else return 0;
  711. }
  712. #ifdef WIN32
  713. char* strtok_r(char *s1, const char *s2, char **savept)
  714. {
  715. char *p = NULL;
  716. char *z = NULL;
  717. if(s1) *savept = s1;
  718. if((*savept) == NULL) return NULL;
  719. z = *savept + strlen(*savept);
  720. p = strtok(*savept,s2);
  721. if(p != NULL && (p + strlen(p) + 1) < z)
  722. *savept = p + strlen(p) + 1;
  723. else
  724. *savept = NULL;
  725. return p;
  726. }
  727. #endif