10

在过去的几天里,试图让它发挥作用时遇到了一些麻烦。但我想要的是我们有一个通过网络发送原始数据的应用程序。然后我读入这个二进制数据并想把它保存到一个 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);

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

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

4

3 回答 3

6

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

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 个字节的数据存储到我的二进制文件中。

于 2012-06-14T00:00:30.053 回答
1

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

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

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

写的时候,你说“文件确实写成功了,但它都是静态的”——你用你自己的java代码以外的东西确认了吗?也许我理解不正确,但听起来您正在尝试使用新的 Java 代码录制和播放 WAV 文件,如果是这种情况,很难判断录制或播放是否有问题。

您应该从原始格式(16 位,立体声,未压缩,44,100 kHz)开始,以便您可以在媒体播放器或 quicktime 或其他工具中打开文件并验证录制是否有效。一旦成功,您可以尝试更改 SR 等等。这是一些用于录制的示例代码。从那开始,验证它是否有效,然后继续进行更复杂的事情:

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

于 2012-06-12T15:05:55.557 回答
0

尝试设置 AudioFormat 的 Encoding 和 frame size 和 frame rate。

new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                  8000f,
                  16,
                  1,
                  2, // frameSize
                  8000f,// frameRate
                  false);
于 2015-12-08T04:13:41.773 回答