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

📄 fe_lsf.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
///////////////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "FE_feature.h"


//#define _TEST_LPC_TO_LSF_
#ifdef _TEST_LPC_TO_LSF_
main()
{
	int i;
	int p=10;
	int N = p/2;

	float a[5] = {(float)0.9, (float)0.8, (float)0.7, (float)0.6, (float)0.5};
	float w[5] = {(float)0.2, (float)0.4, (float)0.6, (float)0.8, (float)1.0};
	Polynomial A = 1.0;
	for(i=0; i < N; i++){
		A *= Polynomial(2,(float)1.0,(float)(-2.0*a[i]*cos(w[i])),(float)(a[i]*a[i]));
	}
	//printf("A=");
	//A.Print();

	vector<float> acf(p+1);
	vector<float> lsf(p+1);
	acf[0] = 1;
	for(i=1; i <= p; i++){
		acf[i] = -A.v[i];
	}
	
	int nf;
	Fe feat;
	vector<CComplex> oldRootsP;
	vector<CComplex> oldRootsQ;
	nf = feat.lpc_to_lsf(&acf[0], p, &lsf[0], oldRootsP, oldRootsQ);

	printf("lsf=");
	for(i=0;i<nf;i++){
		printf("%f ",lsf[i]);
	}
	printf("\n");

	vector<float> formant(p+1);
	vector<CComplex> rootsA;
	nf = feat.lpc_to_formant(&acf[0], p, &formant[0], rootsA);

	printf("formant=");
	for(i=0;i<nf;i++){
		printf("%f ",formant[i]);
	}
	printf("\n");

	return 1;
}
#endif


int Fe::lsf_basic(short *sample, int frameSize, float *lsf, int norder)
{
	float G;
	vector<float> acf(norder+1);
	vector<CComplex> oldRootsP;
	vector<CComplex> oldRootsQ;
	/* A(z) = 1 - sum_{i=1}^p acf_i z^{-i} */
	lpc_basic(sample, frameSize, &acf[0], norder, &G);
	lpc_to_lsf(&acf[0], norder, lsf, oldRootsP, oldRootsQ);
	return 1;
}


/* lpc_to_lsp							*/
/* Converts LPC coefficients to line spectrum pairs */
/* acf[]: LPC coefficients				*/
/*	A(z) = 1 - sum_{i=1}^p acf_i z^{-i} */
/* norder: LPC order					*/
/* lsf[]: LSF values					*/
/* Example:
When norder is 10 and 
	acf[11] = {1.000000, 5.769638, -15.389400, 25.054144, -27.662497, 21.731449,
		-12.362663, 5.059858, -1.437461, 0.258843, -0.022861};
	which means 10 poles at a[i]*e(j*w[i]) and a[i]*e(-j*w[i]), i=1,...,10, 
	a[5] = {0.9, 0.8, 0.7, 0.6, 0.5};
	w[5] = {0.2, 0.4, 0.6, 0.8, 1.0};

	lpc_to_lsp() yields the following output:
	lsp[10] = {0.020972, 0.035827, 0.051702, 0.070526, 0.091851,
		0.117022, 0.147932, 0.188925, 0.250307, 0.352016};
*/

int Fe::lpc_to_lsf(float* acf, int norder, float* lsf, vector<CComplex>& oldRootsP, vector<CComplex>& oldRootsQ)
{
	int i;
	int N=norder/2;
	if(norder%2) norder -= 1;
	vector<float> a(norder+1);
	/* a[i] = -acf[i], i=1,...,norder */
	a[0] = 1;
	for(i=1;i<=norder;i++)
		a[i] = -acf[i];

	vector<float> A(N+1);
	vector<float> B(N+1);
	A[0] = B[0] = 1;
	for(i=1;i<=N;i++){
		A[i] = (a[i]-a[norder+1-i])+A[i-1];
		B[i] = (a[i]+a[norder+1-i])-B[i-1];
	}

	vector<Polynomial> sinn(N+1);
	vector<Polynomial> cosn(N+1);
	Polynomial x = Polynomial((float)1);
	Polynomial cos1 = x;
	Polynomial sin2 = 1 - x*x;
	
	sinn[0] = 0;
	cosn[0] = 1;

	for(i=1; i<=N;i++){
		sinn[i] = sinn[i-1]*cos1 + cosn[i-1];
		//printf("sinn[%d]=",i); sinn[i].Print();
		cosn[i] = cosn[i-1]*cos1 - sinn[i-1]*sin2;
		//printf("cosn[%d]=",i); cosn[i].Print();
	}

	/* P = sum_{i=0}^N  A[i]*cosn[N-i] */
	/* where cosn[i] = (z^i+z^(-i))/2 */
	/* and cosn[0] = 0.5 */
	Polynomial P = Polynomial((float)0);
	Polynomial Q = Polynomial((float)0);
	cosn[0] = Polynomial((float)0.5);
	for(i=0;i<=N;i++){
		P += A[i]*cosn[N-i];
		Q += B[i]*cosn[N-i];
	}
	
	if(oldRootsP.size() != N+1) oldRootsP.resize(N+1);
	if(oldRootsQ.size() != N+1) oldRootsQ.resize(N+1);

	P.Roots(&oldRootsP[0]);
	Q.Roots(&oldRootsQ[0]);

	int n = 0;
	lsf[n++] = (float)0;
	for(i=1;i<=N;i++){
		lsf[n++] = (float)(acos(real(oldRootsQ[N-i+1]))/(2*M_PI));
		lsf[n++] = (float)(acos(real(oldRootsP[N-i+1]))/(2*M_PI));
	}
	
	qsort(lsf, n, sizeof(float), FE_CompareFloat);

	return n;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -