How to use findpeaks in the frequency domain?

81 vues (au cours des 30 derniers jours)
Taylor Gray
Taylor Gray le 6 Mar 2019
Commenté : Star Strider le 8 Mar 2019
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 commentaire
dpb
dpb le 6 Mar 2019
Modifié(e) : dpb le 6 Mar 2019
[pks,locs]=findpeaks(select,Fs,'MinPeakDistance', 0.001);
You didn't provide anywhere for findpeaks to tell you what the answer was...

Connectez-vous pour commenter.

Réponse acceptée

Star Strider
Star Strider le 6 Mar 2019
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 commentaires
Taylor Gray
Taylor Gray le 8 Mar 2019
Modifié(e) : Taylor Gray le 8 Mar 2019
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 le 8 Mar 2019
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.

Connectez-vous pour commenter.

Plus de réponses (0)

Produits


Version

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by