FE_feature.cpp
上传用户:italyroyal
上传日期:2013-05-06
资源大小:473k
文件大小:22k
- ///////////////////////////////////////////////////////////////////////////////
- // This is a part of the Feature program.
- // Version: 1.0
- // Date: February 22, 2003
- // Programmer: Oh-Wook Kwon
- // Copyright(c) 2003 Oh-Wook Kwon. All rights reserved. owkwon@ucsd.edu
- ///////////////////////////////////////////////////////////////////////////////
- /*************************************************************************
- * Feature extraction
- * sampleN = Number of speech samples
- * frameN = Number of output parameter frames
- * frameN = int((sampleN-(frameSize-shiftSize))/shiftSize)
- *************************************************************************/
- #include "StdAfx.h"
- #include "FE_feature.h"
- /* Feature name must be consistent with the declaration of FeatKind */
- const char *FE_featNameA[]={
- "LPC", "LPCC", "PLCC", "MFCC", "FTCC", "FBANK",
- "LPC_D", "LPCC_D", "PLCC_D", "MFCC_D", "FTCC_D", "FBANK_D",
- "FFT_SPEC", "LPC_SPEC", "LPCC_SPEC", "MFCC_SPEC", "FTCC_SPEC",
- "LPCCOV", "LAR", "LSF", "PARCOR", "FORMANT",
- "ZCR", "ENERGY", "PITCH", "VUS", "ENDPOINT",
- "EPOCH", "GLOFLOW", "GLOPULSE", "LPCRES", "FFTCEP",
- "FILE",0
- };
- #ifdef WIN32
- static char* strtok_r(char *s1, const char *s2, char **savept);
- #endif
- /************************************************************************
- * Analysis Condition (Default)
- * ---- Don't Change !!
- *************************************************************************/
- Fe::Fe()
- {
- /* set core parameters for adc data */
- m_sampleRate = DEFAULT_SAMPLING_RATE;
- m_emphFac = (float)FE_PRE_EMPH_FAC;
- /* set core parameters for analysis */
- m_shiftSizeMs = DEFAULT_SHIFT_SIZE_IN_MS;
- m_winSizeMs = DEFAULT_WINDOW_SIZE_IN_MS;
- m_lpcOrder = FE_LPC_ORDER;
- m_cepOrder = FE_CEP_ORDER;
- m_fbOrder = FE_NUM_CHANNELS;
- m_fftSize = DEFAULT_FFT_SIZE;
- m_deltaSize = FE_DELTA;
- m_lifter = LIFT_SIN;
- /* set extra parameters */
- m_dither = FALSE; // set to TRUE in order to prevent underflow in taking log energy
- m_covShiftSizeMs = m_shiftSizeMs/5;
- m_covWinSizeMs = m_winSizeMs/6;
- m_cepSmooth = FALSE;
- if ( little_endian() ) {
- m_byteOrder = MY_LITTLE_ENDIAN;
- m_swapByte = 0;
- }
- else{
- m_byteOrder = MY_BIG_ENDIAN;
- m_swapByte = 1;
- }
- /* PLP */
- init_plp();
- /* MFCC */
- m_MelFBfftSize=0;
- m_logEnergyFloor=FE_MIN_LOG_ENERGY;
- m_energyFloor=(float)exp(m_logEnergyFloor);
- /* control parameters */
- m_pProgress = NULL;
- m_pCancel = NULL;
- }
- Fe::~Fe()
- {
- }
- void Fe::Init(FeatKind fk, CFeature& adcData)
- {
- if(fk==FE_PLCC) m_winSizeMs = PLP_WINDOW_SIZE_IN_MS;
- if(adcData.sampleFreqN>0) m_sampleRate = adcData.sampleFreqN;
- else if(m_sampleRate>0)adcData.sampleFreqN=m_sampleRate;
- if(m_sampleRate==8000){
- m_lpcOrder = FE_LPC_ORDER_1;
- }
- else if(m_sampleRate==16000){
- m_lpcOrder = FE_LPC_ORDER_2;
- }
- if(adcData.shiftN>0)
- m_shiftSizeMs = (int)((adcData.shiftN*1000)/adcData.sampleFreqN+0.5);
- else if(m_shiftSizeMs>0)
- adcData.shiftN=(int)(m_shiftSizeMs*adcData.sampleFreqN/1000);
- m_covShiftSizeMs = m_shiftSizeMs/5;
- }
- int Fe::FeatureMain(FeatKind fk, const char *infile, const char *outfile, const char *parafile, const char* tag)
- {
- if(parafile){
- ReadParaFile(parafile);
- }
- if(tag){
- m_tag=tag;
- }
- FILE *fi, *fo;
- if( (fi = fopen(infile, "rb")) == NULL)
- err_fopen(infile);
- if( (fo = fopen(outfile, "wb")) == NULL)
- err_fopen(outfile);
- fseek(fi,0L,SEEK_END);
- int fsize = ftell(fi);
- rewind(fi);
- CFeature adcData;
- adcData.vec.resize(fsize/sizeof(short));
- int sampleN = ad_read(fi,&adcData.vec[0],fsize/sizeof(short));
- CFeature feature;
- int frameN = FeatureMain(fk, adcData, 0, sampleN, feature, -1, -1);
-
- int dimN = GetDim(fk);
- vector<int> pTag(dimN);
- ReadTag(m_tag.c_str(), &pTag[0], dimN);
- string featname = GetFeatName(fk);
- switch(fk){
- case FE_LPCRES:
- case FE_EPOCH:
- case FE_GLOFLOW:
- ad_write(fo, &feature.vec[0], sampleN);
- break;
- default:
- write_feature_vectors(fo, feature.mat, &pTag[0], featname.c_str());
- break;
- }
- fclose(fi);
- fclose(fo);
- return 1;
- }
- int Fe::FeatureMain(FeatKind fk, CFeature& adcData, int beginX, int endX, CFeature& feature, int outBeginX, int outEndX)
- {
- if(adcData.shiftN != feature.shiftN){
- FE_ERROR("FeatureMain: The shift sizes of adaData and feature are different.n");
- if(feature.shiftN>0) adcData.shiftN=feature.shiftN;
- assert(0);
- }
- if(adcData.sampleFreqN != feature.sampleFreqN){
- FE_ERROR("FeatureMain: The sampling rates of adaData and feature are different.n");
- if(feature.sampleFreqN>0) adcData.sampleFreqN=feature.sampleFreqN;
- }
- Init(fk, adcData);
- if(fk==FE_VUS || fk==FE_FORMANT || fk==FE_PITCH || fk==FE_VUS || FE_ENDPOINT){
- /* First reduce noise by Wiener filtering */
- enhance_basic(&adcData.vec[beginX],(endX-beginX),m_sampleRate,1);
- }
- int i;
- int frameN;
- int sampleN=(endX-beginX);
- vector<float> pitchA;
- switch(fk){
- case FE_PITCH:
- frameN = vus_basic(&adcData.vec[beginX], sampleN, GetFrameSize(), m_vusA);
- frameN = pitch_basic(&adcData.vec[beginX], sampleN, m_sampleRate, GetShiftSize(), m_vusA, pitchA);
- feature.frameN = frameN; feature.dimN = 1; feature.byteN = 4;
- feature.mat.Resize(frameN,1);
- if(outBeginX<0 || outEndX<0){
- outBeginX=0;
- outEndX=frameN;
- }
- for(i=0; i<frameN;i++) feature.mat[outBeginX+i][0] = pitchA[i];
- break;
- case FE_ENDPOINT:
- epd_basic(&adcData.vec[beginX], sampleN, m_sampleRate, feature.label);
- break;
- default:
- frameN = FeatureExtract(fk, adcData, beginX, endX, feature, outBeginX, outEndX);
- break;
- }
- return frameN;
- }
- int Fe::FeatureExtract(FeatKind fk, CFeature& adcData, int beginX, int endX, CFeature& feature, int outBeginX, int outEndX)
- {
- int n,k;
- vector<short> wave1d;
- FeMatrix<float> feature2d;
- short *sample = &adcData.vec[beginX];
- int sampleN = endX-beginX;
- int frameN = 0;
- int dimN = GetDim(fk);
- int frameSize = GetFrameSize();
-
- /* V/U/S classification works for utterance only */
- if(fk==FE_VUS){
- frameN = vus_basic(sample, sampleN, frameSize, m_vusA);
- if(outBeginX<0) outBeginX=0; if(outEndX<0) outEndX=frameN;
- feature.frameN = frameN; feature.dimN = dimN; feature.byteN = 4; feature.mat.Resize(outEndX,1);
- for(n=0; n<frameN && n+outBeginX<outEndX; n++) feature.mat[outBeginX+n][0] = m_vusA[n];
- return frameN;
- }
- /* formant tracking requires pitch information to remove non-voice parts */
- if(fk==FE_FORMANT){
- frameN = vus_basic(sample, sampleN, frameSize, m_vusA);
- int shiftSize = GetShiftSize();
- int n_pitch_frames = pitch_basic(sample, sampleN, m_sampleRate, shiftSize, m_vusA, m_pitchA);
- }
- vector<float> preprocessedA;
- preprocessedA.resize(sampleN);
-
- /* Preprocessing */
- if(fk==FE_ZCR || fk==FE_ENERGY || fk==FE_EPOCH || fk==FE_GLOFLOW || fk==FE_GLOPULSE || fk==FE_VUS){
- /* just convert to float */
- for(int i=0;i<sampleN;i++) preprocessedA[i] = (float)sample[i];
- } else {
- preprocessing(sample, sampleN, &preprocessedA[0]);
- }
-
- /* Feature extraction */
- if(fk==FE_LPCRES || fk==FE_EPOCH || fk==FE_GLOFLOW){
- /* result is a 1-dim short vector */
- frameN = compute_feature_1d(fk,&preprocessedA[0],sampleN,wave1d);
- }
- else{
- /* result is a 2-dim float matrix */
- frameN = compute_feature_2d(fk,&preprocessedA[0],sampleN,feature2d);
- }
- /* Reorder cepstrum coefficients to follow the convention [c1, c2, c3, ..., c12, c0] */
- FeatKind bk=GetBaseFeatKind(fk);
- if(bk==FE_LPCC || bk==FE_PLCC || bk==FE_MFCC || bk==FE_FTCC){
- for(n=0;n<frameN;n++){
- float atmp=feature2d[n][0];
- for(k=0;k<m_cepOrder;k++) feature2d[n][k]=feature2d[n][k+1];
- feature2d[n][m_cepOrder]=atmp;
- }
- }
-
- /* Compute delta coefficients */
- if(HasDeltaFeat(fk)){
- FeMatrix<float> tmp2d=feature2d;
- delta_compute(tmp2d, m_deltaSize, feature2d);
- }
-
- /* Copy the resulting features */
- if(outBeginX<0) outBeginX=0; if(outEndX<0 || outEndX>frameN) outEndX=frameN;
- if(fk==FE_LPCRES || fk==FE_EPOCH || fk==FE_GLOFLOW){
- assert(sampleN==frameN);
- feature.frameN = sampleN; feature.dimN = 1; feature.byteN = 2; feature.vec.resize(sampleN);
- for(n=0; n<sampleN; n++) feature.vec[n] = wave1d[n];
- }
- else{
- feature.frameN = frameN; feature.dimN = dimN; feature.byteN = 4; feature.mat.Resize(outEndX,dimN);
- for(n=0; n<frameN && n+outBeginX<outEndX; n++){
- for(k=0; k<dimN; k++) feature.mat[outBeginX+n][k] = feature2d[n][k];
- }
- }
-
- return frameN;
- }
- int Fe::compute_feature_1d(FeatKind fk, float *sample, int sampleN, vector<short>& featA)
- {
- int n;
- int shiftSize, frameSize;
- if(fk==FE_GLOFLOW){
- shiftSize = (int)(m_covShiftSizeMs*m_sampleRate/1000.0+0.5); if(shiftSize%2) shiftSize += 1;
- frameSize = (int)(m_covWinSizeMs*m_sampleRate/1000.0+0.5); if(frameSize%2) frameSize += 1;
- if(frameSize < 2*m_lpcOrder) frameSize = 2*m_lpcOrder;
- }
- else{
- shiftSize = GetShiftSize();
- frameSize = GetFrameSize();
- }
-
- int frameN = (int)((float)(sampleN-(frameSize-shiftSize))/shiftSize);
- int dimN = 1;
- vector<float> frameA(frameSize);
- vector<float> acf(m_lpcOrder+1);
- vector<float> kcf(m_lpcOrder+1);
- featA.resize(sampleN);
- if(fk==FE_EPOCH) return calc_epoch(sample, sampleN, featA, NULL);
- vector<float> residual_data(frameSize);
- FeMatrix<float> cov(m_lpcOrder+1, m_lpcOrder+1);
- int remainN;
- for (n=0; ; n++){
- int i;
- int begX=n*shiftSize;
- if(!CheckWinMessage()) break;
- ShowProgress((int)((n*100)/frameN));
- remainN=my_min(sampleN-begX,frameSize);
- if(remainN<=0) break;
- for(i=0;i<remainN;i++) frameA[i]=sample[begX+i];
- for(i=remainN;i<frameSize;i++) frameA[i]=0;
- m_window.Windowing(&frameA[0], remainN, WIN_HAMMING);
- switch(fk){
- case FE_LPCRES:
- {
- int k;
- float G;
- if(remainN == frameSize)
- _lpc_basic(&frameA[0], frameSize, &acf[0], m_lpcOrder, &G);
- _lpc_error_basic(&frameA[0], remainN, &acf[0], m_lpcOrder, &residual_data[0]);
- for(k=0; k<shiftSize && begX+k<sampleN;k++) featA[begX+k] = (short)(residual_data[k]);
- }
- break;
- case FE_GLOFLOW:
- {
- float G;
- if(remainN == frameSize)
- lpc_cov(&frameA[0], frameSize, cov, &acf[0], m_lpcOrder, &G);
- lpc_cov_error(&frameA[0], remainN, &acf[0], m_lpcOrder, &residual_data[0]);
- // differentiated glottal flow
- Integrate(&residual_data[0], remainN, &featA[begX]);
- // glottal flow
- //Integrate(&((*featA)[i]), remainN, featA+i);
- }
- break;
- default:
- assert(0);
- return 0;
- break;
- }
- }
- return sampleN;
- }
- int Fe::compute_feature_2d(FeatKind fk, float *sample, int sampleN, FeMatrix<float>& featA)
- {
- int n;
- int shiftSize = GetShiftSize();
- int frameSize = GetFrameSize();
- int frameN = (int)((float)(sampleN-(frameSize-shiftSize))/shiftSize);
- int dimN = GetDim(fk);
- int fft_size; for (fft_size=1; fft_size<frameSize; fft_size*=2) ;
- vector<float> frameA(frameSize);
- vector<float> acf(m_lpcOrder+1);
- vector<float> kcf(m_lpcOrder+1);
- featA.Resize(frameN,dimN);
- FeMatrix<float> featTmpA;
- if(fk==FE_FORMANT) featTmpA.Resize(frameN, m_lpcOrder/2+1);
-
- fk=GetBaseFeatKind(fk);
- int dc_bias=0, level=0;
- float mean=0;
- if(fk==FE_ENERGY || fk==FE_ZCR){
- int i;
- for(i=0;i<sampleN;i++) mean += sample[i]; mean = mean/sampleN;
- dc_bias = (int)((mean >= 0) ? mean+0.5 : mean-0.5);
- if(frameN>10){
- /* Assume that there are at least 3 frames of silence at the beginning */
- float v=0; int m=3*shiftSize;
- for (i=0; i<m;i++) v+=(sample[i]-dc_bias)*(sample[i]-dc_bias);
- v=(float)sqrt(v/m);
- level=(int)(2*v); /* Set ZCR threshold to 2*noiseLevel */
- }
- }
- for (n=0; n<frameN; n++){
- float G=0;
- int begX=n*shiftSize;
- int i, k;
- float energy;
- if(!CheckWinMessage()) break;
- ShowProgress((int)((n*100)/frameN));
-
- if(!(fk==FE_ENERGY || fk==FE_ZCR)){
- for(i=0;i<frameSize;i++) frameA[i]=sample[begX+i];
- m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
- }
- switch(fk){
- case FE_ENERGY:
- energy=compute_energy(sample+begX, frameSize, mean);
- featA[n][0] = 10*LOG10((energy>FE_MIN_ENERGY ? energy : FE_MIN_ENERGY));
- break;
- case FE_ZCR:
- featA[n][0] = (float)compute_zero_cross_rate(sample+begX, frameSize, level, dc_bias);
- break;
- case FE_LAR:
- _lpc_parcor_basic(&frameA[0], frameSize, &acf[0], &kcf[0], m_lpcOrder, &G);
- featA[n][0] = 0;
- for(k=1; k<=m_lpcOrder; k++) featA[n][k] = (float)log((1-kcf[k])/(1+kcf[k]));
- break;
- case FE_LSF:
- {
- vector<CComplex> oldRootsP;
- vector<CComplex> oldRootsQ;
- _lpc_basic(&frameA[0], frameSize, &acf[0], m_lpcOrder, &G);
- lpc_to_lsf(&acf[0],m_lpcOrder,&featA[n][0], oldRootsP, oldRootsQ);
- }
- break;
- case FE_PARCOR:
- _lpc_parcor_basic(&frameA[0], frameSize, &acf[0], &featA[n][0], m_lpcOrder, &G);
- featA[n][0] = 0;
- break;
- case FE_FORMANT:
- {
- vector<CComplex> rootsA(m_lpcOrder+1);
- for(i=0;i<=m_lpcOrder;i++) rootsA[i] = 0;
- _lpc_basic(&frameA[0], frameSize, &acf[0], m_lpcOrder, &G);
- /* Note that we compute all formant frequencies for post-processing */
- int ntmp=lpc_to_formant(&acf[0],m_lpcOrder,&featTmpA[n][0],m_lpcOrder/2,rootsA);
- for(k=0;k<=m_lpcOrder/2;k++) featTmpA[n][k] *= (m_sampleRate/(float)(2*M_PI));
- }
- break;
- case FE_LPC:
- _lpc_basic(&frameA[0], frameSize, &featA[n][0], m_lpcOrder, &G);
- break;
- case FE_FBANK:
- _filterbank_basic(&frameA[0], frameSize, &featA[n][0], m_fbOrder, fft_size, m_cepSmooth, (int)(m_sampleRate/MAX_PITCH_FREQ));
- break;
- case FE_MFCC:
- _mel_cepstrum_basic(&frameA[0], frameSize, &featA[n][0], m_fbOrder, m_cepOrder, m_fftSize);
- cepstral_window(&featA[n][0],m_cepOrder,m_lifter);
- break;
- case FE_PLCC:
- _plp_basic(&frameA[0], frameSize, &featA[n][0], m_plccOrder, m_plpOrder);
- cepstral_window(&featA[n][0],m_plccOrder,m_lifter);
- break;
- case FE_LPCC:
- _lpc_basic(&frameA[0], frameSize, &acf[0], m_lpcOrder, &G);
- lpc_to_cepstrum(&acf[0], m_lpcOrder, &featA[n][0], m_cepOrder, G);
- cepstral_window(&featA[n][0],m_cepOrder,m_lifter);
- break;
- case FE_FTCC:
- _fft_cepstrum_basic(&frameA[0], frameSize, &featA[n][0], m_cepOrder, fft_size);
- cepstral_window(&featA[n][0],m_cepOrder,m_lifter);
- break;
- default:
- assert(0);
- return 0;
- break;
- }
- }
- if(fk==FE_FORMANT){
- /* check formant range, noting that F0 is always zero */
- formant_check_range(featTmpA, m_lpcOrder/2, frameN);
- /* smooth formant trajectory */
- formant_median_filter(featTmpA, m_lpcOrder/2, frameN);
- formant_linear_filter(featTmpA, m_lpcOrder/2, frameN);
- /* Make formant consistent with pitch information */
- assert(m_pitchA.size()>0);
- frameN = formant_remove_nonvoice(featTmpA, m_lpcOrder/2, frameN, m_pitchA);
- /* Copy to the result variable, skipping F0 */
- for(n=0;n<frameN;n++){
- for(int k=0;k<dimN && k<m_lpcOrder/2+1;k++){
- featA[n][k]=featTmpA[n][k+1];
- }
- }
- }
- return frameN;
- }
- int Fe::ReadParaFile(const char *parafile)
- {
- FILE *fi = fopen(parafile,"r");
- if(!fi) return 0;
- char line[1024], arg1[256], arg2[256];
- string name;
- while(fgets(line,sizeof(line)-1,fi)){
- if(line[0]==0) break; // end of file
- if(line[0]=='#') continue; // skip comment line
- sscanf(line,"%s%s", arg1, arg2);
- name=arg1;
- if(name=="SAMPLING_RATE"){ m_sampleRate = atoi(arg2); }
- else if(name=="WINDOW_SIZE"){ m_winSizeMs = atoi(arg2); }
- else if(name=="SHIFT_SIZE"){ m_shiftSizeMs = atoi(arg2); }
- else if(name=="PREEMPHASIS_FACTOR"){ m_emphFac = (float)atof(arg2); }
- else if(name=="FFT_SIZE"){ m_fftSize = atoi(arg2); }
- else if(name=="LPC_ORDER"){ m_lpcOrder = atoi(arg2); }
- else if(name=="CEPSTRUM_ORDER"){ m_cepOrder = atoi(arg2); }
- else if(name=="PLP_ORDER"){ m_plpOrder = atoi(arg2); }
- else if(name=="PLP_CEPSTRUM_ORDER"){ m_plccOrder = atoi(arg2); }
- else if(name=="FILTER_BANK_ORDER"){ m_fbOrder = atoi(arg2); }
- else if(name=="CEPSTRAL_SMOOTHING"){ m_cepSmooth = (strcmp(arg2,"ON")==0); }
- else if(name=="DITHERING"){ m_dither = (strcmp(arg2,"ON")==0); }
- else if(name=="TEMPORAL_FILTER_SIZE"){ m_deltaSize = atoi(arg2); }
- }
- fclose(fi);
- return 1;
- }
- int Fe::ReadTag(const char *tag, int* pTag, int ndim)
- {
- int i;
- for(i=0;i<ndim;i++) pTag[i] = 0;
- if(!tag){
- for(i=0;i<ndim;i++) pTag[i] = 1;
- return 1;
- }
-
- vector<char> tmp(strlen(tag)+1);
- strcpy(&tmp[0],tag);
- char* tmp_save = NULL;
- char* p = strtok_r(&tmp[0], " ,", &tmp_save);
- if(!p){
- for(i=0;i<ndim;i++) pTag[i] = 1;
- }
- while(p){
- int begin = 0, end = 0;
- int len = strlen(p);
- char* p_save = NULL;
- if(*p == '-'){
- begin = 0;
- if(*(p+1) != ' ')
- end = atoi(p+1);
- else
- end = -1;
- }
- else if(*(p+len-1) == '-'){
- end = ndim-1;
- *(p+len-1) = ' ';
- begin = atoi(p);
- }
- else{
- char* q = strtok_r(p, "-", &p_save);
- if(q) begin = end = atoi(q);
- q = strtok_r(NULL, "-", &p_save);
- if(q) end = atoi(q);
- }
- for(i=begin; i<=end; i++) pTag[i] = 1;
- p = strtok_r(NULL, " ,", &tmp_save);
- }
- return 1;
- }
- int Fe::GetShiftSize()
- {
- int nshift = (int)((m_shiftSizeMs*m_sampleRate)/1000.0+0.5);
- if(nshift%2) nshift += 1;
- return nshift;
- }
- int Fe::GetFrameSize()
- {
- int frameSize = (int)((m_winSizeMs*m_sampleRate)/1000.0+0.5);
- if(frameSize%2) frameSize += 1;
- return frameSize;
- }
- const char *GetFeatName(FeatKind fk)
- {
- assert((int)fk>=0 && (int)fk<(int)FE_NUM_FEAT);
- return FE_featNameA[(int)fk];
- }
- string GetFeatExtension(FeatKind fk)
- {
- FeatKind bk=GetBaseFeatKind(fk);
- string name=GetFeatName(bk);
- for(int i=0;i<name.size();i++) name[i]=tolower(name[i]);
- if(HasDeltaFeat(fk)) name=name+"_d";
- if(HasStftFeat(fk)) {
- int k=name.find("_stft");
- name=name.substr(0,k);
- name=name+"_s";
- }
- return name;
- }
- FeatKind GetBaseFeatKind(FeatKind fk)
- {
- string name=GetFeatName(fk);
- int k=name.find("_D");
- if(k==string::npos) return fk;
- if(name[k+2]==0 || name[k+2]=='_'){
- name=name.substr(0,k);
- for(int i=0;i<FE_NUM_FEAT-1;i++){
- if(strcmp(FE_featNameA[i],name.c_str())==0) return (FeatKind)i;
- }
- }
- return fk;
- }
- FeatKind FeatName2Kind(const char* name)
- {
- int i;
- for(i=0;i<FE_NUM_FEAT-1;i++){
- if(strcmp(FE_featNameA[i],name)==0) return (FeatKind)i;
- }
- return (FeatKind)i;
- }
- int HasDeltaFeat(FeatKind fk)
- {
- const char *name=GetFeatName(fk);
- char *i=strstr(name,"_D");
- if(i) return 1;
- else return 0;
- }
- int HasStftFeat(FeatKind fk)
- {
- const char *name=GetFeatName(fk);
- char *i=strstr(name,"_SPEC");
- if(i) return 1;
- else return 0;
- }
- int Fe::GetDim(FeatKind fk)
- {
- int ndim = 0;
- fk=GetBaseFeatKind(fk);
- switch(fk){
- case FE_LPC: case FE_LPCCOV:
- ndim = m_lpcOrder + 1; break;
- case FE_LPCC: case FE_MFCC: case FE_FTCC:
- ndim = m_cepOrder + 1; break;
- case FE_PLCC:
- ndim = m_plccOrder + 1; break;
- case FE_FBANK:
- ndim = m_fbOrder; break;
- case FE_LAR: case FE_LSF: case FE_PARCOR:
- ndim = m_lpcOrder + 1; break;
- case FE_FORMANT:
- /* F1, F2, F3, F4 */
- ndim = 4; break;
- case FE_FFT_SPEC: case FE_LPC_SPEC: case FE_LPCC_SPEC:
- case FE_MFCC_SPEC: case FE_FTCC_SPEC:
- ndim = m_fftSize; break;
- case FE_FFTCEP:
- ndim = m_fftSize; break;
- case FE_ZCR: case FE_ENERGY: case FE_PITCH: case FE_VUS: case FE_ENDPOINT:
- case FE_EPOCH: case FE_GLOFLOW: case FE_GLOPULSE: case FE_LPCRES:
- ndim = 1; break;
- default:
- ndim = 1; break;
- }
- return ndim;
- }
- int GetDefaultDim(enum FeatKind fk)
- {
- int dim=0;
- fk=GetBaseFeatKind(fk);
- switch(fk){
- case FE_FFT_SPEC: case FE_LPC_SPEC: case FE_LPCC_SPEC: case FE_MFCC_SPEC: case FE_FTCC_SPEC:
- dim = DEFAULT_FFT_SIZE/2+1; break;
- case FE_FFTCEP:
- dim = DEFAULT_FFT_SIZE/2+1; break;
- case FE_LPC: case FE_LPCCOV: case FE_LAR: case FE_LSF: case FE_PARCOR:
- dim = FE_LPC_ORDER+1; break;
- case FE_FBANK:
- dim = FE_NUM_CHANNELS+1; break;
- case FE_LPCC: case FE_FTCC: case FE_MFCC:
- dim = FE_CEP_ORDER+1; break;
- case FE_PLCC:
- dim = PLP_CEP_ORDER+1; break;
- case FE_FORMANT:
- dim = 4; break;
- default:
- dim = 1; break;
- }
- return dim;
- }
- int GetDefaultOrder(enum FeatKind fk)
- {
- int order=1;
- fk=GetBaseFeatKind(fk);
- switch(fk){
- case FE_FFT_SPEC:
- order = DEFAULT_FFT_SIZE/2+1; break;
- case FE_FFTCEP:
- order = DEFAULT_FFT_SIZE/2+1; break;
- case FE_LPC_SPEC:
- order = FE_LPC_ORDER; break;
- case FE_LPCC_SPEC: case FE_MFCC_SPEC: case FE_FTCC_SPEC:
- order = FE_CEP_ORDER; break;
- case FE_LPC: case FE_LPCCOV: case FE_LAR: case FE_LSF: case FE_PARCOR:
- order = FE_LPC_ORDER; break;
- case FE_FBANK:
- order = FE_NUM_CHANNELS; break;
- case FE_LPCC: case FE_FTCC: case FE_MFCC: case FE_PLCC:
- order = PLP_CEP_ORDER; break;
- case FE_FORMANT:
- order = 4; break;
- default:
- order = 1; break;
- }
- return order;
- }
- float Fe::LogE(float x)
- {
- if(x>m_energyFloor) return log(x);
- else return m_logEnergyFloor;
- }
- int Fe::Integrate(float *a, int n, short *b)
- {
- float alpha = (float)0.98;
- static float prev = 0;
- for(int i=0;i<n;i++){
- prev = a[i] + alpha*prev;
- b[i] = (short)(prev);
- }
- return 1;
- }
- int Fe::Integrate(short *a, int n, short *b)
- {
- float alpha = (float)0.98;
- static float prev = 0;
- for(int i=0;i<n;i++){
- prev = a[i] + alpha*prev;
- b[i] = (short)(prev);
- }
- return 1;
- }
- float Fe::GetMedian(float* a, int n)
- {
- int i;
- float median = 0;
- vector<float> tmp(n);;
- for(i=0;i<n;i++)
- tmp[i] = a[i];
- qsort(&tmp[0],n,sizeof(float),FE_CompareFloat);
- median = tmp[(n-1)/2];
- return median;
- }
- int Fe::InitProgress(int* pProgress, int* pCancel)
- {
- m_pProgress = pProgress;
- m_pCancel = pCancel;
- return 1;
- }
- int Fe::CheckWinMessage()
- {
- #if defined(_WIN32) && defined(ANALYSIS_LIB)
- MSG message;
- if(PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {
- TranslateMessage(&message);
- DispatchMessage(&message);
- }
- #endif
- if(m_pCancel && (*m_pCancel)) return 0;
- else return 1;
- }
- int Fe::ShowProgress(int progress)
- {
- #if defined(_WIN32) && defined(ANALYSIS_LIB)
- if(m_pProgress) *m_pProgress = progress;
- #endif
- return 1;
- }
- int FE_CompareFloat(const void *a, const void *b)
- {
- float *aa = (float*)a;
- float *bb = (float*)b;
- if(*aa > *bb) return 1;
- else if(*aa < *bb) return -1;
- else return 0;
- }
- #ifdef WIN32
- char* strtok_r(char *s1, const char *s2, char **savept)
- {
- char *p = NULL;
- char *z = NULL;
-
- if(s1) *savept = s1;
- if((*savept) == NULL) return NULL;
- z = *savept + strlen(*savept);
- p = strtok(*savept,s2);
- if(p != NULL && (p + strlen(p) + 1) < z)
- *savept = p + strlen(p) + 1;
- else
- *savept = NULL;
- return p;
- }
- #endif