我正在使用java。
我有一个字节数组(数组的每个位置都有 8 位),我需要做的是将数组的 2 个值放在一起并得到一个值。
我会尝试更好地解释自己;我正在从音频文件中提取音频数据。此数据存储在字节数组中。每个音频样本的大小为 16 位。如果数组是:
字节[] 音频数据;
我需要从样本 audioData[0] 和 audioData[1] 中获取 1 个值,以便获取 1 个音频样本。
谁能解释我如何做到这一点?
提前致谢。
我不是 Java 开发人员,所以这可能完全不合时宜,但是您是否考虑过使用ByteBuffer?
假设 LSB 在 data[0]
int val;
val = (((int)data[0]) & 0x00FF) | ((int)data[1]<<8);
ByteInputStream b = new ByteInputStream(audioData);
DataInputStream data = new DataInputStream(b);
short value = data.readShort();
上述代码的优点是您可以以相同的方式继续读取其余的“数据”。
仅针对两个值的更简单的解决方案可能是:
short value = (short) ((audioData[0]<<8) | (audioData[1] & 0xff));
这个简单的解决方案提取两个字节,并将它们组合在一起,第一个字节是高位,第二个字节是低位(这被称为 Big-Endian;如果您的字节数组包含 Little-Endian 数据,您将移位第二个字节代替 16 位数字;对于 Little-Endian 32 位数字,您必须颠倒所有 4 个字节的顺序,因为 Java 的整数遵循 Big-Endian 顺序)。
如前所述,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);
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 类实例的位数组中
您可以通过将两个字节进行逻辑或运算来转换为short
(2 个字节):
short value = ((short) audioData[0]) | ((short) audioData[1] << 8);
我建议你看看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);
你可以这样做,没有库或外部类。
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();
byte myByte = 0x5B;
boolean bits = new boolean[8];
for(int i = 0 ; i < 8 ; i++)
bit[i] = (myByte%2 == 1);
结果是一个由 0 和 1 组成的数组,其中1=TRUE
和0=FALSE
:)