クリッピングせずにオーディオ信号をミックスするアルゴリズム


49

2つ以上のPCMオーディオチャネル(録音されたサンプルなど)を音響的に忠実に、できればほぼリアルタイム(ピークがほとんどまたはまったくない)でデジタルでミックスしたいと思います。

これを行う物理的に「正しい」方法は、サンプルを合計することです。ただし、2つの任意のサンプルを追加すると、結果の値は最大値の2倍になる可能性があります。

たとえば、サンプルが16ビット値の場合、結果は最大65536 * 2になります。これにより、クリッピングが発生します。

ここでの単純な解決策は、Nで割ることです。ここで、Nは混合されるチャネルの数です。ただし、これにより、各サンプルは1 / Nthの音量になり、完全に非現実的です。現実の世界では、2つの楽器が同時に演奏されると、各楽器の音量は半分になりません。

一般的なミキシング方法は、result = A + B-ABです。ここで、AとBは混合される2つの正規化されたサンプルであり、ABはより大きな音がますます「ソフトクリップ」されることを保証する用語です。

ただし、これにより信号に歪みが生じます。このレベルの歪みは、高品質のオーディオ合成で許容されますか?

この問題を解決する他の方法はありますか?効率の悪い低品質のアルゴリズムと、効率の低い高品質のアルゴリズムに興味があります。

複数の楽器トラックを一緒にミキシングするために、デジタル音楽シンセシスのコンテキストで質問をしています。トラックは、合成オーディオ、事前に録音されたサンプル、またはリアルタイムのマイク入力です。


信号を少しタイムシフトするだけで、クリッピングをどのくらいの頻度で回避できるのでしょうか。
セバスチャンライシェルト

良い考えですが、特にそれほど先読みがない場合(リアルタイムなど)、それほど単純ではないと思います。問題は、どのような種類のタイムシフトが適切かを知るために、事前にサンプルを知る必要があることです。とはいえ、ほとんどの音楽では相関の可能性が高いので、ランダムな時間シフトが少しうまく機能する可能性があります。誰もがここで描く経験がありますか?
-bryhoyt

2
@bryhoyt:実際のミキサーは信号を合計します。それでおしまい。時間遅延や非線形処理は必要ありません。元の信号の大きさはそれほど大きくなかったため、クリッピングは問題になりません。
エンドリス

2
16 + 16ビット= 17ビット;-)
nikwal

1
入力の数で割るだけで、クリッピングはできなくなります。そして、音が...アンプを上げ、小さすぎる場合
Sargeのボルシチ

回答:


14

問題のコンテキストを知らずに関連するテクニックを指摘するのは非常に困難です。

明白な答えは、各サンプルのゲインを調整して、クリッピングがほとんど発生しないようにすることです。ミュージシャンがソロで演奏するように求められたときよりもアンサンブルでソフトに演奏すると仮定することはそれほど非現実的ではありません。

A + B-ABによって導入された歪みは受け入れられません。Bの倍音の両側にAの鏡像を作成します-リング変調に相当します-AとBが整数比ではない倍音で豊かなスペクトルを持っている場合はかなりひどいです。たとえば、220 Hzと400 Hzの2つの方形波で試してください。

サンプルごとのサンプルで機能するより「自然な」クリッピング関数は、tanh関数です-実際には、いくつかのアナログ要素のソフト制限動作に一致します。それを超えて、古典的な動的圧縮技術を調べることができます-システムが先を見て、ピークが来るのを前もって見ることができれば、これはさらに良いです。


4
追加とハードクリッピング。オープンソースのmodプレーヤーを見てください。入力がクリッピングを最小限に抑えるために、適切にスケーリングされ、次いで(必要に応じてソフト)ハードリミッタが標準ではなく例外で...と、混合するための添加を用い
pichenettes

4
ほとんどの場合、これは問題を解決する開発者の責任ではありません。ユーザー/作曲家に各チャンネルの音量を調整する可能性を与えます。そして、クリップが受け入れられるようにミックスを行うのはユーザー次第です。たとえば、Renoiseでは、デフォルトで各楽器/ノートのゲインは1であり、トラックを追加すると物事がひどくクリッピングを開始します-モジュール内のノートまたはインストゥルメントの音量を調整して、マスタートラック(必要な場合を除く)。これを示すスクリーンショットは次のとおりです。i.imgur.com / KVxDt.png
ピクネット

