# Matching an LPC Magnitude Spectrum to FFT Magnitude Spectrum

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 ...

I have a similar function to compute the Spectrum from the predicator coefficients, but instead of your code that I do not understand, I have the following :

pOutSpec[spec] = mMeanSquareError / (sumR * sumR + sumI * sumI);


I have something that computes the real and imaginary parts into my buffer :

data[2 * spec] = sumR / (sumR * sumR + sumI * sumI);
data[(2 * spec) + 1] = -sumI / (sumR * sumR + sumI * sumI);


Then I use different functions to display the spectrum according to the chosen format (Real, Magnitude, Square Magnitude or Log).

I also have some problems with scaling, both for the FFT Spectrum and the LPC Spectrum. I have chosen to scale them based on my display area, but as a result, their scale is not exactly the same on the display.

I found this at http://web.science.mq.edu.au/~cassidy/comp449/html/comp449.html 6.3. Decibels

We commonly transform a spectrum as calculated by the fft into a decibel spectrum to better reflect the response of the human ear. The units of amplitude in the raw spectrum shown above are the same as those of the sampled acoustic signal. The decibel scale is a logarithmic scale of relative amplitude where we first devide by a reference amplitude (which corresponds to 0dB) and then take the naturnal logarithm. Finaly we multiply by 20: