JavaSound 使用流写入音频文件
我正在尝试使用 JavaSound API 创建音频过滤器来读取和写入音频文件。 目前我的代码结构如下:
ByteArrayOutputStream b_out = new ByteArrayOutputStream();
// Read a frame from the file.
while (audioInputStream.read(audioBytes) != -1) {
//Do stuff here....
b_out.write(outputvalue);
}
// Hook output stream to output file
ByteArrayInputStream b_in = new ByteArrayInputStream(b_out.toByteArray());
AudioInputStream ais = new AudioInputStream(b_in, format, length);
AudioSystem.write(ais, inFileFormat.getType(), outputFile);
它将输入文件作为流读取,对其进行处理并将其写入 bytearrayoutputstream,但它会等到整个文件处理完毕后再写入磁盘。 理想情况下,我希望它在处理每个样本时将其写入磁盘。 我已经尝试了流构造的几种组合,但找不到一种方法来实现它,因为 AudioSystem.write() 需要输入流。 有任何想法吗?
I'm attempting to create an audio filter using the JavaSound API to read and write the audio files. Currently my code is structured as follows:
ByteArrayOutputStream b_out = new ByteArrayOutputStream();
// Read a frame from the file.
while (audioInputStream.read(audioBytes) != -1) {
//Do stuff here....
b_out.write(outputvalue);
}
// Hook output stream to output file
ByteArrayInputStream b_in = new ByteArrayInputStream(b_out.toByteArray());
AudioInputStream ais = new AudioInputStream(b_in, format, length);
AudioSystem.write(ais, inFileFormat.getType(), outputFile);
This reads the input file as a stream, processes it and writes it to a bytearrayoutputstream, but it waits until the entire file has been processed before writing to disk. Ideally, I would like it to write each sample to disk as it's processed. I've tried several combinations of stream constructs but can't find a way of doing it as AudioSystem.write() takes an input stream. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
kasperjj的答案是正确的。 您可能正在使用 WAV 文件。 看看这个
用于波形文件的布局。 请注意,整个 WAV 文件的大小都编码在其标头中。
我不知道这是否适用于您的情况,但要按照您的描述处理 WAV 样本,您可以使用“常规”非音频 Java 输出流。 例如,您可以使用 FileOutputStream 将它们写入临时文件,处理后您可以将临时文件转换为有效的 WAV 文件。
kasperjj's answer is right. You are probably working with WAV files. Look at this
for the layout of a wave file. Note that the size of the entire WAV file is encoded in its header.
I don't know if this is applicable in your case, but to process WAV samples as you described, you can use a "regular" non-audio Java output stream. You could use a FileOutputStream for example to write them to a temp file, and after processing you can convert the temp file into a valid WAV file.
某些音频格式需要在其标头中描述流的长度(或块的数量)的元数据,因此无法在整个数据集出现之前开始写入数据。 为了让 Java 声音 API 能够使用相同的 API 处理所有格式,我怀疑他们必须故意施加此限制。
然而,有许多音频格式可以轻松地进行流式传输。 其中许多都有针对 java 的开放库实现,因此如果您愿意添加外部库,那么完成起来应该不难。
Some audio formats require metadata describing the length of the stream (or the number of chunks) in their header, thus making it impossible to start writing the data before the entire dataset is present. Inorder for the Java sound API to handle all formats with the same API, I suspect they have had to impose this limit on purpose.
There are however many audio formats that can easily be streamed. Many of them have open library implementations for java, so if you are willing to add an external lib it shouldn't be that hard to accomplish.
如果重新实现 AudioSystem.write 方法,就可以解决该问题。 它不适用于流和 WAVE 格式。 您应该从 AudioInputStream 读取数据,将其缓存在字节数组中,处理该数组并记录到波形文件。 我建议您检查示例中的类: 如何记录音频到字节数组
It is possible to solve the issue if you reimplement AudioSystem.write method. It doesn't work with stream and WAVE format. You should read data from AudioInputStream, cache it in byte array, process the array and record to wave file. I would recommend you to check classes from the example: How to record audio to byte array