音乐电子琴matlab设计报告材料.docx
- 文档编号:6941046
- 上传时间:2023-01-12
- 格式:DOCX
- 页数:19
- 大小:292.54KB
音乐电子琴matlab设计报告材料.docx
《音乐电子琴matlab设计报告材料.docx》由会员分享,可在线阅读,更多相关《音乐电子琴matlab设计报告材料.docx(19页珍藏版)》请在冰豆网上搜索。
音乐电子琴matlab设计报告材料
《MATLAB实践》
课程设计
学生:
谢冬云
学号:
110900735
专业班级:
09级信通(3)班
指导教师:
晓明
二○一二年六月二十日
一、设计目的
运用MATLAB实现MATLAB的GUI的信号处理程序设计。
做一个基于MATLABGUI的音乐键盘。
二、题目分析
2.1课程设计的基本要求
1)熟悉和掌握MATLAB程序设计方法。
2)掌握MATLABGUI程序设计。
3)学习音乐合成基本知识。
2.2课程设计的容
学习MATLABGUI程序设计,设计和实现一个音乐键盘仿真系统。
要求:
按照软件工程方法,根据需求进行程序的功能分析和界面设计,给出设计详细说明。
然后按照自己拟定的功能要求进行程序设计和调试。
1)设计音乐键盘GUI界面,实现单音键盘的发声。
2)能改变音的长短,即可以实现音的缩短,延长。
3)实现键盘的双音多频,即每个键盘对应低音频组的一个频率和高音频组的一个频率,实现按键的发出双音。
4)能改变音乐包络形式,实现音型的改变。
5)能够演奏一段音乐。
6)为界面添加背景音乐,实现wav格式的声音的播放,同时可以用本软件播放视频,但是matlab不支持画音同步的功能,但是可以看到没有声音的视频。
7)能够实现对键盘的输入按键进行存储,等到输入结束后统一播放刚才输入的键盘按键相对应的声音。
三、总体设计
3.1总体设计框架
总体设计框图如下图所示,其包括单音键盘发音模块,音效长短的选择模块,包络的选择模块,实现键盘代替鼠标输入模块,双音多频模块,演奏音乐模块,播放歌曲,视频模块包括对文件播放的暂停,停止和复位,多键盘输入对输入后统一播放模块和画图模块。
3.2功能模块
1)单音键盘发音模块
设计一个带参子函数实现键盘的发音功能,当实现需要实现音阶的播放时,只要调用这个子函数,并根据不同音阶、不同音调的频率改变子函数的参数即可。
2)音效长短的选择模块
制作一个buttongroup的组控件分别选择不同的控件实现不同的音效长短,音效的长短是通过改变播放一个音阶的时间长短来实现的。
3)包络的选择模块
制作一个buttongroup的组控件分别选择不同的控件实现不同的包络,在模块一的基础上,设置选中不同的控件分别对应不同的包络,x为不同包络(如正弦波、三角波、指数等)的表达形式,将x与模块一中实现单音键盘发音的函数相乘时便可实现不同形式的衰减,实现音型的改变。
4)实现键盘代替鼠标输入模块
根据计算机键盘上的不同按键对应不同的ASCII码的值,利用函数get()获取当前所按下的数字键对应的ASCII码的值,根据ASCII码的值判断对应是按下键盘的值。
并执行相应音阶的功能键。
5)双音多频模块
通过设置一个radiobutton来实现双音多频的功能,设置一个全局变量,当选中该控件时,全局变量的值改变,即在带参的子函数中增加它的频率分量。
就可以实现双音多频功能。
6)演奏音乐模块
通过设置一个pushbutton键来实现,按下该键时,可以选择事先自己编好的txt的文档,通过这个文档就可以播放音乐。
7)播放歌曲,视频模块
根据matlab提供的函数,视频时首先对文件的名字和路径进行提起,直接对文件的播放。
音乐的则是首先对文件的名字和路径进行提起,得到名字和路径后就对该文件进行采样,使其离散化。
最后实现对文件的播放。
8)多键盘输入对输入后统一播放模块
该功能实现先对键盘输入容进行存储,当输入完成后就可以按播放键对刚才的存储容进行播放,本功能通过radiobutton键实现的键盘输入的存储,当该建被选中时,则会不断的扫描键盘是否有键盘按下,并对按下键进行存储,直到该键没有被选中为止,同时设置一个pushbutton键对存储的信息进行播放,播放完成后自动清除存储的容,以便下一次存储。
9)画图模块
该模块的功能是根据播放每一个音符的数组画出每一个音符的波形,使我们对播放的音型可以一目了然,便于观察与分析。
四、具体设计
4.1单音键盘发音模块
(1)GUI界面的设计
根据要求,首先利用pushbutton键作为单音键盘的发音键。
1~7七个音阶对应高中低三种不同的音调共21个键,还有15个辅音,共36个按键。
如图所示,白色的按键代表音调键,前7个是低音的七个音阶,中间7个是中音的七个音阶,后面7个是高音的七个音阶,黑色的代表辅音。
(2)程序设计
查阅相关资料可知,发音频率对应的表达式为f=440*2^((s-49)/12),当所发音为低音时s的取值为31~37,发中音时s的取值为40~46,发高音时s的取值为49~55。
为了程序设计简化目的,设计一个名为gangqin(s)的子函数,程序如下:
functiongangqin(s)%演奏音符
globalr;
globaln;
globalff;
globalT;
globalp;
f=440*2^((s-49)/12);%各音阶的频率
n=0:
1/8000:
T;%各音阶的长短
ifp==1%选用包络
x=exp(-3*n);
elseifp==2
x=exp(-3*n).*sawtooth(2*pi*50*n);
elseifp==3
x=exp(-3*n).*sin(2*pi*n);
end
ifr==1%选用单频还是多频
ff=x.*sin(f*2*pi*n)+0.2*x.*sin(f*4*pi*n)+0.05*x.*sin(f*8*pi*n);
elseff=x.*sin(f*2*pi*n);
end
axes1_CreateFcn();%画图
soundsc(ff);%播放音符
有以上带参的子函数后则每个键盘下面的程序非常简单,然后在每个pushbutton键的callback函数中调用该子函数即可,如qangqin(45);
4.2音效长短的选择模块
(1)GUI界面的设计
制作一个buttongroup的组控件分别选择不同的控件实现不同的音效长短,该组控件包括三个radiobutton分别对应不同的音效长短(长,中,短)。
界面如下图所示:
(2)程序设计
音效长短的改变实质上是改变其音阶播放时间的长短,定义一个全局变量T通过改变T的值来改变音效的长度,gangqin的子函数如上面所示,该组控件的程序如下面所示:
globalT;
g=get(handles.yinxiao,'selectedobject');%获得音效的选中对象
gt=get(g,'tag');%把对象赋给gt
switchgt%确认选中的对象
case'duanyin'
T=0.3;
case'zhongyin'
T=1;
case'changyin'
T=2;
end
4.3包络的选择模块
(1)GUI界面的设计
制作一个buttongroup的组控件分别选择不同的控件实现不同的包络,该组控件包括三个radiobutton分别对应不同的包络。
如图所示,定义了指数波、三角波和正弦波三种不同形式的包络可供选择。
(2)程序设计
将组合键中的buttongroup键的Tag的值设置为“baol”,三个radiobutton键分别对应指数波、三角波、正弦波,相应的Tag设“zhishu”、”sanjiao”、”zhengxian”,def=get(de,'tag')获取三个RadioButton键中Tag的值,设置一个全局变量p,用switch函数实现,当case为'zhishu'时,p的值1;case为'sanjiao'时,p的值2;case为'zhengxian'时p的值为3。
程序如下所示:
globalT;
globaln;
globalp;
de=get(handles.baol,'selectedobject');%获得包络选中的对象
def=get(de,'tag');%把选中对象的tag赋给def
switchdef%确认选中的对象
case'zhishu'
p=1;
case'sanjiao'
p=2;
case'zhengxian'
p=3;
end
把p的值反应到gangqin(s)的子函数中,在子函数中根据不同的p的值选用不同的包络,即可实现不同的包络,所发出的音型便不一样。
gangqin(s)中包络部分程序如下:
ifp==1%选择包络
x=exp(-3*n);
elseifp==2
x=exp(-3*n).*sawtooth(2*pi*50*n);
elseifp==3
x=exp(-3*n).*sin(2*pi*n);
end
4.4实现键盘代替鼠标输入模块
(1)GUI界面的设计
用一个radiobutton键便可实现该功能,可以根据不同的键盘按键发出不同的音乐。
同时将该键的string改为“键盘”,表示这个键是实现键盘的功能。
如图所示:
(2)程序设计
根据计算机键盘上不同键对应的ASCII码的值不同,利用函数get()获取当前所按下的键对应的ASCII码的值,并执行相应播放音阶。
在radiobutton键的KeypressFcn函数中的程序如下:
functionjianpan_KeyPressFcn(hObject,eventdata,handles)
s=get(handles.jianpan,'value');%获得按下键的值
ifs==0%看radiobutton是否按下
elseifget(gcf,'CurrentCharacter')==48
gangqin(28);
elseifget(gcf,'CurrentCharacter')==49
gangqin(29);
elseifget(gcf,'CurrentCharacter')==50
gangqin(30);
elseifget(gcf,'CurrentCharacter')==51
gangqin(31);
elseifget(gcf,'CurrentCharacter')==52
gangqin(32);
elseifget(gcf,'CurrentCharacter')==53
gangqin(33);
elseifget(gcf,'CurrentCharacter')==54
gangqin(34);
elseifget(gcf,'CurrentCharacter')==55
gangqin(35);
elseifget(gcf,'CurrentCharacter')==56
gangqin(36);
elseifget(gcf,'CurrentCharacter')==57
gangqin(37);
elseifget(gcf,'CurrentCharacter')==65
gangqin(38);
elseifget(gcf,'CurrentCharacter')==66
gangqin(39);
elseifget(gcf,'CurrentCharacter')==67
gangqin(40);
elseifget(gcf,'CurrentCharacter')==68
gangqin(41);
elseifget(gcf,'CurrentCharacter')==69
gangqin(42);
elseifget(gcf,'CurrentCharacter')==70
gangqin(43);
elseifget(gcf,'CurrentCharacter')==71
gangqin(44);
elseifget(gcf,'CurrentCharacter')==72
gangqin(45);
elseifget(gcf,'CurrentCharacter')==73
gangqin(46);
elseifget(gcf,'CurrentCharacter')==74
gangqin(47);
elseifget(gcf,'CurrentCharacter')==75
gangqin(48);
elseifget(gcf,'CurrentCharacter')==76
gangqin(49);
elseifget(gcf,'CurrentCharacter')==77
gangqin(50);
elseifget(gcf,'CurrentCharacter')==78
gangqin(51);
elseifget(gcf,'CurrentCharacter')==79
gangqin(52);
elseifget(gcf,'CurrentCharacter')==80
gangqin(53);
elseifget(gcf,'CurrentCharacter')==81
gangqin(54);
elseifget(gcf,'CurrentCharacter')==82
gangqin(55);
elseifget(gcf,'CurrentCharacter')==83
gangqin(56);
elseifget(gcf,'CurrentCharacter')==84
gangqin(57);
elseifget(gcf,'CurrentCharacter')==85
gangqin(58);
elseifget(gcf,'CurrentCharacter')==86
gangqin(59);
elseifget(gcf,'CurrentCharacter')==87
gangqin(60);
elseifget(gcf,'CurrentCharacter')==88
gangqin(61);
elseifget(gcf,'CurrentCharacter')==89
gangqin(62);
elseifget(gcf,'CurrentCharacter')==90
gangqin(63);
end
4.5双音多频模块
(1)GUI界面的设计
通过设置一个radiobutton来实现双音多频的功能,当选中该按钮时,则增加它的频率分量。
使其含有丰富频率分量。
图形如下所示:
(2)程序设计
设置一个全局变量,当选中该控件时,全局变量的值改变,程序如下:
functionduopin_Callback(hObject,eventdata,handles)
globalr;
r=get(handles.duopin,'value');%多频的按钮是否选中
根据r的值不同,则在gangqin(s)函数中选用不同的播放数,在gangqin(s)的部分程序如下:
ifr==1%选单频还是多频
ff=x.*sin(f*2*pi*n)+0.2*x.*sin(f*4*pi*n)+0.05*x.*sin(f*8*pi*n);
elseff=x.*sin(f*2*pi*n);
End
4.6演奏音乐模块
(1)GUI界面的设计
通过设置一个pushbutton键来实现,如下所示:
按下该键时,界面会要求你选择文档,如下图:
可以选择事先自己编好的txt的文档,选中该文档,并按打开键就可以播放音乐。
(2)程序设计
播放音乐不仅需要确定每个音符,还要确定每个音符延长的时间,音符延长的时间是有n的取值大小所确定的。
因此这里就可以调用子函数的形式方便的实现。
子函数qinpu(a,b)程序如下:
functionqinpu(a,b)%播放不同延长音的音符a表示音阶的频率b表示延长音的长度
globalr;
globaln;
globalff;
f=440*2^((a-49)/12);
n=0:
1/8000:
b*0.5;%延长不同的长度
x=exp(-2*n);
ifr==1%选用单频还是多频播放
ff=x.*sin(f*2*pi*n)+0.2*x.*sin(f*4*pi*n)+0.05*x.*sin(f*8*pi*n);
elseff=x.*sin(f*2*pi*n);
end
axes1_CreateFcn();%画图
soundsc(ff);%播放音符
调用的函数写在callback下面,因为是要按下键即可跳出选择文件的窗口,同时选中文件时把文件的name,path给file变量,之后用importdata函数读出file中的信息赋给de,之后就按顺序播放文件的容。
functiondakai_Callback(hObject,eventdata,handles)
[name,path]=uigetfile('*.*','');%读取文件
file=sprintf('%s%s',path,name);
de=importdata(file);%读取文件的数据
fork=1:
length(de)
qinpu(de(k),de(k+length(de)));%按文件数据播放音符
end
txt文件的容如下:
Txt文件代表的意思是如‘441’,是表示频率为44,延长的长度为1.
4.7播放歌曲,视频模块
(1)GUI界面的设计
本功能的实现是通过pushbutton键来实现的。
界面如下图所示:
通过按下播放歌曲键或者播放视频键就可以选择播放的文件,界面如下:
按打开按钮就可以播放音乐或视频。
播放视频时界面:
(2)程序设计
视频时首先对文件的名字和路径进行提起,直接对文件的播放,用的是matlab自带的函数implay()。
程序如下:
functionshipin_Callback(hObject,eventdata,handles)%播放视频程序
[name,path]=uigetfile('*.*','');
file=[path,name];
implay(file);
音乐的则是首先对文件的名字和路径进行提起,得到名字和路径后就对该文件进行采样,使其离散化。
最后实现对文件的播放。
这里不仅可以对音乐的播放,还可以对音乐的暂停,复位和停止。
分别用到matlab自带的函数:
播放play(),暂停pause(),复位resume()和停止stop();程序分别如下:
functionchangge_Callback(hObject,eventdata,handles)
globalyinl;
[name,path]=uigetfile('*.*','');%打开文件
file=[path,name];
[y,fs,bits]=wavread(file);%对打开的wav文件进行采样
yinl=audioplayer(y,fs);%对采样的值进行读取
play(yinl);%播放wav格式文件
functionzanting_Callback(hObject,eventdata,handles)
globalyinl;
pause(yinl);%暂停
functionfuwei_Callback(hObject,eventdata,handles)
globalyinl;
resume(yinl);%复位
functiontingzhi_Callback(hObject,eventdata,handles)
globalyinl;
stop(yinl);%停止
4.8多键盘输入对输入后统一播放模块
(1)GUI界面的设计
本功能通过radiobutton键实现的键盘输入的存储,当该建被选中时,则会不断的扫描键盘是否有键盘按下,并对按下键进行存储,直到该键没有被选中为止,同时设置一个pushbutton键对存储的信息进行播放,播放完成后自动清除存储的容,以便下一次存储。
界面如下所示:
(2)程序设计
该功能实现先对键盘输入容进行存储,当输入完成后就可以按播放键对刚才的存储容进行播放,播放完成后对存储的容进行清空。
Radiobutton键的程序如下,由于是扫描键盘,则子函数应该写在keypressfcn函数下,
functionjianc_KeyPressFcn(hObject,eventdata,handles)
globaly;
globalb;
w=get(handles.jianc,'value');%获取按键是否按下按下为1没有按下为0
d=0;
ifw==1
j=get(gcf,'CurrentCharacter');%获得键盘按下键所对应的ASCII的值
d=d+1;
y(d)=j;%把获得的值赋给y
y=[y,y(d)];%把y的值整合成数组
end
以上程序实现对键盘的输入容进行存储,并把存储的值整合到数组y,pushbutton键是对上述存储的信息进行读取,识别并播放,程序如下:
functionbf_Callback(hObject,eventdata,handles)
globaly;
globalb;
b=0;
fork=2:
length(y)
ify(k)<58%比较大小小于58则按下的是0~9否则是A~Z
gangqin(y(k)-20);%播放按下键的音符
else
gangqin(y(k)-27);
end
end
y=[];%清空数组y
4.9画图模块
(1)GUI界面的设计
通过axse控件实现绘图,绘出播放每个音阶的波形,并把画出的波形显示到axse上,界面如下所示:
(2)程序设计
该模块的功能是根据播放每一个音符的数组画出每一个音符的波形,并把其显示在界面上,程序如下:
functionaxes1_CreateFcn(hObject,eventdata,handles)
globaln;
globalff;
holdoff;%清除图像
plot(n,ff);%画图
axis([0,1,-1,1]);%定义坐标
五、结果分析
整个制作和调试过程都是按模块进行的,对每一个模块功能的实现的情况下才对下一个功能进行制作。
刚开始做模块一时,由于没有想到后面的一些功能所以就没有写子函数,是在每一个按键下都写了一个声音播放的程序,这样做不仅量大也很不方便。
因此后面改成了子函数的形式,这样的话程序不仅简练也很好调用,非常方便。
在调试过程中先将函数gangqin(s)中的全局变量p的不同数字代表不同的波形表达式,鼠标点击包络组控件的不同按钮,选择不同的包络,听起来的效果也相差较大,当包络为指数形式时较符合平时听音乐的习惯。
还有一个是gangqin(s)中的全局变量T,不同的值表示不同的音效长短。
播放的时间是不一样的,因此听起来会有不同的感觉。
调试过程中应根据相关资料和自己的感觉不断改变这两个值的数字,最终选择一个听起来较为合适的取值。
上述完成后就需要做键盘代替鼠标按键的功能,首先需要了解按下键盘电脑获得的是按键的ASCII值。
所以我们必须把按键的ASCII的值对应到播放不同音
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 音乐 电子琴 matlab 设计 报告 材料
![提示](https://static.bdocx.com/images/bang_tan.gif)