Как преобразовать образец аудио данных WAV в двойной тип?

103
12

Я работаю над приложением, которое обрабатывает аудиоданные.
Я использую java (я добавил MP3SPI, Jlayer и Tritonus). Я извлекаю аудиоданные из WAV файла в массив байтов. Образцы аудиоданных, с которыми я работаю, - 16 бит стерео.


В соответствии с тем, что я прочитал, формат для одного примера:


AABBCCDD


где AABB представляет собой канал левого канала и канал CCDD (2 байта для каждого канала).
Мне нужно преобразовать этот образец в двойной тип значения. Я читаю о формате данных. Java использует Big endian,.wav файлы используют немного endian. Я немного смущен. Не могли бы вы помочь мне в процессе преобразования?
Спасибо вам всем

спросил(а) 2021-01-19T13:52:44+03:00 9 месяцев назад
1
Решение
102

Когда вы используете ByteBuffer (java.nio.ByteBuffer), вы можете использовать порядок методов;


[заказать]


публичный окончательный порядок ByteBuffer (ByteOrder bo)


Modifies this buffer byte order.

Parameters:
bo - The new byte order, either BIG_ENDIAN or LITTLE_ENDIAN
Returns:
This buffer

После этого вы можете получить вышеупомянутые значения с помощью


GetChar()
getShort()
GetInt()
GetFloat()
getDouble()


Отличный язык Java;-)

ответил(а) 2021-01-19T13:52:44+03:00 9 месяцев назад
91

Предупреждение: целые числа и байты подписаны. Возможно, вам нужно замаскировать нижние байты при их упаковке:

for (int i =0; i < length; i += 4) {
double left = (double)((bytes [i] & 0xff) | (bytes[i + 1] << 8));
double right = (double)((bytes [i + 2] & 0xff) | (bytes[i + 3] << 8));

... your code here ...

}

ответил(а) 2021-01-19T13:52:44+03:00 9 месяцев назад
46

Маленький Endian означает, что данные находятся в форме BBAA и DDCC. Вы просто поменяли бы его.


С начала кадра:


int left = (bytes[i+1] << 8) + bytes[i];
int right = (bytes[i+3] << 8) + bytes[i+2];

где я - ваш индекс вашего образца.

ответил(а) 2021-01-19T13:52:44+03:00 9 месяцев назад
46

Я бы лично искал библиотеку, которая делает для вас замену endian. В каждом формате аудиофайлов есть предположения о достоверности для вас, и получение этого права сложно для всех поддерживаемых волновыми файлами глубин/типов данных:


    8bit - uint8
    16bit - int16
    24bit - int32
    32bit - int32 as float
    32bit - float
    64bit - double

Если вы хотите поддерживать большинство распространенных типов волновых файлов, вам понадобится преобразование endian для всех этих типов данных.


Я бы посмотрел на ByteSwapper, который даст вам байтов для большинства типов, перечисленных выше.


Слишком плохая Java не имеет поля полномочий в своих классах файлов IO. Возможность просто открыть файл whos edianness большой или маленький - гораздо более легкое решение этой проблемы.

ответил(а) 2021-01-19T13:52:44+03:00 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема