views:

1071

answers:

7

Hi,

I'm working with java.

I have a byte array (8 bits in each position of the array) and what I need to do is to put together 2 of the values of the array and get a value.

I'll try to explain myself better; I'm extracting audio data from a audio file. This data is stored in a byte array. Each audio sample has a size of 16 bits. If the array is:

byte[] audioData;

What I need is to get 1 value from samples audioData[0] and audioData[1] in order to get 1 audio sample.

Can anyone explain me how to do this?

Thanks in advance.

+4  A: 

Assume the LSB is at data[0]

int val;

val = (((int)data[0]) & 0x00FF) | ((int)data[1]<<8);
Artem Barger
this doesn't deal with the sign extension on byte 1
newacct
the question was how to setup integer value while reading byte-byte. So whenever integer is sign extended it will stay the same, I'm completely not sure it the case there we have to take care about it.
Artem Barger
+6  A: 

I'm not a Java developer so this could be completely off-base, but have you considered using a ByteBuffer?

Adam Robinson
It's not completely off-base.
Michael Myers
A: 

You can convert to a short (2 bytes) by logical or-ing the two bytes together:

short value = ((short) audioData[0]) | ((short) audioData[1] << 8);
Paul Morie
Nope, too simple; must use masking to avoid sign extension.
StaxMan
+1 for pointing out my mistake. Will edit (or erase) later.
Paul Morie
Please edit, I want to learn
dedalo
A: 

BitConverter.ToUInt16()

wrong lang...wont let me edit.
You should always be able to edit and/or delete your own answers. What message do you get?
Michael Myers
+1  A: 

As suggested before, Java has classes to help you with this. You can wrap your array with a ByteBuffer and then get an IntBuffer view of it.

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);
safetydan
ShortBuffer may be more appropriate here.
Michael Myers
A: 

I suggest you take a look at Preon. In Preon, you would be able to say something like this:

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);
Wilfred Springer
A: 

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

The advantage of the above code is that you can keep reading the rest of 'data' in the same way.

A simpler solution for just two values might be:


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

This simple solution extracts two bytes, and pieces them together with the first byte being the higher order bits and the second byte the lower order bits (this is known as Big-Endian; if your byte array contained Little-Endian data, you would shift the second byte over instead for 16-bit numbers; for Little-Endian 32-bit numbers, you would have to reverse the order of all 4 bytes, because Java's integers follow Big-Endian ordering).

Chris