收藏 分销(赏)

基于MATLAB的音乐电子琴制作.doc

上传人:a199****6536 文档编号:3929365 上传时间:2024-07-23 格式:DOC 页数:10 大小:56.54KB
下载 相关 举报
基于MATLAB的音乐电子琴制作.doc_第1页
第1页 / 共10页
基于MATLAB的音乐电子琴制作.doc_第2页
第2页 / 共10页
基于MATLAB的音乐电子琴制作.doc_第3页
第3页 / 共10页
基于MATLAB的音乐电子琴制作.doc_第4页
第4页 / 共10页
基于MATLAB的音乐电子琴制作.doc_第5页
第5页 / 共10页
点击查看更多>>
资源描述

1、姓名:吴月月 班级:2013级电子信息工程1班 学号:1308421001基于MATLAB的音乐电子琴制作简述:电子琴的每个音阶均对应一个特定频率的信号,通过调用数字信号发生器产生一系列指定的频率的声音,从而达到虚拟的电子琴的功能.本次设计是基于MATLAB GUI程序实现的一个音乐键盘仿真系统.1 功能介绍总体设计框图如下图所示,其包括单音键盘发音模块,音效长短的选择模块,包络的选择模块,实现键盘代替鼠标输入模块,双音多频模块,演奏音乐模块,播放歌曲,视频模块包括对文件播放的暂停,停止和复位,多键盘输入对输入后统一播放模块和画图模块.Matlab的数据采集工具箱(DAT)提供了一系列的函数和

2、命令来实现实时模拟信号的输出, 通过调用这些函数和命令可以直接控制声卡输出虚拟信号.只需要一台带有普通多媒体声卡并安装了Matlab软件的计算机就可以满足要求实现虚拟信号的输出, 系统结构简单方便.交互界面如图1所示:图1 程序的交互界面1。1功能模块1)单音键盘发音模块设计一个带参子函数实现键盘的发音功能,当实现需要实现音阶的播放时,只要调用这个子函数,并根据不同音阶、不同音调的频率改变子函数的参数即可。2) 音效长短的选择模块制作一个button group的组控件分别选择不同的控件实现不同的音效长短,音效的长短是通过改变播放一个音阶的时间长短来实现的。3)包络的选择模块制作一个butto

3、n group的组控件分别选择不同的控件实现不同的包络,在模块一的基础上,设置选中不同的控件分别对应不同的包络,x为不同包络(如正弦波、三角波、指数等)的表达形式,将x与模块一中实现单音键盘发音的函数相乘时便可实现不同形式的衰减,实现音型的改变。4)实现键盘代替鼠标输入模块根据计算机键盘上的不同按键对应不同的ASCII码的值,利用函数get()获取当前所按下的数字键对应的ASCII码的值,根据 ASCII码的值判断对应是按下键盘的值。并执行相应音阶的功能键。5)双音多频模块通过设置一个radio button 来实现双音多频的功能,设置一个全局变量,当选中该控件时,全局变量的值改变,即在带参的

4、子函数中增加它的频率分量。就可以实现双音多频功能.6)演奏音乐模块通过设置一个push button键来实现,按下该键时,可以选择事先自己编好的txt的文档,通过这个文档就可以播放音乐。7)播放歌曲,视频模块根据matlab提供的函数,视频时首先对文件的名字和路径进行提起,直接对文件的播放.音乐的则是首先对文件的名字和路径进行提起,得到名字和路径后就对该文件进行采样,使其离散化。最后实现对文件的播放.8)多键盘输入对输入后统一播放模块该功能实现先对键盘输入内容进行存储,当输入完成后就可以按播放键对刚才的存储内容进行播放,本功能通过radio button键实现的键盘输入的存储,当该建被选中时,

5、则会不断的扫描键盘是否有键盘按下,并对按下键进行存储,直到该键没有被选中为止,同时设置一个push button键对存储的信息进行播放,播放完成后自动清除存储的内容,以便下一次存储。9)画图模块该模块的功能是根据播放每一个音符的数组画出每一个音符的波形,使我们对播放的音型可以一目了然,便于观察与分析.2 功能实现程序由两个部分组成:MATLAB代码(。m文件)和GUI图形(。fig)。备注:软件版本:MATLAB R2011b2.1单音键盘发音模块根据要求,首先利用push button键作为单音键盘的发音键.17七个音阶对应高中低三种不同的音调共21个键,还有15个辅音,共36个按键。如图2