2
IIRC、FastTrackerは、各トラックに減衰を適用し、設定ダイアログでx1からx32までのグローバルな「メイクアップゲイン」を持つという点で、より保守的でした。私はCDのために.WAVにすべての私のモジュールをレンダリングするために持っていたとき、私はクリッピング起こさなかった最低のものを見つけるまで、ゲインの値を試していたことを覚えておいてください...
pichenettes

2
ループ内にユーザーを配置できない場合の減衰レベルについて。1/32は絶対に安全なレベルです(クリッピングなし)。チャンネルが相関していないと仮定すると(これは音楽にはあまり当てはまりません-背景の雰囲気をミックスする場合により正確です)、1 / sqrt(32)の値はラウドネスとクリッピング確率の適切な妥協点になります。最善の解決策は、1/32を使用してから、動的コンプレッサーでサンプルを後処理することです。
ピクネット

3
追加。それはハードウェアミキサーがとにかくすることであり、それは人々が物事の振る舞いを期待する方法です。システムレベルのミキサーはクリップするだけです。システムドライバーがあらゆる種類の非線形処理を実装している場合、それは大きな問題になります-マスタリングエンジニアが耳にするのは、コンプレッサープラグインの設定なのか、システムレベルの動的な処理なのかを把握しようとする痛みを想像します。音楽制作ソフトウェアは、ダイナミック圧縮プラグインの幅広いパレットを提供します。ミックスがクリップしないことを確認するのはユーザー次第です。
ピクネット

16

これを行う物理的に「正しい」方法は、サンプルを合計することです。ただし、2つの任意のサンプルを追加すると、結果の値は最大値の2倍になる可能性があります。...ここでの単純な解決策は、Nで除算することです。ここで、Nは混合されるチャネルの数です。

それは「単純な」ソリューションではなく唯一のソリューションです。それは、すべてのアナログおよびデジタルミキサーが行うことです。なぜなら、それは空気が行うことであり、脳が行うことだからです。

残念ながら、これはこれらの他の誤った非線形「ミキシング」(歪み)アルゴリズムによって実証されるように、一般的な誤解であると思われます。

「Nによる除算」はヘッドルームと呼ばれます。波形のRMSレベルを超えて割り当てられたピーク用の追加スペース。信号に必要なヘッドルームの量は、信号の波高率によって決まります。(デジタル信号レベルとヘッドルームの誤解は、おそらくラウドネス戦争エレファンクのせいかもしれません。)

アナログハードウェアでは、ヘッドルームはおそらく20 dBです。ハードウェアDSPでは、固定ヘッドルームを備えた固定小数点がよく使用されます。たとえば、ADのSigmaDSPには24 dBのヘッドルームがあります。コンピュータソフトウェアでは、オーディオ処理は通常32ビット浮動小数点で実行されるため、ヘッドルームは膨大です。

理想的には、Nで除算する必要はまったくありません。信号はそもそも0 dBFSで生成されないため、信号を合計するだけです。

とにかく、ほとんどの信号は互いに相関していないため、ミキサーのすべてのチャンネルが同時に建設的に干渉することはまれです。はい、10個の同一の同相正弦波を混合すると、ピークレベルは10倍(20 dB)増加しますが、10個の非コヒーレントノイズソースを混合すると、ピークレベルは3.2倍(10 dB)しか増加しません。実際の信号の場合、値はこれらの両極端の間になります。

クリッピングなしでDACから混合信号を取り出すには、単純に混合のゲインを下げます。ハードクリッピングなしでミックスのRMSレベルを高く保ちたい場合、何らかのタイプの圧縮を適用して波形のピークを制限する必要がありますが、これはミキシングの一部ではなく、別のステップです。必要に応じて、最初に十分な余裕を持ってミックスし、その後ダイナミックレンジ圧縮を行います。


