WAV 形式は 24 ビットですが、ダブルは 64 ビットを使用します。そのため、wav に格納される量を 2 倍にすることはできません。フレームとチャネルごとに 1 つの 24 ビット符号付き整数があり、これは上記の 6 バイトに相当します。
次のようなことができます。
private static double readDouble(ByteBuffer buf) {
int v = (byteBuffer.get() & 0xff);
v |= (byteBuffer.get() & 0xff) << 8;
v |= byteBuffer.get() << 16;
return (double)v;
}
このメソッドは、左チャネルに対して 1 回、右チャネルに対して 1 回呼び出します。正しい順序はわかりませんが、最初に左に行ったと思います。リトルエンディアンが示すように、バイトは最下位から最上位へと読み取られます。0xff
符号なしとして扱うために、下位 2 バイトは でマスクされます。最上位バイトは、符号付き 24 ビット整数の符号を含むため、符号付きとして扱われます。
ByteBuffer
配列を操作する場合、たとえば次のように、なしで実行できます。
double[] doubles = new double[byteArray.length / 3];
for (int i = 0, j = 0; i != doubles.length; ++i, j += 3) {
doubles[i] = (double)( (byteArray[j ] & 0xff) |
((byteArray[j+1] & 0xff) << 8) |
( byteArray[j+2] << 16));
}
インターリーブされた両方のチャネルのサンプルを取得するため、後でこれらを分離することをお勧めします。
モノラルの場合、2 つのチャンネルがインターリーブされるのではなく、1 回だけインターリーブされます。16bitなら使えますbyteBuffer.getShort()
、32bitなら使えますbyteBuffer.getInt()
。しかし、24ビットは計算に一般的に使用されていないため、ByteBuffer
これに対する方法はありません. 署名されていないサンプルがある場合は、すべての符号をマスクして結果を相殺する必要がありますが、署名されていない WAV はあまり一般的ではないと思います。