байтовый массив в короткий массив и обратно в Java - PullRequest
41 голосов
/ 11 апреля 2011

У меня возникли некоторые проблемы с переносом аудиоданных, хранящихся в байтовом массиве, преобразованием их в короткий массив с прямым порядком байтов, кодированием, а затем преобразованием обратно в байтовый массив.Вот что у меня есть.Исходные аудиоданные хранятся в audioBytes2.Я использую тот же формат для декодирования с минусом вместо функции cos.К сожалению, изменение байта и коротких типов данных не подлежит обсуждению.

    short[] audioData = null;
    int nlengthInSamples = audioBytes2.length / 2;
    audioData = new short[nlengthInSamples];

    for (int i = 0; i < nlengthInSamples; i++) {
       short MSB = (short) audioBytes2[2*i+1];
       short LSB = (short) audioBytes2[2*i];
       audioData[i] = (short) (MSB << 8 | (255 & LSB));
    }

    int i = 0;
    while (i < audioData.length) {
        audioData[i] = (short)(audioData[i] + (short)5*Math.cos(2*Math.PI*i/(((Number)EncodeBox.getValue()).intValue())));
        i++;
    }

    short x = 0;
    i = 0;
    while (i < audioData.length) {
        x = audioData[i];
        audioBytes2[2*i+1] = (byte)(x >>> 0);
        audioBytes2[2*i] = (byte)(x >>> 8);
        i++;
    }

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

Ответы [ 6 ]

82 голосов
/ 11 апреля 2011

Я также предлагаю вам попробовать ByteBuffer.

byte[] bytes = {};
short[] shorts = new short[bytes.length/2];
// to turn bytes to shorts as either big endian or little endian. 
ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);

// to turn shorts back to bytes.
byte[] bytes2 = new byte[shortsA.length * 2];
ByteBuffer.wrap(bytes2).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(shortsA);
8 голосов
/ 08 августа 2013
public short bytesToShort(byte[] bytes) {
     return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
}
public byte[] shortToBytes(short value) {
    return ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(value).array();
}
4 голосов
/ 11 апреля 2011

Как насчет байтовых буферов?

byte[] payload = new byte[]{0x7F,0x1B,0x10,0x11};
ByteBuffer bb = ByteBuffer.wrap(payload).order(ByteOrder.BIG_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();
while(sb.hasRemaining()){
  System.out.println(sb.get());
}
1 голос
/ 27 июня 2015
byte[2] bytes;

int r = bytes[1] & 0xFF;
r = (r << 8) | (bytes[0] & 0xFF);

short s = (short)r;
1 голос
/ 11 апреля 2011

Ваш код выполняет короткие байты, а не большие. У вас есть индекс для MSB и LSB поменялись местами.

Поскольку вы используете шорты с прямым порядком байтов, вы можете использовать DataInputStream, обернутый вокруг ByteArrayInputStream (и DataOutputStream / ByteArrayOutputStream) на другом конце, вместо того, чтобы выполнять свое собственное декодирование.

Если вы работаете с любым другим декодером, я думаю, у вас есть нечетное число байтов или ошибка в другом месте, которая приводит к тому, что ваша ошибка исправляется при каждом другом проходе.

Наконец, я бы пошагово прошел через массив с i + = 2 и использовал бы MSB = arr [i] и LSB = arr [i + 1] вместо умножения на 2, но это только я.

0 голосов
/ 11 апреля 2011

Похоже, что вы меняете порядок байтов между считыванием байтов и их выписыванием обратно (не уверен, намеренно это или нет).

...