这一篇和下一篇将会讲解一些混音中常用的效果器,及其背后原理。
滤波处理
有时在混音或声音处理时,我们希望去除、减弱或者增强一些一些频段的信号。比如当你扒带要听贝斯的时候,可以挂一个高切(低通)滤波器只听低频:
这些操作在频域上非常简单,只需要把对应频段的信号乘以一个指定值就行了。如果想要增强高频,可以把所有高频的频率分量$\times2$。
我们非常熟悉的PCM格式记录的是音频的时域信息。那么要想对频率进行处理,当然是先傅里叶变换成频域,处理完后再逆变换回时域啦——对吧?
这么做当然可以,但没必要。原因有很多:首先傅里叶变换的运算量很大,哪怕是$O(n\log n)$复杂度的FFT快速傅里叶算法,也仍需要大量三角函数浮点运算,处理完频域信号后还要用差不多的运算量逆变换回去。这对混音时挂几十个效果器的制作人们来说几乎是不可接受的。其次音频信号的频谱根据时间是不断变化的,必须使用STFT等先分帧,再变换的算法——这期间每次分帧都会有误差产生,累计起来音质会受很大影响。而且别忘了,FFT这样的$O(n\log n)$算法,在采样点少即$n$比较小时和$O(n^2)$区别不大。
如何在不进行傅里叶变换的情况下,对时域信号的频域进行编辑呢?
让我们回到模拟时代来寻找答案。
RC滤波电路
在模拟电路中,音频波形由电压的变化来表示。一个正弦波的音频信号反映在电路中就是一个正弦交变电压,即我们熟悉的交流电。
在电路中,电感和电容通过存储能量来起到类似蓄水池的作用。电感会以磁能存储电能,在电流变化时产生反向电压,阻止电流突变。电容则是在两个极板上存储电荷,当电压变化时电荷会流入流出,减缓电压变化。这种对交流电的阻碍作用被称为阻抗(electrical impedance)。阻抗值是一个复数,对于固定频率的正弦交流电来说,阻抗的实部是电流和电压的比值(同欧姆定理),虚部则是相对相位。
使用复数的原因是因为交流电是动态的,我们不仅需要知道当前电压,还需要知道电压的变化率(相位)。
电压和相位合称为信号的相量。
读者只需要明白相关原理即可,至于具体数学推导,网上资料很多,好奇的话可以自行查找。
理想电容器的阻抗公式为$Z_C=\frac{1}{j \omega C}$ 。其中$\omega $为电压变化的角速度,与频率成正比,关系为$\omega =2\pi f$。理想电容器仅有虚部没有实部,反映在波形上就是振幅不改变,仅有相位变化。当$\omega $趋近于0时,电容器几乎可看做开路。当$\omega $很大时,电容器几乎可看做短路。
理想电阻器的阻抗为$Z_R=R$,为一个与电阻值相等的实数。
利用电容电阻的阻抗特性,我们可以构造如下电路:
根据基尔霍夫电压定律(Kirchhoff laws):
$V_{out}=V_{C}=V_{in}-V_{R}$
是不是很像一个分压器。
当输入的信号频率较高,$\omega$比较大时,电容的阻抗比电阻的阻抗低,此时电阻上的压降比电容上的压降大,较小的电压由$V_{in}$传递到$V_{out}$。相反,当输入信号频率低,$\omega$比较小时,电容的阻抗比电阻大很多,表现为电容上的压降比电阻上的压降大,较多的电压由$V_{in}$传递至$V_{out}$。
这种电路被称为低通RC滤波器,允许低频信号通过并对高频信号有较大的阻碍。
电路中输入信号与输出信号的相量之比被称作电路的网络函数(network function)。以下为这个RC滤波器的网络函数,其实就是把阻抗公式带入到初中的分压公式中,然后化简:
$H(jw)=\frac{V_{out}}{V_{in}}=\frac{\frac{1}{jwC}}{R+\frac{1}{jwC}} =\frac{1}{1+jwRC}$
其中$RC=\tau$为电阻值和电容值的乘积,被称为电路的时间常数。
设$\omega_{c}=\frac{1}{RC}$,那么公式可以被写为$H(jw)=\frac{1}{1+j\frac{\omega}{\omega_{c}}}$。
其中$\omega_{c}$为这个滤波器的截止频率。
用相量表示正弦交流电时,振幅为相量取模。因此输出信号的幅值为:
$\left|H(jw)\right|=\frac{1}{\sqrt{1+(\frac{\omega}{\omega_{c}})^{2}}}$
让我们画出这个输出信号赋值与频率的图像。音乐中音高和频率是对数关系,所以横坐标是对数尺度,$\log x$:
我们提到过音频中响度和振幅是对数关系。因此把纵轴也换成对数尺度:
可以看到,在截止频率$\omega_c$之后,响应以趋近于-10dB/dec的速度快速下降(声音响度就是-20dB/dec,即大约-6dB每倍频)。至此,我们实现了对高于截止频率的信号的过滤。现在只需要在计算机上实现就可以了!
输入与输出信号的频域之比可以看做其傅里叶变换之比。将傅里叶变换由虚数轴推广至整个复平面后可以得到拉普拉斯变换。输入与输出信号的拉普拉斯变换之比被称作传递函数,也就是电路的网络函数。大多数时候,我们设$s=j\omega$。传递函数就可以写成下面的样子:
$H(s)=\frac{Y}{X}=\frac{1}{1+s\tau}$
数字滤波器
音频采样是离散化的。对传递函数使用Z变换进行离散化后得到:
$Y_n=Y_{n-1}+\frac{T_c}{\tau}(X_{n-1}-Y_{n-1})$
这里$T_c$是采样周期。设$a=\frac{T}{\tau}=T\omega_c$,其中$a$被称为滤波系数,可以得到一阶低通数字滤波器的基本公式:
$Y_n=aY_{n-1}+(1-a)Y_{n-1}$
基本公式就是这样不可思议的简单。只需要对采样信号进行迭代即可滤波,代码实现如下:
double f_c=500; //截止频率
double sampleRate=44100.0; //采样率
double a=f_c/sampleRate; //计算滤波系数
for(int i=1;i<samples.length();i++){
samples[i]=a*samples[i]+(1.0-a)*samples[i-1];//进行一个代的迭
}
//搞定。
没错,这个滤波器的时间复杂度居然是$O(n)$,而且不涉及任何三角函数运算!
除了一阶滤波器,还可以将多个滤波器进行串联来实现截止频率后信号的更快速下降。
也有一些滤波器使用不同的传递函数。比如巴特沃斯滤波器、切比雪夫滤波器、椭圆滤波器等。它们会有一些比较有趣的特性。比如巴特沃夫滤波器通过改变Q值可以在截止频率上形成突起或下陷:
是不是感觉有点眼熟?眼熟就对了。加载一个Q3并挂一个高切:
还记得上文中-6dB每倍频的下降速度吗?在音乐中,每倍频是一个八度。让我们验证一下:
可以看到不同下降速率都是6的整数倍,说明下拉列表里的选项实质上是改变滤波器的阶数。
参考文献: