【问题标题】:equal power crossfade in Audio Unit?音频单元中的等功率交叉淡入淡出?
【发布时间】:2012-04-27 11:18:22
【问题描述】:

这实际上更像是一个理论问题,但它是这样的:

我正在开发一个效果器音频单元,它需要在干湿信号之间进行相等功率的交叉渐变。

但是对于干湿流信号幅度从线性推子到比例因子(增益)的映射函数的正确方法,我感到困惑。

基本上,我已经看到它是用 cos / sin 函数或平方根完成的......基本上是近似对数曲线。但是,如果我们对幅度的感知一开始是对数的,那么这些将推子位置映射到幅度的曲线不应该是指数级的吗?

这就是我的意思:

假设:

  • signal[i] 表示信号中的第 i 个样本。
  • 每个样本都是一个浮点数,范围为 [-1, 1],幅度在 [0,1] 之间。
  • 我们的 GUI 控件是一个 NSSlider,范围从 [0,1],所以它在 线性原则。
  • fader 是一个带有 NSSlider 值的变量。

第一次观察: 我们以对数方式感知幅度。因此,如果我们有一个线性推子,并且只是通过执行以下操作来调整信号的幅度:signal[i] * fader 我们所感知的(听到的,无论数学如何)大致如下:

这就是所谓的糟糕推子效果:我们从静音到滑块最左侧部分的音量急剧增加,而中间的音量似乎并没有变得那么响亮。

因此,要“正确”地使用推子,我们要么以 dB 标度表示它,然后就信号而言,执行:signal[i] * 10^(fader/20) 或者,如果我们要保持或推子单位为 [0 ,1],我们可以这样做:signal[i] * (.001*10^(3*fader))

无论哪种方式,我们从 NSSlider 到我们将在代码中用于相乘的推子变量的新映射现在看起来像这样:

这是我们真正想要的,因为我们以对数方式感知幅度,所以我们本质上是从 linear(NSSLider 范围 0-1)映射到 exponential 并输入这个指数输出到我们的对数感知。事实证明:log(10^x)=x 所以我们最终以线性(又名正确)方式感知幅度变化。

太棒了。

现在,我的想法是,两个信号之间的等功率交叉淡入淡出(在这种情况下,一个干/湿水平 NSSlider 将 AU 的输入和处理后的输出混合在一起)与一个信号基本相同滑块作用于假设信号 dry[i] 和 wet[i]。

因此,如果我的滑块范围从 0 到 100,并且干燥是全左,湿是全右),我最终会得到如下代码:

Float32 outputSample, wetSample, drySample = <assume proper initialization>
Float32 mixLevel = .01 * GetParameter(kParameterTypeMixLevel);
Float32 wetPowerLevel = .001 * pow(10, (mixLevel*3)); 
Float32 dryPowerLevel = .001 * pow(10, ((-3*mixLevel)+1));
outputSample = (wetSample * wetPowerLevel) + (drySample * dryPowerLevel);

其中的图表将是:

和以前一样,因为我们以对数方式感知幅度,所以这个指数映射实际上应该使它在我们听到交叉淡入淡出的地方成为线性。

但是,我已经看到了使用近似值来记录曲线的交叉淡入淡出的实现。意思是:

但这些曲线难道不会真正强调我们对幅度的对数感知吗?

【问题讨论】:

  • 我建议在 DSP 姊妹网站上问这个问题:dsp.stackexchange.com
  • 我想我现在知道了,但是我不知道那个网站!
  • 酷。如果你弄明白了,你应该回答你自己的问题——我想知道你想出的答案。

标签: macos audio core-audio audiounit


【解决方案1】:

您正在考虑的“等功率”交叉渐变与在您从湿渐变到干时保持混音的总输出功率恒定有关。保持总功率恒定作为保持总感知响度恒定(实际上可能相当复杂)的合理近似值。

如果您在两个功率相等的不相关信号之间进行交叉淡变,则可以通过使用平方值总和为 1 的任意两个函数在交叉淡变期间保持恒定的输出功率。这方面的一个常见示例是函数集

g1(k) = ( 0.5 + 0.5*cos(pi*k) )^.5

g2(k) = ( 0.5 - 0.5*cos(pi*k) )^.5,

其中 0

假设我们有两个信号 x1(t) 和 x2(t) 具有相等的幂 E[ x1(t)^2 ] = E[ x2(t)^2 ] = Px,它们也是不相关的 ( E[ x1 (t)*x2(t)] = 0)。请注意,满足先前条件的任何一组增益函数都将具有 g2(k) = (1 - g1(k)^2)^.5。现在,形成总和 y(t) = g1(k)*x1(t) + g2(k)*x2(t),我们有:

E[ y(t)^2 ] = E[ (g1(k) * x1(t))^2  +  2*g1(k)*(1 - g1(k)^2)^.5 * x1(t) * x2(t)  +  (1 - g1(k)^2) * x2(t)^2 ] 
= g1(k)^2 * E[ x1(t)^2 ] + 2*g1(k)*(1 - g1(k)^2)^.5 * E[ x1(t)*x2(t) ] + (1 - g1(k)^2) * E[ x2(t)^2 ]
= g1(k)^2 * Px + 0 + (1 - g1(k)^2) * Px = Px,

我们使用了 g1(k) 和 g2(k) 是确定性的,因此可以被拉到期望算子 E[ ] 之外,并且 E[ x1(t)*x2(t) ] = 0 根据定义因为假设 x1(t) 和 x2(t) 不相关。这意味着无论我们在淡入淡出的哪个位置(无论我们选择什么 k),我们的输出都将具有相同的功率 Px,因此希望与感知响度相同。

请注意,对于完全相关的信号,您可以通过执行“线性”衰减来实现恒定的输出功率 - 使用和两个函数之和为 1 ( g1(k) + g2(k) = 1 )。当混合有些相关的信号时,这两者之间的增益函数在理论上是合适的。

你说的时候在想什么

和以前一样,因为我们以对数方式感知幅度, 这个指数映射实际上应该使它在我们听到的地方 交叉淡入淡出为线性。

当应用推导的交叉淡入淡出时,一个信号的响度应该随着滑块位置 (k) 的线性函数而在感知上降低,而另一个信号在响度上应该作为滑块位置的线性函数在感知上增加。虽然您的推导似乎很准确,但不幸的是,这可能不是混合干湿信号一致性的最佳方式 - 通常,无论滑块位置如何,保持相同的输出响度是更好的选择。在任何情况下,可能值得尝试几个不同的功能,看看什么是最有用和最一致的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-12
    • 2020-07-01
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 2011-04-19
    相关资源
    最近更新 更多