Java - 无法合并超过2个.wav文件

时间:2011-06-17 03:24:20

标签: java audio stream wave wav

对于我正在处理的项目,我希望能够连接多个.wav文件。

通过我的研究,我得出了这段代码:

File sample1 = new File("F:\\Programming\\Resources\\Java_Sound\\trumpet1.wav");
File sample2 = new File("F:\\Programming\\Resources\\Java_Sound\\trumpet2.wav");

File fileOut = new File("F:\\Programming\\Resources\\Java_Sound\\Test.wav");

AudioInputStream audio1 = AudioSystem.getAudioInputStream(sample1);
AudioInputStream audio2 = AudioSystem.getAudioInputStream(sample2);

AudioInputStream audioBuild = new AudioInputStream(new SequenceInputStream(audio1, audio2), audio1.getFormat(), audio1.getFrameLength() + audio2.getFrameLength());

//for(int i = 0; i < 5; i++){
//    audioBuild = new AudioInputStream(new SequenceInputStream(audioBuild, audio2), audioBuild.getFormat(), audioBuild.getFrameLength() + audio2.getFrameLength());
//}

AudioSystem.write(audioBuild, AudioFileFormat.Type.WAVE, fileOut);

它可以很好地组合两个.wav文件,但是当我取消注释for循环时,生成的.wav文件只播放第一个连接的音频。音频轨道似乎提前结束,因为wmp的持续时间条仅在整个屏幕的大约1 \ 5处。

我认为问题出在创建的.wav文件中的标题上。我已经研究了许多不同的网页,讨论如何构造一个头,但是所有这些都有不同的定义,但是所有人都说头部应该是十六进制的。转换流(不是音频流,标准FileInputStream)时,我的标题是十进制的。另外,在RIFF部分之后和WAVE部分之前,应该是整个文件的大小,不包括前8个字节。然而,我的一些包括连字符。说实话,我不知道那些意思是什么。但是忽略它们,取消注释上面代码后测试文件的大小仍然是一个更大的数字。

因此,在研究了如何连接多个音频文件以及如何创建\ manage .wav标题之后,我仍然不知道为什么我的音频没有播放,如果它甚至存在。任何帮助是极大的赞赏。提前谢谢。

2 个答案:

答案 0 :(得分:4)

可能是因为输入流不能被多次读取。一旦你读取了一个输入流,它将在它的结尾,并且尝试进一步读取将不再从该流中读取字节。

这应该稍加修改,继续在循环中创建新的音频输入流:

File sample1 = new File("f1.wav");
File sample2 = new File("f2.wav");

File fileOut = new File("combined.wav");

AudioInputStream audio1 = AudioSystem.getAudioInputStream(sample1);
AudioInputStream audio2 = AudioSystem.getAudioInputStream(sample2);

AudioInputStream audioBuild = new AudioInputStream(new SequenceInputStream(audio1, audio2), audio1.getFormat(), audio1.getFrameLength() + audio2.getFrameLength());

for(int i = 0; i < 5; i++)
{
    audioBuild = new AudioInputStream(new SequenceInputStream(audioBuild, /* keep creating new input streams */ AudioSystem.getAudioInputStream(sample2)), audioBuild.getFormat(), audioBuild.getFrameLength() + audio2.getFrameLength());
}

AudioSystem.write(audioBuild, AudioFileFormat.Type.WAVE, fileOut);

另外,请确保文件的音频格式完全相同。也就是说,相同的采样率,相同的通道数,每个样本的相同位数。否则,您将需要其他代码来进行样本转换。

答案 1 :(得分:2)

这是我用来加入任意数量的wave文件。我循环遍历波形文件路径的字符串值列表,每次我将前一个结果的AudioInputStream与下一个剪辑一起加入。

List<String> paths;
AudioInputStream clip1 = null;
for (String path : paths)
{
    if(clip1 == null)
    {
        clip1 = AudioSystem.getAudioInputStream(new File(path));
        continue;
    }
    AudioInputStream clip2 = AudioSystem.getAudioInputStream(new File(path));
    AudioInputStream appendedFiles = new AudioInputStream(
            new SequenceInputStream(clip1, clip2),     
            clip1.getFormat(), 
            clip1.getFrameLength() + clip2.getFrameLength());
    clip1 = appendedFiles;
}
AudioSystem.write(clip1, AudioFileFormat.Type.WAVE, new File("exported.wav"));