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

Java 将音频字节[]保存到wav文件,java,audio,Java,Audio,在过去的几天里,我一直有点麻烦,想让它发挥作用。但我想要的是我们有一个通过网络发送原始数据的应用程序。然后我读入这个二进制数据,并想将其保存到wav(任何音频)文件中。稍后可能会查看压缩 因此,有问题的代码: byte[] allBytes = ... InputStream b_in = new ByteArrayInputStream(allBytes); try { AudioFormat format = new AudioFormat(8000f, 16, 1, true,

在过去的几天里,我一直有点麻烦,想让它发挥作用。但我想要的是我们有一个通过网络发送原始数据的应用程序。然后我读入这个二进制数据,并想将其保存到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.unsupportDaudioFileException:无法从流中获取音频输入流
。所以我认为发生的是,因为我的流是原始音频数据,并且没有波头,所以这会引发异常

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);
该文件确实成功写入,但它都是静态的,我是否需要在输出上创建一个wave头,例如。当我在记事本中查看输出的wav文件时,它似乎有一个以“RIFF”开头的头


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

很难从您的描述中知道错误在哪里,但要回答您的问题,当您打开文件时看到“RIFF”,这意味着它有一个头。尝试构建您自己的头是可能的,但有点耗时(而且没有必要,因为您已经有了头)

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

在编写时,您会说“文件确实成功地编写了,但它都是静态的”——您是否用自己的java代码以外的其他东西确认了这一点?也许我理解得不正确,但听起来好像您正在尝试用新的java代码录制和播放WAV文件,如果是这样的话,很难判断录制或播放是否出了问题

您应该从普通格式(16位、立体声、未压缩、44100 kHz)开始,这样您就可以在media player或quicktime或其他软件中打开文件,并验证录制是否有效。一旦成功,您可以尝试更改SR等。下面是一些用于录制的示例代码。从这一点开始,验证它是否有效,然后转到更复杂的问题:


所以我最终还是让它工作了,不确定为什么,但这就是正在工作的代码:

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)
所以它一定是我的有符号/无符号/小尾端设置。我最后做的是将数据保存到一个二进制文件中。然后在audacity中将该文件作为原始数据导入。这告诉了我一切,除了我已经知道的利率。 我现在唯一的问题是关于页眉的计算。我保存的二进制数据生成4秒的wav,但它只有2秒的声音。这就好像是我的头球算错了。我不确定这是否与刘岩提到的帧长有关

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

尝试设置AudioFormat的编码、帧大小和帧速率

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

你的帖子有问题。您缺少数据/格式。与其他有效的WAVE文件比较如何?当您选择其中一个时,将数据复制到标头之后,然后将原始数据放入数组allBytes的代码中。运行代码后,您可以简单地比较两个wave文件。如果不一样,那么要么代码不好,要么您需要更好地理解波形格式。
AudioInputStream
构造函数中的
length
参数应该是帧长度值,而不是数据长度<代码>帧长度=数据长度/通道/样本大小(字节)Hi Liu Yan。我试着设置你的帧长,但结果更糟了。最后,除了头文件之外,它什么也没放进wav文件,遗漏了所有的二进制数据。请你放上括号好吗。是:帧长=(数据长度/通道)/以字节为单位的样本大小,还是帧长=(数据长度*以字节为单位的样本大小)/通道OK如果有人发现音频有问题,我假设帧长是16。。。。但是当我检查format.getFrameSize()时,值是2,所以需要有以下AudioInputStream=newAudioInputStream(b_in,format,resultArray.length/1/format.getFrameSize());