java 将音频字节 [] 保存到 wav 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10991391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Saving audio byte[] to a wav file
提问by user1434177
Been having a bit of trouble over the last few days trying to get this to work. But what I want is we have an application that sends raw data over the network. I then read this binary data in and want to save it to a wav(any audio) file. Might look at compression later.
在过去的几天里试图让它工作时遇到了一些麻烦。但我想要的是我们有一个通过网络发送原始数据的应用程序。然后我读入这个二进制数据并想将它保存到一个 wav(任何音频)文件中。稍后可能会查看压缩。
So the problematic code:
所以有问题的代码:
byte[] allBytes = ...
InputStream b_in = new ByteArrayInputStream(allBytes);
try
{
AudioFormat format = new AudioFormat(8000f, 16, 1, true, true);
AudioInputStream stream = new AudioInputStream(b_in, format, allBytes.length);
//AudioInputStream stream = AudioSystem.getAudioInputStream(b_in);
Have tried to use the above statement as well but i get the exception: javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from stream
. So what I think is happening is that because my stream is raw audio data and does not have a wave header this is throwing an exception?
也曾尝试使用上述语句,但出现异常:javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from stream
. 所以我认为正在发生的事情是因为我的流是原始音频数据并且没有波头,所以会引发异常?
File newPath = new File(SystemConfiguration.getLatest().voiceNetworkPathDirectory + currentPhoneCall.fileName);
if (!AudioSystem.isFileTypeSupported(Type.WAVE, stream))
{
Logger.error("Audio System file type not supported");
}
AudioSystem.write(stream, Type.WAVE, newPath);
The file does successfully write but it is all static, Do I need to create a wave header on the output using the something like this. When I look at the outputted wav file in notepad and it does seem to have a header as it starts with 'RIFF'.
该文件确实成功写入,但它都是静态的,我是否需要使用类似这样的东西在输出上创建一个波头。当我在记事本中查看输出的 wav 文件时,它似乎确实有一个标题,因为它以“RIFF”开头。
Do I need to add a fake header into my input stream? Should i just create my own output header and just save it with a binary writer?
我需要在我的输入流中添加一个假标头吗?我应该创建自己的输出头文件并用二进制编写器保存它吗?
采纳答案by user1434177
So I ended up getting it working, not really sure why but this is the code that is working:
所以我最终让它工作了,不太确定为什么,但这是有效的代码:
InputStream b_in = new ByteArrayInputStream(resultArray);
try {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"C:\filename.bin"));
dos.write(resultArray);
AudioFormat format = new AudioFormat(8000f, 16, 1, true, false);
AudioInputStream stream = new AudioInputStream(b_in, format,
resultArray.length);
File file = new File("C:\file.wav");
AudioSystem.write(stream, Type.WAVE, file);
Logger.info("File saved: " + file.getName() + ", bytes: "
+ resultArray.length)
So it must have been my signed/unsigned/ little endian settings. What I ended up doing was saving the data to a binary file. Then importing that file as raw data in audacity. This told me everything except the rate which I already new. The only issue I have now is to do with the header calculation. I save the binary data which generates a 4 second wav but it only ever has 2 seconds of sound. Its as if it is calculating my header wrong. I'm not sure if it is to do with the frame-length that LiuYan mentioned.
所以它一定是我的签名/未签名/小端设置。我最终做的是将数据保存到二进制文件中。然后以大胆的方式将该文件作为原始数据导入。这告诉了我一切,除了我已经新的费率。我现在唯一的问题是标题计算。我保存了生成 4 秒 wav 的二进制数据,但它只有 2 秒的声音。就好像它计算我的标题错误一样。不知道是不是跟柳岩说的帧长有关。
If I have an array length of 160. Does this mean I have a framelength of 10? 160 / 1 / 16. If I do this then I only store 10 bytes of data into my binary file.
如果我的数组长度为 160。这是否意味着我的帧长度为 10?160 / 1 / 16。如果我这样做,那么我只会将 10 个字节的数据存储到我的二进制文件中。
回答by Bjorn Roche
It's hard to know from your description where the error is, but to answer your questions, when you see 'RIFF' when you open the file that does mean it has a header. Trying to build you own header is possible but a bit time consuming (and unnecessary since you've got one).
从您的描述中很难知道错误在哪里,但是为了回答您的问题,当您在打开文件时看到“RIFF”时,这确实意味着它有一个标题。尝试构建您自己的标头是可能的,但有点耗时(并且由于您已经有了标头而不必要)。
Now, when reading, it is safest to get the format from the file itself, rather than trying to specify it manually -- that will be less error prone. There is sample code for that here:
现在,在读取时,最安全的是从文件本身获取格式,而不是尝试手动指定它——这样更不容易出错。这里有示例代码:
http://www.jsresources.org/examples/SimpleAudioPlayer.java.html
http://www.jsresources.org/examples/SimpleAudioPlayer.java.html
When writing, you say "The file does successfully write but it is all static" -- have you confirmed that with something other than your own java code? Maybe I am not understanding correctly, but it sounds like you are trying to record and playback WAV files with fresh java code, and if that's the case, it's hard to tell if something is going wrong with the recording or the playback.
编写时,您说“该文件确实写入成功,但都是静态的”——您是否使用自己的 Java 代码以外的其他内容确认过这一点?也许我没有正确理解,但听起来您正在尝试使用新的 Java 代码录制和播放 WAV 文件,如果是这种情况,则很难判断录制或播放是否出现问题。
You should start with a vanilla format (16 bits, stereo, uncompressed, 44,100 kHz) so you can open the file in media player or quicktime or something and verify that the recording worked. Once that works, you can try to change the SR and so on. Here is some sample code for recording. Start with that, verify that it works, and then move on to something more complex:
您应该从普通格式(16 位、立体声、未压缩、44,100 kHz)开始,以便您可以在媒体播放器或 quicktime 或其他东西中打开文件并验证录音是否有效。一旦成功,您可以尝试更改 SR 等。这是一些用于录制的示例代码。从那开始,验证它是否有效,然后转向更复杂的事情:
http://www.jsresources.org/examples/SimpleAudioRecorder.java.html
http://www.jsresources.org/examples/SimpleAudioRecorder.java.html
回答by ernestk
Try setting the Encoding and frame size and frame rate of AudioFormat.
尝试设置 AudioFormat 的编码和帧大小和帧速率。
new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
8000f,
16,
1,
2, // frameSize
8000f,// frameRate
false);