如何用Java读/写高分辨率(24位,8通道).wav文件?

时间:2011-06-23 17:45:59

标签: java audio wav libsndfile

我正在尝试编写一个操作高分辨率.wav文件的Java应用程序。我在导入音频数据时遇到问题,即将.wav文件转换为双打数组。

当我使用标准方法时,会抛出异常。

AudioFileFormat as = AudioSystem.getAudioFileFormat(new File("orig.wav"));
-->
javax.sound.sampled.UnsupportedAudioFileException: file is not a supported file type

这是根据soxi的文件格式信息:


dB$ soxi orig.wav
soxi WARN wav: wave header missing FmtExt chunk

Input File : 'orig.wav' Channels : 8 Sample Rate : 96000 Precision : 24-bit Duration : 00:00:03.16 = 303526 samples ~ 237.13 CDDA sectors File Size : 9.71M Bit Rate : 24.6M Sample Encoding: 32-bit Floating Point PCM

有人能建议将这种音频转换成Java的最简单方法吗?

我尝试过使用一些技巧。如上所述,我已经尝试了Java AudioSystem(在Mac和Windows上)。我也尝试过使用Andrew Greensted的WavFile class,但这也失败了(WavFileException:不支持压缩代码3)。一种解决方法是使用sox将音频转换为16位(使用-b 16标志),但这不是最理想的,因为它会增加本底噪声。

顺便说一下,我注意到libsndfile可以读取该文件。我最好在libsndfile周围写一个jni包装器,或者你能更快地提出建议吗?

请注意,我不需要播放音频,我只需要对其进行分析,操作,然后将其写入新的.wav文件。

*更新*

我通过修改Andrew Greensted的WavFile class解决了这个问题。他的原始版本只读取编码为整数值的文件(“格式代码1”);我的文件编码为浮点数(“格式代码3”),这就是造成问题的原因。

当我有机会时,我会发布Greensted代码的修改版本。在此期间,如果有人想要,请给我发消息。

2 个答案:

答案 0 :(得分:2)

答复非常晚,但其他人可能会从中受益。

现在存在libsndfile java wrapper,这应该有助于解决这样的音频读/写/转换问题。包装器(由swig生成)对于libsndfile API是正确的,因此结构与典型的Java风格略有不同,但完全可用。

在您的特定情况下,使用情况看起来像这样:

String filePath = "path/to/some/audio_8_channels.wav";

// open the sound file
SF_INFO sndInfo = new SF_INFO();
SWIGTYPE_p_SNDFILE_tag sndFile = libsndfile.sf_open(filePath, libsndfile.SFM_READ, sndInfo);

// create a buffer array large enough to hold all channels (double per channel) of all frames
int arraySize = sndInfo.getFrames() * sndInfo.getChannels();
CArrayDouble darray = new CArrayDouble(arraySize);

// read every frame (includes all channels) into the buffer array
long count = libsndfile.sf_readf_double(sndFile, darray.cast(), sndInfo.getFrames());

// iterate over the doubles that make up the audio
for (int i=0; i < arraySize; i++) {
    // every 8 doubles is a frame..
    double d = darray.getitem(i);
}

Google代码项目,包括Windows7上JDK1.7的已编译“可用”版本,此处存在:

http://code.google.com/p/libsndfile-java/

答案 1 :(得分:1)

你可以自己阅读wav数据,实际上并不难。只需搜索WAV文件格式信息。