% Project 3
%% Piano, Jason Cao, May 7 2025, version 1.0
clc;clear;close all;
% draw the piano
a = figure; hold on;
b_w = 2.4;% width of white
h_w = 15;% height of white
b_b = 1.4;%width of black
h_b = 9;% height of black
white_note = ['C','D','E','F','G','A','B'];
black_note = ['C#';'D#';'F#';'G#';'A#'];
% get the frequencies
x = 2^(1/12);
A = 440;% Hz
freq = [];
for j = -9:2
    freq(j+10) = A*x^(j);% get the frequencies
end
wave = [];
fs = 44100;% freq to make the sound
time = 4; % duration of note
% reference to Youtube video: https://www.youtube.com/watch?v=pjMkPxkPAnY
for k = 1:length(freq)
    wave(k,:) = wavefuc(time,fs,freq(k));
end
% I only used the equations he got the wave, all the logarithm is made by myself
for i = 1:7 % white keys
    freq_index = [1 3 5 6 8 10 12]; % Indices of white keys
    userdata = struct('wave', wave(freq_index(i),:), 'orig_color', 'w');
    rectangle('Position',[0+(i-1)*b_w,0,b_w,h_w],'EdgeColor','black','FaceColor','White','UserData', userdata,'ButtonDownFcn', @UIinterf);
    text((i-0.5)*b_w,0+1,white_note(i));
end
axis off;
for i = 1:2 % black key first two
    freq_index = [2 4];
    userdata = struct('wave', wave(freq_index(i),:), 'orig_color', 'k');
    rectangle('Position',[i*b_w-0.5*b_b,h_w-h_b,b_b,h_b],'FaceColor','Black','UserData', userdata,'ButtonDownFcn', @UIinterf);
    text(i*b_w,h_w-h_b+0.5,black_note(i,:),'color','white');
end
for i = 3:5 % the last three black keys
    freq_index = [7 9 11];
    userdata = struct('wave', wave(freq_index(i-2),:), 'orig_color', 'k');
    rectangle('Position',[(i+1)*b_w-0.5*b_b,h_w-h_b,b_b,h_b],'FaceColor','Black','UserData', userdata,'ButtonDownFcn', @UIinterf);
    text((i+1)*b_w,h_w-h_b+0.5,black_note(i,:),'color','white');
end

% Callback function for key
function UIinterf(source, ~)
    % get the original color
    orig_color = source.UserData.orig_color;
    % get the wave for the key clicked only
    wave = source.UserData.wave;
    % Visual feedback
    if orig_color == 'w'
        source.FaceColor = [0.8 0.8 1]; % Light blue for white keys
    elseif orig_color == 'k'
        source.FaceColor = [0.4 0.4 0.8]; % Dark blue for black keys
    end
    % make the sound
    fs = 44100;
    sound(wave,fs);
    % after click change back color
    pause(0.2);
    source.FaceColor = orig_color;
end
