将音频字节[]保存到wav文件

时间:2012-06-12 06:15:38

标签: java audio

在最近几天试图让这个工作起来时遇到了一些麻烦。但我想要的是我们有一个通过网络发送原始数据的应用程序。然后,我读入了这个二进制数据,并希望将其保存到wav(任何音频)文件中。可能会稍后看一下压缩。

所以有问题的代码:

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);                

也试过使用上面的语句,但我得到了例外: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);

文件成功写入但是它都是静态的,我是否需要使用this之类的东西在输出上创建波形标题。当我在记事本中查看输出的wav文件时,它似乎有一个标题,因为它以“RIFF”开头。

我是否需要在输入流中添加假标头?我应该只创建自己的输出标题,并使用二进制编写器保存它吗?

3 个答案:

答案 0 :(得分:3)

所以我最终得到它的工作,不确定为什么,但这是正在运行的代码:

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)

所以它一定是我的签名/未签名/小端设置。我最终做的是将数据保存到二进制文件。然后将该文件作为原始数据导入大胆。这告诉我除了我已经新的比率以外的一切。 我现在唯一的问题是标题计算。我保存了生成4秒wav的二进制数据,但它只有2秒的声音。好像它正在计算我的标题错误。我不确定是否与刘燕提到的帧长有关。

如果我的数组长度为160.这是否意味着我的帧长为10? 160/1/16。 如果我这样做,那么我只将10个字节的数据存储到我的二进制文件中。

答案 1 :(得分:1)

很难从你的描述中知道错误的位置,但要回答你的问题,当你看到'RIFF'时打开文件意味着它有一个标题。尝试建立自己的标题是可能的,但有点耗时(并且因为你有一个不必要)。

现在,在阅读时,最安全的方法是从文件本身获取格式,而不是尝试手动指定格式 - 这样会更容易出错。这里有示例代码:

http://www.jsresources.org/examples/SimpleAudioPlayer.java.html

写作时,你会说“文件写成功但是全部都是静态的” - 你用你自己的java代码确认了吗?也许我没有正确理解,但听起来你正试图用新的java代码录制和播放WAV文件,如果是这样的话,很难判断录制或播放是否出错。

您应该以香草格式(16位,立体声,未压缩,44,100 kHz)开始,这样您就可以在媒体播放器或快速时间等打开文件,并验证录制是否有效。一旦有效,您可以尝试更改SR等。以下是一些录制示例代码。从那开始,验证它是否有效,然后继续进行更复杂的事情:

http://www.jsresources.org/examples/SimpleAudioRecorder.java.html

答案 2 :(得分:0)

尝试设置AudioFormat的编码和帧大小以及帧速率。

new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                  8000f,
                  16,
                  1,
                  2, // frameSize
                  8000f,// frameRate
                  false);