Wednesday, April 23, 2008

Matlab Code

%Sample singing voice
[song,fs] = wavread('stevethirdscale.wav');
soundsc(song,16000)
song_length = length(song);
samples = round(song_length/8000)


%The song we are testing against, find its length
the_song = [523.2 587.3 659.2 698.4 783.9 880 987.7];
test_length = length(the_song);


correct = 0;
deviation = 0;

%matrices to store results
dev_matrix = zeros(1,samples);
pitch_matrix = zeros(1,samples);




x = 1;
note = '0';
index = 1;

while (x < song_length)

newx = x + 8000;

if (newx < song_length)

%The note that should be sung at this time step
%test_note = the_song(1,index);
%test_note_name = freqmap(test_note);

%The note that you sang and its pitch
note = song(x:newx);
pitch = pitch_detec(note,4000,1000,1028);

pitch = max(pitch);

if (pitch < 50)
pitch = 0;
end

if (pitch > 1500)
pitch = 0;
end;

%The note and it's deviation from perfect pitch
[note,deviation_of_note] = freqmap(pitch);

%how close you came to the note that you should have sang
%deviation_from_song = abs(pitch-test_note);

%if test_note_name == note
% correct = correct + 1;
%end;

%display(['You sang a ' note ' at ' num2str(pitch) 'Hz. Target pitch
%for that note is ' num2str(deviation_of_note) 'Hz away. The correct note is ' test_note_name ' at a target pitch ' num2str(deviation_from_song) 'Hz away.'])

%Filter out those pesky zeros
if (pitch > 1)
pitch_matrix(1,index) = pitch;
display(['You sang a ' note ' at ' num2str(pitch) 'Hz. Target pitch for that note is ' num2str(deviation_of_note) 'Hz away.']);
dev_matrix(1,index) = deviation_of_note;
index = index + 1;
end;

end;
x = newx;


end;

%Success_Rate = (correct/samples)


subplot(3,1,1); plot(the_song)
title('Orginal Song')
subplot(3,1,2); plot(pitch_matrix(1:test_length))
title('Your Song')
subplot(3,1,3); plot(dev_matrix)
title('Deviation From Perfect Pitch')

figure(2);

plot(abs(pitch_matrix(1:7)-the_song))

score = sum(abs(pitch_matrix(1:7)-the_song))


---

%Frequency Domain Pitch Detection
%f_y = pitch_detec(x, window, hop, xformlength)

function answer = pitch_detec(x, window, hop, xformlength)

%Windowing input signal
numwinds = ceil((size(x,1) - window)/hop) + 1;
windstart = 1;

h=1;
for(windnum = 1:numwinds)

%First fetch the samples to be used in the current window, zeropadding
%if necessary for the last window.
if(windnum ~= numwinds)
windx = x(windstart:windstart + window - 1);
else
windx = x(windstart:size(x,1));
windx(size(windx,1) + 1:window) = 0;
y(size(x, 1) + 1:windstart + window - 1) = 0;
end

%Apply the Hanning window function to the samples.
windx = windx .* hanning(window);

%STFT (Convert from Time Domain to Freq Domain using fft of length 4096)
f_x = fft(windx, xformlength);


%HPS
%function f_y = hps(f_x)
f_x = f_x(1 : size(f_x,1) / 2);

f_x = abs(f_x);

%HPS, PartI: downsampling
for i = 1:length(f_x)
f_x2(i,1) = 1;
f_x3(i,1) = 1;
f_x4(i,1) = 1;
% f_x5(i,1) = 1;
end

for i = 1:floor((length(f_x)-1)/2)
f_x2(i,1) = (f_x(2*i,1) + f_x((2*i)+1,1))/2;
end

for i = 1:floor((length(f_x)-2)/3)
f_x3(i,1) = (f_x(3*i,1) + f_x((3*i)+1,1) + f_x((3*i)+2,1))/3;
end

for i = 1:floor((length(f_x)-3)/4)
f_x4(i,1) = (f_x(4*i,1) + f_x((4*i)+1,1) + f_x((4*i)+2,1) + f_x((4*i)+3,1))/4;
end



%HPS, PartII: calculate product
f_ym = (1*f_x) .* (1.0*f_x2);% .* (1*f_x3) .* f_x4; %.* f_x5;


%HPS, PartIII: find max
f_y1 = max(f_ym);

for c = 1 : size(f_ym)
if(f_ym(c, 1) == f_y1)
index = c;
end
end

% Convert that to a frequency
f_y(h) = (index / xformlength) * 44100;


%Don't forget to increment the windstart pointer.
windstart = windstart + hop;

% f_y(h) = f_y1;
h=h+1;
f_y = abs(f_y)';


end

%Find Mode

[b,i,j] = unique(f_y);
h = hist(j,length(b));
m=max(h);
y=b(h==m);

answer = y;


----


%Note Mapping

function [the_note,deviation_of_note] = freqmap(pitch)


the_note = '0';
real_pitch = 0;


A0 = 27.5;
B0 = 30.8;
C1 = 32.7;
D1 = 36.7;
E1 = 41.2;
F1 = 43.6;
G1 = 48.9;
A1 = 55;
B1 = 61.7;


C2 = 65.4;
D2 = 73.4;
E2 = 82.4;
F2 = 87.3;
G2 = 97.9;
A2 = 110;
B2 = 123.4;


C3 = 130.8;
D3 = 146.8;
E3 = 164.8;
F3 = 174.6;
G3 = 196;
A3 = 220;
B3 = 246.9;

C4 = 261.6;
D4 = 293.6;
E4 = 329.6;
F4 = 349.2;
G4 = 392;
A4 = 440;
B4 = 493.8;

C5 = 523.2;
D5 = 587.3;
E5 = 659.2;
F5 = 698.4;
G5 = 783.9;
A5 = 880;
B5 = 987.7;

C6 = 1046.5;
D6 = 1174.7;
E6 = 1318.5;
F6 = 1396.9;
G6 = 1568;
A6 = 1760;
B6 = 1975.5;

C7 = 2093;
D7 = 2349.3;
E7 = 2637;
F7 = 2793;
G7 = 3136;
A7 = 3520;
B7 = 3951.1;




C8 = 4186;


AB0 = ((B0-A0)/2);
BC0 = ((C1-B0)/2);
CD1 = ((D1-C1)/2);
DE1 = ((E1-D1)/2);
EF1 = ((F1-E1)/2);
FG1 = ((G1-F1)/2);
GA1 = ((A1-G1)/2);
AB1 = ((B1-A1)/2);

BC2 = ((C2-B1)/2);
CD2 = ((D2-C2)/2);
DE2 = ((E2-D2)/2);
EF2 = ((F2-E2)/2);
FG2 = ((G2-F2)/2);
GA2 = ((A2-G2)/2);
AB2 = ((B2-A2)/2);

BC3 = ((C3-B2)/2);
CD3 = ((D3-C3)/2);
DE3 = ((E3-D3)/2);
EF3 = ((F3-E3)/2);
FG3 = ((G3-F3)/2);
GA3 = ((A3-G3)/2);
AB3 = ((B3-A3)/2);


BC4 = ((C4-B3)/2);
CD4 = ((D4-C4)/2);
DE4 = ((E4-D3)/2);
EF4 = ((F4-E4)/2);
FG4 = ((G4-F4)/2);
GA4 = ((A4-G4)/2);
AB4 = ((B4-A4)/2);

BC5 = ((C5-B4)/2);
CD5 = ((D5-C5)/2);
DE5 = ((E5-D5)/2);
EF5 = ((F5-E5)/2);
FG5 = ((G5-F5)/2);
GA5 = ((A5-G5)/2);
AB5 = ((B5-A5)/2);

BC6 = ((C6-B5)/2);
CD6 = ((D6-C6)/2);
DE6 = ((E6-D6)/2);
EF6 = ((F6-E6)/2);
FG6 = ((G6-F6)/2);
GA6 = ((A6-G6)/2);
AB6 = ((B6-A6)/2);

BC7 = ((C7-B6)/2);
CD7 = ((D7-C7)/2);
DE7 = ((E7-D7)/2);
EF7 = ((F7-E7)/2);
FG7 = ((G7-F7)/2);
GA7 = ((A7-G7)/2);
AB7 = ((B7-A7)/2);

BC8 = ((C8-B7)/2);

if (pitch < (A0+AB0))
the_note = 'A0';
real_pitch = A0;
end;

if (pitch > (A0+AB0))
if (pitch < (B0+BC0))
the_note = 'B0';
real_pitch = B0;
end;
end;


if (pitch > (B0+BC0))
if (pitch < (C1+CD1))
the_note = 'C1';
real_pitch = C1;
end;
end;


if (pitch > (C1+CD1))
if (pitch < (D1+DE1))
the_note = 'D1';
real_pitch = D1;
end;
end;


if (pitch > (D1+DE1))
if (pitch < (E1+EF1))
the_note = 'E1';
real_pitch = E1;
end;
end;


if (pitch > (E1+EF1))
if (pitch < (F1+FG1))
the_note = 'F1';
real_pitch = F1;
end;
end;


if (pitch > (F1+FG1))
if (pitch < (G1+GA1))
the_note = 'G1';
real_pitch = G1;
end;
end;


if (pitch > (G1+GA1))
if (pitch < (A1+AB1))
the_note = 'A1';
real_pitch = A1;
end;
end;


if (pitch > (A1+AB1))
if (pitch < (B1+BC2))
the_note = 'B1';
real_pitch = B1;
end;
end;

%----


if (pitch > (B1+BC2))
if (pitch < (C2+CD2))
the_note = 'C2';
real_pitch = C2;
end;
end;


if (pitch > (C2+CD2))
if (pitch < (D2+DE2))
the_note = 'D2';
real_pitch = D2;
end;
end;


if (pitch > (D2+DE2))
if (pitch < (E2+EF2))
the_note = 'E2';
real_pitch = E2;
end;
end;


if (pitch > (E2+EF2))
if (pitch < (F2+FG2))
the_note = 'F2';
real_pitch = F2;
end;
end;


if (pitch > (F2+FG2))
if (pitch < (G2+GA2))
the_note = 'G2';
real_pitch = G2;
end;
end;


if (pitch > (G2+GA2))
if (pitch < (A2+AB2))
the_note = 'A2';
real_pitch = A2;
end;
end;


if (pitch > (A2+AB2))
if (pitch < (B2+BC3))
the_note = 'B2';
real_pitch = B2;
end;
end;

%-----------


if (pitch > (B2+BC3))
if (pitch < (C3+CD3))
the_note = 'C3';
real_pitch = C3;
end;
end;


if (pitch > (C3+CD3))
if (pitch < (D3+DE3))
the_note = 'D3';
real_pitch = D3;
end;
end;


if (pitch > (D3+DE3))
if (pitch < (E3+EF3))
the_note = 'E3';
real_pitch = E3;
end;
end;


if (pitch > (E3+EF3))
if (pitch < (F3+FG3))
the_note = 'F3';
real_pitch = F3;
end;
end;


if (pitch > (F3+FG3))
if (pitch < (G3+GA3))
the_note = 'G3';
real_pitch = G3;
end;
end;


if (pitch > (G3+GA3))
if (pitch < (A3+AB3))
the_note = 'A3';
real_pitch = A3;
end;
end;


if (pitch > (A3+AB3))
if (pitch < (B3+BC4))
the_note = 'B3';
real_pitch = B3;
end;
end;

%----


if (pitch > (B3+BC4))
if (pitch < (C4+CD4))
the_note = 'C4';
real_pitch = C4;
end;
end;


if (pitch > (C4+CD4))
if (pitch < (D4+DE4))
the_note = 'D4';
real_pitch = D4;
end;
end;


if (pitch > (D4+DE4))
if (pitch < (E4+EF4))
the_note = 'E4';
real_pitch = E4;
end;
end;


if (pitch > (E4+EF4))
if (pitch < (F4+FG4))
the_note = 'F4';
real_pitch = F4;
end;
end;


if (pitch > (F4+FG4))
if (pitch < (G4+GA4))
the_note = 'G4';
real_pitch = G4;
end;
end;


if (pitch > (G4+GA4))
if (pitch < (A4+AB4))
the_note = 'A4';
real_pitch = A4;
end;
end;


if (pitch > (A4+AB4))
if (pitch < (B4+BC5))
the_note = 'B4';
real_pitch = B4;
end;
end;

%------


if (pitch > (B4+BC5))
if (pitch < (C5+CD5))
the_note = 'C5';
real_pitch = C5;
end;
end;


if (pitch > (C5+CD5))
if (pitch < (D5+DE5))
the_note = 'D5';
real_pitch = D5;
end;
end;


if (pitch > (D5+DE5))
if (pitch < (E5+EF5))
the_note = 'E5';
real_pitch = E5;
end;
end;


if (pitch > (E5+EF5))
if (pitch < (F5+FG5))
the_note = 'F5';
real_pitch = F5;
end;
end;


if (pitch > (F5+FG5))
if (pitch < (G5+GA5))
the_note = 'G5';
real_pitch = G5;
end;
end;


if (pitch > (G5+GA5))
if (pitch < (A5+AB5))
the_note = 'A5';
real_pitch = A5;
end;
end;


if (pitch > (A5+AB5))
if (pitch < (B5+BC6))
the_note = 'B5';
real_pitch = B5;
end;
end;

%-----


if (pitch > (B5+BC6))
if (pitch < (C6+CD6))
the_note = 'C6';
real_pitch = C6;
end;
end;


if (pitch > (C6+CD6))
if (pitch < (D6+DE6))
the_note = 'D6';
real_pitch = D6;
end;
end;


if (pitch > (D6+DE6))
if (pitch < (E6+EF6))
the_note = 'E6';
real_pitch = E6;
end;
end;


if (pitch > (E6+EF6))
if (pitch < (F6+FG6))
the_note = 'F6';
real_pitch = F6;
end;
end;


if (pitch > (F6+FG6))
if (pitch < (G6+GA6))
the_note = 'G6';
real_pitch = G6;
end;
end;


if (pitch > (G6+GA6))
if (pitch < (A6+AB6))
the_note = 'A6';
real_pitch = A6;
end;
end;


if (pitch > (A6+AB6))
if (pitch < (B6+BC7))
the_note = 'B6';
real_pitch = B6;
end;
end;

%-----


if (pitch > (B6+BC7))
if (pitch < (C7+CD7))
the_note = 'C7';
real_pitch = C7;
end;
end;


if (pitch > (C7+CD7))
if (pitch < (D7+DE7))
the_note = 'D7';
real_pitch = D7;
end;
end;


if (pitch > (D7+DE7))
if (pitch < (E7+EF7))
the_note = 'E7';
real_pitch = E7;
end;
end;


if (pitch > (E7+EF7))
if (pitch < (F7+FG7))
the_note = 'F7';
real_pitch = F7;
end;
end;


if (pitch > (F7+FG7))
if (pitch < (G7+GA7))
the_note = 'G7';
real_pitch = G7;
end;
end;


if (pitch > (G7+GA7))
if (pitch < (A7+AB7))
the_note = 'A7';
real_pitch = A7;
end;
end;


if (pitch > (A7+AB7))
if (pitch < (B7+BC8))
the_note = 'B7';
real_pitch = B7;
end;
end;

deviation_of_note = real_pitch-pitch;

No comments: