关于弦振动、发声模拟和VST的几个要点
本文写作的目的,主要是为了解决以下问题:
一、简单根据弦振动方程的解作出来的模拟,为什么不似真实乐器。
二、弦乐器发声模拟的一般过程应该是什么样的。
三、为什么许多VST使用的算法完全不像物理模型那样,并不求解这些方程组。
简单弦振动方程,是科普常见的题材,也是有心音乐的爱好者们入门的起始。教科书和各种科普资料里,常常写明讲透了它的求解方法和解的形式(因此在此不再赘述),然后说明泛音列的组成,但很少说明这个弦的振动函数,是如何具体影响听到的声音的。因此,许多人在弦振动方程的解的基础上做出的诸多对真实乐器的模拟,效果都很糟糕。
从发声和传声的过程来看,如果只考虑一根弦,那么弦是首先要激发空气振动,空气振动再传到听者的耳朵里的。因此这里面有三个因素:弦、空气和听者。过程是,首先我们解出弦的振动函数;然后,这个振动函数要作为受迫振动的项,塞进空气中的声波方程里去;这样的声波方程结合所在环境(屋子)的边界条件,解出在听者位置的声压变化函数;这就是听者听到的声音。但是这个过程颇为复杂,实际过程中常常取简便近似方法计算,认为弦上某点对听者位置的相位影响是只和路径的长短有关的,在传播过程中过了多少的相位就是多少,屋子墙壁反射的声波按照走的总路程计算。之所以能这么算,还是因为空气中声波的方程是一个线性方程,它的解是可分散可叠加的。
由此说来,科普材料中常用的一种近似算法——把所有弦上点的振动函数相加,得到对听者的总影响——这种算法相当于认定所有点不论位置对听者的影响相同,不考虑反射、回声,因此是在无限空旷环境中的一个远场近似。这个远场近似相当于把弦振动函数中的位置项直接积分以去掉位置项,口算一下就会发现积出来一个1/n的因子;乘上平常泛音强度的1/n^2,可以认为泛音的衰减在这种近似下是按照1/n^3进行的。如果考虑听者与弦的相对位置,并不考虑环境反射(空旷环境),计算会稍复杂一些,这相当于空旷环境中的近场;这样计算下来是有些不同的,但由于一般的听者距离比上波长都要大很多,实际上相当于远场,所以和远场近似区别不是很大。这些算法,无论怎么考虑空间位置,它的效果普遍都和真实乐器区别很大。
如果对弦振动方程,单独考察其中弦上的某一点,那么这个这一点随时间的位移是个三角波。这条性质后文会使用。
前面已叙述是否以及如何考虑听者与弦相对位置,都不能让模拟的声音接近真实乐器,所以直观上应当考虑是否我们根据的弦振动方程有问题。确实有非线性的弦振动方程,它的解虽然复杂,但也是周期性的;这种非线性的弦振动方程,一般在工程上应用于桥梁钢索一类可能会大幅度振动的弦,并非乐器弦。因此还是要从线性或近似线性的角度来修正弦振动方程:一般采用的修正是一个刚性项(正比于位置的四阶导数),一个阻尼项(正比于对时间的导数),和一个修正阻尼项(正比于对时间的三阶导数);事实上这些项所预测的泛音偏差(非整数比的分音),包络的衰减等等都在实际录音数据中观察到了。定性的来说,这些修正的解决了大部分存在什么频率的问题,但是它没有解决这些频率强度的比例问题。
我们单用弦振动方程模拟出的声音不似真实乐器,有一大部分是因为没有考虑到琴桥、面板与共振腔的缘故;面板才是乐器发声贡献最大的部分(否则为什么那么多乐器都在炒作面板)。
弦乐器发声模拟的一般过程,基本上是弦的振动带动琴桥,琴桥把受力传递给面板,面板受迫振动发声;面板的声音一部分通过空气传递给听者,另一部分被体腔所混响,再传给听者。
弦的振动,分横振动(以上简单和修正弦振动方程所描述的振动),以及一个纵向的压缩/拉伸振动,后者是受前者迫使的振动。琴桥对琴弦振动的作用,由于它的机械阻抗变化不大且接近实值,一般被包含在琴弦振动方程修正项的两个阻尼项里。而琴弦对琴桥的作用,认为是弦末端振动时不断变化的形状曲线的斜率所导致的,牵引在琴桥上的拉力的的竖直分量的变化,当然弦牵拉方向的水平分量也有变化。这其中,纵向振动修正了拉力,令它出现变化;横向振动改变了拉力的作用方向。琴桥的受力,传递到面板上:竖直压力被面板平衡,弦牵拉以及面板抵抗引起的扭矩被平衡;这样就导致琴桥对面板的力不是处处相同的,而是有一个分布。琴桥对面板的力迫使它振动,我们解出面板的振动函数,然后据此代入声波方程的受迫项,可以计算听者的音效和体腔的作用。
这里面几个方程之中所包含的振动模式有三簇:第一簇是弦的横振动的固有频率,这也是音乐上“定音”的模式;其次是纵向振动和面板振动的固有频率,它们起着丰富音色的作用。面板振动的方程,由于涉及二维四阶导数和混合导数,是比较难解的,有的资料上采取了机械阻抗的思维来处理。机械阻抗的思维实际上是:面板振动方程作为一个线性方程,它满足叠加原理,引进虚部构造,此时解关于时间的部分永远保持e^zt的复指数形式;这也就是说,我们可以分频率考察问题,并且解中蕴含的振动模式不会被消灭。机械阻抗,其实也就是某个振动频率的外力作用与系统,系统的速度函数与外力函数之比;在以上的叙述之下,很容易看出如果不解方程而考察机械阻抗,那么每个频率输入的振动模式都可以用阻抗来算出响应的振动模式强弱。需要指出的是:面板各点每时刻的相位都不同,因此每一点都有不同的机械阻抗,各种书籍材料上只给一个,意义上那多是用某种积分去掉了位置参数。
总之过程汇总到最后就是:算出面板的振动函数,然后算体腔和听者的音效。
VST即所谓虚拟乐器,就是用算法来模拟真实乐器发出的声音的。虚拟乐器分两种,其一是内部存放着真实乐器发出来的录音,由录音来推算模拟的声音;其二则完全是算法和少量的必要数据。很显然我说的是第二种。
我们的物理模型模拟实际上计算速度是很慢的,据某论文显示,渲染1s的钢琴声要接近30min。VST显然是做了大量简化。这一类由算法来模拟声音的VST,它们的算法也大致分两类:一类是给出各个频率簇的频率、相对强度和衰减函数,另一类是作出一个激发(例如:一段白噪声或者锯齿/三角波),然后不断的滤波、延迟、混合等等,从而创造最终的波形。第一类算法就是所谓频谱合成,它的物理依据就是各个振动频率不会被消灭,因此可以列举,然后通过计算或者波形数据分析或者手工调整,来指定其他参数。第二类算法是把整个乐器和声波传播的空间当成一个激发源和一组线性或者非线性的滤波器,滤波器本身有频率响应,好似面板的机械阻抗和屋子的声阻抗一般。显然这二者都只关注输出的波形,也就是物理系统里听者收到的波形,而复杂物理系统的细节,却被略去了。虽然常说Karplus-Young合成算法(注:用噪声作为激发源,反复延迟混合和滤波)是一种比较物理的模拟,但也是极其简化的。
上面提到的三角波,常常被用于电声乐器的输入,其原因就在此。三角波包含弦振动的所有泛音以及符合它们的相对强度,在忽略去其他细节的情况下,确实可以拿来制作奇怪的拨弦乐器音效。
之所以VST虚拟乐器们,不求解复杂的方程组,实际上是因为它们使用了很简化的方式,并且预先作了计算或者数据分析。

