2008-11-07 4 views
3

При преобразовании из массива с малым байтом я нашел следующее решение в сети, но не смог понять, в чем состоит эта логика.Как преобразовать (короткий) образец в звуковой файл в массив байтов

//buffer is an array of bytes, bytes[] 
buffer[position] = (byte)(sample & 0xff); 
buffer[position+1] = (byte)((sample >> 8) & 0xff); 

Может кто-нибудь сказать мне, почему 0xff (256) относится к образцу, который является коротким?

ответ

12

Этот код, вероятно, исходит из кода C (или был написан программистом C, который не разбирает Java, а также erickson). Это связано с тем, что в Java отливка от типа с большей информацией к типу с меньшей информацией отбрасывает биты более высокого порядка, и поэтому 0xx0xff не требуется в обоих случаях.

Короткий имеет 16 бит, два байта. Таким образом, в массиве байтов нужно взять два слота, потому что если бы мы просто набрали короткий байт, то один байт был бы потерян.

Итак, код есть ли

1110001100001111 sample 
0000000011111111 0xff 
0000000000001111 sample & 0xff => first byte` 

Затем смещает образец, чтобы получить второй байт

0000000011100011 sample >> 8 
0000000011111111 0xff 
0000000011100011 (sample >> 8) & 0xff => second byte 

, который может быть намного лучше написано, как Эриксон показывает ниже (надеюсь, это» скоро будет выше).

+0

Великого объяснение. Я размышлял, как лучше всего ответить, но вместо этого я проголосую за это. – Dave 2008-11-07 18:22:21

+1

Отличный ответ Винко! Это в сочетании с ответом McWafflestix ниже дает прекрасный ответ. – 2008-11-07 18:35:34

+0

Просто добавил два дополнительных бита (не каламбур) из ответа McWafflestix, которого здесь не было. – 2008-11-07 18:44:56

1

Это гарантирует, что нет переполнения; в частности, первая строка принимает LSByte «sample» и маскирует OUT ваши верхние 8 бит, давая вам только значения в диапазоне 0-255; во второй строке берется MSByte «sample» (путем выполнения сдвига вправо) и делает то же самое. Это не обязательно во второй строке, так как сдвиг вправо на 8 должен выпадать из 8 младших значащих бит, но это делает код немного более симметричным.

Я бы предположил, что это потому, что поскольку образец является коротким (2 байта), любые значения в диапазоне 256-6553 будут интерпретироваться как 255 путем преобразования байтов.

2

Другие ответы содержат некоторую полезную информацию, но, к сожалению, оба они рекламируют неверное представление о батте.

& 0xFF не требуется в обоих случаях в исходном коде.

Сужающийся литье отбрасывает старшие биты, которые не вписываются в более узкий тип. Фактически, фактически & 0xFF приводит к тому, что короткое число должно быть увеличено до int с наиболее значительными 24 битами, очищенными, которые затем отрубаются и заполняются байтом приложением. Подробности см. На странице Java Language Specification Section §5.1.3.

buffer[position] = (byte) sample; 
buffer[position+1] = (byte) (sample >>> 8); 

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

1
buffer[position] = (byte)(sample & 0xff); 
buffer[position+1] = (byte)((sample >> 8) & 0xff); 

должен быть:

buffer[position] = (byte)((sample >> 8) & 0xff); 
buffer[position+1] = (byte)(sample & 0xff); 
Смежные вопросы