Normalising the magnitude of Goertzel

7 views (last 30 days)
Martin
Martin on 13 Jul 2019
Edited: Martin on 14 Jul 2019
Hello,
I am breaking down a simple sine wave with the Goertzel algorithm. However after scaling the result with dividing by the number of samples and multiplying by two the magnitude is not equal to (or close enough for my expectation) the original amplitude. How is the result normalised correctly ? Am I missing something ?
Data: Sine wave with an amplitude of 1
1*sine(2*pi*10*t) + 1*sin(2*pi*40*t)
Result Magnitude:
10 Hz: 0.63
40 Hz; 0.63
%% Goertzel test
% Reference: https://www.embedded.com/design/configurable-systems/4024443/The-Goertzel-Algorithm
%% Data
fs = 2000; % Sample frequency
t = 0:1/fs:10-1/fs; % time vector
x = 1*sin(2*pi*10*t)... % 10 Hz data
+ 1*sin(2*pi*40*(t-2)); % 40 Hz data
data_mono = double(x)'; % Data vector
N = length(data_mono); % Number of samples
target_freq = [1,5,10,15,20,25,30,40,50]; % Target frequencies to look for
%% Goertzel
for z = 1:length(target_freq) % loop over target frequencies
% Pre computing
k = 0.5+(N*target_freq(z)/fs);
w = (2*pi/N)*k;
cosine = cos(w);
sine = sin(w);
coeff = 2*cosine;
% Initialising
z0=0;
z1=0;
z2=0;
for i = 1:N % loop over N samples
z0 = coeff * z1 - z2 + data_mono(i);
z2 = z1;
z1=z0;
end
zzReal = 2*(z1-z2*cosine)/(N); % Scaling result by /N/2
zzImag = 2*(z2*sine)/(N); % Scaling result by /N/2
zzMag(z) = sqrt(zzReal*zzReal + zzImag*zzImag); % Magnitude
end
%% Plotting
figure(1)
plot(target_freq,zzMag,'o')
ylabel('Amplitude')
xlabel('Frequencies')
title('Goertzel')

Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!