MATLAB和简单音乐

您所在的位置:网站首页 基于matlab的音乐信号合成与处理教学设计 MATLAB和简单音乐

MATLAB和简单音乐

2024-07-14 09:19| 来源: 网络整理| 查看: 265

4.1.3、Matlab源代码

根据以上分析在MATLAB中编写如下程序:

clear;clc;

fs=8000;

%抽样频率

f=[261.63 392 261.63 392 261.63 293.66 329.63 261.63 392 261.63 392 261.63 293.66 293.66 261.63 392 261.63 392 293.66 261.63 220 220 196 261.63 293.66 261.63 392 261.63 392 261.63 220 261.63 261.63  261.63  220  196  220 261.63   261.63  293.66  329.63 293.66  293.66  261.63  293.66  293.66  392 392 329.63 329.63 293.66 329.63];%各个音乐对应的频率

time=fs*[3/2,1/2,1/2,1/2,1/2,1/2,4,3/2,1/2,1/2,1/2,1/2,1/2,4,3/2,1/2,1/2,1/2,1/2,1/2,2,1/2,1/2,1/2,1/2,3/2,1/2,1/2,1/2,1/2,1/2,4,1/2,1,1/2,1,1,1,1/2,1/2,2,1/2,1,1/2,1,1/2,1/2,1/2,1/2,1/2,1/2,2];

%各个音乐对应的时间

N=length(time) %各个乐音的抽样点数

east=zeros(1,N)

n=1

for num=1:N  %利用循环产生抽样数据,num表示乐音编号

t=1/fs:1/fs:time(num)/fs; %产生第num个乐音的抽样点

east(n:n+time(num)-1)=sin(2*pi*f(num)*t);

%抽样点对应的幅值

n=n+time(num);

end

sound(east,8000);

%播放音乐

wavwrite(east,'荷塘月色')

%生成.wav文件

4.1.4运行结果分析

初步合成的音乐音调符合曲谱,能听出《荷塘月色》的旋律。但是每个乐音之间有“啪”的杂声,且无法分辨是何种乐器演奏。

 

4.2、用傅里叶变换分析音乐及波形4.2.1原理分析

离散的快速傅里叶变换,设N项的复数序列为x(n),由快速傅里叶变换知,X(m)的计算需要经过N次复数乘法和N-1次的复数加法,而一次复数乘法相当于四次实数乘法加上两次实数加法,一次复数加法相当于两次实数加法。把一次复数乘法和一次复数加法定义成一次“运算”,想要求出N项复数序列的X(m),就需要将近次运算。当N=1024点甚至更多的时候,需要=1048576次运算,

在 FFT中,利用DFT定义中的相乘系数的周期性和共轭对称性及可约性,把一个N项序列(设N=,k为正整数),分为两个N/2项的子序列,每个N/2点DFT变换需要(N/2)2次运算,再用N次运算把两个N/2点的 DFT变换组合成一个N点的DFT变换。

经过变换,总的运算次数就变成N+2*/2=N+/2。继续上面的例子,N=1024时,总的运算次数就变成了525312次,运算量仅仅是之前的50%。如果不断地将序列一分为二继续分下去,直到两个为一组运算单元,那么只需要Nlog次的运算,在1024点仅需要运算10240次,相当于之前的1%。点数越多,节约的计算量就越大。通过这种变换方式对信号做出处理。[6]

4.2.2、Matlab源代码

对HTYS进行傅里叶变换分析[1][2][3]其基波和谐波,得到HTYS的幅值谱,频谱图上的第一个突出的波峰对应的频率即为HTYS的基频,可编写了如下程序:

clear;clc;

[y,Fs]= wavread('HTYS.wav');

fs=3800;

NFFT = 2^nextpow2(length(y));

Y = fft(y,NFFT)/length(y);

g = fs/2*linspace(0,1,NFFT/2+1);

plot(g,2*abs(Y(1:NFFT/2+1)))

4.2.3、运行结果分析

运行后得到的结果如图5

图5 傅里叶变换后的波形图

 

观察上图我们可以知道其频率分布情况,显然不够分立,然而想要解决这种情况不是单靠提高采样率就能处理的。可见图6。

图6  增大采样频率后的波形图

4.3、给乐音加包络消噪并生成.wav 4.3.1、原理分析

你一定注意到4.1的乐曲中相邻乐音之间有“啪”的杂声,这是由于相位不连续产生了高频分量。这种噪声严重影响合成音乐的质量,丧失真实感,下面通过加包络来消噪音。

最简单的包络为指数衰减。最简单的指数衰减是对每个音乘以 “因子,在实验中首先加的是的衰减,这种衰减方法使用的是相同速度的衰减,但是发现噪音并没有完全消除,播放的音乐效果不是很好,感觉音乐起伏性不强。于是采用不同速度的衰减,根据乐音持续时间的长短来确定衰减的快慢,乐音持续时间越长,衰减的越慢,持续时间越短,衰减的越快。[5]

