• 记录下我学习乐理知识,并使用MATLAB编写曲子

学习资料

MATLAB程序

钢琴各音名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
% 记录各音符的音阶,一行为一组

% 升音符号
note_treble = {'A2','A2+','B2', ...
'C1','C1+','D1','D1+','E1','F1','F1+','G1','G1+','A1','A1+','B1', ...
'C','C+','D','D+','E','F','F+','G','G+','A','A+','B', ...
'c','c+','d','d+','e','f','f+','g','g+','a','a+','b', ...
'c1','c1+','d1','d1+','e1','f1','f1+','g1','g1+','a1','a1+','b1', ...
'c2','c2+','d2','d2+','e2','f2','f2+','g2','g2+','a2','a2+','b2', ...
'c3','c3+','d3','d3+','e3','f3','f3+','g3','g3+','a3','a3+','b3', ...
'c4','c4+','d4','d4+','e4','f4','f4+','g4','g4+','a4','a4+','b4', ...
'c5'};

% 降音符号
note_bass = {'A2','B2-','B2', ...
'C1','D1-','D1','E1-','E1','F1','G1-','G1','A1-','A1','B1-','B1', ...
'C','D-','D','E-','E','F','G-','G','A-','A','B-','B', ...
'c','d-','d','e-','e','f','g-','g','a-','a','b-','b', ...
'c1','d1-','d1','e1-','e1','f1','g1-','g1','a1-','a1','b1-','b1', ...
'c2','d2-','d2','e2-','e2','f2','g2-','g2','a2-','a2','b2-','b2', ...
'c3','d3-','d3','e3-','e3','f3','g3-','g3','a3-','a3','b3-','b3', ...
'c4','d4-','d4','e4-','e4','f4','g4-','g4','a4-','a4','b4-','b4', ...
'c5'};

乐谱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
%  高音,57个
Treble = {'d1-','e1-','f1','c2','a1-', ... %1
{'b1-','g1','e1-','c1'},'0',{'a1-','f1','e1-','c1'},'c1',...
'd1-','e1-','f1','c2','a1-','f1',... %3
{'b1-','g1','e1-','c1'},{'b1-','g1','e1-','c1'},'0',{'c2','a1-','f1','e1-'},'c2',...
'a2-','e2-','f2','c3','a2-','f2',... %5
{'b2-','g2','e2-','c2'},'0',{'a2-','f2','e2-','c2'},'c2',...
'd2-','e2-','f2','c3','a2-','f2',... %7
{'b2-','g2','e2-','c2'},{'b2-','g2','e2-','c2'},'0',{'c3','a2-','f2','e2-'},'c2', ...
'd2-','e2-','f2','c3','a2-','f2',... $9
{'b2-','g2','e2-','c2'},'0',{'a2-','f2','e2-','c2'},'a2-','b2-','c3',...
'c3','a2-','a2-','f2'}; %11
% 节拍数
rhyT = [0.5 0.5 0.5 1.5 1 ...
1 0.5 2 0.5 ...
0.5 0.5 0.5 1 1 0.5 ...%3
0.75 0.25 0.5 2 0.5 ...
0.5 0.5 0.5 1 1 0.5 ...%5
1 0.5 2 0.5 ...
0.5 0.5 0.5 1 1 0.5 ...%7
0.75 0.25 0.5 2 0.5 ...
0.5 0.5 0.5 1 1 0.5 ...%9
1 0.5 1 0.5*ones(1,3) ...
1.5 0.5 1.5 0.5];

% 低音,58个
Bass = {{'a-','f'},'c1',... %1
'b-','g','a-','0','a-',...
{'a-','f'},'c1',... %3
'b-','g','a-','c1',...
'd-','0','d-','A-','d-','A-',... %5
'c','0','F','f','F','c',...
'B-','B-','0','0','c','d-','d-',... %7
'c','c','F','G','A-','G',...
'd-','0','d-','A-','d-','A-',... %9
{'g','c'},'0','F','f','e-','d-','c',...
'B-','B-','0','B-','F','c','d-'}; %11
rhyB = [2 2 ... % 1
1 0.5 0.5 1 1 ... % 2
2 2 ... % 3
ones(1,4) ...
1 0.5 1 0.5 0.5 0.5 ...
1 0.5 1 0.5 0.5 0.5 ... % 6
1 0.5*ones(1,6) ...
1 0.5 1 0.5*ones(1,3) ... %8
1 0.5 1 0.5*ones(1,3) ... % 9
1 0.5*ones(1,6) ...
1 0.5*ones(1,6)];

采样函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function x = sampling(note,rhy,fs,speed,note_table)
% note音符 fs采样率 rhy节拍数 speed拍/分钟

%rhy*60/speed:该节拍所需时间
t = 1:(fs*rhy*60/speed); %采样间隔数量

if iscell(note) %多个钢琴键同时按
num = numel(note); % 钢琴音数
x = zeros(num, length(t));
for i=1:num % 不用for,index会乱
index = find(ismember(note_table, note{i}));
p = index + 20;
f = 440*2^((p-69)/12); %振动频率
x(i,:) = sin(t/fs*pi).*cos(t/fs*pi*2*f);
end
x = sum(x)./num;
x = x / max(x);
return;

elseif note ~= '0' %一个钢琴键
index = find(ismember(note_table, note));% 音符所在钢琴位置
p = index + 20; %音阶
f = 440*2^((p-69)/12); %振动频率
x = sin(t/fs*pi).*cos(t/fs*pi*2*f);
x = x / max(x);
return;

else %休止符
x = zeros(1,length(t));
return;
end

end

主函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
%% 设定
fs= 44100;
speed = 100;

%% 高音采样
treble = [];
for i=1:length(Treble)
x = sampling(Treble{i}, rhyT(i), fs, speed, note_bass); % 降A大调
treble = [treble x];
end

%% 低音采样
bass = [];
for i=1:length(Bass)
x = sampling(Bass{i}, rhyB(i), fs, speed, note_bass); % 降A大调
bass = [bass x];
end

%% 合并高低音
% subplot(1,2,1),plot(treble);
% subplot(1,2,2),plot(bass);

song = treble + 0.5*bass;
song = song./max(song);
audiowrite('song.mp4',song,fs);
sound(song, fs);