1
私はこれらの概念を理解していますが、それがまったく正しいかどうかはわかりません。確かに、16ビットのサンプルを大量に追加すると、32ビットで数値の余地が増えます。しかし、実際のサウンドシステムでは、結果のミックスを正規化されたボリュームで再生する必要があります。各チャンネルを個別に再生するよりも2つのチャンネルの音を大きくしたいのですが、クリッピングはしません。32ビットまたは64ビットで合計を実行しても、これには役立ちません。おそらく、私は自分の質問に答え始めています。元のサンプルは最大振幅よりも静かなレベルで正規化する必要があります。ご提案のとおり、ミキシングの余地を残します。
-bryhoyt

3
@bryhoyt:はい。ただし、波が互いに相関することはめったにないので、5つの音を足しても5倍のピークにならないことも覚えておく必要があります。
エンドリス

1
おかげで、@ endolith、それが本当にこのすべての中心にあると思います。なぜ私が最初に思ったほど大きな問題ではないのかを説明します。
-bryhoyt

10の非コヒーレントソースが10 dBを与える場合、sqrt(ソースの数)で割ることは合理的な発見的方法でしょうか?つまり、3つのソースがある場合、それらを合計してsqrt(3)で除算しますか?(古代のスレッドについてコメントして申し訳ありません)
-nerdfever.com

@ nerdfever.comこれがRMSレベルの組み合わせです。だから...おそらく?
エンドリス

6

result=A+BAB

AB=AB

result=g(A+B)

g1

g=0.5g=1/2

g

result[i]=g[i](A[i]+B[i])

g[i]ABgresult

おそらくこれ:

g[i]=f(A[i]+B[i],g[i1])

更新:hotpaw2で示唆されているように、入力信号を遅延させることはできますが、ゲイン抑制はできません。これは「先読みリミッター」と呼ばれます。


「AB」とは「A * B」を意味します。振幅は正でも負でもよいことを理解しています。そうです、私の方程式は負の振幅を含む組み合わせにはあまり意味がありません。
-bryhoyt

8〜10(N)の異なる洞波を混合する必要があります。経験的に、正しい値は0.3前後であることがわかりました...
ジブリ

5

これは、非リアルタイムミキシングで先読みAGCを使用する方法の1つです。この方法では、合計振幅がクリッピング制限を超える前に、一方または両方のチャンネルのゲインが知覚しにくいレートで低下します。先読みが少ないほど、AGCゲイン調整が聞き取りやすくなります。または、ゲイン調整ランプをソフトにした場合の最大ゲインは、限界でチャンネルあたり0.5に近づきます。ある程度の予測可能性を備えた音源の場合、ゲインの制限を適応的に推測するために、エンベロープの経時的な統計に関する統計を使用することもできますが、障害の可能性があります(これは突然のAGCゲイン調整になります)。


これは先読みAGCではなく、先読みリミッターです。
ビヨンロシュ

2
@BjornRoche:リミッターをAGCの一種とみなすことはできませんか?
エンドリス

一部のリミッターはAGCですが、先読みリミッターはAGCではありません。
ビョルン・ロシュ

1
@BjornRocheだけでなく、それは...自動とコントロールゲイン
オッリNiemitalo

2

1990年代後半と2000年代初頭のミキサーデザイナーと話をしました。その男はSPLのデザイナーだったと思うが、それほど大きくはないかもしれない。名前もブランドも絶対に覚えていない。マシンがどれほど大きくて高価だったか覚えている。

長い話をし、最後に、64/128 @ 24ビットチャンネルが混合され、クリッピングのない24ビットの正確な混合出力チャンネルを維持することを本当に保証するためのテクニックについて話しました。

彼が説明したテクニックはかなりシンプルでした。64ビット(24ビット)のトラックが48ビットチャネルに追加され、クリッピングは発生しません。まっすぐ。

その信号がどのように48ビットから24ビットにディザリングされたかは言えません。たぶんそれはトリッキーなキッチンのレシピが適用される場所です。

そして、それを達成するための多くのテクニックがあるかもしれません。とりわけ、リアルタイムで行われるか、ハイピークで記録されたすべての信号で決定されるかによって、異なることが予想されます。


2

