我有一个回调,它以FloatBuffer的形式接收传入的音频数据,其中包含1024个浮点数,每秒调用几次。但是我需要一个AudioInputStream,因为我的系统只和它们一起工作。
将浮点数转换为16位PCM音频数据并不是问题,但我不能用它创建一个InputStream。AudioInputStream构造函数只接受已知长度的数据,但我有一个常量流。如果我向AudioSystem.getAudioInputStream提供包含音频数据的PipedInputStream,则它会抛出一个"java.io.IOException: mark/reset不受支持“。
有什么想法吗?
以下是我的当前代码:
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将正确工作。但我需要AudioInputStream的数据。
发布于 2018-04-10 21:38:06
AudioSystem.getAudioInputStream需要一个符合受支持的AudioFileFormat的流,这意味着它必须符合已知类型。来自文献资料
流必须指向有效的音频文件数据。
从这些文件中也可以看出:
此方法的实现可能需要多个解析器来检查流,以确定它们是否支持它。这些解析器必须能够标记流,读取足够的数据以确定它们是否支持流,并将流的读取指针重置为原始位置。如果输入流不支持这些操作,则此方法可能在
IOException中失败。
您可以使用三个参数构造函数创建自己的AudioInputStream。如果不知道长度,则可以指定为规定。令人沮丧的是,构造函数文档和类文档都没有提到这一点,但是其他构造函数的文档确实提到了这一点。
https://stackoverflow.com/questions/49753947
复制相似问题