come convertire array corti in array di byte

Ho trovato la conversione di un array da corto a byte , e l’ array di byte in array breve , ma non un corto array di array di byte.

Ecco il codice che porta alla conversione

while(!stopped) { Log.i("Map", "Writing new data to buffer"); short[] buffer = buffers[ix++ % buffers.length]; N = recorder.read(buffer,0,buffer.length); track.write(buffer, 0, buffer.length); byte[] bytes2 = new byte[N]; 

Ho provato

  int i = 0; ByteBuffer byteBuf = ByteBuffer.allocate(N); while (buffer.length >= i) { byteBuf.putShort(buffer[i]); i++; } bytes2 = byteBuf.array(); 

e

  ByteBuffer.wrap(bytes2).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(buffer); 

Tuttavia, ho ricevuto questo errore su entrambi (l’errore se non è esattamente lo stesso, ma molto simile per entrambi):

05-29 13: 41: 12.021: W / AudioTrack (9758): getBuffer () traccia 0x30efa0 disabilitata, riavvio

05-29 13: 41: 12.857: W / AudioWorker (9758): errore durante la lettura di Voice AudioWorker

05-29 13: 41: 12,857: W / AudioWorker (9758): java.nio.BufferOverflowException

05-29 13: 41: 12,857: W / AudioWorker (9758): su java.nio.ShortBuffer.put (ShortBuffer.java:422)

05-29 13: 41: 12.857: W / AudioWorker (9758): su java.nio.ShortToByteBufferAdapter.put (ShortToByteBufferAdapter.java:210)

05-29 13: 41: 12,857: W / AudioWorker (9758): su java.nio.ShortBuffer.put (ShortBuffer.java:391)

05-29 13: 41: 12,857: W / AudioWorker (9758): su com.avispl.nicu.audio.AudioWorker.run (AudioWorker.java:126)

E solo per dare più informazioni possibili ecco il codice dopo che utilizza l’array di byte

 Log.i("Map", "test"); //convert to ulaw read(bytes2, 0, N); //send to server os.write(bytes2,0,bytes2.length); System.out.println("bytesRead "+buffer.length); System.out.println("data "+Arrays.toString(buffer)); } 

Java short è un tipo a 16 bit e byte è un tipo a 8 bit. Hai un ciclo che tenta di inserire N cortocircuiti in un buffer lungo N byte; deve essere lungo 2*N byte per adattarsi a tutti i tuoi dati.

 ByteBuffer byteBuf = ByteBuffer.allocate(2*N); while (N >= i) { byteBuf.putShort(buffer[i]); i++; } 

Ho trovato ByteBuffer come il metodo di conversione più lento su tre che ho profilato. Vedi sotto…

Piattaforma: Nexus S, Android 4.1.1, nessuna scheda SIM

Metodo 1: utilizzare un ByteBuffer

 byte [] ShortToByte_ByteBuffer_Method(short [] input) { int index; int iterations = input.length; ByteBuffer bb = ByteBuffer.allocate(input.length * 2); for(index = 0; index != iterations; ++index) { bb.putShort(input[index]); } return bb.array(); } 

Metodo n. 2: bit del Twiddle direttamente

 byte [] ShortToByte_Twiddle_Method(short [] input) { int short_index, byte_index; int iterations = input.length; byte [] buffer = new byte[input.length * 2]; short_index = byte_index = 0; for(/*NOP*/; short_index != iterations; /*NOP*/) { buffer[byte_index] = (byte) (input[short_index] & 0x00FF); buffer[byte_index + 1] = (byte) ((input[short_index] & 0xFF00) >> 8); ++short_index; byte_index += 2; } return buffer; } 

Metodo n. 3: usare C tramite JNI

TypeCast.java

 package mynamespace.util; public class TypeCast { public static native byte [] shortToByte(short [] input); static { System.loadLibrary("type_conversion"); } } 

native.c

 #include  #include  jbyteArray Java_mynamespace_util_TypeCast_shortToByte(JNIEnv *env, jobject obj, jshortArray input) { jshort *input_array_elements; int input_length; jbyte *output_array_elements; jbyteArray output; input_array_elements = (*env)->GetShortArrayElements(env, input, 0); input_length = (*env)->GetArrayLength(env, input); output = (jbyteArray) ((*env)->NewByteArray(env, input_length * 2)); output_array_elements = (*env)->GetByteArrayElements(env, output, 0); memcpy(output_array_elements, input_array_elements, input_length * 2); (*env)->ReleaseShortArrayElements(env, input, input_array_elements, JNI_ABORT); (*env)->ReleaseByteArrayElements(env, output, output_array_elements, 0); return output; } 

risultati:

Per un array di input da un milione di elementi, il tempo di esecuzione è il seguente:

Metodo # 1 ByteBuffer: 865 ms

Metodo n. 2 Twiddle: 299 ms

Metodo # 3 C: 39 ms