How can I detect notes using a spectrogram?
32 views (last 30 days)
I'm building a program to detect the notes from an audio file that contains 5 chords, each containing 3/4 notes. This is my code:
[y,Fs] = audioread('sample1_pm17025.wav');
sg = 400;
ov = 300;
This is the resulting spectrogram: https://imgur.com/eKe3lLk
I assume that the five different sections are chords, however, within those sections how do I actually determine the frequency of the notes? In the first section every line is very close together and very white, in the later sections that seems to be a little bit of a split between notes but how would I know, in the first chord, what the 3/4 notes correspond to in terms of frequency?
Kaashyap Pappu on 24 Dec 2019
Edited: Kaashyap Pappu on 24 Dec 2019
You can assign a variable to spectrogram to extract the values. Then use the findpeaks function on each column of the output of spectrogram to find the peaks with the appropriate settings. A skeleton code is as given:
outputVar = spectrogram(y) %You can add any additional options or input arguments as appropriate
%For first column
temp = outputVar(:,1); %Repeat this step for all columns of outputVar
findpeaks(abs(temp),'NPeaks',4,'MinPeakHeight',20) %Adjust these as per requirement
You may have to scale the x-axis to represent the frequency values appropriately. Alternatively, the spectrogram plot will give a good idea about the frequency values and can be related to the output of findpeaks.
Another workaround for this problem can be to perform frequency domain analysis for time intervals, specifically 0.2 second intervals based on your spectrogram, using pwelch. The input to this function can be just the sequence of a specific interval, for example for 0.6 to 0.8 seconds. The peaks of the curve using this function will indicate the strongest frequency components.
Hope this helps!