将字节转换为位

5
我正在使用Java编程语言。我有一个字节数组,每个位置上有8位。我需要将数组中的两个值合并在一起,得到一个值。
让我更好地解释一下:我正在从音频文件中提取音频数据,这些数据被存储在一个字节数组中。每个音频样本的大小为16位。如果数组是:
byte[] audioData;
我需要从audioData [0]和audioData [1]中获取一个值,以便获得一个音频样本。
请问如何实现这个功能?
提前感谢您的帮助。
9个回答

7

我不是Java开发人员,所以这可能完全错误,但您是否考虑使用ByteBuffer


(说明:该段内容询问是否考虑使用ByteBuffer,ByteBuffer是Java中一种缓冲区类型,可用于处理二进制数据。)

2
这并不完全是离谱的。 - Michael Myers

4
假设LSB位于data[0]。
int val;

val = (((int)data[0]) & 0x00FF) | ((int)data[1]<<8);

这段代码与字节1的符号扩展无关。 - newacct
问题是如何在逐字节读取时设置整数值。因此,每当整数进行符号扩展时,它将保持不变,我完全不确定是否需要注意这种情况。 - Artem Barger

1
ByteInputStream b = new ByteInputStream(audioData);
DataInputStream data = new DataInputStream(b);
short value = data.readShort();

以上代码的优点是您可以以相同的方式继续读取“data”的其余部分。
对于仅包含两个值的更简单的解决方案可能是:
short value = (short) ((audioData[0]<<8) | (audioData[1] & 0xff));

这个简单的解决方案提取了两个字节,并将它们拼接在一起,第一个字节是高位字节,第二个字节是低位字节(这被称为大端序;如果您的字节数组包含小端序数据,则应将第二个字节向左移动以获取16位数字;对于小端序32位数字,您必须颠倒所有4个字节的顺序,因为Java的整数遵循大端序排序)。

1

如之前所建议的,Java有一些类可以帮助你完成这个任务。你可以使用ByteBuffer来包装你的数组,然后获取一个IntBuffer视图。

ByteBuffer bb = ByteBuffer.wrap(audioData);
// optional: bb.order(ByteOrder.BIG_ENDIAN) or bb.order(ByteOrder.LITTLE_ENDIAN)
IntBuffer ib = bb.asIntBuffer();
int firstInt = ib.get(0);

3
这里可能更适合使用ShortBuffer。 - Michael Myers

1

在Java中更简单的解析字节数组为位的方法是 使用JBBP

  class Parsed { @Bin(type = BinType.BIT_ARRAY) byte [] bits;}
  final Parsed parsed = JBBPParser.prepare("bit:1 [_] bits;").parse(theByteArray).mapTo(Parsed.class);

代码将会把每个字节的解析位作为8个字节放入Parsed类实例的bits数组中。

0

你可以这样做,不需要使用任何库或外部类。

byte myByte = (byte) -128;
for(int i = 0 ; i < 8 ; i++) {
    boolean val = (myByte & 256) > 0;
    myByte = (byte) (myByte << 1);
    System.out.print(val ? 1 : 0);
}
System.out.println();

0

我建议你看一下Preon。在Preon中,你可以这样说:

class Sample {

  @BoundNumber(size="16") // Size of the sample in bits
  int value;

}

class AudioFile {

  @BoundList(size="...") // Number of samples
  Sample[] samples;

}

byte[] buffer = ...;
Codec<AudioFile> codec = Codecs.create(AudioFile.class);
AudioFile audioFile = codec.decode(buffer);

0

你可以通过逻辑或(logical or)两个字节来将它们转换为 short(2 字节):

short value = ((short) audioData[0]) | ((short) audioData[1] << 8);

3
不行,太简单了;必须使用掩码来避免符号扩展。 - StaxMan

-4
byte myByte = 0x5B;

boolean bits = new boolean[8];

for(int i = 0 ; i < 8 ; i++)
    bit[i] = (myByte%2 == 1);

结果是一个由零和一组成的数组,其中1=TRUE0=FALSE :)

你不想要类似于 bit[i] = ((myByte & (1 << i)) != 0); 这样的东西吗?我认为这个写法是行不通的。 - Rob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接