2012-05-29 3 views
13

Я нашел converting a short to byte array и byte array to short array, но не короткий массив в массив байтов.как преобразовать короткий массив в массив байтов

Вот код, ведущий к преобразованию

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]; 

Я попытался

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

bytes2 = byteBuf.array(); 

и

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

Однако я получаю эту ошибку на оба (ошибку, если не точно такие же, но очень похожие для обоих):

05-29 13: 41: 12,021: Вт/AudioTrack (9758): obtainBuffer() дорожки 0x30efa0 отключена, перезапуск

05-29 13: 41: 12,857: Вт/AudioWorker (9758): Ошибка чтение голосом AudioWorker

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

05-29 13: 41: 12.857: W/AudioWorker (9758): на java.nio.ShortBuffer.put (ShortBuffer.java:422)

05-29 13: 41: 12,857: Вт/AudioWorker (9758): в java.nio.ShortToByteBufferAdapter.put (ShortToByteBufferAdapter.java:210)

05-29 13: 41: 12.857: Вт/AudioWorker (9758): в java.nio.ShortBuffer.put (ShortBuffer.java:391)

05-29 13: 41: 12.857: W/AudioWorker (9758): в com.avispl.nicu.audio. AudioWorker.run (AudioWorker.java:126)

И просто быть дать как можно больше информации, как можно здесь код после этого использует массив байтов

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

не уверен, что им следует получить от этого. ссылка, которую вы публикуете на испанском и idk, о чем, может быть, шутка об актуальности? Я просто хотел показать, что такое N, и избегать вопросов. –

+0

О, дорогой. Я думаю, @Bohemian означал http://www.sscce.org/, а не http://www.ssccee.org/ –

+0

Возможный дубликат [byte array для короткого массива и обратно в java] (http: // stackoverflow. com/questions/5625573/byte-array-to-short-array-and-back-again-in-java) –

ответ

15

short Java представляет собой тип 16-бит, и byte является типом 8-битный. У вас есть цикл, который пытается вставить N шорты в буфер N -bytes long; он должен быть длиной 2*N, чтобы соответствовать всем вашим данным.

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

Цикл foreach [почти всегда быстрее] (https://stackoverflow.com/questions/256859/is -there-a-performance-difference-between-a-for-loop-and-a-for-each-loop) в Java: 'для (short s: buffer) byteBuf.put (s);' – EntangledLoops

35

Я нашел ByteBuffer самым медленным методом преобразования из трех, которые я профилировал. См. Ниже ...

Платформа: Nexus S, Android 4.1.1, Нет SIM-карты

Способ № 1: Использование 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();  
} 

Способ № 2: Twiddle биты непосредственно

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

Способ № 3: Использование С помощью JNI

TypeCast.java

package mynamespace.util; 

public class TypeCast 
{ 
    public static native byte [] shortToByte(short [] input); 

    static 
    { 
    System.loadLibrary("type_conversion"); 
    } 
} 

native.c

#include <jni.h> 
#include <string.h> 

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

Результаты:

Для получения массива ввода в один миллион элемента, время выполнения заключается в следующем:

Метод # 1 ByteBuffer: 865 мс

Способ № 2 Twiddle: 299 мс

Способ № 3 C: 39 мс

+0

pls can вы загружаете и указываете ссылку на файл .SO для метода C. было бы очень полезно. Я не хочу загружать ndk только для этого. Благодарю. –