как преобразовать короткий массив в массив байтов

Я нашел преобразование короткого массива байтов и массив байтов в короткий массив , но не короткий массив в массив байтов.

Вот код, предшествующий конверсии

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: W / AudioTrack (9758): getBuffer () трек 0x30efa0 отключен, перезапущен

05-29 13: 41: 12.857: W / AudioWorker (9758): Ошибка чтения голоса AudioWorker

05-29 13: 41: 12.857: W / 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: W / AudioWorker (9758): в java.nio.ShortToByteBufferAdapter.put (ShortToByteBufferAdapter.java:210)

05-29 13: 41: 12.857: W / 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)); } 

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

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

Я нашел 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: Прямые биты

 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: использовать C через 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; } 

Результаты:

Для миллионного входного массива время выполнения выглядит следующим образом:

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

Метод № 2 Twiddle: 299 мс

Метод № 3 C: 39 мс

  • Как вернуть массив из JNI в Java?
  • Массив нулевой длины
  • Общие правила передачи / возврата ссылки на массив (не указатель) на / из функции?
  • Как распечатать уникальные элементы в массиве Perl?
  • Является ли std :: vector намного медленнее, чем простые массивы?
  • PDF в байтовый массив и наоборот
  • Можете ли вы resize массива C ++ после инициализации?
  • Использование GSON для анализа массива JSON
  • Преобразование аргументов командной строки в массив в Bash
  • Java, упрощенная проверка, если int array содержит int
  • Ограничение на размер .Net-массива
  • Давайте будем гением компьютера.