java - 获取FloatBuffer的AudioInputStream

标签 java audio audioinputstream

我有一个回调函数,它以 FloatBuffer 的形式获取传入的音频数据,其中包含 1024 个 float ,每秒调用多次。但我需要一个 AudioInputStream 因为我的系统只能使用它们。

将 float 转换为 16 位 PCM 音频数据不是问题,但我无法从中创建 InputStream。 AudioInputStream 构造函数仅接受已知长度的数据,但我有一个恒定的流。如果我使用包含音频数据的 PipedInputStream 来提供 AudioSystem.getAudioInputStream ,则 AudioSystem.getAudioInputStream 会抛出“java.io.IOException:不支持标记/重置”。

有什么想法吗?

<小时/>

这是我当前的代码:

Jack jack = Jack.getInstance();
JackClient client = jack.openClient("Test", EnumSet.noneOf(JackOptions.class), EnumSet.noneOf(JackStatus.class));
JackPort in = client.registerPort("in", JackPortType.AUDIO, EnumSet.of(JackPortFlags.JackPortIsInput));

PipedInputStream pin = new PipedInputStream(1024 * 1024 * 1024);
PipedOutputStream pout = new PipedOutputStream(pin);
client.setProcessCallback(new JackProcessCallback() {
public boolean process(JackClient client, int nframes) {
    FloatBuffer inData = in.getFloatBuffer();
    byte[] buffer = new byte[inData.capacity() * 2];
    for (int i = 0; i < inData.capacity(); i++) {
        int sample = Math.round(inData.get(i) * 32767);
        buffer[i * 2] = (byte) sample;
        buffer[i * 2 + 1] = (byte) (sample >> 8);
    }
    try {
        pout.write(buffer, 0, buffer.length);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return true;
}
});
client.activate();
client.transportStart();

Thread.sleep(10000);
client.transportStop();
client.close();

AudioInputStream audio = AudioSystem.getAudioInputStream(new BufferedInputStream(pin, 1024 * 1024 * 1024));
AudioSystem.write(audio, Type.WAVE, new File("test.wav"));

它使用 JnaJack 库,但数据来自哪里并不重要。顺便说一句,到字节的转换很好:直接将该数据写入 SourceDataLine 将正常工作。但我需要的数据为 音频输入流

最佳答案

AudioSystem.getAudioInputStream 需要一个符合受支持的 AudioFileFormat 的流。 ,这意味着它必须符合 known type 。来自 the documentation :

The stream must point to valid audio file data.

也来自该文档:

The implementation of this method may require multiple parsers to examine the stream to determine whether they support it. These parsers must be able to mark the stream, read enough data to determine whether they support the stream, and reset the stream's read pointer to its original position. If the input stream does not support these operation, this method may fail with an IOException.

您可以使用三参数构造函数创建自己的 AudioInputStream。如果长度未知,可以指定为 AudioSystem.NOT_SPECIFIED 。令人沮丧的是,构造函数文档和类文档都没有提到这一点,但other constructor’s documentation确实如此。

关于java - 获取FloatBuffer的AudioInputStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49753947/

相关文章:

java - JFrame - 使用 JComponent 和 MouseListener 的鼠标点击

Java 字符串操作到列中

java - 动态生成和播放声音(来自频率/幅度数据)

ios - IOS检测其他音乐是否暂停?

java - 如何在JAR文件中播放音频?

Java 音频流平台独立

java - 使音频循环更快

java - 为什么最终没有扩展到适用于数组和引用的对象?

java - 在 GWT 中导入 Gears API 时找不到 org.apache.xerces.jaxp.SAXParserFactoryImpl

python - Discord.py Bot 如何从本地文件播放音频