0
$\begingroup$

I have this wav file that I recorded using my laptop, It contains the sound of a G chord of a guitar. Since the guitar have 6 strings the sound should contain different frequencies I want to determine the top 10 most dominant frequency in the signal.

[X, Fs] = wavread('chordG.wav');
freq = fft(X);
plot(abs(freq)):

I don't know how to proceed after that it shows the graph of the frequency but I don't know how can I extract the values in the graph.

Your answer would be very much appreciated :)

$\endgroup$
  • $\begingroup$ You should probably read up on window functions and spectral leakage. Often, the second strongest frequency is one that's directly adjacent to the main frequency, just because the physical frequency doesn't correspond to a single FFT bin. $\endgroup$ – MSalters Mar 10 '14 at 16:27
1
$\begingroup$

There are research papers on the topic of automatic polyphonic chord estimation/transcription on MIREX (http://www.music-ir.org/mirex/wiki/2014:Audio_Chord_Estimation). Also a book and a thesis by A. Klapuri.

| improve this answer | |
$\endgroup$
0
$\begingroup$

If I understand you right, you are actually asking for a fairly simple process. If not, then I'm sorry. What I understand from "getting the top 10 most dominant frequency components" is to have the top 10 frequency components with highest amplitudes. To do that you can simply follow the method below without any advanced processing.

[y, Fs] = wavread('chordG.wav'); % read the wav file into X with sampling frequency Fs
fftVal = abs(fft(y,63)); % take 63 point FFT of signal and get magnitudes of the frequency components, increase number of points as you might require more frequency samples
mags = fftshift(fftVal); % perform an FFT shift to shift the negative frequencies
freqs = linspace(-Fs/2,Fs/2,length(mags))'; % create a proper frequency axis depending on the FFT length
plot(freqs, mags); % plot the frequency spectrum of your sound
% HERE
mergedData = [freqs, mags]; % merge the frequency data and magnitude data into a Nx2 matrix
sortedFreq = sortrows(mergedData, [-2 1]); % sort the merged columns by descending order wrt mags and then ascending order to freqs
top10freqs = sortedFreq(1:10, 1); % get the first 10 frequency components
top10mags = sortedFreq(1:10, 2); % get the first 10 frequency magnitudes

But this will give you the negative frequency components as well, which might be useless since we're talking about a real signal here. So before getting the top 10, you can eliminate the negative frequencies with a simple line of code that you insert to "% HERE"

mags(freqs < 0) = 0; % zero-out the mags where freqs are less than zero

As a final note, while you are doing this process the number of FFT points you have is going to matter a lot, so my advice would be to experiment with your data a little bit and see how many points work out for you.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.