一、前言
二、整体思想
三、matlab实现代码:
1.主文件:初始化乐谱
2.声波制作函数:
四、总结:
一、前言
本篇文章内容为个人学习分享,读代码须知以下
乐理的基本知识,以及十二平均律(波的频率与音高的标准),个人推荐在维基百科中搜索十二平均律表。
在主函数中,将一些简单的乐谱按照节拍,按键,基调,半音改变经行拆解。
然后我个人学习时,以440hz为标准的do依次类推,得到的基础钢琴七键,然后通过改变基础七键得到其他的音高。
因为相邻的音阶是等差的,且音高p = 69 + 12 x log2(f频率/440),了解更加细致的讲解点击这里
clear;clc
Fs=8192; %sound函数的采样频率
%说明:tone为七节白键,rythm默认为4/4拍,keynote_type为更改基调,
%说明:rythm_change为节拍改变,文中有一部份为3/4拍,Soundzone_change为低中高音设定
%1234567分别对应do,re,mi,fa,so,la,si
tone1=[5,5,6,5,1,7,5,5,6,5,2,...
1,5,5,5,3,1,7,6,4,4,3,1,3,2,5,5,6,5,1,...
7,5,5,6,5,2,1,5,5,5,3,1,7,6];
tone2=[4,4,3,1,2,1,5,5,...
6,5,1,7,5,5,6,5,2,1,5,5,...
5,3,1,7,6,4,4,3,1,3,2,5,5,...
6,5,1,7,5,5,6,5,2,1,5,5,5,3,1,...
7,6,4,4,3,1,2,1];
tone=[tone1,tone2];
rythm1=[0.5,0.5,1,1,1,2,0.5,0.5,1,1,1,...
2,0.5,0.5,1,1,1,1,1,0.5,0.5,1,1,1,2,0.5,0.5,1,1,1,...
2,0.5,0.5,1,1,1,2,0.5,0.5,1,1,1,1,5];
rythm2=[1,1,2,2,2,7,0.5,0.5,...
1.5,1.5,1,3,0.5,0.5,1.5,1.5,1,3,0.5,0.5,...
1.5,1.5,1,1.5,1.5,0.5,0.5,1.5,1.5,1,3,0.5,0.5,...
1.5,1.55,1,3,0.5,0.5,1.5,1.5,1,3,0.5,0.5,1.5,1.5,1,...
1.5,5.5,0.5,0.5,2,2,4,8];
rythm=[rythm1,rythm2];
length1=length(tone1);
length2=length(tone2);
rythm_change_1=ones(1,length1)*3/4/2;
rythm_change_2=ones(1,length2)*1/4;
rythm_change=[rythm_change_1,rythm_change_2];
rythm=rythm.*rythm_change;
y=[];
len=length(tone);
%A调为1,B调为2,C调为3,D调为4,E调为5,F调为6,E调为7;
keynote_type=6;
%3为高音,2为中音,1为低音
Soundzone_change=[1,1,1,1,2,1,1,1,1,1,2,...
2,1,1,2,2,2,1,1,2,2,2,2,2,2,1,1,1,1,2,...
1,1,1,1,1,2,2,1,1,2,2,2,1,1,...
2,2,2,2,2,2,1,1,...
1,1,2,1,1,1,1,1,2,2,1,1,...
2,2,2,1,1,2,2,2,2,2,2,1,1,...
1,1,2,1,1,1,1,1,2,2,1,1,2,2,2,...
1,1,2,2,2,2,2,2];
%3为上升一个全音,2.5为上升一个半音,2为原音,1.5为下调一个半音,1为下调一个全音
up_down=2;
for i=1:1:len
y=[y,get_ware(tone(i),rythm(i),keynote_type,Soundzone_change(i),up_down)];
end
%plot(y)
sound(y,Fs) %按照给定的波,发出声音的函数
function y=get_ware(tone, rythm,keynote_type,Soundzone_change,up_down)
%tone为音节,rythm为节拍,keynote_type为当前基调默认为C调,keynote_change为改变基调,up_down为音节升降
%Sound zone_change为改变音区;
Fs=8192;
freqs=[440*2.^(3/12),440*2^(5/12),440*2^(7/12),440*2^(8/12),440*2^(10/12),440*2^(12/12),440*2^(14/12)];%C调中音
freqs=freqs*2.^((keynote_type-3)/12);
freqs=freqs*2.^((Soundzone_change-2)*12/12);
freqs=freqs*2.^((up_down-2)/12);
x=linspace(0,2*pi*rythm,floor(Fs*rythm));
y=(sin(freqs(tone)*x).*(1-(x/(2*pi*rythm))));
end
上述的音乐绘制还有一些值得研究的地方,比如说,如何发出同时发出多个音,实现更为复杂的乐曲的演奏,以及如何模拟出钢琴按键轻重不同导致的尾音长短的不同。还有就是在转换乐谱上边,如果有更加智能的方式生成就更加好了,因为基础的演奏的函数其实很简单。