本文对笔者关于音频信号处理中的 Limiter 的理解作以记录。如有表述不当之处欢迎批评指正。欢迎任何形式的转载,但请务必注明出处。
文章目录
1. 引言
由于工作上的需要,笔者花了一周左右的时间对 limiter(它属于动态范围控制器里面的一种算法,动态范围控制器包括 compressor, expander, limiter 和 noise gate 等,感兴趣的读者可参考笔者的另一篇博客)进行了研究学习。期间也阅读了不少资料,对 limiter 算是有了较深入地了解。在此对整个学习过程、笔者的感悟以及算法背后所蕴含的思想作以记录,以方便后续回顾和他人学习。
相比于音频信号处理中的其它算法,limiter 是一个存在感较低的算法,各种资料上所呈现出的原理和实现过程也相对简单,基本一看就懂。但是按照该原理所实现的 limiter 仍然需要接后处理才能满足实际需要。
本文首先介绍了 Matlab 上的实现,笔者称之为一阶递归平滑版本的 limiter,该版本也是上面所说的大多数资料上呈现的版本;然后介绍了 FFMPEG 里面的实现,笔者称之为逐采样点过渡平滑的 limiter。两个版本各有优缺点,可根据具体应用的需要选择相应的版本。
2. Limiter 的主要作用
在音频信号处理中,通常的做法是先将音频采样点归一化到 [ − 1.0 , 1.0 ] [-1.0,1.0] [−1.0,1.0],然后再对其施加各种各样的音频算法。然而在算法处理过程中可能会出现某些音频采样点的幅度超过 1 1 1 的情况。或者在将多路音频流混合成一路音频流的时候,采样点相加的过程中也有可能出现幅度超过 1 1 1 的情况。而使用 limiter 的主要目的就是在尽量不变动其它采样点的情况下,将这些采样点的幅度全部限制在 1 1 1 以内,以避免削波。
3. 简单粗暴做法
考虑下面的采样点序列 x ( n ) , n = 1 , 2 , ⋯ , 9 , 10 x(n), n=1,2,\cdots,9,10 x(n),n=1,2,⋯,9,10:
0.990 , 0.995 , 0.997 , 0.999 , 1.010 , 1.005 , 0.998 , 0.997 , 0.995 , 0.992 \; 0.990, \; 0.995, \; 0.997, \; 0.999, \; 1.010, \; 1.005, \; 0.998, \; 0.997, \; 0.995, \; 0.992 0.990,0.995,0.997,0.999,1.010,1.005,0.998,0.997,0.995,0.992
可以看到中间有两个采样点的幅度是超过 1 1 1 的,而最简单粗暴的做法就是令这两个采样点的幅度等于 1 1 1(或者小于 1 1 1 但是又特别特别接近于 1 1 1 的一个数,这个数也称为 limiter 的阈值,此处令该阈值等于 1 1 1)。经过处理之后,上面的采样点序列变为 x ^ ( n ) \hat{x}(n) x^(n):
0.990 , 0.995 , 0.997 , 0.999 , 1.000 , 1.000 , 0.998 , 0.997 , 0.995 , 0.992 \; 0.990, \; 0.995, \; 0.997, \; 0.999, \; 1.000, \; 1.000, \; 0.998, \; 0.997, \; 0.995, \; 0.992 0.990,0.995,0.997,0.999,1.000,1.000,0.998,0.997,0.995,0.992
而这种做法可能存在的一个问题就是,相比处理之前,处理之后的采样点之间出现了突变,变得不平滑,在频谱上看的话就是高频多了些东西出来,听着可能会有杂音。
4. 简单粗暴做法的另一种理解:增益因子
可以换个角度理解上述简单粗暴做法,即 x ^ ( n ) \hat{x}(n) x^(n) 是通过给 x ( n ) x(n) x(n) 中的每个采样点乘以相应的增益因子得到的,而这个增益因子序列 g ( n ) g(n) g(n) 为:
1 , 1 , 1 , 1 , 1 / 1.010 , 1 / 1.005 , 1 , 1 , 1 , 1 , 1, \; 1, \; 1, \; 1, \; 1/1.010, \; 1/1.005, \; 1, \; 1, \; 1, \; 1, 1,1,1,1,1/1.010,1/1.005,1,1,1,1,
也就是说 x ^ ( n ) = x ( n ) g ( n ) \hat{x}(n) = x(n) g(n) x^(n)=x(n)g(n)。可以看到,幅度小于 limiter 阈值的采样点的增益因子为 1 1 1。幅度大于 limiter 阈值的采样点的增益因子小于 1 1 1,且幅度越大,增益因子越小。也就是说,增益因子可由以下公式计算:
g ( n ) = { 1 , abs ( x ( n ) ) ≤ l t l t / abs ( x ( n ) ) , abs ( x ( n ) ) > l t (1-1) g(n) = \begin{cases} 1, & \text{abs}(x(n)) \leq lt \\ lt / \text{abs}(x(n)), & \text{abs}(x(n)) > lt \end{cases} \tag{1-1} g(n)={
1,lt/abs(x(n)),abs(x(n))≤ltabs(x(n))>lt(1-1)
其中 l t lt lt 表示 limiter 的阈值(此处取值为