Преобразовать подписанный int (2bytes, 16 бит) в двойном формате. С Java

StackOverflow https://stackoverflow.com/questions/4616310

Вопрос

У меня есть проблема. В Java мне нужно прочитать образцы из файла WAV. Формат файла: WAV, PCM_Signed, подписанный int в размере 2bytes = 16bits, маленький Endian ... Объект читает образцы аудио в байтах, и мне нужно преобразовать эти два байта в одном двойном значении. Я пытался использовать эту формулу, но это не совсем правильно:

mono = (double)((audioBytes[k] & 0xFF) | (audioBytes[k + 1] << 8));

Сравнивая результаты с MATLAB, я всегда замечаю различия между реальным значением в MatLab и преобразованном в Java. Кто-нибудь может помочь мне, пожалуйста? Спасибо, Дэйв

Это было полезно?

Решение

Вы не дали нам достаточно информации, чтобы узнать, почему вы получаете разные результаты в Matlab и Java. Обычно вы масштабируете короткие данные канала [-32768..32767] к двойным в диапазоне [-1..1], который похоже, вы пытаетесь сделать. Ваш результат Java: -3.0517578125E-5 правильно для короткого значения -1: -1/32768. Я не знаю, почему ваш результат Matlab отличается. Вы не показали нам, как вы приходите к результатам MatLab.

Если у вас есть большая последовательность байтов (которые я догадаюсь, что вы делаете), и вы не хотите беспокоиться о Big-Endian VS Little-Endian или переключаются битами и байтами, пусть Java позаботится об этом для вас:

import java.nio.*;
...
ByteBuffer buf = ByteBuffer.wrap(audioBytes);
buf.order(ByteOrder.LITTLE_ENDIAN);

while (buf.remaining() >= 2) {
    short s = buf.getShort();
    double mono = (double) s;
    double mono_norm = mono / 32768.0;
    ...
}

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

Другие советы

Это правильный путь:

double sampleValue = (double)(( bytes[0]<<8 ) | ( bytes[1]&0x00FF ));

(Измените индексы, чтобы поменяться мало / большой)

Вы не можете просто сделать Most_signefant Byte * 256 + MILL_Significant_byte, а затем отбрасывают в двойное?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top