2011-06-17 15 views
2

私が取り組んでいるプロジェクトでは、複数の.wavファイルを連結したいと考えています。私の研究を通してJava - 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); 

私はループのために生産.wavファイルのみのためにオーディオを再生コメントを解除するとき、それはしかし、2 .wavファイルを結合するために正常に動作します最初の連結。オーディオトラックは早く終了するように見えますが、wmpのデュレーションバーは画面全体の約1/5にしかならないためです。

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

複数のオーディオファイルを連結する方法と.wavヘッダーを管理する方法の両方を研究した後、私のオーディオの残りがなぜ存在しないのかについてはまだわかりません。どんな助けでも大歓迎です。前もって感謝します。

答えて

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

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

+0

いつも新しい入力ストリームを作成していただきありがとうございます。私の唯一の質問は、入力ストリームがforループの最後のコード行として閉じられるべきかどうかです。 – Pojo226

+0

@ Pojo226:シーケンス入力ストリームをクローズすると、その基礎となるすべてのストリームが閉じられ、オーディオ入力ストリームを閉じると、その基礎となるストリームも閉じます。 finallyブロックの最後のaudioBuildを閉じることは十分なはずですが、AudioSystem.write()を呼び出す前にすべてのストリームを読み込む呼び出しであるため、閉じないでください。 – prunge

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")); 
関連する問題