Java - 将byte []转换为double [],反之亦然

时间:2011-08-31 16:31:50

标签: java double bytearray

我正在研究涉及阅读音频数据的事情。我需要将音频数据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. 如何再次将双打转换回字节?
  3. 任何帮助表示赞赏

    谢谢,

    Samer Samy

4 个答案:

答案 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);

答案 1 :(得分: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++;
}

答案 2 :(得分:0)

查看HugeCollections

  

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

我知道这不是一个完整的答案(你要求任何帮助)但是为了处理java中的大量数据,你会在vanillajava博客上找到很多很棒的食谱。

答案 3 :(得分:0)

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

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

java -Xmx512m MyApp