audio - 如何进行音频扩展/归一化(强调高低之间的差异)
问题描述
我试图找到强调音频中高点和低点之间差异的方法。我似乎找不到有关如何执行此操作的文档-也许可以使用 ffmpeg 完成。真的很感谢那些对信号处理有更多了解的人的一些指示。
解决方案
从根本上说,膨胀机是压缩机的对立面*;您可能会更幸运地找到有关如何实现这些的文档。它们与噪音门也有很多共同点。
扩展器
基本方法是实现一个包络跟随器,并使用包络的值来缩放音频源。包络跟随器试图跟踪音频信号的幅度。
一个基本的 pythonic 伪代码框架看起来有点像这样:
envelope_follower e # some envelope follower, we'll replace this
for each sample x:
amplitude = e.get(x) # use the envelope follower to estimate the amplitude of e
x = expand(x, amplitude) # apply some expansion operation
在最基本的情况下,expand
操作如下所示(假设您的样本介于 -1.0 和 1.0 之间):
def expand(x, amplitude):
return x * amplitude
还有更复杂的方法,例如钳位和缩放幅度,使其永远不会低于 0.5,或者在相乘之前对幅度应用一些非线性函数。
# just an example
def expand(x, amplitude):
return x * clamp(1.2 * amplitude - 0.2 * (amplitude * amplitude), 0.3, 1.0)
信封追随者
压缩器/扩展器的质量几乎完全取决于您如何实现包络跟随器。这不是一门精确的科学,因为非常精确的包络跟随器在某些情况下可能会导致一些令人讨厌的声音效果 - 需要做出权衡。
与所有这些事情一样,有很多方法!这是一对:
滤波整流器
最简单的方法之一 - 特别是如果您已经拥有一个信号处理模块库 - 是低通滤波整流器。
它是这样工作的:
class envelope_follower:
lowpassfilter filter;
def get(x):
return filter.process( abs(x) )
您在此处获得的控件基本上围绕您的滤波器设计和低通截止。使用一个简单的泄漏蓄能器过滤器会让你走得很远。
攻击释放追随者
人们通常想要更多地控制他们的扩展器,有时很难考虑滤波整流器的实际效果——调整一个参数可能会改变它的很多行为。
压缩器/扩展器的真实信号通常非常需要快速响应(例如,对钢琴或鼓的冲击),并且释放速度很慢(因此钢琴音符的尾部不会突然被切断)
Attack-Release follower 通过指定多个参数来提供更精确的控制:
- 两个阈值
- 一个阈值,超过该阈值时声音应该变大
- 一个阈值,低于该阈值的声音应该变得更安静(不一定是相同的阈值,但可以!)
- 两个时间段:
- 超过第一个阈值时达到最大响度需要多长时间(这是Attack参数)
- 需要多长时间才能达到安静(发布)
实现其中之一的一种基本方法是:
class envelope_follower:
# Parameters required. These are just made up
attack_threshold = 0.6
release_threshold = 0.3
attack_time = 10 # in samples
release_time = 1000 # in samples
amp = 0.0
def get(x):
# we still work with the absolute value.
# You might use another measure of amplitude here like RMS
# or even the filtered rectifier above
a = abs(x)
if x > attack_threshold:
amp += (1.0 / attack_time)
else if x < release_threshold:
amp -= (1.0 / release_time)
amp = clamp(amp, 0.0, 1.0)
return amp
这种类型的跟随器的一个常见扩展是添加一个Hold参数,它指定扩展器应该完全打开的最小时间长度。这可以避免包络在低频信号上产生可听见的三角波或锯齿波。
一个更复杂的方法是做一个完整的 Attack-Decay-Sustain-Release,它可以让你控制瞬态并且通常用作鼓处理。
变得狂野
从这里,您可以:
创建更平滑的
expand
函数相当简单地将上述调整为压缩器 - 一种组合设备,可以使低音静音,但也可以使过分响亮的声音静音;
将一个信号分成多个频段,并分别压缩/扩展每个频段。这通常会在音乐母带处理期间获得真实的最大振幅;
根据您正在扩展的声音的频谱内容调整 Attack/Hold/Release。非常短的启动/释放时间对于高频信号来说很好,但对于低频信号来说听起来很糟糕;
为超过阈值的声音添加轻微的饱和失真;即使信号仍然具有相同的最大幅度,这也会使事情在感知上更响亮。理想情况下,您需要一个完全不影响阈值以下信号的饱和器。
祝你好运!
* 不要与 MP3 风格的压缩相混淆。压缩器压缩动态范围。
推荐阅读
- ios - 如何在 iOS Safari 上访问完整的相机分辨率?
- r - 难以将数据集中的宽格式转换为整齐的格式
- github - Hydrograph Tool 是否有可用的文档?
- rx-java - RXJava 顺序执行 http 请求
- php - 为什么我会收到 ERR_NAME_NOT_RESOLVED?
- kubernetes - 如何测量 kubernetes POD 内的容器执行时间?
- javascript - Vuejs 动态添加 ref undefined
- linux - “go build”命令后找不到可执行文件/二进制文件
- python-3.x - 如何更改选择器scrapy?
- python - 在不同的列中分离 Python Web 抓取的数据 (Excel)