Thanks a lot, that looks promising.
I have used Erics code (Macleod's algorithm) to implement the following snipped:
% Amplitude of signal.
ACW=1;
% Specify signal.
Fs = 8000; % samples per second
dt = 1/Fs; % seconds per sample
nHarmonic = 7; % order of harmonic
Fc = 21.5; % Hz
StopTime = 0.25; % seconds
t = (0:dt:StopTime-dt)'; % seconds
% Specify evaluation tolerance
Tol = 0.01;
% Effective length of test vector.
tstlen=length(t);
% Generate signal
cw = ACW * sin(2*pi*(1:tstlen)*Fc/tstlen) + 1.5 * ACW * sin(2*pi*(1:tstlen)*(Fc/tstlen) * 3) ...
+ 2.5 * ACW * sin(2*pi*(1:tstlen)*(Fc/tstlen) * 5)+ 0.3 * ACW * sin(2*pi*(1:tstlen)*(Fc/tstlen) * 7);
% Number of trials in test.
N=10000;
% Desired bin number of tone relative to long test length.
bin=Fc;
% Allocate vector for results.
macldest=zeros(size(1:N));
% Calculate desired target result for comparison.
target=bin;
fprintf('Peak is at %f.\n',bin);
for I = 1:N, % Run trials.
% Calculate signal power.
sigp=sum(abs(cw(1:tstlen).^2));
% DFT.
dftshrt(1:tstlen)=fft(cw(1:tstlen));
% DFT magnitude.
magshrt(1:tstlen)=abs(dftshrt);
% Find raw peak magnitude and location.
[rawmag,rawind]=max(magshrt);
% Isolated 3 samples around peak.
pk3vect(1:3)=dftshrt(rawind-1:rawind+1);
%Do Macleod's estimation.
ref = pk3vect(2); % Isolate phase reference.
R = real(pk3vect.*conj(ref)); % Generate phase corrected coefficient vector.
gamma = (R(1)-R(3))/((2*R(2))+R(1)+R(3)); % Calculate offset.
delta = (sqrt(1 + 8*gamma*gamma)-1)/(4*gamma); % Final estimate.
macldest=rawind-1+delta;
end
% Calculate average result.
macldr=mean(macldest)
% Evaluate estimated frequency
Factor = round(macldr/Fc)
if (macldr > (Fc-Tol) & macldr<(Fc+Tol) )
result=macldr
elseif ((macldr/Factor)>(Fc-Tol) & (macldr/Factor)<(Fc+Tol))
result=macldr/Factor
end
But what is the most accurate method now to estimate the fundamentals peak value?