Forums

Goertzel algorithm

Started by elwiz October 25, 2005
Hello.

I'm new to DSP programming and I need your help. I'm implementing the
Goertzel algorithm for detection of DTMF codes and I'm having trouble with
interpreting the results.
I created a sample signal and tested the whole frequency range for a peek.
A peek was found at the desired frequency but the value of the result is
very strange. It doesn't resemble in any way the original amplitude of the
sample signal. I was curious and tested the result for different input
frequencies. Different frequencies resulted in different magnitudes. Also
a change of the sample block size results in a change of the magnitude.
Help me out here. If someone would like to have a look at the code and
data results please leave a post.

..:: ElwiZ :...


"elwiz" <elwiz@stud.ics.p.lodz.pl> wrote in message 
news:opmdnR-UiIGF_8PeRVn-qA@giganews.com...
> Hello. > > I'm new to DSP programming and I need your help. I'm implementing the > Goertzel algorithm for detection of DTMF codes and I'm having trouble with > interpreting the results. > I created a sample signal and tested the whole frequency range for a peek. > A peek was found at the desired frequency but the value of the result is > very strange. It doesn't resemble in any way the original amplitude of the > sample signal. I was curious and tested the result for different input > frequencies. Different frequencies resulted in different magnitudes. Also > a change of the sample block size results in a change of the magnitude. > Help me out here. If someone would like to have a look at the code and > data results please leave a post. > > ..:: ElwiZ :... >
Hello Elwiz, The gain is N/2, so if your signal has an amplitude of A, then the goertzel output has a magnitude of A*N/2. Don't forget sometimes the magnitude^2 is used, so you now have (A*N/2)^2. Clay
>The gain is N/2, so if your signal has an amplitude of A, then the
goertzel
>output has a magnitude of A*N/2. Don't forget sometimes the magnitude^2
is
>used, so you now have (A*N/2)^2.
Tested it and it works ... but only if I set the sample block size to the same value as the sampling frequency. I don't think that the size should matter (in DSP of course :-D) . Maybe there something wrong in my code. If you could be so kind and check it for me. It's short, simple and written in Java: test.java --------- public class test { final int A = 150; final int N = 8000; final int F = 8000; final int DTMF[] = {697,770,852,941,1209,1336,1477,1633}; int x[] = new int[N]; private test() { for (int j=0;j<8;j++) { for (int i=0;i<N;i++) x[i] = (int)(A*Math.sin(DTMF[j]*2*Math.PI*i/F)); int magnitude = (int)goertzel(x,DTMF[j],F); System.out.println(j+"\t"+DTMF[j]+"\t"+magnitude+"\t"+magnitude*2/N); } } public double goertzel(int[] block, int searched_f, int sampling_f) { int k = (int)(0.5 + block.length*searched_f/sampling_f); double omega = 2*k*Math.PI/block.length; double cosinus = Math.cos(omega); double sinus = Math.sin(omega); double sthing = 2.0 * cosinus; double Q0 = 0; double Q1 = 0; double Q2 = 0; for (int i=0; i<block.length; i++) { Q0 = sthing * Q1 - Q2 + block[i]; Q2 = Q1; Q1 = Q0; } return Math.sqrt(Q1*Q1 + Q2*Q2 - Q1*Q2*sthing); } public static void main (String[] args) { new test(); } }
>>The gain is N/2, so if your signal has an amplitude of A, then the >goertzel >>output has a magnitude of A*N/2. Don't forget sometimes the magnitude^2 >is >>used, so you now have (A*N/2)^2. > >Tested it and it works ... but only if I set the sample block size to the >same value as the sampling frequency. I don't think that the size should >matter (in DSP of course :-D) . Maybe there something wrong in my code.
If
>you could be so kind and check it for me. It's short, simple and written
in
>Java: > >test.java >--------- > >public class test { > > final int A = 150; > final int N = 8000; > final int F = 8000; > final int DTMF[] = {697,770,852,941,1209,1336,1477,1633}; > > int x[] = new int[N]; > > private test() { > for (int j=0;j<8;j++) { > for (int i=0;i<N;i++) x[i] = >(int)(A*Math.sin(DTMF[j]*2*Math.PI*i/F)); > int magnitude = (int)goertzel(x,DTMF[j],F); > >System.out.println(j+"\t"+DTMF[j]+"\t"+magnitude+"\t"+magnitude*2/N); > } > } > > > public double goertzel(int[] block, int searched_f, int sampling_f) { > > int k = (int)(0.5 + block.length*searched_f/sampling_f); > double omega = 2*k*Math.PI/block.length; > double cosinus = Math.cos(omega); > double sinus = Math.sin(omega); > double sthing = 2.0 * cosinus; > double Q0 = 0; > double Q1 = 0; > double Q2 = 0; > > for (int i=0; i<block.length; i++) { > Q0 = sthing * Q1 - Q2 + block[i]; > Q2 = Q1; > Q1 = Q0; > } > return Math.sqrt(Q1*Q1 + Q2*Q2 - Q1*Q2*sthing); > } > > public static void main (String[] args) { > new test(); > } > >} >
Hello I have a problem which the same as the past massage "Goertzel algorithm - elwiz - 2005-10-25 12:49:00" in your website. I use the Goertzel filter to catch 2nd harmonic current written in DSP28335. And all the results of the 2nd value are proportionally matching the gain of N/2, i.e., for example, the input current is 0.5A(peak) and then the value of catching by the algorithm is 83.5 ( N is 334 , 0.5 * ( N / 2 ) is 83.5 ) shown in the DSP's watch window. So my question is that why the value shown in DSP shoult multiply the gain? Why the value shown in DSP is not the exactly real current peak value? Thank you Best wishes.
>Tested it and it works ... but only if I set the sample block size to the >same value as the sampling frequency. I don't think that the size should >matter (in DSP of course :-D) . Maybe there something wrong in my code.
If
>you could be so kind and check it for me. It's short, simple and written
in
>Java:
In order for that gain term to be correct, the frequency that you are looking for needs to be an integer multiple of the sample rate divided by the block length. In other words, the block needs to be able to contain an integer number of cycles of the frequency you are looking for. Otherwise, the gain could get a bit wacky, perhaps someone else on here could provide a better explanation as to what happens.