MATLAB: Finding peaks at specific indices/values

fftfind peaksfrequencypeaks

Hey guys, I am given a wav file with 3 notes playing. The standard fundamental frequencies for these three notes are 196 Hz, 246.9 Hz, and 329.6 Hz. I have found the fundamental frequencies of these notes by finding the peaks within the range of these frequencies shown below. Now I need to find the amplitude of the first 5 harmonics where the fundamental is called the first harmonic, the component at twice the fundamental frequency is called the second harmonic etc. To do this I created an array of 1 through 5 and stored where the fundamental frequency of g was and multiplied it by the array giving me the harmonic frequency values. Now i was wondering if there was a way to find the peaks at these frequency values rather than a range like i did for the fundamental frequency. Below is the graph with the 3 fundamental frequencies pointed out.
%read the audio file x samples, output Fs
[x,Fs]= audioread('Guitar_notes.wav');
%take the fourier transform
xdft = fft(x);
xdft = xdft(1:length(x)/2+1);
% create a frequency vector
freq = 0:Fs/length(x):Fs/2;
%locs is now in frequency
[pks,locs] = findpeaks(20*log10(abs(xdft)));
%finds the peaks within the range of the fundamental frequency of the notes
indesiredrange = locs > 150 & locs < 500;
%gets the subsets within range
pks_subset = pks(indesiredrange);
locs_subset = locs(indesiredrange);
figure(3)
semilogx(freq,20*log10(abs(xdft)))
hold on
plot(freq(locs_subset), pks_subset, 'or')
hold off
xlabel('f(Hz)');
title('FFT of signal')
%harmonics 1 through 5
k = 5;
harm = 1:k;
%points of frequencies in range
z = freq(locs_subset);
%stores fundamental frequency of note g(193.8 hz)
freqG = z(36);
%gets harmonics 1 through 5
harmG = harm*freqG;

Best Answer

The actual bin frequency is unlikely to match the harmonics frequencies exactly (as in they won't match) so simply selecting the bin number is likely not going to hit the peak frequency identically.
The simplest is probably to just return the closed frequency to the actual frequency of interest returned from the findpeaks function for the peaks.
If you pass the frequency vector to findpeaks, the returned locations will be in frequency so can do direct comparison.