Prev: BPSK demodulation
Next: Viterbi Decoder
From: Sohaib Afzal on 2 Jan 2010 02:07 I am probably doing everything wrong: The frequency i am searching for is stored in K. this code runs for K= 120, 260, ...12000 NN is my bin width, x is the signal. for N=NN:NN:size of x for each K find coeff, put Q1 and Q2 = 0 for n=NN consecutive integers, determined using N Q0(K) = coeff*Q1(K) - Q2(K) + x(n); Q2(K) = Q1(K); Q1(K) = Q0(K); end; pow(K) = Q1(K)*Q1(K) + Q2(K)*Q2(K) - coeff*Q1(K)*Q2(K); i plot pow. Different plots for different values of N. Ten lines of code :) When i did fft, i got large peaks at 2000, 4500, 6000 as well as at some smaller frequencies. But my code gives only tiny or no peaks above 1200. My implementation is probably/definitely wrong, but please also tell me if it is recommended to use goertzel algo to view the audio spectrum in real time, or would i be better-off using fft? I think differentiation etc would be very difficult in the PIC controller. By "sweeping it across the frequency range" do you mean i need to apply goertzel to all values of K between 120 and 12000, i.e. also to 121, 122, 123... etc? Thanks for helping!
From: Jerry Avins on 2 Jan 2010 11:10 Sohaib Afzal wrote: > I am probably doing everything wrong: > > The frequency i am searching for is stored in K. this code runs for K= > 120, 260, ...12000 > NN is my bin width, x is the signal. > > for N=NN:NN:size of x > for each K > find coeff, put Q1 and Q2 = 0 > for n=NN consecutive integers, determined using N > Q0(K) = coeff*Q1(K) - Q2(K) + x(n); > Q2(K) = Q1(K); > Q1(K) = Q0(K); > end; > pow(K) = Q1(K)*Q1(K) + Q2(K)*Q2(K) - coeff*Q1(K)*Q2(K); > > i plot pow. Different plots for different values of N. > Ten lines of code :) > > When i did fft, i got large peaks at 2000, 4500, 6000 as well as at > some smaller frequencies. But my code gives only tiny or no peaks > above 1200. > > My implementation is probably/definitely wrong, but please also tell > me if it is recommended to use goertzel algo to view the audio > spectrum in real time, or would i be better-off using fft? I think > differentiation etc would be very difficult in the PIC controller. > > By "sweeping it across the frequency range" do you mean i need to > apply goertzel to all values of K between 120 and 12000, i.e. also to > 121, 122, 123... etc? What do you expect from your code? If you think of an FT as a banl of filters, each tuned to the center frequency of a "bin"m then a Goertzel is a single filter tuned to a single bin. You may be enlightened by http://www.mstarlabs.com/dsp/goertzel/goertzel.html Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
From: Jerry Avins on 2 Jan 2010 11:17 Jerry Avins wrote a jumble. What do you expect from your code? If you think of an FT as a bank of filters, each tuned to the center frequency of a "bin", then a Goertzel is a single filter tuned to a single bin. You may be enlightened by http://www.mstarlabs.com/dsp/goertzel/goertzel.html (Particularly by the figure with the green border that shows the response to a wide spectrum. Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
From: maury on 4 Jan 2010 17:21 On Jan 2, 1:07 am, Sohaib Afzal <504...(a)gmail.com> wrote: > I am probably doing everything wrong: > > The frequency i am searching for is stored in K. this code runs for K= > 120, 260, ...12000 > NN is my bin width, x is the signal. > > for N=NN:NN:size of x > for each K > find coeff, put Q1 and Q2 = 0 > for n=NN consecutive integers, determined using N > Q0(K) = coeff*Q1(K) - Q2(K) + x(n); > Q2(K) = Q1(K); > Q1(K) = Q0(K); > end; > pow(K) = Q1(K)*Q1(K) + Q2(K)*Q2(K) - coeff*Q1(K)*Q2(K); > > i plot pow. Different plots for different values of N. > Ten lines of code :) > > When i did fft, i got large peaks at 2000, 4500, 6000 as well as at > some smaller frequencies. But my code gives only tiny or no peaks > above 1200. > > My implementation is probably/definitely wrong, but please also tell > me if it is recommended to use goertzel algo to view the audio > spectrum in real time, or would i be better-off using fft? I think > differentiation etc would be very difficult in the PIC controller. > > By "sweeping it across the frequency range" do you mean i need to > apply goertzel to all values of K between 120 and 12000, i.e. also to > 121, 122, 123... etc? > > Thanks for helping! Sohaib, I am assuming that your are running the Goertzel aganist K for each tone you need, and NN is the number of samples taken from K in consecutive order in NN steps. What I use to give a fairly accurate amplitude measure is (using your notation) y(N:N+NN-1) = sqrt(Q1^2 + Q2^2 - (Q1 * Q2 * coeff))*2/NN For an approximate of power square y, pow(N:N+NN-1) = (Q1^2 + Q2^2 - (Q1 * Q2 * coeff))*4/NN^2. This might work. Also, there's a lot going on where you say for each K find coeff in Matlab lingo, you should have something like k = fix(0.5 + NN*f/Fs); w = (2*pi/NN)*k; cosine = cos(w); coeff = 2 * cosine; CAUTION: in Matlab the use of fix( ) could be important. Maurice Givens
From: Sohaib Afzal on 5 Jan 2010 14:17
Thanks for your interest. This is what i am trying to do: K is an array of the frequencies i am looking for (sorry about the confusing naming). K = [120, 260, 660, 990, 1200, 2400, 6000, 10000]; (in Hertz) I take NN samples from my input signal x, and then for each value of K, i apply the code i gave above. I use the formula you have given for magnitude calculation (although i didnt scale with 2/NN) I do find the coefficients exactly as you have described, (although i hav named f as K...) After i get the values for magnitude, y, for NN consecutive samples of signal x, i plot all the magnitudes y (corresponding to each frequency K) on the same plot. Ascii art: | | | | | o |o | || | || | || | || | || | || | o || | | o || | | | o ||_|_|_|_________| _____________________________o_______________________________o_______ 0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 The problem is that for low frequencies, y has a very large value, and for high frequencies, a very low value. I plot this graph for each NN samples of x, and all the plots have this same problem. What i expect from my code: plots for each NN consecutive values. The x axis of the plots has values of frequency, K, and the y axis has amplitude. The amplitudes should be the same order of magnitude, but aren't. When i apply the goertzel function in matlab: y = goertzel(x, K); plot(K, abs(y)); then i get the kind of plot i am looking for. If i succeed in making my own code work, i eventually aim to implement it in the PIC microcontroller. ..... The sampling frequency is 22050 Hz. I have tried taking various values of NN. Larger NN, say 900, give an even greater difference between the values of y corresponding to high and low values of frequency K. My code works quite well if i generate a signal myself in Matlab (sum of a few sinusoids of different frequencies). But the problem is happening when i get the signal from the function wavread (which reads a .wav file and generates an array containing samples of its magnitude). Two questions: Why does the goertzel function of Matlab not need sampling frequency as an input? And why does it give an error when i give it NN samples of x, and a frequency K greater than NN? Does Goertzel algorithm require the sample window NN to be larger than the greatest frequency being searched for? Thank you all for helping! |