オーディオダイナミックレンジ圧縮の実装を支援する


8

JavaScriptでオーディオダイナミックレンジ圧縮を実装しようとしています(WebオーディオAPIを使用していません)。

サウンド技術者向けの記事は多く、高レベルのドキュメントもいくつかありますが、デジタルダイナミックレンジ圧縮を実際に実装するための参考資料は見つかりませんでした。

私が理解していることから、整流された信号の計算には少なくとも3つのステップがあります。

  1. 入力レベルの計算
  2. 信号に適用するゲインを計算する
  3. ゲインを適用する

私はオーディオをブロックで処理するので、1)は1つのブロックのRMSを計算することを考えていました

適切なリファレンスへのポインタはありますか?または、これを実装するために必要な手順を少し説明してくれる人はいますか?


1
念のために言うと、次のようなものを実装する必要があります。waves.com / plugins / c1-compressorですよね?
2013

はい:)しかし、はるかに簡単です!私が必要とするコントロールは、しきい値、膝、比率、攻撃、リリースです。しかし、もっと簡単に始めることができます
sebpiq 2013

回答:


4

ここにいくつかの提案があります:

  • オープンソースの実装はたくさんあります(Sox、Audacityなど)。それらを理解していない場合でも、コードをCからJavaScriptに変換できる場合があります。
  • オンラインでのプロセスの適切な説明はわかりませんが、このテーマに関する本はたくさんあります。
    • デジタルオーディオ信号処理はこのトピックをカバーし、よく書かれています。(DAFXの場合と同様ですが、DAFXは整理が不十分であり、カバレッジは簡単ではありません)
    • Javaを使用したデジタルオーディオもこのトピックをカバーしており、javascriptなどの他の言語に簡単に変換できるはずの動作するJavaコードが付属しています。この本には多くの欠点がありますが、オーディオプログラミングの経験がない人には適しています。

原則は、信号のエンベロープ(アタックとリリースによって制御)を作成し、伝達関数(比率、しきい値、ニーによって制御)を使用してそのエンベロープを成形し、その結果を元の信号に適用することです。多くの場合、メイクアップゲインステージが続きます。

@Deveの回答は、いくつかの可能な伝達関数を示唆しています。


問題は、私がCを知らないことです。それは、オーディオdspを操作するときに大きな障害です。既存の実装を確認できないためです。それ以外の場合は、本のおかげで、少なくとも最初のものは必ず確認します。
sebpiq 2013

DAFXブックには、MATLABコードが含まれています。IDK(コンプレッサーのMATLABコードがある場合)。
ビョルンロシュ

「デジタルオーディオ信号処理」の本に関して、amazonへのコメントは、電気技師のバックグラウンドを持つ人々にとってはより良いと述べています。アルゴリズムに重点を置いた本を知っていますか?たとえば、最高のコードは疑似コードでしょうか?
sebpiq

1
どういうわけか、あなたはいくつかの新しいスキルを習得する必要があると思います。
ビョルンロシュ

はい、知っています!そして、私はその準備ができています。それらをテストするためにmatlabにお金をかけたくないので、たとえば、私は実際にmatlabコードを望んでいないだけです。そのため、特定の言語ではなく(たとえば、Javaのように、本当に学習に興味がない)疑似コードなどの他の本を知っているかどうかを尋ねました。
sebpiq 2013

2

単純な開始では、非線形特性を使用します gバツ 入力信号を圧縮します:

y=gバツ

どこに(コメントのendolithによって指摘されたように) バツあるエンベロープ入力オーディオ信号のとy 実際のオーディオ信号に適用される出力エンベロープです。 gバツ大きな入力値を小さな入力値よりも強く減衰させる任意の関数を使用できます。A-法μ-法律機能は、電話などの音声信号を圧縮するために開発されました。でも、これが音楽にとってどれほどいい音かわかりません。

別の非常に単純な圧縮機能は、特定のしきい値を超えるすべての振幅を減衰させることです。 δ

gバツ={バツためにバツδaバツ+1aδためにバツ>δ
どこ a<1減衰です。しかし、私たちの聴覚は対数的であり、減衰が強すぎる可能性があるため、これはあまりうまく機能しません。これが、オーディオコンプレッサーが対数スケールで動作し、上記と同じ機能につながる理由ですが、すべての値は対数であり、可能な最大値に関してです。ためにバツ>0
ログgバツ={ログバツためにバツδ1rログバツ+11rログδためにバツ>δ

オーディオコンプレッサーの場合、 δ 通常dBで与えられ、 r ある比率、例えば3:1で表されます(つまり r=)。これは線形関数で指数関数を生成します(それが正しいことを願って、それをチェックしてください、またバツ>0):

gバツ={バツためにバツδδ11/rバツ1/rためにバツ>δ
この関数には「ハードニー」があります。つまり、関数は ログgバツ で区別できません バツ=δ。「ソフトニー」の場合、その時点でスムーズな移行が必要になります。ネガティブのための上記の関数の拡張バツ 簡単です。signum関数を乗算して、次の絶対値を取ります。 バツ

アタックとリリースは、キック、スネア、ボーカルなどのさまざまなサウンドに影響を与えます。しきい値に達する前にコンプレッサーが動作を開始する時間と、信号がしきい値を下回った後もコンプレッサーが動作し続ける時間を決定します。これを実装するには、ある種の先読みを使用する必要があります。

以下のすべての振幅として δ減衰され、利用可能なダイナミックレンジは十分に活用されていません。これは、いわゆる「メイクアップゲイン」によって修正されます。これは、圧縮された信号とゲイン係数の単純な乗算です。G>1。最初にダイナミックレンジを減らし、次に信号コンプレッサーを増幅することで、音楽を「大きく」表示することができます。


ありがとう!素晴らしい説明。私はあなたが与えたものに近い伝達関数に来ましたが、私のはしきい値を含んでいなかったので(しきい値= 0で簡略化しました)、再計算する必要があります。
sebpiq 2013

実際、しきい値を追加して得られる伝達関数はx ^(1 / r)* 10 ^(-sigma /(20 * r))
sebpiq

申し訳ありませんが、一定のバイアスを追加するのを忘れていたため、機能の定義はめちゃくちゃでした。私はそれを修正しました。しかし、最後の表現は私の意見では正しいです。それは満たす必要がありますgδ=δ。ここでは20の因数はありません。一定の因数が相殺されるように、左側と右側の対数を取るためです。
2013

これらは圧縮ではなく、歪みのように見えます。歪みはサンプルごとに発生するレベルの変化ですが、圧縮は波形の多くのサイクル(それぞれが多数のサンプルで構成されています)にわたって発生するものです。非線形歪みはひどい音になります。
内部石2013

@endolithその通り、ヒントをありがとう。私はそれに応じて私の答えを更新しました。
Deve
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.