How to use findpeaks in the frequency domain?

30 ビュー (過去 30 日間)
Taylor Gray
Taylor Gray 2019 年 3 月 6 日
コメント済み: Star Strider 2019 年 3 月 8 日
I'm able to use findpeaks to find out the amplitude and time of each mode but i'm trying to use it to also find frequency, below was my attempt however as I am still very new to this software I was looking for a little help?
clear;
clc;
close all;
[audio_file, Fs] = audioread("honours_gun.wav");
audio_file = audio_file(:, 1);
select = audio_file;
findpeaks(select,Fs,'MinPeakDistance', 0.001);
figure(2), semilogx(audio_file), xlabel('Frequency, Hz'), ylabel('magnitude');
I'm able to plot the frequency with a logarithmic scale and if I could manage to identify the peaks I will have all the information from the sample I need.
  1 件のコメント
dpb
dpb 2019 年 3 月 6 日
編集済み: dpb 2019 年 3 月 6 日
[pks,locs]=findpeaks(select,Fs,'MinPeakDistance', 0.001);
You didn't provide anywhere for findpeaks to tell you what the answer was...

サインインしてコメントする。

採用された回答

Star Strider
Star Strider 2019 年 3 月 6 日
I would do something like this:
[audio_file, Fs] = audioread("honours_gun.wav");
L = size(audio_file,1);
Ts = 1/Fs; % Sampling Interval
Fn = Fs/2; % Nyquist Frequency
FT_af = fft(audio_file)/L; % Fourier Transform
Fv = linspace(0, 1, fix(L/2)+1)*Fn; % Frequency Vector
Iv = 1:numel(Fv); % Index Vector
[PksL,LocsL] = findpeaks(abs(FT_af(Iv,1))*2, 'MinPeakHeight',4E-3);
[PksR,LocsR] = findpeaks(abs(FT_af(Iv,2))*2, 'MinPeakHeight',4E-3);
figure
subplot(2,1,1)
plot(Fv, abs(FT_af(Iv,1))*2)
hold on
plot(Fv(LocsL), PksL, '^r', 'MarkerFaceColor','r')
hold off
ylabel('Amplitude')
title('Left Channel')
subplot(2,1,2)
plot(Fv, abs(FT_af(Iv,2))*2)
hold on
plot(Fv(LocsR), PksR, '^r', 'MarkerFaceColor','r')
hold off
xlabel('Frequency (Hz)')
ylabel('Amplitude')
title('Left Channel')
The frequency peaks are in ‘Fv(LocsL)’ and ‘Fv(LocsR)’ respectively. The peak values for each correspond to those.
Experiment (especially with the findpeaks name-value pairs) to get the result you want.
  2 件のコメント
Taylor Gray
Taylor Gray 2019 年 3 月 8 日
編集済み: Taylor Gray 2019 年 3 月 8 日
Honestly this answer helped a lot and is giving me the frequency peaks, however what would I need to add to the code to see the sample like the picture below and still have the peaks identified?
Or can findpeaks not be used when looking at the wave in this form?
Star Strider
Star Strider 2019 年 3 月 8 日
Thank you.
The findpeaks function has several name-value pair arguments you can use (such as 'MinPeakHeight' that I use here) that allow you specify the characteristics of the peaks you want the function to return. I encourage you to experiment with them to determine the ones that give you the results you want.
There are also functions such as sgolayfilt (link) that you can use on your spectrum results to eliminate some of the noise, making it easier to identify the peaks. (In this sense, it works as a low-pass filter on the frequency-domain spectrum results.) Use it with your spectrum with arguments similar to what I use in my findpeaks calls, specifically:
abs(FT_af(Iv,1))*2
for the best results.
In my experience, signal processing tends to require a bit of experimentation in order to get the desired result.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeDescriptive Statistics についてさらに検索

製品


リリース

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by