我正在研究涉及阅读音频数据的事情。我需要将音频数据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
答案 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)
Huge集合库旨在高效地支持内存中数据的大型集合,而不会影响GC。它使用堆少的内存和生成的代码来提高效率。
我知道这不是一个完整的答案(你要求任何帮助)但是为了处理java中的大量数据,你会在vanillajava博客上找到很多很棒的食谱。
答案 3 :(得分:0)
你使用大量堆的唯一东西是“数据”,特别是“doubleData”。因此,如果您正在寻找减少堆空间的方法,那么您正在寻找错误的位置 - 您必须找到一种工作方式,而无需同时在内存中使用所有双打。还是......
您知道如何扩展Java堆大小吗?如果没有,你需要学习 - 默认大小很小 - 只有64MB,如果内存服务(可以这么说)。从命令行,例如,为半场演出添加“-Xmx512m”:
java -Xmx512m MyApp