Конвертировать со знаком int (2 байта, 16 бит) в двойной формат.С Java - PullRequest
3 голосов
/ 06 января 2011

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

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

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

Ответы [ 3 ]

2 голосов
/ 06 января 2011

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

Если у вас большая последовательность байтов (что, я полагаю, у вас), и вы не хотите беспокоиться о БОЛЬШИХENDIAN против 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 () читает следующие два байта буфера, принимаетзаботится о порядке байтов Little-Endian, преобразует байты в короткие и позиционирует себя для следующего вызова getXXX ().

0 голосов
/ 06 января 2011

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

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

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

0 голосов
/ 06 января 2011

Не можете ли вы просто сделать самый_значительный байт * 256 + наименьший_значительный_байт, а затем привести к удвоению?

...