10

これは実際には理論的な問題ですが、次のようになります。

エフェクト オーディオ ユニットを開発していますが、ドライ信号とウェット信号の間で等しいパワーのクロスフェードが必要です。

しかし、ドライ ストリームとウェット ストリームの信号振幅のリニア フェーダーからスケーリング ファクター (ゲイン) へのマッピング機能を実行する正しい方法について、私は混乱しています。

基本的に、cos / sin関数または平方根で行われるのを見ました...本質的に対数曲線を近似しています。しかし、私たちの振幅の知覚が最初から対数的である場合、フェーダー位置を振幅にマッピングするこれらの曲線は実際には指数関数的ではないでしょうか?

これが私が意味することです:

仮定:

  • signal[i]信号の i 番目のサンプルを意味します。
  • 各サンプルは、[0,1] の間の振幅に対して [-1, 1] の範囲の float です。
  • GUI コントロールは [0,1] の範囲の NSSlider であるため、原則として線形です。
  • faderNSSlider の値を持つ変数です。

最初の観察: 対数的に振幅を知覚します。したがって、線形フェーダーがあり、信号の振幅を調整するだけの場合:signal[i] * fader私たちが知覚しているもの (数学に関係なく聴覚) は、次のようなものです。

ここに画像の説明を入力

これはいわゆるくだらないフェーダー効果です。スライダーの左端のセグメントで無音から劇的な音量増加に移行し、中央を過ぎると音量がそれほど大きくならないように見えます。

したがって、フェーダーを「正しく」行うには、代わりに dB スケールで表現してから、信号に関する限り、次のようにします。signal[i] * 10^(fader/20)または、[0,1] でフェーダー単位を保持する場合は行う :signal[i] * (.001*10^(3*fader))

いずれにせよ、NSSlider からコード内で乗算に使用するフェーダー変数への新しいマッピングは、次のようになります。

ここに画像の説明を入力

対数的に振幅を知覚するため、基本的に線形(NSSLider 範囲 0-1) から指数関数にマッピングし、この指数出力を対数知覚に供給するため、これが実際に必要なことです。そして、次のことが判明しました。つまりlog(10^x)=x、振幅の変化を線形 (つまり正しい) 方法で知覚することになります。

偉大な。

ここで、私の考えでは、2 つの信号間の等パワー クロスフェード (この場合、AU への入力とそこからの処理済み出力を混合するためのドライ/ウェット水平 NSSlider) は、1 つのスライダーが作用する場合と本質的に同じです。仮想信号 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);

そのグラフは次のようになります。

ここに画像の説明を入力

前と同じように、対数的に振幅を知覚するため、この指数マッピングは、実際には、クロスフェードが線形として聞こえる場所になるはずです。

ただし、近似を使用して曲線を記録するクロスフェードの実装を見てきました。代わりに、次のことを意味します。

ここに画像の説明を入力

しかし、これらの曲線は実際には振幅の対数的知覚を強調しているのではないでしょうか?

4

1 に答える 1

9

あなたが考えている「等しいパワー」クロスフェードは、ウェットからドライにフェードするときに、ミックスの総出力パワーを一定に保つことに関係しています。総パワーを一定に保つことは、全体の知覚ラウドネスを一定に保つための合理的な近似として機能します (実際にはかなり複雑になる可能性があります)。

等しい電力の 2 つの無相関信号間でクロスフェードを行う場合、2 乗値の合計が 1 になる任意の 2 つの関数を使用することで、クロスフェード中に一定の出力電力を維持できます。これの一般的な例は、一連の関数です。

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 を満たすことに注意してください)。これにより、相関のない信号に対して一定のパワー クロスフェードが発生することが証明されます。

等しいパワー E[ x1(t)^2 ] = E[ x2(t)^2 ] = Px を持つ 2 つの信号 x1(t) と x2(t) があり、これらも無相関 ( 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 であることを使用しました。 t) と x2(t) は無相関であると仮定されます。これは、クロスフェードのどこにいても (選択した k が何であれ)、出力は同じパワー Px を持ち、知覚されるラウドネスが等しいことを意味します。

完全に相関した信号の場合、「線形」フェードを実行することで一定の出力パワーを実現できることに注意してください。これには、2 つの関数の合計が 1 になる ( g1(k) + g2(k) = 1 ) を使用します。ある程度相関する信号を混合する場合、理論的には、これら 2 つの間のゲイン関数が適切です。

と言う時に何を考えているのか

前と同じように、対数的に振幅を知覚するため、この指数マッピングは、実際には、クロスフェードが線形として聞こえる場所になるはずです。

派生したクロスフェードを適用すると、一方の信号はスライダー位置 (k) の線形関数としてラウドネスが知覚的に減少し、もう一方の信号はスライダー位置の線形関数としてラウドネスが知覚的に増加する必要があります。その導出はかなり的を射ているように見えますが、残念ながら、一貫性の点でドライ信号とウェット信号をブレンドする最良の方法ではない可能性があります.多くの場合、スライダーの位置に関係なく、出力ラウドネスを等しく維持することがより良い方法です. いずれにせよ、いくつかの異なる関数を試して、何が最も使いやすく一貫性があるかを確認する価値があるかもしれません。

于 2012-07-01T06:42:42.583 に答える