SourceDataLine 格式支持问题

Issues with SourceDataLine format support

我有一个用 Java 编写的应用程序,我需要在其中播放音频。我使用 OpenAL(带有 java-openal 库)来完成任务,但是我想使用 OpenAL 不直接支持的 WSOLA。我找到了一个很好的 java-native 库,叫做 TarsosDSP,它支持 WSOLA。

库使用标准 Java API 进行音频输出。问题发生在 SourceDataLine 设置期间:

IllegalArgumentException: No line matching interface SourceDataLine supporting format PCM_UNSIGNED 16000.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian is supported.

我确定问题不是由缺少权限引起的(运行 它在 Linux 上以 root 身份运行 + 在 Windows 10 上尝试过)并且没有其他 SourceDataLines在项目中使用。

修改格式后,我发现格式从 PCM_UNSIGNED 更改为 PCM_SIGNED 时可以接受。这似乎是一个小问题,因为仅将字节 运行ge 形式从无符号移动到有符号应该很容易。但是奇怪的是它不被原生支持。

那么,是否有一些解决方案可以让我不必修改源数据?

谢谢,简

您不必手动移动字节范围。创建 AudioInputStream 后,您将创建另一个 AudioInputStream,它具有签名格式并连接到第一个未签名流。如果您随后使用签名流读取数据,Sound API 会自动转换格式。这样就不需要修改源数据了。

File fileWithUnsignedFormat;

AudioInputStream sourceInputStream;
AudioInputStream targetInputStream;

AudioFormat sourceFormat;
AudioFormat targetFormat;

SourceDataLine sourceDataLine;

sourceInputStream = AudioSystem.getAudioInputStream(fileWithUnsignedFormat);
sourceFormat = sourceInputStream.getFormat();

targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
    sourceFormat.getSampleRate(), 
    sourceFormat.getSampleSizeInBits(), 
    sourceFormat.getChannels(), 
    sourceFormat.getFrameSize(), 
    sourceFormat.getFrameRate(), 
    false);

targetInputStream = AudioSystem.getAudioInputStream(targetFormat, sourceInputStream);

DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, targetFormat);
sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);

sourceDataLine.open(targetFormat);
sourceLine.start();


// schematic
targetInputStream.read(byteArray, 0, byteArray.length);
sourceDataLine.write(byteArray, 0, byteArray.length);