You are on page 1of 14

PIANO NOTE RECOGNITION

By Morgan Robinson

WHY I CHOSE THIS TOPIC


I was in band for 8 years of my life

I play the piano


Matlab is a strong program for signal processing

BASIC CONCEPT
Import wav file of simple piano song ex. Mary had a little lamb

Separate the file into segments of data for each note


Determine the frequency of each note Transform the frequency into one octave Compare that to the known frequency of notes

Print the result

SOURCE CODE
F = frequency(onsets,y,Fs); F1 = correction1(F); notes = Note1(F1); end onsets = findonsets(y); function [ notes ] = project1( file ) [y, Fs] = wavread(file);

IMPORT WAV FILE


Wavread

[y,fs] = waveread(file);
y = sample data fs = the sample rate in Hertz used to encode the data in the file, basically the number of samples per second (fs = frames per second)

DETERMINING NOTE WINDOWS (ONSETS)


Tried a lot of different methods function [ onsets ] = findonsets ( y ) L = length(y); S = 1; %status trying to find begining (on/true)

k = 1; %position in array
topthresh = .2*(max(y)); bottomthresh = .05*(max(y)); for P = 51:L-50 if S == 1 if max(abs(y(P-50:P+50))) > topthresh S = 0; onsets(k) = P; k=k+1; end else

end

if max(abs(y(P-50:P+50))) < bottomthresh


S = 1; onsets(k) = P; k=k+1; end end

DETERMINING FREQUENCY
function [ F ] = frequency( onsets,y,Fs) i = length(onsets)/2; a=1; b=2; for j=1:i z=y(onsets(a):onsets(b));

L = length(z);
fftz = fft(z)/L; power = 2*abs( fftz(1:round(L/2))); freq = ((1:L/2)*Fs/L); [C,I]= max(power); F(j) = freq(I); a=a+2; b=b+2; end

FFT picks out individual frequencies in some signal and shows you how much of your total signal (in the time domain) is in a particular place in your frequency domain.

end

TRANSFORM THE FREQUENCY


function [ F1 ] = correction1( F )

i=length(F);
for j=1:i [F1(j)] = correction(F(j)); end

end

TRANSFORM THE FREQUENCY


function [ F1 ] = correction( F ) if F >= 254.284 && F <= 508.5675 F1=F; elseif F < 254.284

[F1] = correction(2*F);
elseif F > 508.5675 [F1] = correction(F/2); end end

DETERMINE THE NOTES


function [ Note1 ] = Note1( F ) i=length(F); for j=1:i Note1{j} = Note(F(j));

Cell array

end
end

DETERMINE THE NOTES

function [ Note ] = Note( F ) if F >= 254.28 && F < 269.40 Note = 'C'; elseif F >= 269.40 && F < 285.42 Note = 'C#'; elseif F >= 285.42 && F < 302.40 Note = 'D'; elseif F >= 302.40 && F < 320.38 Note = 'D#'; elseif F >= 320.38 && F < 339.43 Note = 'E'; elseif F >= 339.43 && F < 359.61 Note = 'F'; elseif F >= 359.61 && F < 380.99 Note = 'F#'; elseif F >= 380.99 && F < 403.65 Note = 'G'; elseif F >= 403.65 && F < 427.65 Note = 'G#'; elseif F >= 427.65 && F < 453.08 Note = 'A'; elseif F >= 453.08 && F < 480.02 Note = 'A#'; elseif F >= 480.02 && F < 508.57 Note = 'B'; else error('frequency outside of acceptable range') end end

Demo

OTHER USES
Print sheet music

Length of notes
Octave Voice verification

Voice Identification

REFERENCES
www.phy.mtu.edu/~suits/notefreqs.html www.mathworks.com/matlabcentral/ www.reddit.com/search?q=subreddit%3A+matlab