matlab code for musical note recognition based on frequency
52 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
varun taliparambe vitel
am 14 Jun. 2020
Kommentiert: Geetesh Mokhare
am 29 Mär. 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 Kommentar
Akzeptierte Antwort
Thiago Henrique Gomes Lobato
am 14 Jun. 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.
Weitere Antworten (1)
Geetesh Mokhare
am 29 Mär. 2021
endPart = frameLength*ceil(length(y)/frameLength
WHAT IS THE MEANING OF THIS?
2 Kommentare
Geetesh Mokhare
am 29 Mär. 2021
One more help Can you tell me the application of this code in 5-6 lines ? Please request
Siehe auch
Kategorien
Mehr zu Audio I/O and Waveform Generation finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!