你的WAV格式是24位,但double使用64位。因此,存储在你的wav中的数量不能是double类型的。每个帧和通道都有一个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;
}
您需要为左声道和右声道分别调用该方法。不确定正确的顺序,但我猜先处理左声道。字节按照从最低有效位到最高有效位的顺序读取,因为这是little-endian(小端)的指示方式。最低的两个字节被掩码为
0xff
,以便将它们看作无符号数。最高有效字节被视为有符号的,因为它将包含有符号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));
}
您将获得两个通道交错的样本,因此您可能希望在此之后将它们分开。
如果您拥有单声道,则仅拥有一个通道交错。对于16位,您可以使用byteBuffer.getShort()
,对于32位,您可以使用byteBuffer.getInt()
。但24位不常用于计算,因此ByteBuffer
没有相应的方法。如果您有无符号样本,则需要屏蔽所有符号并偏移结果,但我想无符号WAV不太常见。