我正在研究行走模式的声音信号,它具有明显的规则模式:
然后我想我可以使用FFT函数获得行走频率(距图像大约1.7Hz):
x = walk_5; % Walking sound with a size of 711680x2 double
Fs = 48000; % sound frquency
L=length(x);
t=(1:L)/Fs; %time base
plot(t,x);
figure;
NFFT=2^nextpow2(L);
X=fft(x,NFFT);
Px=X.*conj(X)/(NFFT*L); %Power of each freq components
fVals=Fs*(0:NFFT/2-1)/NFFT;
plot(fVals,Px(1:NFFT/2),'b','LineSmoothing','on','LineWidth',1);
title('One Sided Power Spectral Density');
xlabel('Frequency (Hz)')
ylabel('PSD');
但是它没有给我我的期望:
FFT结果:
以下是使用
的日志域图表 semilogy(fVals,Px(1:NFFT));
我发现我的代码没有任何问题。你有什么解决方案可以轻松地从行走模式中提取1.7Hz吗?
这是mat中音频文件的链接 https://www.dropbox.com/s/craof8qkz9n5dr1/walk_sound.mat?dl=0
非常感谢!
启
答案 0 :(得分:3)
我建议您忘记DFT方法,因为由于许多原因您的信号不适合此类分析。即使通过查看您感兴趣的频率范围内的频谱,也无法轻松估算峰值:
当然你可以试试PSD / STFT和其他时髦的方法,但这是一种矫枉过正。对于这项任务,我可以想到两种相当简单的方法。
第一个仅基于自动关联功能。
这给了我大约1.72 Hz的频率。
第二种方法是基于对你的信号的观察已经有一些周期性的峰值。因此,我们可以使用findpeaks
函数简单地搜索它们。
这使我的平均频率为1.7 Hz。
简单快捷的方法。显然有些事情可以改进,例如:
无论如何,这应该让你开始,而不是陷入蹩脚的FFT和懒惰的semilogx。
代码段:
load walk_sound
fs = 48000;
dt = 1/fs;
x = walk_5(:,1);
x = x - mean(x);
N = length(x);
t = 0:dt:(N-1)*dt;
% FFT based
win = hamming(N);
X = abs(fft(x.*win));
X = 2*X(1:N/2+1)/sum(win);
X = 20*log10(X/max(abs(X)));
f = 0:fs/N:fs/2;
subplot(2,1,1)
plot(t, x)
grid on
xlabel('t [s]')
ylabel('A')
title('Time domain signal')
subplot(2,1,2)
plot(f, X)
grid on
xlabel('f [Hz]')
ylabel('A [dB]')
title('Signal Spectrum')
% Autocorrelation
[ac, lag] = xcorr(x);
min_dist = ceil(0.5*fs);
[pks, loc] = findpeaks(ac, 'MinPeakDistance', min_dist);
% Average distance/frequency
avg_dt = mean(gradient(loc))*dt;
avg_f = 1/avg_dt;
figure
plot(lag*dt, ac);
hold on
grid on
plot(lag(loc)*dt, pks, 'xr')
title(sprintf('ACF - Average frequency: %.2f Hz', avg_f))
% Simple peak finding in time domain
[pkst, loct] = findpeaks(x, 'MinPeakDistance', min_dist, ...
'MinPeakHeight', 0.1*max(x));
avg_dt2 = mean(gradient(loct))*dt;
avg_f2 = 1/avg_dt2;
figure
plot(t, x)
grid on
hold on
plot(loct*dt, pkst, 'xr')
xlabel('t [s]')
ylabel('A')
title(sprintf('Peak search in time domain - Average frequency: %.2f Hz', avg_f2))