C ++からWaveFormオーディオを増幅する正しい式は何だろうと思っています。
次の 16 ビットの波形データがあるとします: 0x0000 0x2000, 0x3000, 0x2000, 0x0000, (負の部分), ...
音響上の理由により、数値を 2 倍にしただけでは、次のように 2 倍のオーディオにはなりません: 0x0000 0x4000、0x6000、0x4000、0x0000、(2 倍の負の部分)、...
音声加工に詳しい方がいらっしゃいましたら教えてください。
すべてのサンプル値を 2 倍にすると、「2 倍の音量」、つまり 6dB 大きくなります。もちろん、クリッピングによる歪みを避けるように注意する必要があります。これが、今日のすべてのプロ用オーディオ処理ソフトウェアが内部で浮動小数点サンプルを使用する主な理由です。
最終的にサウンド データを出力するときに、整数に戻す必要がある場合があります。いくつかの DAW 用のプラグインを作成している場合 (シンプルでありながら効果的なサウンド FX をプログラムしたい場合にお勧めします)、このプラグインがすべての作業を行います。再び float を出力します。しかし、たとえば .wav ファイルを直接出力したい場合は、最初に出力を制限して、0dB (通常のフロート ストリームでは +-1) を超えるすべてが +-1 にクリップされるようにする必要があります。次に、目的の整数型が -1 に達する最大値を掛けて、その型にキャストするだけです。終わり。
とにかく、ボリュームノブを線形ではなく対数的にスケーリングすることが重要であるという点で、あなたは確かに正しいです(多くの消費者向けプログラムはそうではありません。ノブの左端に非常に近い値を使用することになるため、これはばかげていますしかし、それは増幅の計算自体とは何の関係もありません。対数スケールで信号のラウドネスを知覚するからです。それでも、ラウドネス自体は、音圧の定数係数の単純な乗算によって決定されます。これは、アナログ回路の電圧と任意の DSP のデジタル サンプルの値に比例します。
別のこと: どこまで行くつもりなのかわかりませんが、これを本当に適切に行いたい場合は、0dB を超えるピークを切り取るだけではなく (クリッピングは非常に耳障りに聞こえます)、適切なコンプレッサーを実装する必要があります。 /リミッタ。これにより、最も音量の大きい部分のレベルを下げることで、クリッピングが自動的に防止されます。これも無理はしたくありませんが (ポピュラー音楽はいずれにしても過度に圧縮されているため、ダイナミックな音楽表現の多くが失われます)、オーディオ レベルを上げる「危険性の低い」方法であることには変わりありません。
毎回線形乗算を使用しましたが、失敗することはありませんでした。たとえば、フェードアウトにも機能しました...
それで
float amp=1.2;
short sample;
short newSample=(short)amp*sample;
フェードアウトを線形にしたい場合は、サンプル処理ループで次のようにします。
amp-=0.03;
対数にしたい場合は、サンプル処理ループで
amp*=0.97;
amp が小さな値に達するまで (amp < 0.1)
これは単なる認識の問題かもしれません。あなたの耳 (そして目 - ガンマ wrt ビデオを調べます) は、入力に対する線形応答でラウドネスを認識しません。その良いモデルは、音量の増加に対して ln(n) の増加を知覚するように耳が反応することです。リニア ポットとオーディオ ポットの違いを調べます。
とにかく、あなたの出力アンプがそれを説明するかもしれないので、それがここで重要かどうかはわかりませんが、2 倍の音量で知覚させたい場合は、e^2 倍の音量にする必要があるかもしれません. つまり、今はクリッピングの領域にいるということです。