2011-08-31 61 views
0

我正在研究某些涉及读取音频数据的内容。我需要将音频数据字节[]转换为double [](反之亦然)。 我需要通过低通滤波器转换信号。Java - 将byte []转换为double [],反之亦然

用于转换形式字节双打我用下面的代码片段:

// where data is the byte array. 
ByteBuffer byteBuffer = ByteBuffer.wrap(data); 
// make sure that the data is in Little endian order. 
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 
// every double will represent 2 bytes (16bit audio sample) 
// so the double[] is half length of byte[] 
double[] doubleData = new double[data.length/2]; 
int i = 0; 
while (byteBuffer.remaining() > 2) { 
    // read shorts (16bits) and cast them to doubles 
    short t = byteBuffer.getShort(); 
    doubleData[i] = t; 
    doubleData[i] /= 32768.0; 
    i++; 
} 

我不知道这是否是最好的方式还是不特别,因为它给的“Java出堆空间异常”大的数据字节。

所以总结起来:

  1. 是有更好的方法来进行转换,不消耗堆空间
  2. 如何将双打再次转换为字节?

任何帮助表示赞赏

感谢,

萨默尔萨米

+2

似乎是http://stackoverflow.com/questions/2905556/how-can-i-convert-a-byte-array-into的副本 - 双后面 –

+0

是的,我遇到了这个问题,但它没有提到任何有关堆问题。 –

回答

1

它真正需要的是一个double[]我不是浮动的大风扇,但它会给你足够多的数字多的精度和一半的大小。

如果要避免使用堆使用直接内存,即不要使用byte []或double [],而是使用ByteBuffer,ShortBuffer和FloatBuffer作为直接内存。

BTW:设置字节的字节顺序不做任何事情。

ByteBuffer bb = // use direct memory if possible. 
ShortBuffer sb = bb.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); 
FloatBuffer fb = ByteBuffer.allocateDirect(sb.remaining() * 4) 
       .order(ByteOrder.nativeOrder()).asFloatBuffer(); 
while(sb.remaining()>0) 
    fb.put(sb.get()/32768.0f); 
+0

我会尝试缓冲区的想法。 –

+0

+1今天我学到了FloatBuffer和ShortBuffer – bpgergo

+0

@Peter小问题,为什么要将FloatBuffer分配给(sb.remaining()* 4)?为什么不只是“sb”的大小? –

0

上堆空间只是一个随机的想法:可以使/= 32768.0后,当你处理你的阵列

编辑于:错字代码

short[] shortData = new short[data.length/2]; 
int i = 0; 
while (byteBuffer.remaining() > 2) { 
    // read shorts (16bits) and cast them to doubles 
    short t = byteBuffer.getShort(); 
    shortData[i] = t; 
    i++; 
} 
+0

我还会怎么做呢?! ...我将需要保留一个相同大小的双打数组,堆问题来自该线: double [] doubleData = new double [data.length/2]; –

+0

对不起,我在代码中编辑了一个错字。不,你不需要保留相同大小的双打数组。之后,当你处理你的短阵列时,你会一个接一个地加倍。无论如何,彼得劳瑞的缓冲提示更好。 – bpgergo

0

退房HugeCollections

巨大集合库旨在高效支持内存中数据的大型集合,而不会影响GC。它使用堆少的内存和生成的代码来提高效率。

我知道这不是一个完整的答案(你问任何帮助),但在Java中处理数据的一个大的量,你会发现很多伟大的食谱对vanillajava博客。

0

您使用的唯一使用大量堆的东西是“数据”,尤其是“doubleData”。因此,如果您正在寻找一种减少堆空间的方法,那么您正在寻找一个错误的地方 - 您必须找到一种工作方式,而无需同时在内存中存储所有双打。或...

你知道如何扩展Java堆大小吗?如果没有,你需要学习 - 默认大小很小 - 如果内存服务(可以这么说)只有64MB。从命令行,例如,加上“-Xmx512m”半演出:

java -Xmx512m MyApp 
相关问题