# medfreq with delta-F threshold ?

2 views (last 30 days)
LO on 10 May 2019
Commented: LO on 28 May 2019
I am using the medfreq function to extract fast freq changes (few ms) in a sinewave signal. The function seems to work pretty well and better than "tfridge" (less artifacts), "sst" (faster) and instfreq (less artifacts).
however, when the source causes the signal to change in amplitude and no freq changes are present, it is when my problem starts. If one would imagine a spectrogram rapresentation of this: the signal would be a constant line, with some fast peaks occurring here and there (chirps). Using the medfreq function these are nicely detected.
Changes in amplitude are caused by movements in the signal source and cause the spectrogram trace to have gaps. In absence of freq modulations (chirps), the medfreq function detects a lot of noise - in correspondence of those gaps.
This suggests me that the medfreq function works "point to point", otherwise the gaps would be detected as "sinks" in the medfreq trace (but I could be wrong). Is there a way to impose a fixed range of freq in which the median is searched ? or somehow make it so that gaps in the main freq component are not creating artifacts which would be confused for chirps ?
LO on 14 May 2019
thanks Greg
see if you can open these mat files. they should be sinewave signals, half of those depicted above. In the second file there are some gaps. They both last 30 seconds . The sampling freq is 20kHz

Greg Dionne on 14 May 2019
Edited: Greg Dionne on 14 May 2019
From what I can tell your sinusoid is around ~895 Hz and has fairly clean second and third harmonics. So I took that as the starting point. The approach is to bandpass about each of the harmonics, mix down, filter and reconstruct the instantaneous frequency; if you divide each of the harmonics by its order, the overlaid results have reasonable agreement.
Anyways, this should hopefully get you started.
Fs = 20e3;
% carrier
Fc = 895;
% choose 100 Hz (one-sided) bandwidth about carrier
bw = 100;
% attempt FM demodulation about carrier
[Finst1, Tinst] = instfreq_bb(seg1, Fs, Fc, bw);
[Finst2, Tinst] = instfreq_bb(seg1, Fs, 2*Fc, bw);
[Finst3, Tinst] = instfreq_bb(seg1, Fs, 3*Fc, bw);
% superimpose
plot(Tinst,[Finst1(:) Finst2(:)/2 Finst3(:)/3 (Finst1(:)+Finst2(:)/2+Finst3(:)/3)/3])
ylabel('Freq');
xlabel('Time');
legend('1st','2nd / 2','3rd / 3','average')
function [Finst, Tinst] = instfreq_bb(xx, Fs, Fc, bw)
%spectrogram(xx,kaiser(1024,10),1000,1024,20e3,'yaxis','power')
x = bandpass(xx, Fc+[-bw bw], Fs, 'Steepness',.5);
%spectrogram(x,kaiser(1024,10),1000,1024,20e3,'yaxis','power')
t = (0:numel(x)-1)./Fs;
% mix down
z = complex(x .* cos(-2*pi*Fc*t), ...
x .* sin(-2*pi*Fc*t));
% filter
bb = lowpass(z,bw,Fs,'Steepness',0.99);
%spectrogram(bb,kaiser(1024,10),1000,1024,20e3,'yaxis','power','centered')
% fetch instantaneous frequency from angular component.
Finst = angle(bb(2:end).*conj(bb(1:end-1))).*Fs/(2*pi)+Fc;
% fetch weighted time.
Tinst = t(1:end-1)+t(2)/2;
end
LO on 28 May 2019
Thanks Greg
I forgot to mention I have tried to apply your suggestion: no, considering the harmonics does not make it any better. I agree with you: there is not much to do in case of noise.
however what I want to achieve is not measauring the signal in the noisy spots. Is the opposite (exclude it). this could be achieved a little bit by changing the window and by thresholding the spectrogram (without reassignment, as it would eventually increase the noise for medfreq). I was wondering whether there is another way to apply a threshold directly on medfreq (or whether a similar function exists).