6、所示,白色的按键代表音调键,前7个是低音的七个音阶,中间7个是中音的七个音阶,后面7个是高音的七个音阶,黑色的代表辅音。查阅相关资料可知,发音频率对应的表达式为f=4402(s49)/12),当所发音为低音时s的取值为3137,发中音时s的取值为4046,发高音时s的取值为4955。为了程序设计简化目的,设计一个名为gangqin(s)的子函数.有以上带参的子函数后则每个键盘下面的程序非常简单,然后在每个push button键的callback函数中调用该子函数即可,如gangqin(45);图2 单音键盘发音模块具体代码参见:function gangqin(s)2。1.1音效长短的选择模

7、块制作一个button group的组控件分别选择不同的控件实现不同的音效长短,该组控件包括三个radio button分别对应不同的音效长短(长,中,短)。音效长短的改变实质上是改变其音阶播放时间的长短,定义一个全局变量T通过改变T的值来改变音效的长度,gangqin的子函数如上面所示.界面如图3所示:图3 音效长短的选择模块具体代码参见:Function yinxiao_Callback (hObject, eventdata, handles)2。2包络的选择模块制作一个button group的组控件分别选择不同的控件实现不同的包络,该组控件包括三个radio button分别对应不同

8、的包络。如图4所示,定义了方波、三角波和正弦波三种不同形式的包络可供选择.图4 包络的选择模块将组合键中的button group键的Tag的值设置为“baol”,三个radio button键分别对应指数波、三角波、正弦波,相应的Tag设“zhishu”、 sanjiao”、 zhengxian”, def=get(de,tag)获取三个Radio Button键中Tag的值,设置一个全局变量p,用switch函数实现,当case为 zhishu 时,p的值1; case 为 sanjiao 时,p的值2; case 为 zhengxian 时p的值为3。把p的值反应到gangqin(s)的

9、子函数中,在子函数中根据不同的p的值选用不同的包络,即可实现不同的包络,所发出的音型便不一样。由于电子琴的实验结果是声音,难以用文字表达,在下面仅用几张图片展示一下结果.图5 正弦波包络图6 方波包络图7 三角波具体代码参见:Function baoluo_Callback (hObject, eventdata, handles)2.3实现键盘代替鼠标输入模块用一个radio button键便可实现该功能,可以根据不同的键盘按键发出不同的音乐。同时将该键的string改为“键盘”,表示这个键是实现键盘的功能.如图8所示:图8 键盘代替鼠标输入根据计算机键盘上不同键对应的ASCII码的值不同,

10、利用函数get()获取当前所按下的键对应的ASCII码的值,并执行相应播放音阶。具体代码参见:function jianpan_KeyPressFcn(hObject, eventdata, handles)2。4双音多频模块通过设置一个radio button 来实现双音多频的功能,当选中该按钮时,则增加它的频率分量。使其含有丰富频率分量。如图9所示:图9 双音多频模块具体代码参见:function duopin_Callback(hObject, eventdata, handles)2.5演奏音乐模块通过设置一个push button键来实现,如图10所示:图10 播放谱曲按下该键时,界

11、面会要求你选择文档,可以选择事先自己编好的txt的文档,选中该文档,并按打开键就可以播放音乐。txt文件的内容如图11所示:图11 乐谱内容Txt文件代表的意思是如44 1,是表示频率为44,延长的长度为1.播放音乐不仅需要确定每个音符,还要确定每个音符延长的时间,音符延长的时间是有n的取值大小所确定的。因此这里就可以调用子函数的形式方便的实现。具体代码参见:function qinpu(a,b)function dakai_Callback(hObject, eventdata, handles)2。6播放歌曲,视频模块本功能的实现是通过push button键来实现的。界面如图12所示:图

