matlab音乐合成报告.docx
- 文档编号:25979462
- 上传时间:2023-06-16
- 格式:DOCX
- 页数:26
- 大小:454.08KB
matlab音乐合成报告.docx
《matlab音乐合成报告.docx》由会员分享,可在线阅读,更多相关《matlab音乐合成报告.docx(26页珍藏版)》请在冰豆网上搜索。
matlab音乐合成报告
MATLAB音乐合成综合实验
学院:
班级:
***********************
同做者:
二0一六年十二月
摘要
本实验共有三部分:
1.简单的音乐合成;2.用傅里叶变换分析音乐;3.基于傅里叶级数的音乐合成。
一步一步分析了用MATLAB进行音乐合成的过程。
通过本实验达到加深对傅里叶级数和傅里叶分析的理解,熟悉对MATLAB基本使用的目标。
该实验采用MATLAB软件仿真来实现。
首先,通过编程对一段真实的音乐进行分析、处理,求得这段音乐的基频、谐波分量、等数据;然后,通过对乐理的研究,根据分析中求得的数据编写程序,进行基于傅里叶分析的音乐合成设计,并设计了图形用户界面。
1.绪论
1.1引言..........................................................3
1.2实验要求......................................................3
1.3实验原理......................................................3
2.简单的合成音乐
2.1乐理知识介绍..................................................4
2.2利用MATLAB实现音乐合成器,生成WAV文件.......................5
2.3除噪音,加包络................................................5
2.4音乐升高和降八度..............................................9
2.5加入谐波......................................................9
3.用傅里叶变换分析音乐
3.1载入fmt.wav并播放............................................11
3.2处理realware.................................................11
3.3分析wave2proc的基波和谐波....................................13
3.4自动分析fmt.wav的音调和节拍..................................16
4.基于傅里叶级数的音乐合成
4.1重新加谐波...................................................17
4.2通过音调信息弹奏《送别》.....................................19
5.制作GUI界面......................................................20
6.实验难点及问题...................................................21
7.实验收获.........................................................22
1.绪论
1.1引言
信号与系统的概念及分析方法广泛应用于通信、自动控制、航空航天、电子信息、地震学、生物工程等领域,因此“信号与系统”是一门电子信息学科相关专业的主干技术课程。
MATLAB是国际上公认的优秀的科技应用软件,随着版本的不断升级,内容也在不断扩充。
基于MATLAB的音乐分析与合成实验是针对“信号与系统”课程的重点和难点之一的傅里叶变换和傅里叶级数等内容而设计的。
由于该实验是真实音乐的实际应用,可以增进对傅里叶级数和傅里叶变换的理解,加深对信号分析工程应用的理解,提高在信号分析领域的应用能力。
1.2实验要求
1、3-5人一组,选择不同乐曲,利用MATLAB实现音乐合成器,生成WAV文件;
2、给乐音加包络消噪;
3、实现音乐的升八度和降八度;
4、在音乐中添加谐波;
5、用傅里叶级数分析音乐的基频、音调和节拍;
6、模仿一些常用乐器(如钢琴、吉他等)实现音乐合成;
7、设计GUI界面;
8、提交设计报告。
1.3实验原理
傅里叶变换建立了信号频谱的概念。
所谓傅里叶分析即分析信号的频谱(频率构成)、频带宽度等。
要想合成出一段音乐,就要了解该段音乐的基波频率、谐波构成等。
因此,必须采用傅里叶变换这一工具。
对于连续时间信号f(t),其傅里叶变换为:
由于其变换两边的函数f(t)和F(w)都是连续函数,不适合于计算机处理。
MATLAB语言提供了符号函数FOURIER来实现傅里叶变换,但该函数需要信号的解析表达式。
而工程应用中经常需要对抽样数据进行傅里叶分析,这种情况下往往无法得到信号的解析表达式,必须采用傅里叶变换的数值计算方法。
如果f(t)的主要取值区间为[t1,t2],定义T=t2-t1为区间长度。
在该区间内抽样N个点,抽样间隔为:
则有:
可以计算出任意频点的傅里叶变换值,假设F(ω)的主要取值区间位于[ω1,ω2],要计算其间均匀抽样的k个值,则有:
式中,
为频域抽样间隔。
2.简单的合成音乐
2.1乐理知识介绍
乐音的基本特征可以用基波频率、谐波频谱和包络波形3个方面来描述。
基波频率:
每个指定音调的唱名都对应固定的基波信号频率。
所谓唱名是指平日读乐谱唱出的1(do)、2(re)、3(mi)……,每个唱名并未固定基波频率。
当指定乐曲的音调时才知道此时唱名对应的频率值。
如C调“1”的基波频率为261.63HZ,F调“1”的基波频率为349.23HZ,F调“5”的基波频率为523.25HZ。
谐波频谱:
在音乐领域中称谐波为“泛音”,由谐波产生的作用称为音色变化。
当指定音调之后,仅指定了乐音信号的基波频率,谐波情况并未说明。
各种乐器,如钢琴或单簧管,都可以发出某一音调下的唱名,而人的听觉会明显感觉两者不同,这是由于谐波成分有所区别,频谱结构各异。
包络波形:
不同类型的乐器,包络形状也不相同。
在音乐合成实验中,为简化编程描述,通常把复杂的包络函数用少量直线近似。
于是,乐音波形的包络呈拆线。
有时为了保证在乐音的邻接处信号幅度为零,也可以用指数衰减的包络来表示,这也是最简单的办法。
2.2利用MATLAB实现音乐合成器,生成WAV文件
而在MATLAB中表示乐音所用的抽样频率为fs=10000Hz,也就是所1s钟内有1000个点,抽样点数的多少就可表示出每个乐音的持续时间的长短。
用一个行向量来存储这段音乐对应的抽样点,在用sound函数播放即可。
根据以上分析在MATLAB中编写如下程序:
Clearclc;
fs=10000;
f=[78465978410478801047784784523587659587523587784659784104798888010477847845876596984945238801047104798888098810478809881047880880784659523587];
time=fs*[10.50.5211210.50.510.50.5410.50.510.511210.50.510.5411210.50.520.50.50.50.50.50.50.50.54];
N=length(time);%这段音乐的总抽样点数
y=zeros(1,N);%用y向量来储存抽样点
n=1;
fornum=1:
N%利用循环产生抽样数据,num表示乐音编号
t=1/fs:
1/fs:
time(num)/fs;%产生第num个乐音的抽样点
y(n:
n+time(num)-1)=sin(2*pi*f(num)*t);
%抽样点对应的幅值
n=n+time(num);
end
sound(y,fs);
Wavwrite(y,’test4’);
在MATLAB中运行,但是可以听出效果不是很好。
2.3除噪音,加包络
下面通过加包络来消噪音。
最简单的包络为指数衰减。
最简单的指数衰减是对每个音乘以
因子,在实验中首先加的是
的衰减,这种衰减方法使用的是相同速度的衰减,但是发现噪音并没有完全消除,播放的音乐效果不是很好,感觉音乐起伏性不强。
于是采用不同速度的衰减,根据乐音持续时间的长短来确定衰减的快慢,乐音持续时间越长,衰减的越慢,持续时间越短,衰减的越快。
在1.1程序的基础上加上包络,编写如下程序:
加包络前:
clear;clc;
fs=10000;
f=[78465978410478801047784784523587659587523587784659784104798888010477847845876596984945238801047104798888098810478809881047880880784659523587];
time=fs*[10.50.5211210.50.510.50.5410.50.510.511210.50.510.5411210.50.520.50.50.50.50.50.50.50.54];
N=length(time);%这段音乐的总抽样点数
y=zeros(1,N);%用y向量来储存抽样点
n=1;
fornum=1:
N%利用循环产生抽样数据,num表示乐音编号
t=1/fs:
1/fs:
time(num)/fs;%产生第num个乐音的抽样点
y(n:
n+time(num)-1)=sin(2*pi*f(num)*t);
%抽样点对应的幅值
n=n+time(num);
end
sound(y,fs);
播放后可以听出噪音已经消除,同时因为不同时长的乐音衰减的快慢不一样,音乐听起来更有起伏感,下图是加包络后的east图像(未放大):
更科学的包络如下图所示,每个乐音都经过冲激、衰减、持续、消失四个阶段。
由上图可以看出这个包络是四段直线段构成的,因此只要确定了每段线段的端点,即可用端点数据写出直线方程,因为直线方程可以用通式写出(我用的是斜截式),因此这段包络可以用简单的循环来完成。
例如认为包络线上的数据如下图所示:
据此在MATLAB中编写如下程序:
clear;clc;
fs=10000;
f=[78465978410478801047784784523587659587523587784659784104798888010477847845876596984945238801047104798888098810478809881047880880784659523587];
time=fs*[10.50.5211210.50.510.50.5410.50.510.511210.50.510.5411210.50.520.50.50.50.50.50.50.50.54];
N=length(time);%这段音乐的总抽样点数
y=zeros(1,N);%用y向量来储存抽样点
n=1;
fornum=1:
N%利用循环产生抽样数据,num表示乐音编号
t=1/fs:
1/fs:
(time(num))/fs;%产生第num个乐音的抽样点
P=zeros(1,time(num));%P为存储包络数据的向量
L=(time(num))*[01/5333/1000333/5001];
%包络线端点对应的横坐标
T=[010.50.50];%包络线端点对应的纵坐标
s=1;
b=1:
1:
time(num);%产生包络线抽样点
fork=1:
4P(s:
L(k+1)-1)=(T(k+1)-T(k))/(L(k+1)-L(k))*(b(s:
L(k+1)-1)-L(k+1)*ones(1,L(k+1)-s))+T(k+1)*ones(1,L(k+1)-s);
%包络线直线方程通式
s=L(k+1);
end
y(n:
n+time(num)-1)=sin(2*pi*f(num)*t).*P(1:
time(num));
%给第num个乐音加上包络
n=n+time(num);
end
sound(y,fs);
plot(y);
运行得到的图像为:
下图是两个乐音交接处的局部放大图,可以看到前一个乐音一直衰减到0,后一个乐音从0开始增加,因此消除了噪音。
2.4音乐升高和降八度
升高一个八度即每个乐音的频率都提高一倍,变为原来的2被;降低一个八度即每个乐音的频率都减小一倍,变为原来的1/2。
因此最简单的办法是将存储乐音频率的向量每个元素改变为2或1/2倍。
即将程序中的f=[78465978410478801047784784523587659587523587784659784104798888010477847845876596984945238801047104798888098810478809881047880880784659523587]改为
f=[78465978410478801047784784523587659587523587784659784104798888010477847845876596984945238801047104798888098810478809881047880880784659523587]*2或
f=[78465978410478801047784784523587659587523587784659784104798888010477847845876596984945238801047104798888098810478809881047880880784659523587]/2.
将上述音乐上高半个音阶,即将频率变为原来的
(1.06)倍,可以利用resamlpe函数对原来的数据点进行重采样来实现,因为resample进行重新采样后会使每个乐音的持续时间改变,但是因为升高半个音阶,频率改变不大,所以每个音的持续时间是基本不变的。
2.5加入谐波
在1.2的音乐中加上二、三、四次谐波,基波幅度为1,高次谐波幅度分别为0.2、0.3、0.1。
只需将1.2程序改为:
clear;clc;
fs=10000;%抽样频率
f=[78465978410478801047784784523587659587523587784659784104798888010477847845876596984945238801047104798888098810478809881047880880784659523587];
time=fs*[10.50.5211210.50.510.50.5410.50.510.511210.50.510.5411210.50.520.50.50.50.50.50.50.50.54];
N=length(time);%这段音乐的总抽样点数
east=zeros(1,N);%用east向量来储存抽样点
n=1;
fornum=1:
N%利用循环产生抽样数据,num表示乐音编号
t=1/fs:
1/fs:
(time(num))/fs;%产生第num个乐音的抽样点
P=zeros(1,time(num));%P为存储包络数据的向量
L=(time(num))*[01/5333/1000333/5001];
%包络线端点对应的横坐标
T=[01.5110];%包络线端点对应的纵坐标
s=1;
b=1:
1:
time(num);%产生包络线抽样点
fork=1:
4P(s:
L(k+1)-1)=(T(k+1)-T(k))/(L(k+1)-L(k))*(b(s:
L(k+1)-1)-L(k+1)*ones(1,L(k+1)-s))+T(k+1)*ones(1,L(k+1)-s);
%包络线直线方程通式
s=L(k+1);
end
m=[10.30.2];%波形幅值矩阵
ss=zeros(1,length(t));
fori=1:
length(m)
ss=ss+m(i)*sin(2*i*pi*f(num)*t);%加谐波
end
east(n:
n+time(num)-1)=ss.*P(1:
time(num));
%给第num个乐音加上包络
n=n+time(num);
end
sound(2*east,8000);
plot(east);
即可,加颜色部分为修改的部分,加上谐波后音乐效果变得更好了。
运行得到的图像为:
3.用傅里叶变换分析音乐
3.1载入fmt.wav并播放
步骤:
载入fmt.wav并播放,利用wavread函数载入,用sound函数播放,程序如下:
wave=wavread('fmt.wav');
sound(wave)
这段音乐听起来比之前合成的音乐更加真实,因为里边含有丰富的谐波。
3.2载入文件Guitar.mat,处理原始数据realwave
步骤:
载入文件Guitar.mat,分析wave2proc是怎么由realwave得到的。
利用loadGuitar.mat;载入并用plot函数将realwave、wave2proc分别画出,得到以下两幅图
wave2proc
可以看到,wave2proc比realwave的周期性好得多,去掉了非线性谐波和噪声。
在时域做,从图上可以看到,realwave的数据大约是10个周期的共243个数据,因此可以用resample函数对realwave进行重新采样,将采样点提高到250个,那么重采样后每个周期有25个点,将这25个点对应相加求平均值后得到一个周期的值,因为进行了平均,减小了非线性谐波和噪音,然后将这25个数据延托成十个周期即250个点,在利用resample函数对得到的函数重新采样将采样点数恢复到243个。
根据以上分析,编写实现这个思路的程序如下:
clear;clc;
loadGuitar.mat;
wave=resample(realwave,250,243);%重采样,将点数变为250
w=zeros(1,25);
fori=1:
25
fork=0:
9
w(i)=w(i)+wave(25*k+i);%10个周期的对应点分别求和
end
end
w=w/10;%取平均值
wave2=repmat(w,1,10);%将1个周期的10个点延拓至250个点
wave2=resample(wave2,243,250);%重采样,将点数变回243
holdon,plot(wave2,'r'),holdoff;%将处理后的数据绘出,红色
holdon,plot(wave2proc);%将所给的数据绘出,蓝色
运行后的结果为:
由图可见,两组数据重合的很好,说明这种方法是很不错的方法。
3.3分析wave2proc的基波和谐波
为了分析wave2proc的基波和谐波,可以对wave2proc进行傅里叶变换,得到wave2proc的幅值谱,在频谱图上的第一个突出的波峰对应的频率即为wave2proc基频,利用helpfft学习了MATLAB中快速傅里叶变换函数fft的用法,编写了如下程序:
clear;clc;
loadGuitar.mat;
fs=8000;
NFFT=2^nextpow2(length(wave2proc));
Y=fft(wave2proc,NFFT)/length(wave2proc);
g=fs/2*linspace(0,1,NFFT/2+1);
plot(g,2*abs(Y(1:
NFFT/2+1)))
运行后得到的结果为
虽然从图上可以大概看出包络,但是非常不明显,假如提高频域的抽样频率,例如将抽样频率由NFFT=2^nextpow2(length(wave2proc))改为
NFFT=8^nextpow2(length(wave2proc))得到的结果如下;
由图可见虽然频域的抽样频率提高了很多,但是得到的包络依然不精确,这是因为wave2proc是周期函数,但是现在的wave2proc只有243个数据点,并不能非常明显的体现出其周期性,因此它的幅值谱的离散化程度不高,虽然提高了频域的抽样频率,但是wave2proc数据点的周期性并没有增加,所以要显示出离散化程度高的幅值谱,就要增加wave2proc的周期性,即让wave2proc在时域重复多次后在进行傅里叶变换。
利用repmat函数可以将wave2proc在时域重复。
将程序修改为:
clear;clc;
loadGuitar.mat;
fs=8000;
wave2proc=repmat(wave2proc,20,1);%将wave2proc重复20次
NFFT=2^nextpow2(length(wave2proc));
Y=fft(wave2proc,NFFT)/length(wave2proc);
g=fs/2*linspace(0,1,NFFT/2+1);
plot(g,2*abs(Y(1:
NFFT/2+1)))
由图读出wave2proc的基频为329.1Hz,幅值为0.05401,高次谐波幅值分别为:
谐波
2
3
4
5
6
7
8
9
幅值
0.07676
0.04841
0.0519
0
0.005709
0.01923
0.006741
0.007326
3.4自动分析fmt.wav的音调和节拍
思路分析:
将fmt.wav导入后得到的是一个向量,它包含了这段音乐的所有信息,要自动分析这段音乐的音调就需要将每个音调对应的点进行傅里叶变换得到其幅值谱,在幅值谱上找到第一个幅值较大的极大值点,该点对应的就是该音调的基频,得到基频后就可以得到高次谐波的幅值。
为了使对每个音调进行傅里叶变换后得到的幅值谱离
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- matlab 音乐 合成 报告