转自:http://blog.csdn.net/ahyswang/article/details/7691541
1.1混响的作用与基本原理
混响器即是人为地给声音加上混响的效果。这样通过改变场景的混响时间,可以对比较“干”的信号进行再加工,增加空间感,提高声音的丰满度,同时可以制造一些特殊的声音效果,如回声等,通过改变混响声和直达声的比例,还可以体现声音的远近感和空间感。
下图一直观的解释了混响的简单原理。为了研究的方便,声学上把混响分为几个部份,规定了一些习惯用语。混响的第一个声音也就是直达声(Direct sound),也就是源声音,在效果器里叫做 dry out (干声输出),随后的几个明显的相隔比较开的声音叫做“早反射声”(Early reflectedsounds),它们都是只经过几次反射就到达了的声音,声音比较大,比较明显,它们特别能够反映空间中的源声音、耳朵及墙壁之间的距离关系。后面的一堆连绵不绝的声音叫做 reverberation。图五中,老师在讲台上讲课,学生在座位上听到的声音除了直接到达的声音(DIRETO)外,还有R1.R2.R3.R4等等这些反射声。可以看见不同的反射声达到人耳的时间有着不同的延迟。所有这些声音的叠加才是人耳听到的最终声音。然而实际上,这些反射声是无穷尽的,这样我们似乎就没办法得到混响声了。
然而如果我们假定源声音是一个脉冲,得到结果如图二。
图一
图二
得到的是一串简单的脉冲序列。这个混响特征是用脉冲得到的,声学上我们叫做Impulse Response脉冲反应,简称IR。经过混响的声音即可看作源声音与IR的卷积得到的结果。
依据IR的来源不同,混响效果器,象合成器一样分为三种类型:采样混响、“算法”混响、模拟合成混响。
1.2 混响分类
(一)采样 IR 混响
Sony ,Yamaha 都出过采样混响,价格不菲。软件的采样混响效果器有著名的 SonicFoundry 的 Acoustic Mirror ,还有Samplitude 的 Room Simulator 。 采样混响的 IR ,全部是真实采样得来的 wave 文件。可以存放于任何存储器,例如硬盘、光盘、软盘等等。Sony ,Yamaha 的硬件采样混响器,里面也带有容量较大的存储器。 采样混响的 IR 都是录音采样得来的,最简单的获取 IR 的方式是:在图一教师的位置放置一个音箱,学生的位置放置一个话筒。音箱播放一个脉冲,话筒进行录音。录到的声音就是
IR ,也就是这个房间的从讲台到学生座位的混响特征曲线。目前 Sony 、Samplitude 等所采用的具体方式是: 在想要获得混响特征的地方,例如音乐厅,舞台上安置音箱(当然会是极好的音箱),座位席中安置立体声话筒(极好的话筒)。然后播放一系列测试信号,这些信号以脉冲为主,各种速度的全频段正弦波连续扫描为辅,录得声音,然后经过一些计算得到 IR 。用这种采样方法得到的 IR ,极为真实。 采样混响的 IR ,不但厂家可以预置给你,你自己也可以根据厂家提供的工具进行制作。因此从数量上来说是无限的。下图三就是一个真实的采样混响IR。
图三
(二)“算法”混响
这是最常见的混响效果器。目前大多数的数字混响效果器以及软件混响都是此类。这类效果器的本质是跟采样混响一样的,只是采样混响的 IR 可以自由更换,而“算法”混响其实也带有 IR ,但这些个 IR是厂家固定好的,是一组组简易的脉冲序列,通过对这些脉冲序列进行调制和编辑控制,从而得到最终的混响效果。例如Waves 的 Renaissance Reberberator 带有几十个简易的脉冲序列 ,这些脉冲序列都产品自带的,不能更改。很多厂家把这些的脉冲序列称之为“算法”,它们其实可以算作一种简化过后的IR
。 许多硬件混响器也是如此,例如 Lexicon 和TC 的,原理都一样。而采样混响内带有可擦写存储器,可以自由更换 IR 。 这类混响器虽然不带有真实 IR ,但是却提供了很多方法可以让你对它自带的原始的脉冲序列进行修改,例如可以让你拉长或者缩短这组脉冲序列(也就是拉大或者缩短脉冲之间的距离),这样可以模拟墙壁漫反射的效果,还提供了滤波器和 EQ ,前反射时间,等等,很多控制。这些实际上都是对原始 IR 进行修改,以达到控制混响效果的目的。因此虽然它不带有真实 IR ,但通过对 IR 进行编辑,可以获得无数种混响效果。
为了容量上的考虑,“算法”混响所带有的原始脉冲序列都作了很大的简化,不会象采样混响的 IR 里那样无数个脉冲有如滔滔江水连绵不绝。下图四是“算法”混响经过调节后最终得到的 IR 。将之与上面采样 IR 对比一下就可以知道区别了。
图四
(三)模拟合成 IR 混响
这类混响效果器并不带有IR 曲线,而是用模拟合成方法“临时”生成 IR 。 几乎所有的非数字混响器都是这一类(包括所有的传统电子管混响效果器、调音台上的非数字混响等),还有少数软件混响效果器也是,例如 Spin Audio 的 RoomVerb M2 ,Samplitude 的 Track Reverb 等等。 它会根据你提出的要求,比如空间大小,墙壁的吸音程度,等等,用它自己的计算方法(例如 Spin Audio 的“虚拟房间声学建模技术”),生成一个 IR ,并且有许多方法对IR
进行编辑控制,例如滤波,EQ 等。因此虽然 SpinAudio 的 RoomVerb M2 不带有任何 IR ,却也能模拟出无数种混响效果。
1.3混响的特征参数
下面以Waves的“文艺复兴混响器”来说明混响器的特征参数,如图五所示:
图五
大多数的混响效果器会有一些参数选项给你调节,现在就来讲讲这些参数具体是什么意思。
(1)衰减时间(Decay time)
也就是整个混响的总长度。不同的环境会有不同的长度,有以下几个特点:空间越大,decay 越长;反之越短。空间越空旷,decay 越长;反之越短。空间中家具或别的物体(比如柱子之类)越少,decay 越长;反之越短。空间表面越光滑平整,decay 越长,反之越短。因此,大厅的混响比办公室的混响长;无家具的房间的混响比有家具的房间长;荒山山谷的混响比森林山谷的混响长;水泥墙壁的空间的混响比布制墙壁的空间的混响长 …… 一般很多人喜欢把混响时间设得很长。其实真正的一些剧院、音乐厅的混响时间并没有我们想象得那么长。例如波士顿音乐厅的混响时间是
1.8 秒,纽约卡内基音乐厅是 1.7 秒,维也纳音乐厅是 2.05 秒。
(2)前反射的延迟时间(Predelay)
就是直达声与前反射声的时间距离。有以下几个特点: 空间越大,Predelay 越长;反之越短。空间越宽广,Predelay 越长;反之越短。因此,大厅的 Predelay 比办公室的长;而隧道的空间虽然大,但是它很窄,所以 Predelay就很短。 想要表现很宽大空旷的空间,就把 Predelay 设大一点。
(3)wet out
也就是混响效果声的大小。有以下几个特点: wet out 与空间大小无关,而只与空间内杂物的多少以及墙壁及物体的材质有关。 墙壁及室内物体的表面材质越松软,wet out 越小;反之越大 空间内物体越多,wet out 越小;反之越大墙壁越不光滑,wet out 越小,反之越大 墙壁上越多坑坑凹凹,wetout 越小,反之越大 因此,挤满了人的车厢的混响就比空车要小得多;放满了家具的房间的混响就比空房间要小;有地毯的房间的混响比无地毯的小;森林山谷的混响比荒山山谷的混响要小。
(4)高低频截止(low cut / high cut)
这个参数在有些效果器里是以 EQ 的形式来表现的,例如 Waves 的 RVerb 。这项内容实际上跟现实情况没有太直接的联系,它只是为了我们做混响处理时声音好听而设计的。不过它也能表现高频声音在传播中损失比较厉害的现象。一般在做处理的时候,为了混响声的清晰和温暖,都会把低频和高频去掉一部份。只有在表现一些诸如“宇宙声”等科幻环境时,才把高低频保留。 另外有些效果器也把这个叫做“color”( {MOD}彩)。例如 TC 的效果器就是 color 。color 也就是“冷”和“暖”的感觉,高频就是冷,低频就是暖。所以这些效果器用颜 {MOD}来表示高低频截止,暖 {MOD}(红)表示混响声偏向低频,冷 {MOD}(蓝)表示混响声偏向高频。补充:高低频截止实际上在现实中是不存在的,现实中的普遍现象是:低频声音的混响无论是声音大小还是衰减时间,都要比高频声音大。这是因为不同频率的声音由于波长不同,因此绕过障碍的能力不同,高频声音波长短,不容易绕过障碍,低频声音波长长,容易绕过障碍。加上它们在空气中传播时的衰弱程度不同(频率越高越容易衰弱),被墙壁吸收的程度不同(频率越高越容易损失),所以不同频率的声音的混响时间和大小是不相同的。在真实世界中,在大多数中小空间里,越低的声音具有越长的混响时间,越高的声音具有越短的混响时间,而不可能做到反过来。如何做到降低低频混响是任何一个录音棚头疼的难题。唯独有一种情况,是低频混响小于高频混响的,那就是很大的空间,并且里面布满了由硬质材料制成的障碍和表面,比如采用硬塑料凳子和水泥墙壁地板的室内体育馆。
(5)衰减形状(Decay Shape)
有的混响器里提供了这个参数,用来控制混响的衰减形状。如下图六所示是几种常见衰减形状:
图六
上图中第一个是我们最常用的线性衰减,第二个和第三个是EXP型衰减,其中第三个可以成为门式混响(Gate Reverb),第四和第五个是Reverse型衰减,通常用来制造一些特殊声音效果。
(6)散射度(Diffusion)
一般也称作Early Reflections Diffusion(早反射的散射度)。这些早反射是比较明显的反射声,它们之间的相互接近程度就是散射度。一般来说,墙壁越不光滑,反射声越多,相互之间越接近,散射度越大,混响声连成一片;墙壁越不光滑,反射声越小,相互之间分得越开,散射度越小,混响声听起来比较接近回声,比较清晰。
然而对于用户来讲,这些参数既繁多又难以确定,调节得不好反而不如不加混响。这时最好的选择是套用软件中得预置参数,比如“Large Hall”就可以实现大厅的混响效果。对于UItrafunkfxReverbR3效果器,可以给出下面一组参数:Input 0.0 Low cut 145 Highcut 4.5 Predelay 160 Room size 100 Diffusiin 100 Bass Multiplier 2.6 Crossover116 Decay Time 1.8 High Damping
2.2 Dry 1.0 E.R. -3.5 Reverb -7
这里笔者认为在音效处理要求不高的时候Gold Wave软件以其小巧玲珑和调节简便的特点,有着很大的借鉴意义。其做出的混响效果基本令人满意,最重要的是它只有三个最重要的参数需要调节。然而其不足之处在于添加的可选场景混响效果较少。
1.4 混响算法
混响的算法实现通常通过听觉逼近方式实现,这种方式产生与人耳听觉无差异的混响效果,着重重建混响的重点部分。最著名的混响算法是由贝尔实验室的Schroeder提出的,他提出的混响算法包含两个IIR滤波器:梳状滤波器和全通滤波器。其中梳状滤波器是一个带后向反馈的延时电路,而全通滤波器则是一个带前向反馈支路的梳状滤波器。原理图如下:
图七
通过并联的梳状滤波器模拟延时较大的回声,串联的全通滤波器模拟延时较小的回声。然而这种方法的缺点则是它模拟的混响中回声密度不够,对此可以通过增加滤波器个数等方法进行改进。
1.5混响的实现代码
参考
[cpp] view
plaincopy
-
#define dsound_allpass_process(_allpass, _input)
-
{
-
dsound_real_t output;
-
dsound_real_t bufout;
-
bufout = _allpass.buffer[_allpass.bufidx];
-
output = bufout-_input;
-
_allpass.buffer[_allpass.bufidx] = _input + (bufout * _allpass.feedback);
-
if (++_allpass.bufidx >= _allpass.bufsize) {
-
_allpass.bufidx = 0;
-
}
-
_input = output;
-
}
[cpp] view
plaincopy
-
#define dsound_comb_process(_comb, _input, _output)
-
{
-
dsound_real_t _tmp = _comb.buffer[_comb.bufidx];
-
_comb.filterstore = (_tmp * _comb.damp2) + (_comb.filterstore * _comb.damp1);
-
_comb.buffer[_comb.bufidx] = _input + (_comb.filterstore * _comb.feedback);
-
if (++_comb.bufidx >= _comb.bufsize) {
-
_comb.bufidx = 0;
-
}
-
_output += _tmp;
-
}
[cpp] view
plaincopy
-
void dsound_revmodel_processreplace(dsound_revmodel_t * rev, dsound_real_t * in, dsound_real_t * left_out, dsound_real_t * right_out)
-
{
-
int i, k = 0;
-
dsound_real_t outL, outR, input;
-
-
for (k = 0; k < FLUID_BUFSIZE; ++k){
-
-
outL = outR = 0;
-
-
-
-
-
-
input = (2.0f * in[k] + DC_OFFSET) * rev->gain;
-
-
-
for (i = 0; i < numcombs; i++) {
-
dsound_comb_process(rev->combL[i], input, outL);
-
dsound_comb_process(rev->combR[i], input, outR);
-
}
-
-
for (i = 0; i < numallpasses; i++) {
-
dsound_allpass_process(rev->allpassL[i], outL);
-
dsound_allpass_process(rev->allpassR[i], outR);
-
}
-
-
-
outL -= DC_OFFSET;
-
outR -= DC_OFFSET;
-
-
-
left_out[k] = outL * rev->wet1 + outR * rev->wet2;
-
right_out[k] = outR * rev->wet1 + outL * rev->wet2;
-
}
-
-
}