12、12 播放歌曲视频模块通过按下播放歌曲键或者播放视频键就可以选择播放的文件,界面如图13所示:按打开按钮就可以播放音乐或视频。图13 播放视频视频时首先对文件的名字和路径进行提起,直接对文件的播放,用的是matlab自带的函数implay()。音乐的则是首先对文件的名字和路径进行提起,得到名字和路径后就对该文件进行采样,使其离散化。最后实现对文件的播放.这里不仅可以对音乐的播放,还可以对音乐的暂停,复位和停止。分别用到matlab自带的函数:播放play(),暂停pause(),复位resume()和停止stop()。具体代码参见:function shipin_Callback(hObjec

13、t, eventdata, handles)function changge_Callback(hObject, eventdata, handles)2。7多键盘输入后统一播放模块本功能通过radio button键实现的键盘输入的存储,当该建被选中时,则会不断的扫描键盘是否有键盘按下,并对按下键进行存储,直到该键没有被选中为止,同时设置一个push button键对存储的信息进行播放,播放完成后自动清除存储的内容,以便下一次存储。界面如图14所示:图14 多键盘输入后播放该功能实现先对键盘输入内容进行存储,当输入完成后就可以按播放键对刚才的存储内容进行播放,播放完成后对存储的内容进行清空。

14、实现对键盘的输入内容进行存储,并把存储的值整合到数组y内,push button键是对上述存储的信息进行读取,识别并播放。具体代码参见:function jianc_KeyPressFcn(hObject, eventdata, handles)function bf_Callback(hObject, eventdata, handles)2。8画图模块通过axse控件实现绘图,绘出播放每个音阶的波形,并把画出的波形显示到axse上,界面如图15所示:图15 音阶的波形该模块的功能是根据播放每一个音符的数组画出每一个音符的波形,并把其显示在界面上。具体代码参见:function axes1_

15、CreateFcn(hObject, eventdata, handles)3 程序总结本程序实现简单的音频处理功能及便捷的图形化交互界面。具有以下特点与缺陷:1、图形化用户交互界面简洁明了。右侧放置音频视频播放的各选项控件,且从上到下的排布体现操作步骤;上侧显示音频文件的数据波形。提示信息丰富,方便操作。2、程序可扩展性好,方便功能扩展。未尽功能:(1)没有调节音量大小的按钮,可以优化。(2)声音播放时,实时的显示播放进度。(3)更为实际的音频处理功能待加强。4 课程总结整个制作和调试过程都是按模块进行的,对每一个模块功能的实现的情况下才对下一个功能进行制作。刚开始做模块一时,由于没有想到后

16、面的一些功能所以就没有写子函数,是在每一个按键下都写了一个声音播放的程序,这样做不仅量大也很不方便.因此后面改成了子函数的形式,这样的话程序不仅简练也很好调用,非常方便.在调试过程中先将函数gangqin(s)中的全局变量p的不同数字代表不同的波形表达式,鼠标点击包络组控件的不同按钮,选择不同的包络,听起来的效果也相差较大,当包络为指数形式时较符合平时听音乐的习惯。还有一个是gangqin(s)中的全局变量T,不同的值表示不同的音效长短。播放的时间是不一样的,因此听起来会有不同的感觉。调试过程中应根据相关资料和自己的感觉不断改变这两个值的数字,最终选择一个听起来较为合适的取值.上述完成后就需要

17、做键盘代替鼠标按键的功能,首先需要了解按下键盘电脑获得的是按键的ASCII值。所以我们必须把按键的ASCII的值对应到播放不同音符的频率上去,这样才能灵活的控制每一个音符,每个音符要与键盘的按键形成一一对应关系,不然的话程序很容易出错。程序完成后,需要对程序进行调试,使得每一个键盘的按钮按下对应的音符会播放出来。接下来制作的是键盘的存储功能,即实现对键盘的多输入,输入过程中音符是不会响的,当输入结束后可以控制对刚才输入的按键对应的音符进行播放声音。刚开始是一直对数字的存储个数会多很多,后面才知道但你按下键时程序已经运行了好多遍了,每次按键是当然就会存储多个相同的值。改进后就一直只能对最后一次按

18、键进行存储,前面的被当前的值覆盖,后面设置了一个存储数据的数组进行存储,使得功能才能实现。本次课程设计,我花了大量的时间来做这些功能,但是做完后感觉功能又特别简单,而且做的大部分时间都是做一些无用的工作,程序一直不够简单,经常用一条很长的程序来实现一个简单的功能,做完过后发现可以用简单的程序就可以实现,整个制作过程中大部分的时间都花在这样的工作上,工作效率很低.同时感觉到自己对matlab的编程了解太少,很多基本功能多不了解.完成实践后我深深的体会到了MATLAB功能的强大,它不但可以实现对声音信号的处理,对图像的处理,同时还可以对视频,wav格式歌曲的播放以及还有很多我现在还不知道的很多强大

19、的功能。在实验过程中,遇到了很多问题。首先是资料的缺乏,没能找到老师推荐的信号与系统MATLAB综合实验,所以大部分的参考资料只能上网查找没有什么权威性.还有自己对matlab的了解本来就很浅,很多知识都不懂,经常需要问老师,同学或者上网查资料。在设计刚开始没有什么明确的思路导致经常改GUI界面,最后实在无法改了就重新设计,思路很不明确,希望在以后的学习和工作中能好好利用这次实践的经验,要先想好总体思路,不能到临时才改,这样的话,不仅工作量大,还耗时多。本次实践使我受益匪浅.附录(部分程序)function gangqin(s) 演奏音符global r;global n;global ff;

20、global T;global p;f=4402(s49)/12); 各音阶的频率n=0:1/8000:T; %各音阶的长短if p=1 选用包络 x=exp(3*n);elseif p=2 x=exp(-3n)。sawtooth(2*pi50*n);elseif p=3 x=exp(3*n).sin(2pi*n);endif r=1 选用单频还是多频 ff=x。sin(f2*pi*n)+0。2x。*sin(f4pi*n)+0。05x。sin(f8pi*n);else ff=x。*sin(f*2pin);endaxes1_CreateFcn(); %画图soundsc(ff); 播放音符Fun

21、ction yinxiao_Callback (hObject, eventdata, handles)global T;g=get(handles。yinxiao,selectedobject); 获得音效的选中对象gt=get(g,tag); 把对象赋给gtswitch gt %确认选中的对象 case duanyin T=0。3; case zhongyin T=1; case changyin T=2;EndFunction baoluo_Callback (hObject, eventdata, handles)global T;global n;global p;de=get(ha

22、ndles。baol,selectedobject); 获得包络选中的对象def=get(de,tag); %把选中对象的tag赋给defswitchdef case 正弦波 x=0:0.001:1; y1=A*sin(2f*pi*x+c); plot(x,y1); case 三角波 x=0:0.001:1; y2=Asawtooth(2pi*fx+c); plot(x,y2); case 方波 x=0:0。001:1; y3=Asquare(2fpix+c); plot(x,y3);endfunction jianpan_KeyPressFcn(hObject, eventdata, han

23、dles)s=get(handles。jianpan,value); 获得按下键的值if s=0 看radio button 是否按下elseif get(gcf,CurrentCharacter)=48 gangqin(28);elseif get(gcf,CurrentCharacter)=49 gangqin(29);elseif get(gcf,CurrentCharacter)=50 gangqin(30);elseif get(gcf,CurrentCharacter)=51 gangqin(31);elseif get(gcf,CurrentCharacter)=52 gangq

24、in(32);elseif get(gcf,CurrentCharacter)=53 gangqin(33);elseif get(gcf,CurrentCharacter)=54 gangqin(34);elseif get(gcf,CurrentCharacter)=55 gangqin(35);elseif get(gcf,CurrentCharacter)=56 gangqin(36);elseif get(gcf,CurrentCharacter)=57 gangqin(37);elseif get(gcf,CurrentCharacter)=65 gangqin(38);elsei

25、f get(gcf,CurrentCharacter)=66 gangqin(39);elseif get(gcf,CurrentCharacter)=67 gangqin(40);elseif get(gcf,CurrentCharacter)=68 gangqin(41);elseif get(gcf,CurrentCharacter)=69 gangqin(42);elseif get(gcf,CurrentCharacter)=70 gangqin(43);elseif get(gcf,CurrentCharacter)=71 gangqin(44);elseif get(gcf,Cu

26、rrentCharacter)=72 gangqin(45);elseif get(gcf,CurrentCharacter)=73 gangqin(46);elseif get(gcf,CurrentCharacter)=74 gangqin(47);elseif get(gcf,CurrentCharacter)=75 gangqin(48);elseif get(gcf,CurrentCharacter)=76 gangqin(49);elseif get(gcf,CurrentCharacter)=77 gangqin(50);elseif get(gcf,CurrentCharact

27、er)=78 gangqin(51);elseif get(gcf,CurrentCharacter)=79 gangqin(52);elseif get(gcf,CurrentCharacter)=80 gangqin(53);elseif get(gcf,CurrentCharacter)=81 gangqin(54);elseif get(gcf,CurrentCharacter)=82 gangqin(55);elseif get(gcf,CurrentCharacter)=83 gangqin(56);elseif get(gcf,CurrentCharacter)=84 gangq

