Java 如何将.WAV音频数据样本转换为双重类型?

Java 如何将.WAV音频数据样本转换为双重类型?,java,audio,signal-processing,wav,sampling,Java,Audio,Signal Processing,Wav,Sampling,我正在开发一个处理音频数据的应用程序。 我正在使用java(我添加了MP3SPI、Jlayer和Tritonus)。我正在将音频数据从.wav文件提取到字节数组。我正在使用的音频数据样本是16位立体声 根据我阅读的内容,一个样本的格式是: AABBCCDD 其中AABB表示左通道和CCDD右通道(每个通道2字节)。 我需要将此示例转换为双值类型。我读过关于数据格式的书。Java使用Big-endian,.wav文件使用little-endian。我有点困惑。你能帮我转换一下吗? 谢谢大家Litt

我正在开发一个处理音频数据的应用程序。 我正在使用java(我添加了MP3SPI、Jlayer和Tritonus)。我正在将音频数据从.wav文件提取到字节数组。我正在使用的音频数据样本是16位立体声

根据我阅读的内容,一个样本的格式是:

AABBCCDD

其中AABB表示左通道和CCDD右通道(每个通道2字节)。 我需要将此示例转换为双值类型。我读过关于数据格式的书。Java使用Big-endian,.wav文件使用little-endian。我有点困惑。你能帮我转换一下吗?
谢谢大家

Little Endian表示数据的格式为BBAA和DDCC。你只需要交换一下就行了

从帧的开始:

int left = (bytes[i+1] << 8) + bytes[i];
int right = (bytes[i+3] << 8) + bytes[i+2];

int left=(bytes[i+1]警告:整数和字节是有符号的。在将它们打包在一起时,可能需要屏蔽低位字节:

for (int i =0; i < length; i += 4) {
    double left = (double)((bytes [i] & 0xff) | (bytes[i + 1] << 8));
    double right = (double)((bytes [i + 2] & 0xff) | (bytes[i + 3] << 8));

    ... your code here ...

}
for(int i=0;idouble left=(double)((bytes[i]&0xff)|(bytes[i+1]我个人会寻找一个为您进行endian交换的库。每种音频文件格式都有关于endian性的假设,对于所有位深/数据类型wave文件支持来说,将其正确化是很棘手的:

  • 8bit-uint8
  • 16位-int16
  • 24位-int32
  • 32位-int32作为浮点
  • 32位浮点
  • 64位双精度
如果您想支持最常见的wave文件类型,那么需要对所有这些数据类型进行endian转换

我看一下,上面列出的大多数类型都会显示byteswapping


Java在其文件IO类中没有endianness字段,这太糟糕了。能够简单地打开一个文件,而这个文件的edianness是大的还是小的,这是解决这个问题的一个更简单的方法。

当您使用ByteBuffer()时,您可以使用方法order

[命令]

公共最终字节缓冲顺序(字节顺序bo)

在此之后,您可以使用获得上述值

getChar() getShort() getInt() getFloat() getDouble()


Java是一种多么伟大的语言;-)

我个人会在移位处加上括号-我似乎记得优先级可能有点奇怪…这缺乏对低阶位的适当屏蔽。这一点很好,但您需要在所有字节[]访问上都这样做(除非它们向左移位24位或更多)。它们被提升为int,所以0x80变成0xFFFF80这正是我想要的,保留高字节的符号。实际上,我没有测试它(我不知道它是否有效,特别是对于浮点值),但有符号的16位值在提升为32位或更高时不应丢失符号。您好,谢谢您的回答。@erickson;我真的不理解您的评论。@GB;通过这样做,我得到了左通道中每个样本的左值,右通道中每个样本的右值。因此,最后每个样本有2个值,不是吗?是否可以为每个样本只获取一个值?@dedalo:这取决于您试图对这些样本执行的操作。如果您想要一个32位的值,则需要屏蔽并移动所有4字节的值。或者您想对它们进行平均?@GB:我试图做的是计算Mel系数(MFCC)这些系数用于语音识别。为了计算这些系数,第一步是从音频文件中获取样本,应用汉明窗口并计算FFT。
Modifies this buffer's byte order.

Parameters:
    bo - The new byte order, either BIG_ENDIAN or LITTLE_ENDIAN
Returns:
    This buffer