2

私が取り組んでいるプロジェクトでは、複数の .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);

2 つの .wav ファイルを結合する場合は問題なく動作しますが、for ループのコメントを外すと、生成された .wav ファイルは最初の連結のオーディオのみを再生します。wmp のデュレーション バーは画面全体の約 1\5 しか移動しないため、オーディオ トラックが早く終了するように見えます。

問題は、作成された .wav ファイルのヘッダーにあると想定しています。ヘッダーがどのように構築されているかについて議論している多くの異なる Web ページを調査しましたが、それらはすべてわずかに異なる定義を持っていましたが、ヘッダーは 16 進数でなければならないと言っていました。ストリーム (オーディオ ストリームではなく、標準の FileInputStream) を変換するとき、私が持っていたヘッダーは 10 進数でした。また、RIFF 部分の後、WAVE 部分の前は、最初の 8 バイトを含まないファイル全体のサイズであると想定されています。ただし、一部にはハイフンが含まれていました。正直なところ、私はそれらが何を意味するのか見当がつきません。ただし、それらを無視しても、上記のコードのコメントを外した後のテスト ファイルのサイズは依然として大きい数値です。

したがって、複数のオーディオ ファイルを連結する方法と .wav ヘッダーを作成/管理する方法の両方を調査した後でも、オーディオの残りの部分が再生されない理由がわかりません。どんな助けでも大歓迎です。前もって感謝します。

4

2 に答える 2

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

また、ファイルのオーディオ形式がまったく同じであることを確認してください。つまり、同じサンプル レート、同じチャンネル数、同じサンプルあたりのビット数です。それ以外の場合は、サンプル変換を行うために追加のコードが必要になります。

于 2011-06-17T04:37:26.340 に答える
2

これは、任意の量の wave ファイルを結合するために使用したものです。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"));
于 2013-04-01T23:59:16.597 に答える