如何将短数组转换为字节数组
我发现将一个短数组转换为字节数组 , 将字节数组转换 为短数组 ,但不是短数组转换为字节数组。
以下是导致转换的代码
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毫秒