音频单元中的等功率交叉淡入淡出?

时间:2012-04-16 04:49:45

标签: macos audio core-audio audiounit

这实际上更像是一个理论问题,但在这里:

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

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

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

这就是我的意思:

假设:

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

第一次观察: 我们以对数方式感知振幅。因此,如果我们有一个线性推子,只是通过这样做来调整信号的幅度:signal[i] * fader我们所感知的东西(听觉,无论数学如何)都是这样的:

enter image description here

这就是所谓的蹩脚的推子效应:我们从静音变为滑块中最左边一段的剧烈音量增加,经过中间音量似乎没有那么响亮。

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

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

enter image description here

这是我们真正想要的,因为我们以对数方式感知振幅,我们实质上是从线性(NSSLider范围0-1)映射到指数并且以指数方式提供输出到我们的对数感知。事实证明: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);

图表为:

enter image description here

和以前一样,因为我们以对数方式感知振幅,这种指数映射实际上应该使我们听到交叉渐变是线性的。

但是,我已经看到使用近似值来记录交叉渐变的实现。意思是:

enter image description here

但这些曲线实际上不会强调我们对振幅的对数感知吗?

1 个答案:

答案 0 :(得分:7)

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

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

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

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

其中0 <= k <= 1(注意,如上所述,满足g1(k)^ 2 + g2(k)^ 2 = 1)。这证明了这导致了不相关信号的恒定功率交叉衰减:

假设我们有两个信号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)的线性函数在感知上降低,而另一个信号应该在响度上作为滑块位置的线性函数在感知上增加,当应用您的导出交叉渐变时。虽然你的推导似乎相当不错,但不幸的是,这可能不是在干燥和潮湿信号融合方面的最佳方式 - 通常,无论滑块位置如何,保持相等的输出响度都是最好的选择。无论如何,可能值得尝试几种不同的功能来查看最有用和最一致的功能。