8ビット(0〜255の値)に量子化したい多くの正の16ビット値(doubleとして格納されている)を持つバッファーがあります。
ウィキペディアによると、プロセスは次のようになります。
- 16ビット値を正規化します。つまり、最大のものを見つけて、これで分割します。
- M = 8のQ(x)式を使用します。
では、Cにこの量子化を実行できる関数があるのか、それとも私が使用できるCの実装を知っている人がいるのでしょうか。
たくさんの愛、ルイーズ
8ビット(0〜255の値)に量子化したい多くの正の16ビット値(doubleとして格納されている)を持つバッファーがあります。
ウィキペディアによると、プロセスは次のようになります。
では、Cにこの量子化を実行できる関数があるのか、それとも私が使用できるCの実装を知っている人がいるのでしょうか。
たくさんの愛、ルイーズ
値d
が間隔内にあると仮定します[0.0, max]
:
unsigned char quantize(double d, double max)
{
return (unsigned char)((d / max) * 255.0);
}
「16ビット値」の意味がわかりません。IEEE-754を使用するシステムでは、倍精度値は64ビットです。ただし、別の数値タイプの値がある場合、プロセスは実質的に同じです。
これは波形オーディオ処理のように聞こえます。入力は16PCMデータ、出力は8ビットPCMデータであり、中間値としてdoubleを使用しています。
ただし、8ビットPCM波データは量子化されているだけでなく、128を超える符号なしの値で表されます。(指数が浮動小数点数に格納される方法のように)
最初に最大値を見つけることは、量子化だけでなく、スケーリングでもあります。したがって、擬似コードでは
double dMax = max_of_all_values(); //
...
foreach (dValue in array_of_doubles)
{
signed char bValue = (signed char)((dValue / dMax)*127.0);
}
精度を高めたい場合は、切り捨てるのではなく丸めることもできますが、オーディオ処理では、切り捨て順序をランダム化するか、基本的にdoubleからsignedcharへの切り捨ての一部としてフィルタリングアルゴリズムを実行して整形する方が一般的に優れています。
注:出力が8ビットPCMデータの場合、signed charは正しくありませんが、質問では特に要求されていないため、省略しました。
編集:これをピクセルデータとして使用する場合は、符号なしの値が必要です。入力が符号なしの場合、Jamesはすでに符号なしの値に対して正しい答えを出しているようです(正規化されたデータのdB値は、実際にはすべて負である必要があります)
「正の16ビット値(doubleとして格納される)」は実際には意味がないため、エンコーディングが何であるかはあなたの質問からは明らかではありません。それらは16ビットまたはダブルのいずれかであり、両方にすることはできません。
ただし、これが1.0に正規化された16ビットの符号なしデータであると仮定すると(値の範囲は0.0 <= s <= 1.0)、8ビット整数値に拡張するために必要なのは各サンプルに255を掛けることだけです。
unsigned char s8 = s * 255 ;
範囲が0.0<= s <= 1.0ではなく、0.0 <= s <= maxの場合、次のようになります。
unsigned char s8 = s / max * 255 ;
いずれにせよ、あなたが自分で書くかもしれないもの以外に「量子化」機能はありません。しかし、必要な変換は間違いなく単純な算術式になります(ただし、データがおそらく圧縮されている場合はそれほど単純ではありません-たとえば、μ-layまたはA-lawエンコードされています)。