切り捨てることによりサンプルビット深さを減少させます
-
26-09-2019 - |
質問
私は24から16ビットにデジタルオーディオ信号のビット深度を低減する必要があります。
各試料の唯一の上位16ビット(すなわち、切り捨て)を取って比例計算を行うことと等価である(*は0xFFFF / 0xFFFFFFのIN = OUT)
解決
私は、その場合には、はいています。
、平均(in * 0xFFFF) / 0xFFFFFF
あなたを想定します 他のヒント
あなたは(別称、ディザリング)切り捨てる前に、ちょうど切り捨てしきい値以下に、元の信号に慎重に細工されたノイズ信号を加えることで、より良い響きの結果を得ることができます。
ディザリングの一般的なギブあなたより良い結果にノイズの意志を追加します。この鍵は、ノイズの形状です。 populaの POW-R ののディザリングアルゴリズムは、特定の形状を有することデジタル・オーディオ・ワークステーションアプリケーション(Cakewalk社のSONAR、ロジックなど)の多くで非常に人気があります。
あなたはPOW-Rの忠実度でフルを必要としない場合は、は、あなたは、単にいくつかのノイズを生成することができます>かなり低い振幅で、あなたの信号にそれを混ぜます。あなたはこのマスクに量子化効果のいくつかを見つけることができます。
x * 0xffff / 0xffffff
は過度に知識をひけらかすのであるが、良い方法であなたのサンプルが署名されていない場合 - 一般的には良い方法では、おそらくいない
はい、あなたは、ソースの範囲の最大値は、あなたの目的地の範囲の最大値と一致するようにしたいが、値は、符号なし範囲のみにある使用され、量子化の分布は、それは非常に稀だろうということを意味し、手順あなたが可能な最大出力値を使用します。
次に、サンプルをピーク負値が-0x8000と-0x800000であろうが、正の値は、は0x7FFFと0x7fffffあろうピークを締結している場合。あなたの最初の問題は、1つのISが0x7FFFのに等しい、または-1 -0x8000に等しいかどうかを決定されます。あなたは後者を選択した場合、それは簡単なシフト操作です。あなたは両方を持ってしようとした場合、ゼロはゼロである停止します。
その後、あなたがゼロに向かって除算の丸めという問題を抱えています。あまりにも多くの値が他の値と比較して、ゼロに丸められ得る。この手段。これは、歪みが発生します。
あなたは正のピーク値に応じて拡張したい場合は、正しい形式は以下のようになります:
out = rint((float)in * 0x7fff / 0x7fffff);
あなたは少し周りの魚ならば、あなたはおそらく、算術と分割なし整数であることを行うための効率的な方法を見つけることができます。
このフォームは正しくラウンド任意の入力に対して最も近い可能な出力値にすべきで、それが可能な最大出力値に可能な最大入力値をマップする必要がありますが、範囲に散在量子化ステップの醜い分布を持つようになるだろうます。
ほとんどの人が好むます:
out = (in + 128) >> 8;
if (out > 0x7fff) out = 0x7fff;
このフォームは、正の値はわずかにクリップすることができるが、量子化ステップが均一に分布していることがポイントに、物事最も小さいビット大声を行います。
あなたは負の無限大への右シフトラウンドため、128を追加します。 平均の量子化誤差は-128にあり、0x7fffffの入力値が、さもなければ0x8000の結果を与え、そして場合なるので、オーバーフローのためのテストが必要である正確に0に0を維持するために、これを修正するために128を追加しますあなたはそれがピーク負の値を与えるラップアラウンドう16ビット・ワードでこれを保管します。
Cのpedantsは右シフトと分裂行動に関する仮定に穴を突くことができますが、私は明確にするため、それらを眺めています。
しかし、他の人とあなたは、一般的にディザリングすることなく、オーディオのビット深度を減らすべきではない、理想的にはノイズシェイピングを指摘しています。次のようにTPDFディザがあります:
out = (in + (rand() & 255) - (rand() & 255)) >> 8;
if (out < -0x8000) out = -0x8000;
if (out > 0x7fff) out = 0x7fff;
繰り返しますが、私は明確にするため見過ごすつもりrand()
の使用で大きな問題ます。