matlab code for musical note recognition based on frequency
52 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
varun taliparambe vitel
le 14 Juin 2020
Commenté : Geetesh Mokhare
le 29 Mar 2021
i am working on a project to identify the musical note based on frequencies using window methods i need help to write the code and understanding it . ihave a code but its to advanced to understand......
clear;
clc;
close all;
% Note Recognition
%% Note Initialization
mainNames = char('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B');
names = char('A0', 'A#0' ,'B0');
A0 = 27.5;
ind = 4;
for i = 0:87
data(i+1) = A0 * (2^(1/12))^i;
if i>2
a = [mainNames( rem((ind - 4), 12)+1,:) num2str(fix((ind - 4)/12)+1)];
names = char(names, a);
ind = ind + 1;
end
end
% Band Initialization
bands(1) = 20;
for i = 1:87
bands(i+1) = +7+(data(i) + data(i+1))/2;
end
bands(89) = 4500;
%%
fileName = 'c.wav'; % File name
[y, Fs] = audioread(fileName); % Read audio file
y = (y(:,1) + y(:,2))*4; % Decrease 2 channels to 1
%y = (y(:,1));
y(1:2:end) = 0; %from big vector take only odd index values % Do decimation(decreace the no of samples)
frameLength = 4410*2; % 2 Güzel oldu
endPart = frameLength*ceil(length(y)/frameLength); % complete the last frame %ceil is to round off to nearest integer
y(length(y)+1 : endPart) = 0;
f = linspace(1,Fs,frameLength); %creates linearly spaced vector
%%
harmonics = 0;
for i = 1:round(length(y)/frameLength) % For each frame
% Divide audio into frames
frames(i, 1:frameLength) = y( (frameLength*(i-1)+1):(frameLength*i) )';
frame = y( (frameLength*(i-1)+1):(frameLength*i) )';
frame = frame .* hamming(length(frame))'; % Hamming Window
fframe = abs(fft(frame)); % FFT
fp = sum(fframe);
p = sum(abs(frame));
b = true;
if(p < 200 || fp < 1000) % Put a threshold for processing
b = false;
end
% Bands
for i=1:88
freqBand(i) = mean(fframe( round(bands(i)/(Fs/frameLength) ):round(bands(i+1)/(Fs/frameLength))))^2;
end
% Plotting
subplot(3,1,1)
stem(freqBand)
subplot(3,1,2)
plot(fframe)
xlim([0,500])
subplot(3,1,3)
plot(fframe)
ylim([-1 1])
hold off
pause(0.1)
sound(fframe,Fs)
% Desicion
m = find(freqBand == max(freqBand(:)));
if(b) disp(names(m,:)); % Print the result
else disp('.'); end
if(b)
index = 1;
for i = 1:88
if(freqBand(i) > 2000)
harmonics(index) = i;
index = index+1;
end
end
end
end
this is the code.....
1 commentaire
Réponse acceptée
Thiago Henrique Gomes Lobato
le 14 Juin 2020
To really undestand the method, first try to define how exactly you gonna get the frequencies. Your main steps are :
- Define your notes and which frequency do they have (Line 5-23)
- Read your sound data and define the window size to evaluate the sound (Line 24-33). Here your code has some flaws. Ex: Decimation change the sampling rate, so you can't simply do it to "decrease number of samples" and don't compensate it afterwards. If you want a mono channel from a stereo recording you normally take the mean, not the sum times 4.
- For each evaluation window, take the FFT and check which note has the frequency closest to the maximum amplitude (Line 34-86). In your code the FFT is summed in bands so each note has its "own" band and then you can just check the strongest band.
The algorithm is quite simple, but the way it was implemented in your code is indeed not so optimal. I would suggest you to try to implement it yourself in a more clean way based in those main steps. This should also help you to better internalize it.
Plus de réponses (1)
Geetesh Mokhare
le 29 Mar 2021
endPart = frameLength*ceil(length(y)/frameLength
WHAT IS THE MEANING OF THIS?
2 commentaires
Geetesh Mokhare
le 29 Mar 2021
One more help Can you tell me the application of this code in 5-6 lines ? Please request
Voir également
Catégories
En savoir plus sur Audio I/O and Waveform Generation dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!