Java - проблема с объединением более 2 WAV-файлов - PullRequest
2 голосов
/ 17 июня 2011

для проекта, над которым я работаю, я хочу иметь возможность объединять несколько файлов .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 байтов. Однако некоторые из моих включали дефисы. Если честно, я понятия не имею, что это значит. Однако, игнорируя их, размер тестового файла после раскомментирования приведенного выше кода все еще больше.

Итак, после изучения как объединения нескольких аудиофайлов, так и создания / управления заголовками .wav, я все еще не понимаю, почему остальная часть моего звука не воспроизводится, если она вообще существует. Любая помощь очень ценится. Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 17 июня 2011

Это может быть потому, что входные потоки не могут быть прочитаны более одного раза. Как только вы прочитаете входной поток, он будет в конце и попытка читать дальше не будет читать больше байтов из этого потока.

Это должно работать с небольшой модификацией, продолжайте создавать новые аудио входные потоки в вашем цикле:

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

Кроме того, убедитесь, что ваши аудио форматы для файлов точно такие же. То есть одинаковая частота дискретизации, одинаковое количество каналов, одинаковые биты на выборку. В противном случае вам потребуется дополнительный код для преобразования примера.

2 голосов
/ 02 апреля 2013

Это то, что я использовал для соединения любого количества волновых файлов.Я перебрал список строковых значений для путей волнового файла и каждый раз присоединяюсь к предыдущему результирующему 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"));
...