Как преобразовать (короткий) семпл в звуковом файле в массив байтов - PullRequest
3 голосов
/ 07 ноября 2008

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

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

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

Ответы [ 4 ]

12 голосов
/ 07 ноября 2008

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

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

Итак, ваш код делает

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

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

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

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

2 голосов
/ 07 ноября 2008

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

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

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

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

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

1 голос
/ 31 марта 2011
buffer[position] = (byte)(sample & 0xff);
buffer[position+1] = (byte)((sample >> 8) & 0xff);

должно быть:

buffer[position] = (byte)((sample >> 8) & 0xff);
buffer[position+1] = (byte)(sample & 0xff);
1 голос
/ 07 ноября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...