⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fe_formant.cpp

📁 这是一个语音特征提取的程序源码
💻 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 + -