如何将短数组转换为字节数组

我发现将一个短数组转换为字节数组 , 将字节数组转换 为短数组 ,但不是短数组转换为字节数组。

以下是导致转换的代码

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):gainBuffer()轨道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):at java.nio.ShortBuffer.put(ShortBuffer.java:422)

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

05-29 13:41:12.857:W / AudioWorker(9758):at java.nio.ShortBuffer.put(ShortBuffer.java:391)

05-29 13:41:12.857:W / AudioWorker(9758):at 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:通过JNI使用C.

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 ms

方法#2旋转:299毫秒

方法#3 C:39毫秒