我正在尝试在 JavaScript 中实现音频动态范围压缩(不使用网络音频 API)。
有很多针对声音技术人员的文章和一些高级文档,但我找不到任何有用的参考来实际实现数字动态范围压缩。
据我了解,计算整流信号至少有 3 个步骤。
- 计算输入电平
- 计算应用于信号的增益
- 应用增益
我以块为单位处理音频,所以对于 1)我正在考虑计算一个块的 RMS
任何指向一个好的参考?或者有人愿意向我解释一下实现这一点所需的步骤吗?
我正在尝试在 JavaScript 中实现音频动态范围压缩(不使用网络音频 API)。
有很多针对声音技术人员的文章和一些高级文档,但我找不到任何有用的参考来实际实现数字动态范围压缩。
据我了解,计算整流信号至少有 3 个步骤。
我以块为单位处理音频,所以对于 1)我正在考虑计算一个块的 RMS
任何指向一个好的参考?或者有人愿意向我解释一下实现这一点所需的步骤吗?
以下是一些建议:
原理是创建信号的包络(由启动和释放控制),使用一些传递函数(由比率、阈值和拐点控制)对该包络进行整形,然后将该结果应用回原始信号。化妆增益阶段通常会随之而来。
@Deve 的回答提出了一些可能的传递函数。
作为一个简单的开始,我将使用一个非线性特性来压缩您的输入信号:
其中(正如 endolith 在评论中指出的那样)是输入音频信号的包络是应用于实际音频信号的输出包络。可以是比小输入值衰减大输入值的任何函数。例如,已经开发了A-Law和 - Law函数来压缩电话的语音信号。不过,我不知道这听起来对音乐有多好。
另一个非常简单的压缩函数是衰减高于某个阈值的所有幅度: 其中是衰减。但这不会很好地工作,因为我们的听觉是对数的,因此衰减可能太强了。这就是为什么音频压缩器在对数刻度上工作的原因,它导致与上述相同的功能,但所有值都取对数并且相对于最大可能值。对于:
对于音频压缩器,通常以 dB 为单位给出,表示为某个比率,例如 3:1(即)。这会产生一个指数函数,当线性表示时(希望它是正确的,请检查它,也): 这个函数有一个“硬拐点”,意味着函数处不可微。对于“软膝盖”,此时您需要一些平滑的过渡。上述函数对负
起音和放音会影响不同的声音,例如底鼓、军鼓和人声。它们确定在达到阈值之前压缩器应该开始工作多长时间,以及在信号低于阈值后它应该继续工作多长时间。要实现这一点,您将不得不使用某种前瞻性。
的所有幅度都被衰减,可用的动态范围没有被充分利用。这通过所谓的“补偿增益”来校正,它只是压缩信号与增益因子的简单乘法。通过首先降低动态范围然后放大信号压缩器可以使音乐显得“响亮”。