网上找的一份《左手指月》的谱子,需要了解一些基础的音乐知识,看懂谱子就可以写程序了。
主函数
%% 《左手指月》——(香蜜沉沉烬如霜)
%% 清空
clear;clc;
%% 采样频率
Fs = 8192;
%% keynote_type:当前基调
F = 'F';
keynote_type = [F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,F,...
F,F,F,F,F,F,F,F,F,F,F,F,F];
%% tone:取哪个音节
% 写法:1 2 3 4 5 6 7
% 读法:Do Re Mi Fa Sol La Si
tone = [6,3,3,5,6,6,7,6,5,3,5,3,0,2,3,4,5,6,5,6,1,...
7,6,7,6,1,2,2,3,2,6,1,7,1,6,1,...
2,0,1,2,4,3,0,6,3,3,5,6,6,7,6,5,3,5,3,0,...
2,3,4,5,6,5,6,1,7,1,7,6,7,6,1,2,2,3,2,6,...
1,7,1,6,1,2,0,1,2,4,3,6,3,3,5,6,6,7,6,5,...
3,5,3,0,2,3,4,5,6,5,6,1,7,6,7,6,1,2,2,3,2,6,...
1,7,1,6,1,2,0,1,2,4,3,0,1,0,1,4,3,2,1,...
3,2,4,1,0,1,4,3,2,1,3,3,7];
%% rythm:节拍数(音的长短)
% 全音符 “5---” 全休符 “0000” 1
% 二分音符 “5-” 二分休止符 “00” 1/2
% 四分音符(?) “5” 四分休止符 “0” 1/4
% 八分音符(?或?) “5_” 八分休止符 “0_” 1/8
% 十六分音符(?) “5__” 十六分休止符 “0__” 1/16
% 附点音符(?):延长前面音符时值的一半 5? = 5 + 5_
% 延音线(~):连接起来的若干个音要唱成一个音,时值为这些音的总和 5~5=5+5
% 连音符(~3~):将音符的时值自由均分 555~3~=55=5_ 5_5_5_~3~=5_5_=5
a = 1; b = 1/2; c = 1/4; d = 1/8; e = 1/16; f = 1/32;
c1 = 1/6; c2 = 2/6; c3 = 3/4; d3 = 3/8; d4 = 1/12; d5 = 5/12;
e3 = 3/16; e5 = 5/16;
rythm = [b,b,c3,c,a,c,c,c,c, c3,c,b,a, b,b,b,b,c3,c,b,b,...
c3,c,b,b,b, c3,c,c,c,c, c3,c,b,b,b,...
b,c3,c,b,b, c3,a, b,b,c3,c,a,c,c,c,c, c3,c,b,a,...
b,b,c3,c,c3,c,b,b, c,c,c,c,b,b,b, c3,c,c,c,c,...
c3,c,b,b,b, b,c3,c,b,b, a, b,b,c3,c,a,c,c,c,c,...
c3,c,b,a, b,b,b,b,c3,c,b,b, c3,c,b,b,b, c3,c,c,c,c,...
c3,c,b,b,b, b,c3,c,b,b, c3,a, a,c3,c,b,b,b,b,...
b,b,c3, a,c3,c,b,b,b,b, b,b,c3];
%% keynote_change:升降调8度
% 中音:不带点的基本符号
% 高音:基本符号上面加一个点 倍高音:基本符号上面加两个点
% 低音:基本符号下面加一个点 倍低音:基本符号下面加两个点
% 1代表中音,2代表高音
keynote_change = [0.25,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0,...
0.5,0.5,0.5,0.5,1, 1,1,1,1,0.5, 1,0.5,1,0.5,1,...
1,1,1,1,1, 1,1, 0.5,1,1,1,1,1,1,1,1, 1,1,1,1,...
1,1,1,1,1,1,1,2, 1,2,1,1,1,1,2, 2,2,2,2,1,...
2,1,2,1,2, 2,1,2,2,2, 2, 0.5,1,1,1,1,1,1,1,1,...
1,1,1,1, 1,1,1,1,1,1,1,2, 1,1,1,1,2, 2,2,2,2,1,...
2,1,2,1,2, 2,1,2,2,2, 2,1, 1,1,1,1,1,1,1,...
1,1,1, 1,1,1,1,1,1,1, 1,1,1];
%% up_down:音节升降
% 临时变音记号有:“?”升号---升高半音,“?”降号---降低半音,
% “?”还原号---将小节内“?”或“?”过的音回到原来的位置
% 0代表正常,1代表升号
up_down = [0,0,0,0,0,0,0,0,0, 0,0,0,0, 0,0,0,0,0,0,0,0,...
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,...
0,0,0,0,0, 0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,...
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,...
0,0,0,0,0, 0,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,...
0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,...
0,0,0,0,0, 0,0,0,0,0, 0,0, 0,0,0,0,0,0,0,...
0,0,0, 0,0,0,0,0,0,0, 0,0,0];
%% 调用get_wave
y = [];
len = length(tone);
for i = 1:1:len
y = [y, get_wave(tone(i), rythm(i), keynote_change(i), keynote_type(i), up_down(i))];
end
sound(y, Fs);
get_wave函数
function y = get_wave(tone, rythm, keynote_change, keynote_type, up_down)
% get_wave:
% tone: 取哪个音节; rythm: 节拍数; up_down:音节升降
% keynote_change:升降调8度; keynote_type:当前基调
Fs = 8192; %采样频率
keynote_B = 493; %开始的节奏降E
keynote_Ab = 415; %中间变为降A
keynote_Fd = 739; %开始的节奏降E
rythm = 1.25 * rythm;
tones_normal = [1, 3, 5, 6, 8, 10, 12]; % 1-7 到 C D E F G A B映射
if nargin == 5 %有改变基调&可能有升降调&可能有音节升降
if keynote_type == 'A'
keynote = keynote_Ab;
elseif keynote_type == 'B'
keynote = keynote_B;
elseif keynote_type == 'F'
keynote = keynote_Fd;
end
keynote = keynote * keynote_change;
end
if tone == 0 % 停顿
tone = 13;
else
tone = tones_normal(tone);
end
freqs = [1, 1.059, 1.122, 1.189, 1.260, 1.335, 1.414, 1.498, 1.587, 1.682, 1.782, 1.888, 0] .* keynote.*(1.059^up_down);
x = linspace(0, 2*pi*rythm, floor(Fs*rythm));
y = sin(freqs(tone) * x) .* (1 - x/(2*pi*rythm));
end