简体   繁体   English

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

[英]Java - Convert byte[] to double[] and vice versa

I am working on something involves reading audio data. 我正在做一些涉及读取音频数据的工作。 I need to convert the audio data byte[] to double[] (and vice versa). 我需要将音频数据byte []转换为double [](反之亦然)。 I need the conversion to pass the signal through a low pass filter. 我需要进行转换以使信号通过低通滤波器。

For converting form bytes to doubles i use the following code snippet: 为了将格式字节转换为双精度,我使用以下代码片段:

// 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++;
}

I don know whether this is the best way or not especially as it give "Java out of heap space exception" with large of data bytes. 我不知道这是否是最好的方法,尤其是因为它会给“ Java内存不足的堆空间异常”提供大量数据字节。

So to sum up: 所以总结一下:

  1. is there a better way to do the conversion, that doesn't consume heap space ? 有没有更好的方法来进行转换, 而不会消耗堆空间
  2. how convert back the doubles to bytes again ? 如何再次将双打转换为字节?

Any help appreciated 任何帮助表示赞赏

Thanks, 谢谢,

Samer Samy 萨默·萨米(Samer Samy)

Does it really need to be a double[] I am not a big fan of float but it will give you more than enough digits of accuracy and be half the size. 它真的需要成为double[]吗?我不是float的忠实拥护者,但它可以为您提供足够多的精度,并且只有一半大小。

If you want to avoid using the heap use direct memory ie don't use a byte[], or double[] and instead using a ByteBuffer, ShortBuffer and FloatBuffer for direct memory. 如果要避免使用堆,请使用直接内存,即不要使用byte []或double [],而应将ByteBuffer,ShortBuffer和FloatBuffer用作直接内存。

BTW: setting the byte order for bytes doesn't do anything. 顺便说一句:设置字节的字节顺序没有任何作用。

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

just a random idea on heap space: you can make the /= 32768.0 later on when you process your array 只是关于堆空间的一个随机想法:在以后处理数组时,可以使/= 32768.0

EDIT: typo in code 编辑:代码中的错字

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++;
}

Check out HugeCollections . 查看HugeCollections

The Huge collections library is designed to support large collections on data in memory efficiently without GC impact. 庞大的集合库旨在有效地支持内存中数据的大型集合,而不会影响GC。 It does this using heap less memory and generated code for efficiency. 它使用较少的堆内存并生成代码来提高效率。

I know it's not a full answer (you asked for any help ) but for processing a big amount of data in java you will find a lot of great recipes on vanillajava blog. 我知道这不是一个完整的答案(您需要任何帮助 ),但是要在Java中处理大量数据,您会在vanillajava博客上找到很多不错的食谱。

The only things you're using that use a lot of heap are "data" and especially "doubleData". 您使用的唯一使用大量堆的东西是“数据”,尤其是“ doubleData”。 So if you're looking for a way to reduce heap space, you're looking in the wrong place - you have to find a way to work without having all the doubles in memory at the same time. 因此,如果您正在寻找一种减少堆空间的方法,那么您来的地方就错了–您必须找到一种工作方式,而不要同时拥有所有内存的两倍。 Or... 要么...

Do you know how to expand the Java heap size? 您知道如何扩展Java堆大小吗? If not, you need to learn - the default size is small - only 64MB, if memory serves (so to speak). 如果不是,则需要学习-默认大小很小-如果有内存可用(可以这么说),则只有64MB。 From command line, eg, add "-Xmx512m" for half a gig: 从命令行,例如,添加“ -Xmx512m”半个演出:

java -Xmx512m MyApp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM