实现音频延迟效果单元
Posted
技术标签:
【中文标题】实现音频延迟效果单元【英文标题】:Implementing audio delay effects unit 【发布时间】:2013-10-12 23:12:27 【问题描述】:我正在创建一个音频延迟单元。本质上,传入的样本进入一个循环缓冲区,并从一些读指针中挑选出来,该读指针是写指针后面的一些样本。对于每个新样本,这些指针都会加一。
此外,为了允许分数延迟,我实际上有两个读取指针,它们相隔一个样本,并根据浮点延迟参数使用双线性插值在它们之间进行混合。 (我可以使用 sinc 插值或其他东西,但还没有考虑过。)
当延迟设置为特定值时,一切正常。但是当用户在播放声音时改变延迟时,由于延迟抽头的变化,噼啪声也很明显。据推测,它是在不同样本处提取信号并在音频波形中引入随机阶跃不连续性。
我想知道是否有任何 DSP 音频爱好者知道如何解决这个问题,因为我知道我玩过延迟盒,但不会发生这种效果,但目前我想不出一个解决方案。
【问题讨论】:
你不是在做双线性插值,只是普通的旧线性插值。例如,在成像中将使用双线性插值。 en.wikipedia.org/wiki/Bilinear_interpolation 【参考方案1】:当您更改延迟时,总会出现某种失真。只需选择您想要的。
正如您所发现的,如果您只是掉入一个随机点,从一个样本值到下一个样本值的急剧跳跃通常会导致可听见的爆裂声。一种选择是简单地将音频静音一小段时间,然后重新启动。如果这仍然太突然,您可以在几毫秒内将值缩小到零,然后在几毫秒内将它们放大到新的缓冲区位置。 (有效地快速调低音量,然后在您处于新位置时再调高。)
Propellerhead 的 Reason 实际上模拟了加快和减慢录制速度,就好像它是磁带延迟一样,并且您正在移动磁头。这非常复杂...您实际上是在动态重新采样缓冲区音频,直到到达新的缓冲区位置。
【讨论】:
这是一个很酷的答案。我对最后一个很感兴趣。问题是用户动态地改变控制器上的延迟,所以我收到可能经常出现的控制消息,所以静音不是一个选项,因为我不想中断音频。我确实提出了一种与您类似的可能解决方案,即在 10 毫秒内将音频从一个延迟交叉淡化到另一个延迟。这引入了控制延迟,但我怀疑它会在过渡中混合。然而,簿记相当复杂,尤其是在交叉淡入淡出完成之前,新的控制消息可能会到达。 这是一个很好的答案。请注意,它确实引入了伪影,因为您正在重新采样您的信号。特别是,如果您正在调高(减少延迟时间),您可能会产生混叠失真。【参考方案2】:我不知道 DSP 单元是如何做到的,但我建议您对用户设置的延迟应用 低通滤波器,以消除任何突然的变化。
令set_delay[n]
代表用户在时间样本n
设置的延迟,令filtered_delay[n]
为过滤后的延迟。最简单的低通滤波器是单极点 IIR 滤波器:
filtered_delay[n] = (1-alpha)*filtered_delay[n-1] + alpha*set_delay[n]
值alpha
控制滤波器的时间常数。应该选择它作为响应性和平滑性之间的权衡。
例如,如果用户突然将 set_delay
从 100 个样本更改为 50 个样本,则 filtered_delay
与 alpha=0.1
将是:95, 90.5, 86.45, ...,因此慢慢地 从 100 减少到 50。
【讨论】:
【参考方案3】:当用户在播放声音时改变延迟时,会发出噼啪声 由于延迟抽头的变化,噪声也很明显。大概是 在不同的样本中提取信号并引入随机 音频波形中的阶跃不连续性。
是的。这是完全正确的。我认为解决这个问题最自然的方法是平滑延迟时间的变化。例如,不是从 200 毫秒延迟跳到 500 毫秒,您的延迟效果应该在一段时间内平滑地从 200 毫秒变为 500 毫秒。使用这种技术,延迟的音频会根据延迟时间的变化速度下降或上升。
这种技术会引入混叠(正如 Bjorn Roche 在 cmets 中指出的那样)。如果这是一个问题,一种解决方案是使用bandlimited interpolation。
【讨论】:
以上是关于实现音频延迟效果单元的主要内容,如果未能解决你的问题,请参考以下文章
当我需要自定义音频效果时,我是不是需要处理音频单元,或者我可以依赖音频队列服务?