**写在前面:**前段时间通过学习Music and Math试着用Matlab编写一些简单的钢琴曲,于是经过查阅相关资料以及一些乐理知识,基本达到了目的。
-
钢琴共88个键,其中A键(49号键)为国际标准高音即440Hz,如下图:
-
其他各按键与标准键之间的关系,以及各按键频率如下图:
-
其中++、+为升调,--、-为降调;括号内的数字是与标准键之间相隔的键数。
-
简谱中,单独一个3,表示一拍,时值要看每分钟多少拍的记号,每分钟六十拍,则一拍为一秒钟,每分钟一百二十拍则一拍为半秒。后面如有横线,则为延音线,每条横线延长一拍,如果接的是点,则延长半拍。下面有横线的话,每条横线时值减半,即一条为半拍,两条为四分之一拍,三条为八分之一拍。
最后,奉上《致爱丽丝》Matlab版本代码如下:
play.m
% Usage : play(treble, treble_duration, bass, bass_duration)
%
% treble -> 高音音符
% treble_duration -> 高音音符持续时间
% bass -> 低音音符
% bass_duration -> 低音音符持续时间
function music = play(treble, treble_duration, bass, bass_duration)
fs = 11025; % sampling frequency, 11025 Hz on PC/Mac
speed_factor = 2; % cpu speed compensation factor
treble_vector = zeros(1,sum(treble_duration)*fs+1); % treble vector generator
n1 = 1; % starting index
for kk = 1:length(treble)
keynum = treble(kk);
%
if (keynum == 0) % rest period definition
A = 0.0; % amplitude at 0.0
freq = 440;
else
A = 0.5; % note amplitude at 0.5
freq = 440 * (2^( (keynum-49)/12 )); % frequency definition
end
tt = 0 : (1/fs) : (treble_duration(kk)/speed_factor); % duration generator
tone = A * cos( 2* pi* freq* tt); % tone generator
%
n2 = n1 + length(tone) - 1; % ending index & concatenate vector
treble_vector(n1:n2) = treble_vector(n1:n2) + tone; % vector generator
n1 = n2; % reset index
end
bass_vector = zeros(1,sum(bass_duration)*fs+1); % bass vector generator
n1 = 1;
for kk = 1:length(bass)
keynum = bass(kk);
%
if (keynum == 0)
A = 0;
freq = 440;
else
A = 0.5;
freq = 440 * (2^( (keynum-49)/12 ));
end
tt = 0 : (1/fs) : (bass_duration(kk)/speed_factor);
tone = A * cos( 2* pi* freq* tt);
%
n2 = n1 + length(tone) - 1;
bass_vector(n1:n2) = bass_vector(n1:n2) + tone;
n1 = n2;
end
music_vector = treble_vector + bass_vector; % treble and bass vector combination
sound( music_vector, fs ) % generate sound
play_love.m
% These are the piano key numbers and the corresponding durations for
% the song Fur Elise.
% t and tdur are for the treble clef or upper part and b and bdur are for
% the bass clef or lower part. A duration of 1 corresponds to an eighth note
% and a note value of 0 is a rest.
clear, clc
t = [ 56 55 56 55 56 51 54 52 49 0 40 44 49 51 0 44 48 51 52 0 44 56 55 ...
56 55 56 51 54 52 49 0 40 44 49 51 0 44 52 51 49 0 51 52 54 56 47 57 56 ...
54 45 56 54 52 44 54 52 51 0 44 56 0 0 56 68 0 0 55 56 0 0 55 56 55 ...
56 55 56 51 54 52 49 0 40 44 49 51 0 44 48 51 52 0 44 56 55 56 55 56 51 54 52 ...
49 0 40 44 49 51 0 44 52 51 49];
tdur = [ .5 .5 .5 .5 .5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 .5 ...
.5 .5 .5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 .5 1.5 .5 .5 .5 ...
1.5 .5 .5 .5 1.5 .5 .5 .5 1 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 ...
.5 .5 .5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 ...
1 .5 .5 .5 .5 1 .5 .5 .5 .5 2];
b = [ 0 0 25 32 37 0 0 20 32 36 0 0 25 32 39 0 0 ...
0 25 32 37 0 0 20 32 36 0 0 25 32 37 0 28 35 40 0 0 ...
23 35 39 0 0 25 32 37 0 0 20 32 44 0 44 56 0 0 55 56 0 0 55 56 0 0 ...
0 25 32 37 0 0 20 32 36 0 0 25 32 37 0 0 0 ...
25 32 37 0 0 20 32 36 0 0 25 32 37 0];
bdur = [ 1 3 .5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 .5 1 ...
3 .5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 1.5 .5 .5 .5 .5 1 ...
.5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 1 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 .5 1 ...
3 .5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 .5 1 3 ...
.5 .5 .5 .5 1 .5 .5 .5 .5 1 .5 .5 .5 .5];
play(t,tdur,b,bdur)