2011-04-11 22 views
34

Tengo algunos problemas al tomar datos de audio almacenados en una matriz de bytes, convertirla en una matriz corta de big-endian, codificarla y luego volver a convertirla en una matriz de bytes. Esto es lo que tengo. Los datos de audio originales se almacenan en audioBytes2. Estoy utilizando el mismo formato para la decodificación con un menos en la función cos en su lugar. Desafortunadamente, cambiar el byte y los tipos de datos cortos no es negociable.matriz de bytes a matriz corta y viceversa en java

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

he hecho todo lo que puedo pensar para hacer este trabajo, pero lo más cerca que he llegado es conseguir que funcione cualquier otro envío/recepción y no tengo ni idea de por qué. Gracias por cualquier ayuda.

+1

¿Qué problemas tienes? –

+2

¿es big-endian o little-endian? Creo que necesitas 'java.nio.ByteBuffer' para manejar esta conversión. –

+0

Posible duplicado de [cómo convertir matriz corta a matriz de bytes] (http://stackoverflow.com/questions/10804852/how-to-convert-short-array-to-byte-array) –

Respuesta

1

Su código está haciendo shorts little-endian, no grandes. Has cambiado la indexación para MSB y LSB.

Dado que está utilizando pantalones cortos de big-endian, podría estar utilizando un DataInputStream envuelto alrededor de ByteArrayInputStream (y DataOutputStream/ByteArrayOutputStream) en el otro extremo, en lugar de hacer su propia decodificación.

Si está logrando que todas las demás decodificaciones funcionen, supongo que tiene un número impar de bytes, o un error "uno a uno" en otro lugar, lo que está causando que su error se solucione con cada otro pase.

Finalmente, paso por la matriz con i + = 2 y uso MSB = arr [i] y LSB = arr [i + 1] en lugar de multiplicar por 2, pero así soy yo.

+0

En realidad estoy usando algo similar a eso después de la reconversión con un audioInputStream. – Aaron

-1

Parece que está intercambiando el orden de bytes entre leer los bytes y escribirlos de nuevo (no sé si esto es intencional o no).

4

¿Qué tal algunos 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()); 
} 
72

También sugiero que pruebes 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); 
+2

short [] audioData = ByteBuffer.wrap (audioBytes2) .order (ByteOrder.BIG_ENDIAN) .asShortBuffer(). Array(); Lanza una UnsupportedOperationException. – Aaron

+1

@ Aaron - sí, pero * ¿qué * arroja esa excepción? (sugerencia: un 'ShortBuffer' actúa como * vista * en un' ByteBuffer' subyacente, y su método 'get()' debe hacer exactamente lo que usted quiere). – kdgregory

+0

@kdgregory, gracias por su solución. ;) –

8
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(); 
} 
0

byte [2] bytes;

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

corto s = (corto) r;

Cuestiones relacionadas