将有符号整型(2 字节,16 位)转换为双精度格式。使用Java
我有一个问题。 在 Java 中,我需要从 wav 文件中读取样本。 文件格式为:wav、PCM_SIGNED、signed int of 2bytes = 16bits、little endian... 该对象读取字节中的音频样本,我需要将这两个字节转换为一个双精度值。 我尝试使用这个公式,但它并不完全正确:
mono = (double)((audioBytes[k] & 0xFF) | (audioBytes[k + 1] << 8));
将结果与 Matlab 进行比较,我总是注意到 Matlab 中的实际值与 Java 中转换后的值之间的差异。 有人可以帮我吗? 谢谢你, 戴夫
I've got a problem.
In Java I need to read samples from a wav file.
The file format is: wav, PCM_SIGNED, signed int of 2bytes = 16bits, little endian...
The object reads the audio samples in BYTES and I need to convert this two bytes in one double value.
I tried to use this formula but it's not completely correct:
mono = (double)((audioBytes[k] & 0xFF) | (audioBytes[k + 1] << 8));
Comparing the results with Matlab I always notice differences between the real value in Matlab and the converted one in Java.
Can anybody help me please?
Thank you,
Dave
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您没有向我们提供足够的信息来了解为什么在 Matlab 和 Java 中得到不同的结果。通常,您会将短通道数据 [-32768..32767] 缩放到 [-1..1] 范围内的双倍,这看起来像是您正在尝试执行的操作。您的 java 结果:-3.0517578125E-5 对于短值 -1:-1/32768 是正确的。我不知道为什么你的Matlab结果不同。您还没有向我们展示您是如何得出 Matlab 结果的。
如果你有一个大的字节序列(我猜你有),并且你不想担心 BIG-ENDIAN 与 LITTLE-ENDIAN 或移位位和字节,让 java 为你处理它:
< a href="http://download.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html#getShort%28%29" rel="nofollow">ByteBuffer.getShort() 读取缓冲区的接下来两个字节,处理 Little-Endian 排序,将字节转换为短字节,并为下一个 getXXX() 调用定位自身。
You haven't given us enough information to know why you're getting different results in Matlab and Java. Usually you scale the short channel data [-32768..32767] to a double in the range [-1..1] which it looks like you are attempting to do. Your java result: -3.0517578125E-5 is correct for the short value -1: -1/32768. I don't know why your Matlab result is different. You haven't shown us how you are arriving at your Matlab results.
If you have a large sequence of bytes (which I'm guessing you do), and you don't want to worry about BIG-ENDIAN vs LITTLE-ENDIAN or shifting bits and bytes, let java take care of it for you:
ByteBuffer.getShort() reads the next two bytes of the buffer, takes care of the Little-Endian ordering, converts the bytes to a short, and positions itself for the next getXXX() call.
这是正确的方法:(
更改索引以交换小/大)
This is the correct way:
(Change indices to swap little/big)
难道你不能只做most_significant byte * 256+least_significant_byte然后转换为double吗?
Cant you just do most_significant byte * 256 + least_significant_byte and then cast to double?