web-dev-qa-db-fra.com

tableau d'octets en tableau court et vice-versa dans java

J'ai des problèmes pour prendre des données audio stockées dans un tableau d'octets, les convertir en un tableau court big-endian, les encoder, puis les reconvertir en un tableau d'octets. Voici ce que j'ai. Les données audio d'origine sont stockées dans audioBytes2. J'utilise le même format pour le décodage avec un moins sur la fonction cos à la place. Malheureusement, la modification des octets et des types de données courts n'est pas négociable.

    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++;
    }

J'ai fait tout ce que je pouvais penser pour que cela fonctionne, mais le plus proche que je suis venu est de le faire fonctionner tous les autres encoder/décoder et je n'ai aucune idée pourquoi. Merci pour toute aide.

42
Aaron

Je vous suggère également d'essayer 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);
82
Peter Lawrey
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();
}
9
Scott Izu

Que diriez-vous de certains ByteBuffers?

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());
}
4
Edwin Dalorzo
byte[2] bytes;

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

short s = (short)r;
1
Jagadeesh

Votre code fait des shorts peu endiens, pas gros. Vous avez l'indexation pour MSB et LSB échangés.

Puisque vous utilisez des shorts big-endian, vous pourriez utiliser un DataInputStream enroulé autour d'un ByteArrayInputStream (et DataOutputStream/ByteArrayOutputStream) à l'autre extrémité, plutôt que de faire votre propre décodage.

Si vous faites fonctionner tous les autres décodages, je suppose que vous avez un nombre impair d'octets, ou une erreur off-by-one ailleurs, ce qui fait que votre erreur est corrigée à chaque autre passage.

Enfin, je parcourrais le tableau avec i + = 2 et j'utilisais MSB = arr [i] et LSB = arr [i + 1] plutôt que de multiplier par 2, mais c'est juste moi.

1
Matt DiMeo