FE_lsf.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
- ///////////////////////////////////////////////////////////////////////////////
- #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;
- }