I'm trying to get an LPC magnitude spectrum to match to an FFT magnitude spectrum. Basically I want the peak height in the LPC Spectrum to match the peak height in the FFT Spectrum.
Thanks to numerical recipes I have some code that produces me an LPC spectrum with what looks like the correct shape.
bool CLPC::BuildMagitudeSpectrumFromLPC( float* pOutSpec, unsigned int outSpecSize )
{
int spec = 0;
while( spec < outSpecSize )
{
const float theta = (M_PI * 2.0f) * ((1.0f / (outSpecSize * 2)) * spec);
const float wpr = cosf( theta );
const float wpi = sinf( theta );
float sumR = 1.0f;
float sumI = 0.0f;
float wR = 1.0f;
float wI = 0.0f;
int i = 0;
while( i < mNumLPC )
{
const float wTemp = wR;
wR = wR * wpr - wI * wpi;
wI = wI * wpr + wTemp * wpi;
sumR -= mLPCs[i] * wR;
sumI -= mLPCs[i] * wI;
i++;
}
pOutSpec[spec] = mMeanSquareError / (sumR * sumR + sumI * sumI);
spec++;
}
}
Its worth noting that I manually re-scale it to a dB scale elsewhere.
My problem appears to be that I can't figure out the scaling on this spectrum. The above code returns values of greater than 1 (at seemingly the correct peak locations) for values that are not greater than 0dBFS on the FFT magnitude spectrum. When I overlay the 2 the toughs also appear to be too high as well.
Has anyone any idea how to get the peak heights and troughs to correspond between the 2?
I'm NOT windowing before passing to the LPC. Should I be?
Aso, Am I right in thinking that this line is a bit odd:
pOutSpec[spec] = mMeanSquareError / (sumR * sumR + sumI * sumI);
I would have thought I'm taking the absoloute of the complex number represented by sumR and sumI. Wouldn't this mean calling sqrt on it? ie.
pOutSpec[spec] = mMeanSquareError / std::sqrt( sumR * sumR + sumI * sumI );
Doing the above doesn't help my problem all it does is squash up the LPC spectrum somewhat ...
No comments:
Post a Comment