I am implementing a BFSK algorithm with frequency hopping on an embedded system and I am using the Goertezel algorithm in my demodulation approach. Basically, I use the goertzel alorithm to determine the powers of the signal at the next expected frequencies for both both bits 0 and 1 and whichever gives a higher power (generally in order of 10000) is the bit received. My implementation of the algorithm in C is as follows :
float goertzel(int numSamples,int TARGET_FREQUENCY,int SAMPLING_RATE, int* modData)
{
int k,i;
float floatnumSamples;
float omega,sine,cosine,coeff,q0,q1,q2,result;
floatnumSamples = (float) numSamples;
k = (int) (0.5 + ((floatnumSamples * TARGET_FREQUENCY) / SAMPLING_RATE));
omega = (2.0 * 3.1416 * k) / floatnumSamples;
sine = sin(omega);
cosine = cos(omega);
coeff = 2.0 * cosine;
q0=0;
q1=0;
q2=0;
result=0;
for(i=0; i<numSamples; i++)
{
q0 = coeff * q1 - q2 + modData[i];
q2 = q1;
q1 = q0;
}
result = sqrtf(q1 * q1 + q2 * q2 - q1 * q2 * coeff);
return result;
}
The data at the receiver end is always in the form of a 32-bit integer.
The problem is that my received signal is a baseband signal and the band width is spread from -2KHz to 2KHz. Hence half of the hopping frequencies are in the negative side of the spectrum and goertzel algorithm is not working correctly for the negative frequencies. So I tried to use the frequency bins in the next set i.e. at (sampling frequency + hopping frequency), just as in fft. However, my algorithm gives the same output power for both the frequencies, current hopping frequency and (sampling frequency + hopping frequency). for example, my sampling frequency is 18000 and the current hopping is -2000. So the power should be higher at -2000Hz and 16000Hz than at 2000Hz, but in my case the power is the same at 2000 and 16000Hz, which defeats the demodulation purpose. This is not the case when I use the goertzel algorithm defined in Matlab. The Matlab function gives the powers distinctly for both current hopping frequency and (sampling frequency + hopping frequency).
Is there something that I am missing from my C implementation which can solve this issue? Is there any other method (other than using DFT, I have already tried it) that I can use for the demodulation procedure.
--Anshu