我正在尝试编写一个操作高分辨率.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代码的修改版本。在此期间,如果有人想要,请给我发消息。
答案 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的已编译“可用”版本,此处存在:
答案 1 :(得分:1)
你可以自己阅读wav数据,实际上并不难。只需搜索WAV文件格式信息。