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:
我有一个问题。在Java中,我需要从wav文件中读取示例。文件格式为:wav, PCM_SIGNED,签名int(2字节= 16位),小endian…对象以字节读取音频样本,我需要将这两个字节转换为一个双值。我试着用这个公式,但它并不完全正确:
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
将结果与Matlab进行比较,我总是注意到Matlab中的实际值与Java中的转换值之间的差异。谁能帮帮我吗?谢谢你,戴夫
3 个解决方案
#1
2
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.
您没有给我们足够的信息来了解为什么在Matlab和Java中会得到不同的结果。通常你会扩展短通道数据[-32768..]在范围内加倍[-1.. .]看起来你正试图这么做。您的java结果:-3.0517578125E-5是正确的短值-1:-1/32768。我不知道为什么你们的Matlab结果不同。您还没有向我们展示如何得到Matlab结果。
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:
如果你有一个大的字节序列(我猜你有),并且你不想担心BIG-ENDIAN vs LITTLE-ENDIAN或者移动比特和字节,让java来替你处理:
import java.nio.*;
...
ByteBuffer buf = ByteBuffer.wrap(audioBytes);
buf.order(ByteOrder.LITTLE_ENDIAN);
while (buf.remaining() >= 2) {
short s = buf.getShort();
double mono = (double) s;
double mono_norm = mono / 32768.0;
...
}
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.
ByteBuffer.getShort()读取缓冲区的下两个字节,处理Little-Endian排序,将字节转换为短字节,并为下一个getXXX()调用定位自身。
#2
0
This is the correct way:
这是正确的方法:
double sampleValue = (double)(( bytes[0]<<8 ) | ( bytes[1]&0x00FF ));
(Change indices to swap little/big)
(改变指数以交换小/大)
#3
-1
Cant you just do most_significant byte * 256 + least_significant_byte and then cast to double?
难道你就不能只执行大部分有意义的字节* 256 +最小有意义的字节然后转换为双字节吗?
#1
2
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.
您没有给我们足够的信息来了解为什么在Matlab和Java中会得到不同的结果。通常你会扩展短通道数据[-32768..]在范围内加倍[-1.. .]看起来你正试图这么做。您的java结果:-3.0517578125E-5是正确的短值-1:-1/32768。我不知道为什么你们的Matlab结果不同。您还没有向我们展示如何得到Matlab结果。
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:
如果你有一个大的字节序列(我猜你有),并且你不想担心BIG-ENDIAN vs LITTLE-ENDIAN或者移动比特和字节,让java来替你处理:
import java.nio.*;
...
ByteBuffer buf = ByteBuffer.wrap(audioBytes);
buf.order(ByteOrder.LITTLE_ENDIAN);
while (buf.remaining() >= 2) {
short s = buf.getShort();
double mono = (double) s;
double mono_norm = mono / 32768.0;
...
}
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.
ByteBuffer.getShort()读取缓冲区的下两个字节,处理Little-Endian排序,将字节转换为短字节,并为下一个getXXX()调用定位自身。
#2
0
This is the correct way:
这是正确的方法:
double sampleValue = (double)(( bytes[0]<<8 ) | ( bytes[1]&0x00FF ));
(Change indices to swap little/big)
(改变指数以交换小/大)
#3
-1
Cant you just do most_significant byte * 256 + least_significant_byte and then cast to double?
难道你就不能只执行大部分有意义的字节* 256 +最小有意义的字节然后转换为双字节吗?