📄 fe_formant.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
// 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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -