matlab实现声音转换精品资料.doc

上传人:封****n 文档编号:96697044 上传时间:2024-03-10 格式:DOC 页数:36 大小:161.43KB
返回 下载 相关 举报
matlab实现声音转换精品资料.doc_第1页
第1页 / 共36页
matlab实现声音转换精品资料.doc_第2页
第2页 / 共36页
点击查看更多>>
资源描述

《matlab实现声音转换精品资料.doc》由会员分享,可在线阅读,更多相关《matlab实现声音转换精品资料.doc(36页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、数字信号处理声音转换课题报告1.课题研究目标利用matlab或其他编程软件对音频信号进行处理,要求实现声音的转换。如男声和女声的转换,老人声音与童声的转换。2课题使用工具Matlab3课题技术线路分析和处理音频信号,首先要对声音信号进行采集。Matlab的数据采集工具箱提供了一整套命令和函数,通过调用这些命令和函数,可直接控制声卡进行数据采集。Windows自带的录音机程序也可驱动声卡来采集语音信号,并能保存为wav格式文件,供matlab相关函数直接读取,写入和播放。本文以wav格式音频信号作为分析处理的输入数据,用matlab处理音频信号的基本流程是:先将wav格式音频信号经wavread

2、函数转换成matlab列数组变量;用matlab强大的运算能力进行数据分析和处理,即时域分析,频域分析,信号合成,识别和增强等;处理后的数据如是音频数据,则可用wavread转换成wav格式文件或用sound,wavplay等函数直接回放。4课题实现的原理本程序使用的方法是 通过改变基频然后时长规整的方式来达到目的。(1) 更改基频通过资料的查询和整理, 可以知道不同人的基频不同 统计如下:正常成年男声:0200Hz;正常成年女声:200450Hz;小孩声音的基频要比女声的高,老年人的基频要比男声的低。经过整理统计可知女声基频=男声基频*1.5。本程序使用的是通过抽样与插值的方式来达到基频的改

3、变。以女变男为例:用整数D对语音信号X(n)进行抽取Xd=X(Dn);然后将X(n)的抽样频率提高到I(整数)倍 ,即为对X(n)的插值。D/I=3/2;(2) 时长规整通过抽样插值来改变基频 也使播放速度,播放时间发生改变, 因此通过时长规整的方式来使播放速度 和时间恢复到原来。本程序使用的是用重叠叠加算法来达到时长规整。重叠叠加算法原理:它分为两个阶段分解和合成将原始信号以帧长N,帧间距sa进行分解,然后以帧间距ss进行合成。sa与ss的的比值决定了时长规整因子F=sa/ss。为保证重叠区域幅度不变,加了汉明窗。5Matlab的实现及程序流程分为编程和gui的设计(1) 编程y=resam

4、ple(x,i,d);%重采样来达到抽值和插值的目的然后就是时长规整在具体介绍算法之前,先简要地介绍一下几种参数:1) W:窗长度(Window Length)。它代表了接受处理的语音信号的最小长度。2) Sa:分析延时(Analysis shift)。它代表了依次截取并进行处理的语音段首地址之间的间隔。3) Ss:综合延时(Synthesis shift)。依次输出的语音段首地址之间的间隔。4) kmax:查找延时。这一延时是指分析窗口为了与输出信号的尾部相一致而必须发生的一段延时。5) Wov:后一段语音与前一段语音相叠加的长度。为了能使上面的参数更容易理解,用下面的图标是各参量之间的关系

5、。整个算法首先将语音段中的前W个数值取出来,直接存入到输出序列中。然后根据Sa的值取出下一段语音,也就是从第Sa个点开始取,一直取W个点。然后将这W个点中的前Wov个点与输出序列的最后Wov个点进行比较,比较它们之间的一致性。记录下比较的情况,然后整个分析窗口(也就是截取W个点的窗口)向后移动一个样值,再将新的序列中的前Wov个点与输出序列中的后Wov个点进行比较,同时记录下比较结果。这样依次做Kmax次,然后取出比较结果中最一致的那种情况。将这种情况下,所截取的语音序列的前Wov个点与输出序列的最后Wov个点按某种方式进行叠加,然后再将W个点的窗口中剩余的Ss个点存入到输出序列中去。至此完成

6、了一轮语音操作。下一轮语音段处理,与上面基本相同,只不过从输入序列中截取的语音段不是从原先的起点开始而是在原先的起点的基础上向后延时Sa个点。如果我们用表示第m段语音信号,用表示原始信号的序列。那么两者的关系可以用下面的等式表示:km是第m个分析窗口的移动量。km的值得变化范围是0至Kmax。对于每一个分析窗口,km的值取遍这些值,同时比较每次语音段的前Wov个点与输出序列中的最后Wov个点的一致性。取出其中一致性最好的那个语音段将其前Wov个点叠加到输出序列中去。设叠加时所用的窗用表示,输出序列用那么公式表明,已经在输出序列中的最后Wov个点通过与所选定的窗口中的前Wov个语音点以加权的方式

7、叠加。加权值与有关。叠加后将W个点中剩余的Ss(Ss=W-Wov)个点补充到输出序列中去。通过调整Sa的值和Ss的值(或者是Wov)的值就可以达到对语音信号进行时间长度上的变化。那么具体的每一段语音的km值究竟如何确定呢?要解决这一问题,关键在于解决一致性的判决标准。我们采用互相关系数来表示一致性的程度。那么对于第m轮处理,其中是所取的分析窗口的前Wov个点和输出序列的最后Wov个点之间的互相关性,它的定义是这样的:几点初步的讨论:1) 首先从每一次处理后,我们从输入语音段中取序列的起点向后推迟了Sa个点,而输出序列的长度也增大了Ss个点。所以可以认为每处理一次有Sa-Ss个点被丢弃(如果Sa

8、要大于Ss),如果我们处理的语音信号长度较长。可以很容易地证明,新旧序列的长度之比是:Ss / Sa。根据这一比例关系,我们就可以认为地控制输出序列的长度(当然,这种控制是十分粗略的,并且只是在语音信号较长时有效)。2)的选取应当使得输入与输出序列之间实现平滑的连接。实验表明,采用简单的斜坡函数也可以达到较好的语音效果(只要采样率足够大)。3) 对于km的求取是降低时间复杂度的重要一步。实际上,我们不需要每轮处理数据时都去计算一遍km,计算一遍km会花去不少时间。我们假定在任何一点,最多有两个窗会在这点上重叠。现在考虑第m个窗,从输出端的最后Wov个点可以看出,它其实就是输入序列中的某些点:其

9、中,。从上面几个等式可以看出:如果。那么,不需要计算km的值,只需要将km的值直接取为tm就可以了。而如果tm的值超出了上面的这个范围,就必须按照前面的计算方法进行计算。从前面的讨论中可以看出,要使得在每一点只有最多两个窗相互叠加,实际上是要求,输出序列的最后Wov个点在前一轮没有参与到叠加运算中。这就要求在参数选择上要满足Ss Wov。另外,为了减小对于km的计算次数,可以选择将Kmax选取得大一些,比如取为500,同时Sa与Ss要尽量接近。4) 对于采用互相关法求km的情况,作如下算法上的改动:首先,对于所有的k值,要比较它们对应得互相关之间的关系,只需要比较就可以了,这样就避免了开方这一

10、麻烦得运算。同时,由于对于所有的k值都是一样的,所以比较时不需要去考虑它。因此最终我们对于每一个k值只要比较。最后,对于的计算算可以采用递推的方法,即:(2) Gui设计参考一定量的资料 完成了比较简陋的界面频谱搬移后的界面6.程序清单function Y=voice1(x)%更改采样率使基频改变d=resample(x,3,2);%时长整合使语音文件恢复原来时长W=400;Wov=W/2;Kmax=W*2;Wsim=Wov;xdecim=8;kdecim=2;X=d;F=1.5;Ss =W-Wov;xpts = size(X,2);ypts = round(xpts / F);Y = zer

11、os(1, ypts);xfwin = (1:Wov)/(Wov+1);ovix = (1-Wov):0;newix = 1:(W-Wov);simix = (1:xdecim:Wsim) - Wsim;padX = zeros(1, Wsim), X, zeros(1,Kmax+W-Wov);Y(1:Wsim) = X(1:Wsim);xabs = 0;lastxpos = 0;km = 0;for ypos = Wsim:Ss:(ypts-W);xpos = F * ypos;kmpred = km + (xpos - lastxpos);lastxpos = xpos;if (kmpre

12、d a1,1ans =cellclassa1,2ans = 1 2 2a2,:ans =abcans = 9 5 6 b=a1,1b =cellclass元胞数组:元胞数组是MATLAB的一种特殊数据类型,可以将元胞数组看做一种无所不包的通用矩阵,或者叫做广义矩阵。组成元胞数组的元素可以是任何一种数据类型的常数或者常量,每一个元素也可以具有不同的尺寸和内存占用空间,每一个元素的内容也可以完全不同,所以元胞数组的元素叫做元胞(cell)。和一般的数值矩阵一样,元胞数组的内存空间也是动态分配的。(1)元胞数组的创建 a=matlab,20;ones(2,3),1:10a = matlab 20 2

13、x3 double 1x10 double b=matlab,20;ones(2,3),1:10b = matlab 20 2x3 double 1x10 double c=10c = 10c(1,2)=2c = 10 2c(2,2)=5c = 10 2 5isequal(a,b)ans = 1whosName Size Bytes Class Attributesa 2x2 388 cell ans 1x1 1 logical b 2x2 388 cell c 2x2 208 cell 用cell函数创建元胞数组,创建的数组为空元胞。cell函数创建空元胞数组的主要目的是为数组预先分配连续的

14、存储空间,节约内存占用,提高执行效率。 a=cell(1)a = b=cell(1,2)b = c=cell(3,3)c = d=cell(2,2,2)d(:,:,1) = d(:,:,2) = whosName Size Bytes Class Attributesa 1x1 4 cell ans 1x1 1 logical b 1x2 8 cell c 3x3 36 cell d 2x2x2 32 cell (2)元胞数组的数据获得从元胞数组中读取数据,可保存为一个标准的数组或一个新的单元数组,或取出数组进行计算。元胞数组中数据的访问,可通过元胞内容的下标进行,用元胞数组名加大括号。大括号

15、中数值表示元胞的下标。如a1,2表示元胞数组中第一行第二列的元胞。 a=20,matlab;ones(2,3),1:3a = 20 matlab 2x3 double 1x3 doublestr=a(1,2)str = matlabclass(str)ans =cellstr=a1,2str =matlabclass(str)ans =char()和有着本质的区别,大括号用于表示元胞的内容,小括号表示指定的元胞。a = 20 matlab 2x3 double 1x3 doublea2,1(2,2)ans = 0.9134a2,1(2,3)ans = 0.0975a1,2(2)ans =a使用

16、元胞的下标,可将一个元胞数组的子集赋值给另一个变量,创建新的元胞数组。 a=1,2,3;4,5,6;7,8,9a = 1 2 3 4 5 6 7 8 9 b=a(2:3,2:3)b = 5 6 8 9 c=a(1:3,2:3)c = 2 3 5 6 8 9本例使用元胞下标的方式创建了新的元胞数组b和c,通过结果看出b和c就是元胞数组a的一部分。(3)元胞数组的删除和重塑要删除单元数组中的行或列,可以用冒号表示单元数组中的行或列,然后对其赋一个空矩阵即可。a=20,matlab;ones(2,3),1:3a = 20 matlab 2x3 double 1x3 doublea(1,:)=a =

17、2x3 double 1x3 double a=20,matlab;ones(2,3),1:3;a1=a = matlab 2x3 double 1x3 doublea(1)=a = 2x3 double matlab 1x3 doublea(2)=a = 2x3 double 1x3 doublea(1,2)=? A null assignment can have only one non-colon index.a(1)=a = 1x3 double元宝数组和其他数组一样,也可以通过reshape函数改变形状,改变后的元胞数组与原元胞数组的元素个数相同,不能通过改变形状来添加或删除元胞数

18、组中的元素。 a=cell(4,4)a = size(a)ans = 4 4 b=reshape(a,2,8)b = size(b)ans = 2 8(5)元胞数组中的操作函数 cell:创建空的元胞数组cellfun:为元胞数组的每个元胞执行指定的函数celldisp:显示所有元胞的内容cellplot:利用图形方式显示元胞数组 cell2mat:将元胞数组转变成为普通的矩阵 mat2cell:将数值矩阵转变成为元胞数组 num2cell:将数值数组转变成为元胞数组 deal:将输入参数赋值给输出 cell2struct:将元胞数组转变成为结构 struct2cell:将结构转变为元胞数组i

19、scell:判断输入是否为元胞数组 a=20,matlab,3-7i;ones(2,3),1:3,0a = 20 matlab 3.0000 - 7.0000i 2x3 double 1x3 double 0 b=cellfun(isreal,a)b = 1 1 0 1 1 1 c=cellfun(length,a)c = 1 6 1 3 3 1 d=cellfun(isclass,a,double)d = 1 0 1 1 1 1(函数的应用)cellfun函数的主要功能是对元胞数组的元素(元胞)分别指定不同的函数,不过,能够在cellfun函数中使用的函数ushuliang是有限的。能在ce

20、llfun中使用的函数:isempty:若元胞元素为空,则返回逻辑真islogical:若元胞元素为逻辑类型,则返回逻辑真isreal:若元胞元素为实数,则返回逻辑真 length:元胞元素的长度ndims:元胞元素的维数prodofsize:元胞元素包含的元素个数(7)元胞数组的嵌套元胞数组的元胞中包含其他的元胞数,称为嵌套元胞数组,没有嵌套结构的元胞则称为页元胞。使用嵌套的大括号或cell函数,或直接用赋值表达式,都可以创建嵌套单元数组,另外还可以访问嵌套元胞数组的子数组、元胞或元胞的元素。 a=cell(1,2)a = a(1,2)=cell(2,2)a = 2x2 cella(1,1)

21、=magic(3);a1,2(1,1)=1 2 3;4 5 6;7 8 9;a1,2(2,1)=2-i;4+7i;a1,2(2,2)=cell(1,2);a1,22,2(2)=5;cellplot(a)(8)元胞数组与数值数组间的转化应用循环,可以将元胞数组转化为数值数组。2010-11-08 12:06:44zz: Matlab Cell功能最近完成模式分类的作业,需要大量使用matlab,期间发现了一个问题,是matlab代码的复用程度。在面向过程编程里,基本的复用单位是函数,程序的复杂度籍此下放到函数的接口上。设计好函数间的接口,基本上就成功了一半。在面向对象编程里,基本的复用单位是对象

22、,对象使得数据具有了一定程度的自维护。而在matlab里,我很长时间都没有找到方向,因为我搞不清楚复用的单位是什么。matlab中,基本的单位是矩阵,针对矩阵系统有一大堆的函数供你调用。但是,想自己写程序还是有一定的麻烦的。for循环语句在matlab里似乎是一个禁忌,所有老师都敦敦告诫,不要轻易使用for。而函数调用也是同样的低效,有兴趣的同学可以参见此文。那么我们应该基于什么模块进行复用呢?答案是Cell模式。 Cell是matlab的一个特色功能,将一段代码以%标记为cell以后,就可以重复执行了,相当于在命令行输入该代码块。以前,为了测试不同参数的结果,往往要用up arrow执行上一条指令。遇到需要多条指令的地方,就很容易出错。而算法又没有完善到可以封装成函数的地步,整天来回跑代码让人不堪其烦。通过cell模式,可以非常方便地在不同的代码块之间跳转,或重复执行一个代码块。对于我来说,matlab中的编程越来越趋向于bash编程,所用到的语言只是起到一个粘合剂的作用,负责把系统内置的高性能函数组合起来。这种对语句块的复用方式能够快速地调试出需要的功能,有点类似传统的goto,但是可以一直观察着执行的结果,事前无须编译,也不用考虑函数的接口问题。当算法稳定下来,就可以考虑用一个接口轻易地封装成函数了。同时也可以直接保存为mfile供以后使用。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 期刊短文 > 互联网

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