matlab code for musical note recognition based on frequency
52 次查看(过去 30 天)
显示 更早的评论
varun taliparambe vitel
2020-6-14
评论: Geetesh Mokhare
2021-3-29
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.....
采纳的回答
Thiago Henrique Gomes Lobato
2020-6-14
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.
更多回答(1 个)
Geetesh Mokhare
2021-3-29
endPart = frameLength*ceil(length(y)/frameLength
WHAT IS THE MEANING OF THIS?
2 个评论
Geetesh Mokhare
2021-3-29
One more help Can you tell me the application of this code in 5-6 lines ? Please request
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Audio I/O and Waveform Generation 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!