MATLAB Answers


Isolating k fourier peaks

Asked by Shawn Cooper on 22 Oct 2019 at 1:32
Latest activity Commented on by Star Strider
on 22 Oct 2019 at 21:06
I have imported an audio file of a musical triad (three notes) and then taken its fourier transform to find the fundamental frequencies of the chord. From this transform, I would like to automatically select the three highest peaks in magnitude and determine where they fall on the x (frequency) axis.
My initial thought was to utilize maxk, but this obviously chooses the three highest points overall, even if they are on the same "peak".
Ultimately, I would like the return to be a vector (or array) with the three most prominent frequencies (and their magnitude, if it's an array).
clear all
%import file
[x,Fs] = audioread('eqt-CMajor.wav');
T = 1/Fs;
L = length(x);
t = (0:L-1)*T;
%change two channel input to one channel output
xMono = sum(x, 2) / size(x, 2);
%fourier transform and plot
Y = fft(xMono);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(L/2))/L;
%attempt to identify frequency of the three highest magnitude peaks
[M, Hz] = maxk(f,3,'ComparisonMethod','abs')


Sign in to comment.

1 Answer

Star Strider
Answer by Star Strider
on 22 Oct 2019 at 1:53
 Accepted Answer

Use the Signal Processing Toolbox findpeaks function, with the name-value pair arguments SortStr and NPeaks.


Show 1 older comment
Star Strider
on 22 Oct 2019 at 5:20
You are passing the frequency vector, not the Fourier transform vector, to findpeaks.
Try this instead:
[pks, locs] = findpeaks(P1,'SortStr','descend','NPeaks',3,'MinPeakDistance',200)
I don’t have your data to work with, however that should do what you want.
You can then plot the peaks as:
plot(f,P1, f(locs),pks,'^r')
Shawn Cooper on 22 Oct 2019 at 21:03
Works as advertised, thank you for the help!
Star Strider
on 22 Oct 2019 at 21:06
As always, my pleasure!
(I apologise for the delay in responding last night — I was off doing other things for a while.)

Sign in to comment.