MATLAB Answers

regarding music note code can anyone explain this code line by line?

2 views (last 30 days)
Geetesh Mokhare
Geetesh Mokhare on 29 Mar 2021
Commented: Robert Brown on 29 Mar 2021
%%
fileName = 'g-piano1.wav'; % File name
[y, Fs] = audioread(fileName); % Read audio file from input
y = (y(:,1) + y(:,1))*4; % Decrease 2 channels to 1 (left and right chANNEL CONVERGE INTO TWO channel)
%y = (y(:,1));% extracting first column
y(1:2:end) = 0; %from big vector take only odd index values % Do decimation(decreace the no of samples)
frameLength = 4410*2; %samples ratecalculation for two channels
endPart = frameLength*ceil(length(y)/frameLength); % complete the last frame %ceil is to round off to nearest integer
y(length(y)+1 : endPart) = 0;% setting up in matrix form
f = linspace(1,Fs,frameLength); %creates linearly spaced vector
%%
harmonics = 0;% SETTING UP haarmonics at zero for beginning the loop structure
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) )';% diving into two frames
frame = y( (frameLength*(i-1)+1):(frameLength*i) )';same as above
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
  2 Comments
Geetesh Mokhare
Geetesh Mokhare on 29 Mar 2021
Okay. Thank you But I want a explanation for the code since I am able to understand.

Sign in to comment.

Answers (2)

Walter Roberson
Walter Roberson on 29 Mar 2021
Yes, I can explain it line by line. My current estimate is that doing so would take approximately 7 one-term university level courses... but as I start mentally reviewing the details, I start remembering more, so it might be 9 one-term courses. Or 10.
Since, for example, fft() does not make any sense without The Calculus, and The Calculus does not make any sense without the theory of real numbers, and the theory of real numbers requires Predicate Calculus, and Predicate Calculus requires a course in Logic and Rhetoric, and those beg for several lectures on comparing the writings of the ancient Greek philosophers...

Robert Brown
Robert Brown on 29 Mar 2021
Edited: Rik on 29 Mar 2021
First trick with understanding this code is that you need the *.wav file. WAV is an audio recording format. Without that, the code won't run.
Since I didn't have the original *.wav file, I went into my computer and found a "replacement wav" file, which was just an audio recording of people talking.
ACTUAL MODIFIED MATLAB CODE IS HERE: (CUT AND PASTE THIS INTO A SCRIPT FILE OR INTO THE COMMAND WINDOW)
%% This is an attempt to answer a MATLAB question submitted to MathWorks
%
% regarding music note code can anyone explain this code line by line?
% - Geetesh Mokhare
% Solution edits by Robb Brown, 3/29/2021
%
%% Prepare workspace for processing
clear all
close all
clc
format compact
format shortG
%%
% fileName = 'g-piano1.wav'; % Original File name
fileName = '1074_Pos_1_2020_05_06_21_30_23_by_Start_Time_desc.wav'; % Didn't have user file, using this one as as surrogate...
INFO = audioinfo(fileName) % Get information about the audio file % Don't end with ; and instead see the INFO
[y, Fs] = audioread(fileName); % Read audio into array y from input file, and read the sampling rate Fs
% y = (y(:,1) + y(:,1))*4; % Decrease 2 channels to 1 (left and right channel converge into channel)
y = (y(:,1) + y(:,2)); % Decrease 2 channels to 1 (left and right channel are added together)
% The number 4 appeared to be a gain (4 x louder)
% and will also be louder since adding left and right together
%y = (y(:,1));% extracting first column
% y(1:2:end) = 0; %from big vector take only odd index values % Do decimation(decrease the number of samples)
% This does not take only odd values, it ZEROES OUT every odd value, not the same thing... (and not necessary)
% frameLength = 4410*2; %samples ratecalculation for two channels
% Don't do this either, make 1 frame be 1 second of data. which is equal to Fs (since Fs is samples PER SECOND)
frameLength = Fs
% endPart = frameLength*ceil(length(y)/frameLength); % fill up the last frame % ceil is to round off to higher integer
% Bad logic here, FL * ceil... /FL = ceil...
% here's what you wanted...
endPart = frameLength - mod(length(y),frameLength);
y(length(y)+1 : length(y) + endPart) = 0;% fill in zeros to next full second
f = linspace(1,Fs,frameLength); % now that we've changed to 1 second blocks of audio, the frequency bins are already Hz !!!
%%
harmonics = 0;% SETTING UP harmonics at zero for beginning the loop structure
%for i = 1:round(length(y)/frameLength) % round wasn't necessary since we added endPart in the code above to make sure it matches
for i = 1:length(y)/frameLength % round wasn't necessary since we added endPart in the code above to make sure it matches
% Divide audio into frames
% frames(i, 1:frameLength) = y( (frameLength*(i-1)+1):(frameLength*i) )';% diving into two frames
frames(1:frameLength,1:length(y)/frameLength) = reshape(y,frameLength,length(y)/frameLength);% dividing into 1-second frames
frame = frames(:,i); % grab a frame, 1 second of data
% frame = frame .* hamming(length(frame))'; % Don't do Hamming Window
frame_fft = abs(fft(frame)); % FFT
% fp = sum(fframe); % some sort of attempt at thresholding !? skip and just display the data as-is
% 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)
plot(real(frame))
xlabel('Sample number')
ylabel('Amplitude')
title('Time Domain Signal')
subplot(3,1,2)
plot((1:Fs/4)-1,frame_fft(1:Fs/4))
xlabel('Frequency Bin (Hz)')
ylabel('Amplitude')
title('Frequency Domain Signal')
% xlim([0,500])
subplot(3,1,3)
plot((1:Fs/2)-1,frame_fft(1:Fs/2))
xlabel('Frequency Bin (Hz)')
ylabel('Amplitude')
title('Frequency Domain Signal')
% ylim([-1 1])
hold off
% pause(0.1) % this pauses for 0.1 second, not sure why this is necessary, delete or comment out ...
'pausing now, press any key to hear this second of audio...'
pause
sound(frame,Fs) % the "sound" command will turn the fframe signal into audio and play through the computer speakers
% % Decision
% 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
  5 Comments

Sign in to comment.

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!