您的 WAV 格式是 24 位,但双精度使用 64 位。因此,存储在您的 wav 中的数量不能翻倍。每个帧和通道有一个 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 相当罕见。