28、in(57);elseif get(gcf,CurrentCharacter)=85 gangqin(58);elseif get(gcf,CurrentCharacter)=86 gangqin(59);elseif get(gcf,CurrentCharacter)=87 gangqin(60);elseif get(gcf,CurrentCharacter)=88 gangqin(61);elseif get(gcf,CurrentCharacter)=89 gangqin(62);elseif get(gcf,CurrentCharacter)=90 gangqin(63);end f

29、unction duopin_Callback(hObject, eventdata, handles)global r; r=get(handles。duopin,value); %多频的按钮是否选中if r=1 选单频还是多频 ff=x。*sin(f*2pin)+0。2x.sin(f4pin)+0。05*x。sin(f*8*pi*n);else ff=x。sin(f2*pin);Endfunction qinpu(a,b) 播放不同延长音的音符 a表示音阶的频率 b表示延长音的长度global r;global n;global ff;f=4402((a49)/12);n=0:1/8000

30、:b0.5; 延长不同的长度x=exp(-2n);if r=1 选用单频还是多频播放 ff=x.sin(f2*pi*n)+0。2*x。*sin(f4pin)+0.05x.sin(f8pin);else ff=x。sin(f2pin);endaxes1_CreateFcn(); 画图soundsc(ff); 播放音符function dakai_Callback(hObject, eventdata, handles)name,path=uigetfile(.*,); 读取文件file=sprintf(ss,path,name);de=importdata(file); 读取文件的数据for k

31、=1:length(de) qinpu(de(k),de(k+length(de); 按文件数据播放音符endfunction shipin_Callback(hObject, eventdata, handles)播放视频程序name,path=uigetfile(.,);file=path,name;implay(file);function changge_Callback(hObject, eventdata, handles)global yinl;name,path=uigetfile(.*,); 打开文件file=path,name;y,fs,bits=wavread(file)

32、; %对打开的wav文件进行采样yinl = audioplayer(y, fs); %对采样的值进行读取play(yinl); %播放wav格式文件function zanting_Callback(hObject, eventdata, handles)global yinl;pause(yinl); %暂停function fuwei_Callback(hObject, eventdata, handles)global yinl;resume(yinl); %复位function tingzhi_Callback(hObject, eventdata, handles)global y

33、inl;stop(yinl); 停止function jianc_KeyPressFcn(hObject, eventdata, handles)global y;global b;w=get(handles.jianc,value); 获取按键是否按下按下为1 没有按下为0d=0;if w=1 j=get(gcf,CurrentCharacter); 获得键盘按下键所对应的ASCII值 d=d+1; y(d)=j; 把获得的值赋给y y=y,y(d); 把y的值整合成数组endfunction bf_Callback(hObject, eventdata, handles)global y;global b;b=0;for k=2:length(y) if y(k)58 比较大小小于58则按下的是09否则是AZ gangqin(y(k)20); %播放按下键的音符 else gangqin(y(k)27); endendy=; %清空数组yfunction axes1_CreateFcn(hObject, eventdata, handles)global n;global ff;hold off; %清除图像plot(n,ff); 画图axis(0,1,-1,1); %定义坐标 10 / 10

展开阅读全文
部分上传会员的收益排行 01、路***(¥15400+),02、曲****(¥15300+),
03、wei****016(¥13200+),04、大***流(¥12600+),
05、Fis****915(¥4200+),06、h****i(¥4100+),
07、Q**(¥3400+),08、自******点(¥2400+),
09、h*****x(¥1400+),10、c****e(¥1100+),
11、be*****ha(¥800+),12、13********8(¥800+)。
相似文档                                   自信AI助手自信AI助手
搜索标签

当前位置:首页 > 学术论文 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服