2009-06-03 4 views
4

Я работаю с java.Преобразование байтов в биты

У меня есть байтовый массив (8 бит в каждой позиции массива), и мне нужно сделать, чтобы собрать 2 значения массива и получить значение.

Я попробую объяснить себя лучше; Я извлекаю аудиоданные из аудиофайла. Эти данные хранятся в массиве байтов. Каждый образец аудио имеет размер 16 бит. Если массив равен:

байт [] audioData;

Что мне нужно, чтобы получить 1 значение из образцов audioData [0] и audioData [1], чтобы получить 1 аудио-образец.

Может ли кто-нибудь объяснить мне, как это сделать?

Заранее спасибо.

ответ

6

Я не разработчик Java, так что это может быть полностью вне базы, но вы считали, используя ByteBuffer?

+2

Это не совсем вне базы. –

4

Предположим, что LSB находится в данных [0]

int val; 

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

это не касается расширения знака на байте 1 – newacct

+0

вопрос в том, как установить целочисленное значение при чтении байта. Поэтому, когда целое число выражается знаком, оно останется неизменным, я совершенно не уверен, что в этом случае мы должны позаботиться об этом. –

0

Вы можете преобразовать в short (2 байта) с помощью логического ИЛИ-два байта вместе:

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

Нет, слишком просто; должен использовать маскировку, чтобы избежать расширения знака. – StaxMan

+0

+1 для указания моей ошибки. Будет редактировать (или стирать) позже. –

+0

Пожалуйста, отредактируйте, я хочу узнать – dedalo

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 может быть более уместным здесь. –

0

Предлагаю взглянуть на 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); 
1
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-битные числа, а для 32-разрядных чисел Little-Endian вам пришлось бы отменить порядок всех 4 байта, потому что целые числа Java следуют по порядку больших чисел).

-4
byte myByte = 0x5B; 

boolean bits = new boolean[8]; 

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

Результаты является массивом нулей и единиц, где 1=TRUE и 0=FALSE :)

+0

Вам не нужно что-то вроде бит [i] = ((myByte & (1 << i))! = 0); '? Я не думаю, что это будет работать так, как написано. – Rob

0

простой способ в Java для разбора массив байтов в битах JBBP usage

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

код будет размещать разобранные биты каждого байта как 8 байтов в массиве бит экземпляра класса Parsed

Смежные вопросы