4.3.2、Matlab源代码

根据以上分析在MATLAB中编写如下程序:

clear;clc;

fs=3800; %抽样频率

f=[261.63 392 261.63 392 261.63 293.66 329.63 261.63 392 261.63 392 261.63 293.66 293.66 261.63 392 261.63 392 293.66 261.63 220 220 196 261.63 293.66 261.63 392 261.63 392 261.63 220 261.63 261.63  261.63  220  196  220 261.63   261.63  293.66  329.63 293.66  293.66  261.63  293.66  293.66  392 392 329.63 329.63 293.66 329.63];%各个音乐对应的频率

time=fs*[3/2,1/2,1/2,1/2,1/2,1/2,4,3/2,1/2,1/2,1/2,1/2,1/2,4,3/2,1/2,1/2,1/2,1/2,1/2,2,1/2,1/2,1/2,1/2,3/2,1/2,1/2,1/2,1/2,1/2,4,1/2,1,1/2,1,1,1,1/2,1/2,2,1/2,1,1/2,1,1/2,1/2,1/2,1/2,1/2,1/2,2];%各音乐对应时间

N=length(time); %这段音乐的总抽样点数

east=zeros(1,N); %用east向量来储存抽样点

n=1;

for num=1:N%利用循环产生抽样数据,num表示乐音编号

t=1/fs:1/fs:(time(num))/fs;

%产生第 num个乐音的抽样点

P=zeros(1,time(num));

%P为存储包络数据的向量

L=(time(num))*[0 1/5 333/1000 333/500 1];

%包络线端点对应的横坐标

T=[0 1.5 1 1 0];

%包络线端点对应的纵坐标

s=1;

b=1:1:time(num);

%产生包络线抽样点

              

   for k=1:4

P(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

HeTangYueSe(n:n+time(num)-1)=sin(2*pi*f(num)*t).*P(1:time(num));

%给第num个乐音加上包络

n=n+time(num);

sound(HeTangYueSe,8000);%播放音乐

plot(HeTangYueSe);%画波形

wavwrite(HeTangYueSe,'荷塘月色1') %生成.wav文件

 

end

4.3.3、运行结果分析

播放后可以听出噪音已经消除同时也可以在下图看到噪音被消除,像前一个乐音一直衰减到0,后一个乐音从0开始增加。此外不同时长的乐音衰减的快慢不一样,音乐听起来更有起伏感,如图5波形图。

 

 

                     图7 音乐信号的包络图像

4.3.4、包络分析[5]

由图7知每个乐音都经过冲激、衰减、持续、消失四个阶段。因此只要确定了每段线段的端点,即可用端点数据写出直线方程,根据包络直线方程通式写出数据并画出包络图,所以包络线上的数据如下图所示:

 

图8 包络图

 

 

4.4、音乐的升八度和降八度4.4.1、音乐高八度原理分析

升高一个八度即每个乐音的频率都提高一倍,变为原来的2倍;因此最简单的办法是将存储乐音频率的向量每个元素改变为2或1/2倍。将上述音乐上高半个音阶,即将频率变为原来的1.06倍,可以利用resamlpe函数对原来的数据点进行重采样来实现,因为resample函数1][2][3]进行重新采样后会使每个乐音的持续时间改变,但是因为升高半个音阶,频率改变不大,所以每个音的持续时间是基本不变的。

4.4.2、Matlab源代码

fs=3800;%抽样频率

f=[261.63 392 261.63 392 261.63 293.66 329.63 261.63 392 261.63 392 261.63 293.66 293.66 261.63 392 261.63 392 293.66 261.63 220 220 196 261.63 293.66 261.63 392 261.63 392 261.63 220 261.63 261.63  261.63  220  196  220 261.63   261.63  293.66  329.63 293.66  293.66  261.63  293.66  293.66  392 392 329.63 329.63 293.66 329.63]*2;%各个音乐对应的频率

time=fs*[3/2,1/2,1/2,1/2,1/2,1/2,4,3/2,1/2,1/2,1/2,1/2,1/2,4,3/2,1/2,1/2,1/2,1/2,1/2,2,1/2,1/2,1/2,1/2,3/2,1/2,1/2,1/2,1/2,1/2,4,1/2,1,1/2,1,1,1,1/2,1/2,2,1/2,1,1/2,1,1/2,1/2,1/2,1/2,1/2,1/2,2];

%各个乐音的抽样点数

N=length( time) ;%这段音乐的总抽样点数

east=zeros(1,N) ;%用east向量来储存抽样点

n=1;

for num=1:N%利用循环产生抽样数据, num表示乐音编号

t=1/fs:1/fs:time(num)/fs;%产生第num个乐音的抽样点

east(n:n+time(num)-1)=sin(2*pi*f(num)*t);

