问题
I'm having some issues taking audio data stored in a byte array, converting it to a big-endian short array, encoding it, then changing it back into a byte array. Here is what I have. The original audio data is stored in audioBytes2. I am using the same format for decode with a minus on the cos function instead. Unfortunately, changing the byte and short data types is non-negotiable.
short[] audioData = null;
int nlengthInSamples = audioBytes2.length / 2;
audioData = new short[nlengthInSamples];
for (int i = 0; i < nlengthInSamples; i++) {
short MSB = (short) audioBytes2[2*i+1];
short LSB = (short) audioBytes2[2*i];
audioData[i] = (short) (MSB << 8 | (255 & LSB));
}
int i = 0;
while (i < audioData.length) {
audioData[i] = (short)(audioData[i] + (short)5*Math.cos(2*Math.PI*i/(((Number)EncodeBox.getValue()).intValue())));
i++;
}
short x = 0;
i = 0;
while (i < audioData.length) {
x = audioData[i];
audioBytes2[2*i+1] = (byte)(x >>> 0);
audioBytes2[2*i] = (byte)(x >>> 8);
i++;
}
I have done everything that I can think of to make this work, but the closest I've come is getting it to work every other encode/decode and I have no idea why. Thanks for any help.
回答1:
I also suggest you try ByteBuffer.
byte[] bytes = {};
short[] shorts = new short[bytes.length/2];
// to turn bytes to shorts as either big endian or little endian.
ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
// to turn shorts back to bytes.
byte[] bytes2 = new byte[shortsA.length * 2];
ByteBuffer.wrap(bytes2).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(shortsA);
回答2:
public short bytesToShort(byte[] bytes) {
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
}
public byte[] shortToBytes(short value) {
return ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(value).array();
}
回答3:
How about some ByteBuffers?
byte[] payload = new byte[]{0x7F,0x1B,0x10,0x11};
ByteBuffer bb = ByteBuffer.wrap(payload).order(ByteOrder.BIG_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();
while(sb.hasRemaining()){
System.out.println(sb.get());
}
回答4:
byte[2] bytes;
int r = bytes[1] & 0xFF;
r = (r << 8) | (bytes[0] & 0xFF);
short s = (short)r;
回答5:
Your code is doing little-endian shorts, not big. You've the indexing for MSB and LSB swapped.
Since you are using big-endian shorts, you could be using a DataInputStream wrapped around a ByteArrayInputStream (and DataOutputStream/ByteArrayOutputStream) on the other end, rather than doing your own decoding.
If you're getting every other decode working, I'd guess you've got an odd number of bytes, or an off-by-one error elsewhere which is causing your mistake to get fixed on every other pass.
Finally, I'd step through the array with i+=2 and use MSB= arr[i] and LSB=arr[i+1] rather than multiplying by 2, but that's just me.
回答6:
It looks like you are swapping the byte order between reading the bytes in and writing them back out (unsure if this is intentional or not).
来源:https://stackoverflow.com/questions/5625573/byte-array-to-short-array-and-back-again-in-java