信号与系统
- 综合实验之音乐合成
(1) 请根据《东方红》片断的简谱和“十二平均律”计算出该片断中各个乐音的
频率,在MATLAB 中生成幅度为1 、抽样频率为8kHz 的正弦信号表示这些乐音。请用sound 函数播放每个乐音,听一听音调是否正确。最后用这一系列乐音信号拼出《东方红》片断,注意控制每个乐音持续的时间要符合节拍,用sound 播放你合成的音乐,听起来感觉如何 代码如下: f =8000;
t2=[0:1/f:1]; t4=[0:1/f:]; t8=[0:1/f:]; omg5=; omg6=; omg2=392; omg1=; omg6l=;
m1=sin(2*pi*omg5*t4); m2=sin(2*pi*omg5*t8); m3=sin(2*pi*omg6*t8); m4=sin(2*pi*omg2*t2); m6=sin(2*pi*omg1*t4); m7=sin(2*pi*omg1*t8); m8=sin(2*pi*omg6l*t8); m9=sin(2*pi*omg2*t2);
m=[m1 m2 m3 m4 m6 m7 m8 m9]; sound(m);
听的时候发现在相邻乐音之间有杂音,这是由于相位不连续造成的。
(2) 你一定注意到(1) 的乐曲中相邻乐音之间有“啪”的杂声,这是由于相位不
连续产生了高频分量。这种噪声严重影响合成音乐的质量,丧失真实感。为了消除它,我们可以用图 所示包络修正每个乐音,以保证在乐音的邻接处信号幅度为零。此外建议用指数衰减的包络来表示。 我采用的是指数衰减的包络。 代码如下: f =8000;
t2=[0:1/f:1]; t4=[0:1/f:]; t8=[0:1/f:]; omg5=; omg6=; omg2=392;
omg1=; omg6l=;
m1=exp(-2*t4).*sin(2*pi*omg5*t4); m2=exp(-4*t8).*sin(2*pi*omg5*t8); m3=exp(-4*t8).*sin(2*pi*omg6*t8); m4=exp(-1*t2).*sin(2*pi*omg2*t2); m6=exp(-2*t4).*sin(2*pi*omg1*t4); m7=exp(-4*t8).*sin(2*pi*omg1*t8); m8=exp(-4*t8).*sin(2*pi*omg6l*t8); m9=exp(-1*t2).*sin(2*pi*omg2*t2); m=[m1 m2 m3 m4 m6 m7 m8 m9]; sound(m);
第一次我采用的指数衰减没有时间前面的系数,即每个都只乘exp(t),没有系数;后来根据不同节拍,更改了不同的衰减系数,这样声音听起来感觉更加圆润。
(3) 请用最简单的方法将(2) 中的音乐分别升高和降低一个八度。(提示:音乐
播放的时间可以变化)再难一些,请用resample 函数(也可以用interp 和decimate 函数)将上述音乐升高半个音阶。(提示:视计算复杂度,不必特别精确)
答:最简单的方法是直接更改抽样频率f。将f从8K改为4K,则升高一个八度,并且播放速度增快了一倍;将f从8k改为16k,则降低一个八度,速度也变慢了一倍。 升高半个音阶,只须在(2)代码最后加一句resample(m,1000,1059)即可。
f =8000; %改为4000或者16000 t2=[0:1/f:1]; t4=[0:1/f:]; t8=[0:1/f:]; omg5=; omg6=; omg2=392; omg1=; omg6l=;
m1=exp(-2*t4).*sin(2*pi*omg5*t4); m2=exp(-4*t8).*sin(2*pi*omg5*t8); m3=exp(-4*t8).*sin(2*pi*omg6*t8); m4=exp(-1*t2).*sin(2*pi*omg2*t2); m6=exp(-2*t4).*sin(2*pi*omg1*t4); m7=exp(-4*t8).*sin(2*pi*omg1*t8); m8=exp(-4*t8).*sin(2*pi*omg6l*t8); m9=exp(-1*t2).*sin(2*pi*omg2*t2); m=[m1 m2 m3 m4 m6 m7 m8 m9]; resample(m,1000,1059); sound(m);
(4) 试着在(2) 的音乐中增加一些谐波分量,听一听音乐是否更有“厚度”了注
意谐波分量的能量要小,否则掩盖住基音反而听不清音调了。(如果选择基波幅度为1 ,二次谐波幅度0:2 ,三次谐波幅度0:3 ,听起来像不像象风琴) 代码如下: f =8000;
t2=[0:1/f:1]; t4=[0:1/f:]; t8=[0:1/f:]; omg5=; omg6=; omg2=392; omg1=; omg6l=;
m1=exp(-2*t4).*sin(2*pi*omg5*t4)+*exp(-2*t4).*sin(2*pi*2*omg5*t4)+*exp(-2*t4).*sin(2*pi*3*omg5*t4);
m2=exp(-4*t8).*sin(2*pi*omg5*t8)+*exp(-4*t8).*sin(2*pi*2*omg5*t8)+*exp(-4*t8).*sin(2*pi*3*omg5*t8);
m3=exp(-4*t8).*sin(2*pi*omg6*t8)+*exp(-4*t8).*sin(2*pi*2*omg6*t8)+*exp(-4*t8).*sin(2*pi*3*omg6*t8);
m4=exp(-1*t2).*sin(2*pi*omg2*t2)+*exp(-1*t2).*sin(2*pi*2*omg2*t2)+*exp(-1*t2).*sin(2*pi*3*omg2*t2);
m6=exp(-2*t4).*sin(2*pi*omg1*t4)+*exp(-2*t4).*sin(2*pi*2*omg1*t4)+*exp(-2*t4).*sin(2*pi*3*omg1*t4);
m7=exp(-4*t8).*sin(2*pi*omg1*t8)+*exp(-4*t8).*sin(2*pi*2*omg1*t8)+*exp(-4*t8).*sin(2*pi*3*omg1*t8);
m8=exp(-4*t8).*sin(2*pi*omg6l*t8)+*exp(-4*t8).*sin(2*pi*2*omg6l*t8)+*exp(-4*t8).*sin(2*pi*3*omg6l*t8);
m9=exp(-1*t2).*sin(2*pi*omg2*t2)+*exp(-1*t2).*sin(2*pi*2*omg2*t2)+*exp(-1*t2).*sin(2*pi*3*omg2*t2);
m=[m1 m2 m3 m4 m6 m7 m8 m9]; sound(m);
加入谐波分量后,音色有所变化,感觉更加清脆一些。
(5) 自选其它音乐合成,例如贝多芬第五交响乐的开头两小节。 我选取的是《晴天》的第一句 代码如下: f=8000;
t2=[0:1/f:1]; t4=[0:1/f:]; t8=[0:1/f:]; t=[0:1/f:]; omg1=392; omg2=440; omg3=;
omg4=; omg5=; omg6=; omg7=; omg5l=; m0=0;
m1=exp(-2*t4).*sin(2*pi*omg5*t4); m2=exp(-2*t4).*sin(2*pi*omg5*t4); m3=exp(-2*t4).*sin(2*pi*omg1*t4); m4=exp(-1*t2).*sin(2*pi*omg1*t2); m5=exp(-2*t4).*sin(2*pi*omg2*t4); m6=exp(-2*t2).*sin(2*pi*omg3*t2); m7=exp(-2*t4).*sin(2*pi*omg5*t4); m8=exp(-2*t4).*sin(2*pi*omg5*t4); m9=exp(-2*t4).*sin(2*pi*omg1*t4); m10=exp(-2*t4).*sin(2*pi*omg1*t4); m11=exp(-4*t8).*sin(2*pi*omg2*t8); m12=exp(-4*t8).*sin(2*pi*omg3*t8); m13=exp(-4*t8).*sin(2*pi*omg2*t8); m14=exp(-4*t8).*sin(2*pi*omg1*t8); m15=exp(-2*t2).*sin(2*pi*omg5l*t2);
m=[m0 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15]; sound(m);
(6) 先用wavread 函数载入光盘中的 文件,播放出来听听效果如何是否比刚才的合成音乐真实多了 x=wavread(''); sound(x); (7)你知道待处理的wave2proc 是如何从真实值realwave 中得到的么这个预处理过程可以去除真实乐曲中的非线性谐波和噪声,对于正确分析音调是非常重要的。提示:从时域做,可以继续使用resample 函数。
realwave中的波形有十个周期,要除去其中的噪声可以采用时域求均值的方法。步骤如下:首先用resample函数将其采样率增大为十倍,再等分十份取平均,然后重复这个平均后的波形十次,还原其长度,最后在用resample函数还原采样率到1/10。 代码如下: load('');
wavetemp = zeros(length(realwave), 1); waveresampled = resample(realwave,10,1); for n = 1 : 10
wavetemp = wavetemp + waveresampled((n - 1) * length(realwave) + 1 : n * length(realwave)) / 10; end
mywave2proc = repmat(wavetemp, 10, 1); mywave2proc = resample(mywave2proc, 1, 10);
figure;
subplot(3, 1, 1);plot(realwave); subplot(3, 1, 2);plot(wave2proc); subplot(3, 1, 3);plot(mywave2proc);
0.50-0.50.50-0.50.50-0.5050100150200250050100150200250050100150200250
(8) 这段音乐的基频是多少是哪个音调请用傅里叶级数或者变换的方法分析它的谐波分量分别是什么。提示:简单的方法是近似取出一个周期求傅里叶级数但这样明显不准确,因为你应该已经发现基音周期不是整数(这里不允许使用resample 函数)。复杂些的方法是对整个信号求傅里叶变换(回忆周期性信号的傅里叶变换),但你可能发现无论你如何提高频域的分辨率,也得不到精确的包络(应该近似于冲激函数而不是sinc 函数),可选的方法是增加时域的数据量,即再把时域信号重复若干次,看看这样是否效果好多了请解释之。
答:共计221-2=219个周期;基因频率约为8000 / (219 / 9) = . 用FFT对该信号做DFT变换: load('');
my_wave2proc = repmat(wave2proc, 25, 1); Fs = 8000; Length = length(my_wave2proc); NFFT = 2 ^ nextpow2(Length); Y = fft(my_wave2proc, NFFT) / Length; amplitude = 2 * abs(Y(1 : NFFT / 2 + 1));
frequency = Fs / 2 * linspace(0, 1 ,NFFT / 2 + 1); plot(frequency, amplitude);
[max_rate_of_grade, max_position] = max(amplitude(1 : 100));