Question

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.

Was it helpful?

Solution

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

OTHER TIPS

Assume the LSB is at data[0]

int val;

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

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);
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] & 0xff));

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).

easier way in Java to parse an array of bytes to bits is JBBP usage

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

the code will place parsed bits of each byte as 8 bytes in the bits array of the Parsed class instance

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);

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);
byte myByte = 0x5B;

boolean bits = new boolean[8];

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

The results is an array of zeros and ones where 1=TRUE and 0=FALSE :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top