Monday, January 6, 2020

fft - Normalizing the magnitude of Goertzel Filter c#


I'm trying to detect some frequencies of 18Khz with sample rate of 44100 [samples/sec].


When I pass a buffer(~4500 samples) to the algorithm it returns a magnitude in a very strange range. Sometimes i get 0.1, or 7 or 250(!) or 154 or 25000 - very strange. I can't decide on a threshold boundary for the filter. Is there any way noramlizing that result? (My result is the magnitude of the complex calculation of real and image)


This is my Goertzel code:


public float goertzel_mag(float[] data,int numSamples, int TARGET_FREQUENCY, int SAMPLING_RATE,int start,int end)
{
int k, i;

float floatnumSamples;
float omega, sine, cosine, coeff, q0, q1, q2, magnitude, real, imag;

float scalingFactor = (float)(numSamples / 2.0);

floatnumSamples = (float)numSamples;
k = (int)(0.5 + ((floatnumSamples * TARGET_FREQUENCY) / SAMPLING_RATE));
omega = (float)(2.0 * Math.PI * k) / floatnumSamples;
sine = (float)Math.Sin(omega);
cosine = (float)Math.Cos(omega);

coeff = (float)2.0 * cosine;
q0 = 0;
q1 = 0;
q2 = 0;

for (i = start; i < end; i++)
{
q0 = coeff * q1 - q2 + data[i];
q2 = q1;
q1 = q0;

}

// calculate the real and imaginary results
// scaling appropriately
real = (q1 - q2 * cosine) / scalingFactor;
imag = (q2 * sine) / scalingFactor;

magnitude = (float)Math.Sqrt(real * real + imag * imag);
return magnitude;
}


Answer



Your Goertzel code looks okay, the standard fare.


Regarding normalization and thresholds, if you're detecting 18kHz, you should calibrate your signal at different levels and establish a threshold from that data



  • Start with full-scale (1.0, 0dBFS) 18kHz tones, as those should give you the highest magnitude over the course of your buffer (4500 samples) and then

  • Repeat the Goertzel filter mag measurements on tones all the way down in level, as much as you care but I would measure at least 6dB.

  • Finally, run your Goertzel filter over non-tonal material, or buffers of audio that don't contain what you're looking for. This will give you an idea of what the filter will output in the non-tone case. In my application, environmental audio/speech can have incidental tones in the range I'm looking for (400-600Hz) and I want to make sure to understand what Goertzel magnitudes I would get versus Goertzel magnitudes in the presence of a real tone.


No comments:

Post a Comment

digital communications - Understanding the Matched Filter

I have a question about matched filtering. Does the matched filter maximise the SNR at the moment of decision only? As far as I understand, ...