ByteBuffer.array() returns 比 byteBuffer 更大的数组 Android
ByteBuffer.array() returns a larger array than byteBuffer Android
基本上我有以下场景:
inputByteBuffer (capacity in debug) => 1024
byte[] inByteBufferArray = inputByteBuffer.array();
inByteBufferArray.length => 1031 ????
ByteBuffer array() 方法说明了 "Returns the byte array which this buffer is based on, if there is one." ref
这是在 Android API 18 年工作的,有什么变化吗?有一个 ByterBuffer arrayOffset() 方法,我需要那个吗?
这是在 Nexus 6 设备上发生的,但我认为这无关紧要。
谢谢
private static int bufferSizeStatic = 1024;
private float[] Read(){
mAudioRecord.read(inputByteBuffer, bufferSize);
return readByteArray(inputByteBuffer.array(), inputByteBuffer.arrayOffset());
}
private float[] readByteArray(byte[] byteArray, int offSet) {
if (floatArray == null || floatArray.length!=(byteArray.length-offSet) / (numChannels*numBytePerFrame)){
floatArray = new float[(byteArray.length-offSet) / (numChannels*numBytePerFrame)];
}
if (numChannels == 1){
for (int i = 0; i < floatArray.length; i++){
short tempShort = (short) ((byteArray[2*i+1+offSet]<<8) + byteArray[2*i+offSet]);
floatArray[i] = (float) (tempShort / Math.pow(2,15));
}
} //TODO add stereo support
return floatArray;
}
我不明白你为什么关心。您的代码当然不应该关心。它这样做的唯一原因是因为您滥用了 API。您不应该从不在其中的缓冲区中获取数据,这些数据由 limit(),
而不是 array().length()
或 capacity()
给出。
你只需要调整调用顺序,直接使用ByteBuffer
:
private static int bufferSizeStatic = 1024;
private float[] Read(){
// I don't know why you need to pass `bufferSize` here: `inputByteBuffer` already knows its own limit
mAudioRecord.read(inputByteBuffer, bufferSize);
return readByteArray(inputByteBuffer);
}
private float[] readByteArray(ByteBuffer byteBuffer) {
if (floatArray == null || floatArray.length!=(byteArray.limit()-byteArray.position()) / (numChannels*numBytePerFrame)){
floatArray = new float[(byteArray.limit()-byteArray.position()) / (numChannels*numBytePerFrame)];
}
byteBuffer.flip();
if (numChannels == 1){
for (int i = 0; i < floatArray.length; i++){
short tempShort = (short) ((ByteBuffer.getShort(i*2));
floatArray[i] = (float) (tempShort / 32768.0);
}
} //TODO add stereo support
byteBuffer.compact();
return floatArray;
}
E&OE
您会发现这至少同样有效。
我找到了 android 代码:
MemoryRef(int capacity) {
VMRuntime runtime = VMRuntime.getRuntime();
buffer = (byte[])runtime.newNonMovableArray(byte.class, capacity + 7);
allocatedAddress = runtime.addressOf(buffer);
// Offset is set to handle the alignment: http://b/16449607
offset = (int)(((allocatedAddress + 7) & ~(long)7) - allocatedAddress);
isAccessible = true;
}
基本上我有以下场景:
inputByteBuffer (capacity in debug) => 1024
byte[] inByteBufferArray = inputByteBuffer.array();
inByteBufferArray.length => 1031 ????
ByteBuffer array() 方法说明了 "Returns the byte array which this buffer is based on, if there is one." ref
这是在 Android API 18 年工作的,有什么变化吗?有一个 ByterBuffer arrayOffset() 方法,我需要那个吗?
这是在 Nexus 6 设备上发生的,但我认为这无关紧要。
谢谢
private static int bufferSizeStatic = 1024;
private float[] Read(){
mAudioRecord.read(inputByteBuffer, bufferSize);
return readByteArray(inputByteBuffer.array(), inputByteBuffer.arrayOffset());
}
private float[] readByteArray(byte[] byteArray, int offSet) {
if (floatArray == null || floatArray.length!=(byteArray.length-offSet) / (numChannels*numBytePerFrame)){
floatArray = new float[(byteArray.length-offSet) / (numChannels*numBytePerFrame)];
}
if (numChannels == 1){
for (int i = 0; i < floatArray.length; i++){
short tempShort = (short) ((byteArray[2*i+1+offSet]<<8) + byteArray[2*i+offSet]);
floatArray[i] = (float) (tempShort / Math.pow(2,15));
}
} //TODO add stereo support
return floatArray;
}
我不明白你为什么关心。您的代码当然不应该关心。它这样做的唯一原因是因为您滥用了 API。您不应该从不在其中的缓冲区中获取数据,这些数据由 limit(),
而不是 array().length()
或 capacity()
给出。
你只需要调整调用顺序,直接使用ByteBuffer
:
private static int bufferSizeStatic = 1024;
private float[] Read(){
// I don't know why you need to pass `bufferSize` here: `inputByteBuffer` already knows its own limit
mAudioRecord.read(inputByteBuffer, bufferSize);
return readByteArray(inputByteBuffer);
}
private float[] readByteArray(ByteBuffer byteBuffer) {
if (floatArray == null || floatArray.length!=(byteArray.limit()-byteArray.position()) / (numChannels*numBytePerFrame)){
floatArray = new float[(byteArray.limit()-byteArray.position()) / (numChannels*numBytePerFrame)];
}
byteBuffer.flip();
if (numChannels == 1){
for (int i = 0; i < floatArray.length; i++){
short tempShort = (short) ((ByteBuffer.getShort(i*2));
floatArray[i] = (float) (tempShort / 32768.0);
}
} //TODO add stereo support
byteBuffer.compact();
return floatArray;
}
E&OE
您会发现这至少同样有效。
我找到了 android 代码:
MemoryRef(int capacity) {
VMRuntime runtime = VMRuntime.getRuntime();
buffer = (byte[])runtime.newNonMovableArray(byte.class, capacity + 7);
allocatedAddress = runtime.addressOf(buffer);
// Offset is set to handle the alignment: http://b/16449607
offset = (int)(((allocatedAddress + 7) & ~(long)7) - allocatedAddress);
isAccessible = true;
}