グローバルボリュームを下げます。インパルストラッカーは、デフォルトでデフォルトで最大約33%の音量でチャンネルを出力します。

これは、数チャンネル(4チャンネルAmiga MOD)の音楽には十分な大きさで、50チャンネルの曲には十分な大きさのようです(チャンネルの内容は通常相関していないため、音量が一定レベルを超えると速くなりません...)加えて、いくつかのチャンネルが最大音量で出力され、それだけの量が進行します)。また、ハードレフトまたはハードライトパンチャンネル(範囲の66%を使用)に十分なヘッドルームを残します。

また、チャンネルを16ビットで一緒に追加するのではなく、それらを32ビットで一緒に追加し、最後に結果をクリップして16ビットに減らします。計算中にラップアラウンドしないように、より高い範囲が必要になります。もう1つのオプションは、32ビット浮動小数点を使用することです(フィルターやエフェクトなどを行うのに便利です)。


0

重要なのは、16ビット値があり、最大値を超える可能性のある2つの値を加算する場合、2つのオプションがあるということです。

1)両方を32ビット加算にキャストし、加算がその値を超えた場合に最大値を返します。次に、16ビットにキャストします。たとえば、値が32768と34567の場合、65535を超え、65535を返すことが重要です。最小値の末尾で符号付きの値を使用する場合も同じことを行います。

2)両方の値を圧縮してから、それらを一緒に追加します。

最初は本質的にハードクリッピングで、2番目はソフトクリッピングです。アナログシステムはすべてハードクリッピングです。


0

両方のトラックの周波数が同じスペース周波数を使用する場合、それらはスペースの2倍になります。これを回避するには、eqと圧縮を使用して、各サウンドの周波数スペクトルの領域を切り分け、サウンドのトランジェントとサステインを制御して、すべてが必要な場所を突き出すようにします。たぶんそれは質問に答えません。低周波数の信号を最大2ミリ秒遅延させることができます。波長が高周波数よりも長いため、位相を介してキャンセルされません。また、過渡状態がパワーに飢えた低音信号に完全に間に合わないため、スペースが追加されます。信号が低ければ低いほど遅延を直線的に追加するものは、テストするのに興味深いでしょう。


-1
A + B + {
    (|A| = A) = (|B| = B) = true: -AB;
    (|A| = A) = (|B| = B) = false: AB;
    else: 0
}

つまり、AとBの両方が符号を共有している場合、制限オフセットを適用します。オフセットの大きさは、AとBの積です。オフセットの方向は、AとBの方向と反対です。

AとBが符号を共有しない場合、オーバーフローする方法がないため、制限は適用されません。


これは可換ではないことに注意してください。3つ以上のボイスをミックスする場合は、一度にすべてをミックスする必要があります。この場合、すべてを一方向に「フラット化」する必要があります(高すぎる場合は正の値を負の値でフラット化します。低すぎる場合は負の値を正の値でフラット化します)。オフセットを考慮したら(残りの値に比例して適用されます); バイナリアプローチを使用しますが、混合値の数に基づいてリミッターをスケーリングします。
リッチリマー

-1

私のおすすめ:

  1. トラックのオーディオ形式を16ビット固定小数点から32ビット浮動小数点に変換します。
  2. 混合するすべてのトラックの現在のサンプル値を追加します。
  3. 他に何もしないでください。

ユーザーは、この混合ストリームをディザリングおよび16ビット固定小数点形式への再変換の前に圧縮および/または制限して処理することができます(この変換を想定しています...マスタリングエンジニアに渡すためのミックスダウンは、通常、より高い解像度形式のままです)


2
こんにちは、DSP.seへようこそ。貢献してくれたことに感謝しますが、これがOPの質問にまったく答えているとは思いません。OPは自分のシステムの「ユーザー」については言及していませんでした。彼は自分でシステムを操作したり、特定の要件に合わせてプログラムを作成したりする可能性があります。賛成票を投じて申し訳ありません。あなたがその点にさらに答えを出せば、投票を修正させていただきます。また、書式設定の世話をしてください。を見てみましょうよくある質問良い答えを書く方法を参照してください。
ペネロペ14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.