如何将声音文件中的(短)样本转换为字节数组

时间:2008-11-07 18:11:48

标签: java

在从短数组转换为字节数组时,我在网上找到了以下解决方案,但无法理解所涉及的逻辑。

//buffer is an array of bytes, bytes[]
buffer[position] = (byte)(sample & 0xff);
buffer[position+1] = (byte)((sample >> 8) & 0xff);

有人能告诉我为什么0xff(256)对样本是短的吗?

4 个答案:

答案 0 :(得分:12)

这段代码可能来自C代码(或者是由不解析Java以及erickson的C程序员编写的)。这是因为在Java中,从具有更多信息的类型到具有更少信息的类型的强制转换将丢弃更高阶的比特,因此&在这两种情况下都不需要0xff。

短路有16位,两个字节。所以它需要在字节数组中占用两个槽,因为如果我们只是将一个short转换成一个字节,那么一个字节就会丢失。

所以,你所拥有的代码

1110001100001111 sample
0000000011111111 0xff
0000000000001111 sample & 0xff => first byte`

然后,取代样本以获得第二个字节

0000000011100011 sample >> 8
0000000011111111 0xff
0000000011100011 (sample >> 8 ) & 0xff => second byte

如下面的erickson所示,这可以写得更好(希望它很快就会出现)。

答案 1 :(得分:2)

其他答案有一些很好的信息,但不幸的是,他们都提出了关于强制转换为字节的错误想法。

原始代码中两种情况都不需要& 0xFF

缩小演员会丢弃不适合较窄类型的高阶位。事实上,& 0xFF实际上首先导致短路被提升为int,其中最重要的24位被清除,然后被斩波并由演员填充一个字节。有关详细信息,请参阅Java Language Specification Section §5.1.3

buffer[position] = (byte) sample;
buffer[position+1] = (byte) (sample >>> 8);

另外,请注意我使用零扩展的右移,而不是符号扩展。在这种情况下,由于您立即将移位结果转换为字节,因此无关紧要。但是,一般情况下,操作员会给出不同的结果,您应该慎重考虑所选择的内容。

答案 2 :(得分:1)

确保没有溢出;具体来说,第一行是采用“样本”的LSByte并屏蔽你的高8位,只给出0-255范围内的值;第二行是采用MSByte的“样本”(通过执行右移)并做同样的事情。它不应该在第二行,因为右移8应该丢弃8个最低有效位,但它确实使代码更加对称。

我认为这是因为由于样本是短(2个字节),因此字节转换将256-6553范围内的任何值解释为255。

答案 3 :(得分:1)

buffer[position] = (byte)(sample & 0xff);
buffer[position+1] = (byte)((sample >> 8) & 0xff);

必须是:

buffer[position] = (byte)((sample >> 8) & 0xff);
buffer[position+1] = (byte)(sample & 0xff);