matlabmatlabmatlabmatlab实验一
音乐合成综合实验
电子系无 71717171 2007011252200701125220070112522007011252 李乾
(6.2.26.2.26.2.26.2.2部分第二题由 realwaverealwaverealwaverealwave得到wave2procwave2procwave2procwave2proc 思路为参考资料得到,其它都为原创)
6.2.16.2.16.2.16.2.1
(1111)
思路:
1,定义出小字 a(220Hz)为基准,分别循环列出其 1/12 倍的各个音阶,以备
组合乐谱。
2,用矩形窗函数选取出各个需要音符,并将其相加,得到需要的音乐 x。
3,查
得所需音符,与对应小字 a的倍数为:
4,为编程方便,把第一小节分为 16份。
代码:
f=8000;
E=1;
t=[0:1/f:4-1/f];
for n=1:16
u{n}=(t>(n-1)/4&t
n-1.1&tn-0.8&tn-0.35&tn-1&t标准的四倍时间,所以基准音调降低了四倍,
播放速度比正常提高了 4倍。实际原采样率为 8000.)
在不改变播放速度的情况下,则将基准音调频率小字一组 a1提高到二倍。
代码:
a0=220*pi/2;
改为:
a0=220*pi;
用 resample 函数时,可以将
代码:
sound(x,32000);
改为:
y=resample(x,50,53);%大约为高一个音阶
sound(y,32000);
这样,采样率为原来的50/53,即提高了半个音阶。但是这样做会使播放时间发
生变化。而且根据数据可以看出:采样点减少,是一种有损数据的改变方式。
(4)
加入谐波后,代码如下:
代码:
f=8000;
E=1;
t=[0:1/f:16-1/f];
for n=1:16
u{n}=(t>n-1&t
n-1.1&tn-0.8&tn-0.35&tn-1&tn-1+0.35&tn-1+0.55&tn-1+0.75&t内容 ,求得最大值。
[C I]=max(R1)
C =
0.0120
I =
2070
由图可知,最大值点对应图中的二次谐波,幅度 0.012,频率为 I/pi=
658.9015.
由图大致看出,几波频率在0~4000间,所以
[C I]=max(R1(1:2000))
C =
0.0082
I =
1036
可知,基波幅度为0.0082,频率为I/pi= 329.7690。
查得,基波为e1.频率为329.63Hz。
二次谐波幅度为0.012,同基波的比值为1.4634.同理求得,三次,四次谐波
幅度分别为:0.0079,和0.0091,同基波的比值为0.9634和1.1098.
(4)
首先,将fmt.wav分开。
开始时选取了整个包络,发现由于太长,内存不够用,总是报错。
后来意识到,其实像上面的realwave波形一样,十个周期比较合适。于是截取
的基本都是各个音符的包含10个周期的波形。
同(2)中的一样进行整形,去掉噪声和非线性谐波,然后同(3)进行傅里叶
变换。
前7个波形:
0 5000
0
0.005
0.01
0.015
0.02
0 5000
0
0.5
1
1.5
2
x 10-3
0 5000
0
0.5
1
1.5
x 10 -3
0 5000
0
0.5
1
x 10-3
0 5000
0
0.5
1
1.5
2
x 10 -3
0 5000
0
2
4
6
8
x 10-4
0 5000
0
2
4
6
x 10 -3
第8到14个波形:
0 5000
0
0.5
1
1.5
x 10 -3
0 5000
0
0.5
1
1.5
2
x 10-3
0 5000
0
0.5
1
1.5
2
x 10 -3
0 5000
0
0.5
1
1.5
x 10-3
0 5000
0
0.5
1
1.5
2
x 10 -3
0 5000
0
1
2
3
4
x 10-3
0 5000
0
1
2
3
4
x 10 -4
第15到21个波形:
0 5000
0
2
4
6
x 10-4
0 5000
0
0.005
0.01
0.015
0 5000
0
0.5
1
1.5
2
x 10-3
0 5000
0
2
4
6
x 10 -3
0 5000
0
1
2
3
4
x 10-3
0 5000
0
2
4
6
x 10 -3
0 5000
0
2
4
6
8
x 10-4
最后七个波形:
0 5000
0
0.5
1
1.5
2
x 10 -3
0 5000
0
2
4
6
8
x 10-4
0 5000
0
0.5
1
1.5
x 10 -3
0 5000
0
2
4
6
x 10-3
0 5000
0
1
2
3
4
x 10 -3
0 5000
0
0.5
1
x 10-3
0 5000
0
1
2
3
4
x 10 -3
在很多音调中,基波的幅度值不是最大。
而且可以看出,基波与最大幅度值的比值差别不会很大,可以取一个范围,即:
低于最大幅度值10%的谐波可以忽略不计,这样,既可以排除一些杂的谐波分量,
也可以不漏掉重要的谐波分量。
对各段波形分别进行逐步的探测,每一步截取一小段作分析,取出该段的最大值,
记下频率值。
由于傅里叶变换后的波形不是标准的冲击函数,所以,可能将一个波峰分在两个
段内,这样就要在每段判断最大值后,再判断与前一个波峰的距离。
如果距离小于选定的距离(选定距离为T=2*pi*100),则可知这是同一个波峰,
所以取出波峰的最大值,以及坐标。
此处应注意,max函数取得的坐标值为相对位置,即离R波形起点的位置。由于
不清楚这一点,犯了很大的错误,一直解决不掉。
最后求得数据存入两个数组a和b中,并将a的谐波幅值转换成与基波的比值。基
波设为1.
代码:
读入各音符进行处理:
clear all,close all,clc;
%figure;
for n=21:28
f=['fmt' num2str(n)]
% subplot(2,4,n-21);
p_24_0(wavread(f));
end
进行整形,以及傅里叶变换部分:
function [none] = p_24_0(ans)
%wave=wavread('fmt2');
wave=ans;
%load('guitar');
%wave=wave2proc;
%plot(wave);
%sound(wave);
l=length(wave);
sample1=resample(wave,10,1);
sample2=zeros(1,l);
for m=1:10
sample2=sample2+(sample1((m-1)*l+1:m*l))';
end
sample1=[sample2,sample2,sample2,sample2,sample2,sample2,sample2,
sample2,sample2,sample2];
sample2=resample(sample1/10,1,10);
%figure;
%plot(sample2);
%title('sample2');
F=8000;
%l=length(wave2proc);
l1=5*l;
clear wave;
wave=sample2';
%wave=wave2proc;
[t omg FT IFT]=prefourier([0,(l1-1)/F],l1,[0,5000],5000);
%r=[wave;wave;wave;wave;wave;wave;wave;wave;wave;wave];
r=[wave;wave;wave;wave;wave];
R=FT*r;
R1=abs(R);
%plot(omg,R1);
%set(gca,'XGrid','on','YGrid','on');
temp(R1);
return;
查找基波和谐波,以及幅度值的部分:
function [none] = temp(R1)
%TEMP Summary of this function goes here
% Detailed explanation goes here
%load('R1');
%plot(R1);
[MaxA MaxB]=max(R1);
A=MaxA/10;
T=round(100*2*pi);
a=zeros(1,7);
b=zeros(1,7);
b(1)=1;
k=1;
n=T;
a_tmp=0;
b_tmp=0;
bb=0;
%count1=0;
while (n<5000)&(bb<200)
if n+T<=5000
n_tmp=n+T;
elseif n+T>5000
n_tmp=5000;
end
[a_tmp b_tmp]=max(R1(n:n_tmp));
b_tmp=b_tmp+n;
if a_tmp>=A
bb=bb+1;
if k==1
a(k)=a_tmp;
b(k)=b_tmp;
n=b(k)+1;
k=k+1;
elseif k>1
if (b_tmp-b(k-1))<=T
[a(k-1) b_tmp1]=max(R1(b(k-1):b_tmp+1));
b(k-1)=b_tmp1+b(k-1);
n=b_tmp+T;
elseif (b_tmp-b(k-1))>T
a(k)=a_tmp;
b(k)=b_tmp;
n=b(k)+1;
k=k+1;
% count1=count1+1;
end
end
elseif a_tmp
n-1.1&tn-0.8&tn-0.35&tn-1&tn-1&t总结 :
1,由于后来波形的判断采用较多的循环,所以编程出错时往往会造成死循环。
也无法停止,只能结束进程。Matlab7.4 启动的初始化要用很长时间,所以频繁
出错造成大量时间浪费。
后来想到一个办法,可以在循环中加入控制循环次数的变量,然后调试时方便了
很多。
2,分块的思想还是应深入贯彻。尤其是 2部分第四题,得到的每一步骤尽量将
结果保存。
这样避免了每次调试都重新进行波形整形,傅里叶变换的步骤。大大节省时间。
3,包络的不同加法会造成音乐的听觉效果不同。