java - 如何在Java中读取/写入高分辨率(24位,8 channel ).wav文件?

标签 java audio wav libsndfile

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

当我使用标准方法时,会引发异常。

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<p></p>

<p>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
</p>

任何人都可以建议将音频导入 Java 的最简单方法吗?

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

顺便说一句,我注意到该文件可以由 libsndfile 读取。我最好的选择是在 libsndfile 周围编写一个 jni 包装器,或者你能建议更快的东西吗?

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

* 更新 *

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

当我有机会时,我会发布格林斯泰德代码的修改版本。同时,如果有人想要,请给我留言。

最佳答案

回复很晚,但其他人可能会从中受益。

一个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/

关于java - 如何在Java中读取/写入高分辨率(24位,8 channel ).wav文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6458377/

相关文章:

java.lang.IllegalArgumentException : The attribute [A] from the managed type [T] is not present 异常

java - 通过子类引用使用基类对象 - java

swift - Swift:响应中带有应用程序/八位字节流的GET请求

c# - 使用 .net 多次异步播放 wav 文件

android - 如何在Android中包含外部WAV文件

java - 光CP : Timeout after 30000 waiting for a connection

java - 如何在 mac 上从 java 读取和写入原始 ip 数据包?

java - 画出麦克风输入的轮廓

html - HTML5 Canvas将鼠标悬停在 Canvas 上的事件上

audio - 延迟混合Sox