[英]Java - Convert byte[] to double[] and vice versa
我正在做一些涉及读取音频数据的工作。 我需要将音频数据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内存不足的堆空间异常”提供大量数据字节。
所以总结一下:
任何帮助表示赞赏
谢谢,
萨默·萨米(Samer Samy)
它真的需要成为double[]
吗?我不是float的忠实拥护者,但它可以为您提供足够多的精度,并且只有一半大小。
如果要避免使用堆,请使用直接内存,即不要使用byte []或double [],而应将ByteBuffer,ShortBuffer和FloatBuffer用作直接内存。
顺便说一句:设置字节的字节顺序没有任何作用。
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);
只是关于堆空间的一个随机想法:在以后处理数组时,可以使/= 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++;
}
查看HugeCollections 。
庞大的集合库旨在有效地支持内存中数据的大型集合,而不会影响GC。 它使用较少的堆内存并生成代码来提高效率。
我知道这不是一个完整的答案(您需要任何帮助 ),但是要在Java中处理大量数据,您会在vanillajava博客上找到很多不错的食谱。
您使用的唯一使用大量堆的东西是“数据”,尤其是“ doubleData”。 因此,如果您正在寻找一种减少堆空间的方法,那么您来的地方就错了–您必须找到一种工作方式,而不要同时拥有所有内存的两倍。 要么...
您知道如何扩展Java堆大小吗? 如果不是,则需要学习-默认大小很小-如果有内存可用(可以这么说),则只有64MB。 从命令行,例如,添加“ -Xmx512m”半个演出:
java -Xmx512m MyApp
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.