n=n+time(num);

end

east=resample(east,100,106);%resample函数重新采样

sound(east,3800)%播放音乐

plot(east)

 

4.4.3、运行结果分析

用sound函数播放后音乐听起来比较醇厚,具体波形如图7所示。

 

图9  音乐高八度波形

4.4.4、音乐低八度原理分析

降低一个八度即每个乐音的频率都减小一倍,变为原来的1/2。

4.4.5、Matlab源代码

fs=3800;%抽样频率

f=[261.63 392 261.63 392 261.63 293.66 329.63 261.63 392 261.63 392 261.63 293.66 293.66 261.63 392 261.63 392 293.66 261.63 220 220 196 261.63 293.66 261.63 392 261.63 392 261.63 220 261.63 261.63  261.63  220  196  220 261.63   261.63  293.66  329.63 293.66  293.66  261.63  293.66  293.66  392 392 329.63 329.63 293.66 329.63];%各个音乐对应的频率

time=fs*[3/2,1/2,1/2,1/2,1/2,1/2,4,3/2,1/2,1/2,1/2,1/2,1/2,4,3/2,1/2,1/2,1/2,1/2,1/2,2,1/2,1/2,1/2,1/2,3/2,1/2,1/2,1/2,1/2,1/2,4,1/2,1,1/2,1,1,1,1/2,1/2,2,1/2,1,1/2,1,1/2,1/2,1/2,1/2,1/2,1/2,2];

%各个乐音的抽样点数

N=length( time) ;%这段音乐的总抽样点数

east=zeros(1,N) ;%用east向量来储存抽样点

n=1;

for num=1:N%利用循环产生抽样数据, num表示乐音编号

f=f/2;%音乐低八度

t=1/fs:1/fs:time(num)/fs;%产生第num个乐音的抽样点

east(n:n+time(num)-1)=sin(2*pi*f(num)*t);

n=n+time(num);

end

sound(east,3800)%播放音乐

plot(east)

 

4.4.6、运行结果分析

用sound函数播放后音乐听起来像风琴声音,具体波形如图8所示。

 

图10  音乐低八度波形

 

4.5、给音乐加谐波并生成.wav文件4.5.1、原理分析 [4]

在音乐中加上二、三、四次谐波,基波幅度为1,高次谐波幅度分别为0.2、0.3、0.1。在4.2给乐音加包络去噪音的基础对代码进行修改加上谐波的代码即可。

4.5.2、Matlab源代码

clear;clc;

fs=3800; %抽样频率

f=[261.63 392 261.63 392 261.63 293.66 329.63 261.63 392 261.63 392 261.63 293.66 293.66 261.63 392 261.63 392 293.66 261.63 220 220 196 261.63 293.66 261.63 392 261.63 392 261.63 220 261.63 261.63  261.63  220  196  220 261.63   261.63  293.66  329.63 293.66  293.66  261.63  293.66  293.66  392 392 329.63 329.63 293.66 329.63];

%各个音乐对应的频率

time=fs*[3/2,1/2,1/2,1/2,1/2,1/2,4,3/2,1/2,1/2,1/2,1/2,1/2,4,3/2,1/2,1/2,1/2,1/2,1/2,2,1/2,1/2,1/2,1/2,3/2,1/2,1/2,1/2,1/2,1/2,4,1/2,1,1/2,1,1,1,1/2,1/2,2,1/2,1,1/2,1,1/2,1/2,1/2,1/2,1/2,1/2,2];

%各个音乐对应的时间

N=length(time); %这段音乐的总抽样点数

east=zeros(1,N); %用east向量来储存抽样点

n=1;

for num=1:N%利用循环产生抽样数据,num表示乐音编号

t=1/fs:1/fs:(time(num))/fs;

%产生第 num个乐音的抽样点

P=zeros(1,time(num));

%P为存储包络数据的向量

L=(time(num))*[0 1/5 333/1000 333/500 1];

%包络线端点对应的横坐标

T=[0 1.5 1 1 0];

%包络线端点对应的纵坐标

s=1;

b=1:1:time(num);

%产生包络线抽样点

for k=1:4

    P(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=[1 0.3 0.2];

%波形幅值矩阵

ss=zeros( 1,length(t));

for i=1:length(m)

ss=ss+m(i)*sin(2*i*pi*f(num)*t);

%加谐波

    end

hetangyuese(n:n+time(num)-1)=ss.*P(1:time(num));%给第num个乐音加上包络

hetangyuese(n:n+time(num)-1)=sin(2*pi*f(num)*t).*P( 1:time(num));

%给第num个乐音加上包络

n=n+time(num);

end

sound(hetangyuese,8000);

plot(hetangyuese);

wavwrite(hetangyuese,'荷塘月色2')

4.5.3、运行结果分析

加上谐波后音乐效果变得更好了。如图9波形图。

 

图11  加谐波的波形图

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3