我发现将一个短数组转换为字节数组,将字节数组转换为短数组,但不是短数组转换为字节数组.
以下是导致转换的代码
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];
Run Code Online (Sandbox Code Playgroud)
我试过了
int i = 0;
ByteBuffer byteBuf = ByteBuffer.allocate(N);
while (buffer.length >= i) {
byteBuf.putShort(buffer[i]);
i++;
}
bytes2 = byteBuf.array();
Run Code Online (Sandbox Code Playgroud)
和
ByteBuffer.wrap(bytes2).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(buffer);
Run Code Online (Sandbox Code Playgroud)
但是我在两者上都收到了这个错误(错误如果不完全相同但两者非常相似):
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));
}
Run Code Online (Sandbox Code Playgroud)
evi*_*ate 40
我发现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();
}
Run Code Online (Sandbox Code Playgroud)
方法#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;
}
Run Code Online (Sandbox Code Playgroud)
方法#3:通过JNI使用C.
TypeCast.java
package mynamespace.util;
public class TypeCast
{
public static native byte [] shortToByte(short [] input);
static
{
System.loadLibrary("type_conversion");
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
结果:
对于一百万个元素输入数组,执行时间如下:
方法#1 ByteBuffer:865 ms
方法#2旋转:299毫秒
方法#3 C:39毫秒
das*_*ght 15
Java short
是16位类型,byte
是8位类型.你有一个循环试图将N
短片插入一个N
长的字节的缓冲区; 它需要是2*N
字节长,以适应您的所有数据.
ByteBuffer byteBuf = ByteBuffer.allocate(2*N);
while (N >= i) {
byteBuf.putShort(buffer[i]);
i++;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
20268 次 |
最近记录: |