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