FE_formant.cpp
上传用户:italyroyal
上传日期:2013-05-06
资源大小:473k
文件大小:4k
- ///////////////////////////////////////////////////////////////////////////////
- // 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"
- /* Note that lpc_to_formant() returns formantN frequencies */
- int Fe::lpc_to_formant(float* acf, int norder, float* formant, int formantN, vector<CComplex>& rootsA)
- {
- int i;
- float ztmp[]={0,1};
Polynomial z(1,ztmp);
Polynomial A = 1;
- for(i=1;i<=norder;i++)
- A = A*z - acf[i];
- if(rootsA.size() != norder+1) rootsA.resize(norder+1);
- vector<float> allFormantA(norder+1);
-
- A.Roots(&rootsA[0]);
- for(i=0;i<=norder;i++)
- allFormantA[i] = (float)0;
- int n=0;
- allFormantA[n++]=0;
- for(i=1; i<=norder;i++){
- if(imag(rootsA[i]) > 0){
- allFormantA[n++] = arg(rootsA[i]);
- }
- }
- qsort(&allFormantA[0], n, sizeof(float), FE_CompareFloat);
- for(i=0;i<=formantN && i<n;i++) formant[i]=allFormantA[i];
- return formantN;
- }
- int Fe::formant_check_range(FeMatrix<float>& formant, int formantN, int frameN)
- {
- /* F0: 80 - 500 Hz, F1: 200 - 1200 Hz, F2: 400 - 3500Hz, F3: 1000 - 5000 Hz, F4: 2000 - 6000 Hz */
- int i,k;
- float fmin, fmax;
- for(k=1;k<formantN;k++) {
- if(k==0) { fmin=80, fmax=500; }
- else if(k==1) { fmin=200, fmax=1200; }
- else if(k==2) { fmin=400, fmax=3500; }
- else if(k==3) { fmin=1000, fmax=5000; }
- else if(k==4) { fmin=1500, fmax=6000; }
- else { fmin=2500, fmax=8000; }
- for(i=2;i<frameN-2;i++){
- formant[i][k]=my_max(fmin, my_min(fmax, formant[i][k]));
- }
- }
- return frameN;
- }
- int Fe::formant_median_filter(FeMatrix<float>& formant, int formantN, int frameN)
- {
- int i;
- float smoothFormant[32];
- int margin=7;
- float ftmp[7];
- for(i=3;i<frameN-3;i++){
- int j;
- for(j=0;j<=formantN;j++){
- for(int n=0;n<7;n++){
- ftmp[n]=formant[i+n-3][j];
- }
- smoothFormant[j]=GetMedian(ftmp,7);
- }
- float a0,a1,a2;
- for(j=0;j<formantN;j++){
- a0=fabs(formant[i][j]-smoothFormant[j]);
- if(j>0) a1=fabs(formant[i][j]-smoothFormant[j-1]);
- else a1=FLT_MAX;
- a2=fabs(formant[i][j]-smoothFormant[j+1]);
- if(a1<a0 && a1<a2){
- formant[i][j-1]=formant[i][j];
- formant[i][j]=smoothFormant[j];
- }
- else if(a2<a0 && a2<a1){
- formant[i][j+1]=formant[i][j];
- formant[i][j]=smoothFormant[j];
- }
- }
- }
- return(frameN);
- }
- int Fe::formant_linear_filter(FeMatrix<float>& formant, int formantN, int frameN)
- {
- int i,k;
- /* low-pass filter, x=filter([1 2 1]/4, [1], x); */
- vector<float> x;
- for(k=0;k<formantN;k++) {
- x.resize(frameN);
- for(i=0;i<frameN;i++) x[i]=formant[i][k];
-
- formant[0][k]=(x[0]+2*x[0]+x[1])/4;
- for(i=1;i<frameN-1;i++){
- formant[i][k]=(x[i-1]+2*x[i]+x[i+1])/4;
- }
- formant[frameN-1][k]=(x[frameN-2]+2*x[frameN-1]+x[frameN-1])/4;
- }
- return(frameN);
- }
- int Fe::formant_remove_nonvoice(FeMatrix<float>& formant, int formantN, int frameN, vector<float>& pitchA)
- {
- assert(pitchA.size()>0);
- int n;
- for(n=0; n<pitchA.size() && n<frameN; n++){
- if(pitchA[n] == 0){
- for(int k=0;k<formantN;k++) formant[n][k] = 0;
- }
- }
- for( ; n < frameN; n++){
- for(int k=0;k<formantN;k++) formant[n][k] = 0;
- }
- return(frameN);
- }