2009-03-21 29 views
1

wavファイルの "ループ"を含む一時ファイルを作成することはできますか?Javaでwavファイルを再生する - 再生したサウンドを拡張または連結するにはどうすればよいですか?

ストリームリーダ/ライタに送信されるストリームを操作することは可能ですか?

基本的には、ある期間wavファイルを再生したい場合、その時間がwavファイルが提供する時間より長い場合、ループしたいです。

答えて

4
 AudioInputStream audioIn = AudioSystem.getAudioInputStream(url); 
    Clip clip = AudioSystem.getClip(); 
    clip.loop((int)(Math.ceil(timeRequested/audioIn.getFrameLength()))); 
+0

Iいくつか質問があります。私が使用している既存のDataLineにループをどのように「接続」すればよいですか?クリップをどうしたらいいですか?それをSourceDataLineに送る方法は? – Tim

+0

これは現在のアクティブなDataLineに自動的にアタッチされ、クリップは別のプレーヤーのインスタンスと同じように、開始することも、いつでも停止することもできます。同時に再生できるクリップの数を表示することができます。キューを定義します。しかし、私はあなた自身を混合することをお勧めしません。 –

+0

私はそれを試してみますが、私のコードが存在するようにデータラインで動作するかどうかはわかりません。ありがとう – Tim

0

解決策を実装するための厳密な制限がわかりませんが、これを行う最もクリーンな方法は、ファイルを初めて再生するときにバッファにオーディオデータを保存することです。次に、ユーザーが必要とする反復(完全または部分)がさらにある場合は、キャッシュしたデータをSourceDataLineに必要な回数書き戻します。

ここでは、非常に簡単に変更する(または学習する)コードを持つサンプルサウンドファイルプレーヤー(PCM)にlinkがあります。私はまた、上で説明したロジックを示している(テストされていない)いくつかのコードをハッキングしました:(複数のサイズのデータ​​を書き込むというルールに従うために、 )フレームサイズの

public void playSoundFile(SourceDataLine line, InputStream inputStream, AudioFormat format, long length, float times) 
{ 
    int index = 0; 
    int size = length * format.getFrameSize(); 
    int currentSize = 0; 
    byte[] buffer = new byte[size]; 
    AudioInputStream audioInputStream = new AudioInputStream(inputStream, format, length); 
    while (index < size) 
    { 
     currentSize = audioInputStream.read(buffer, index, size - index); 
     line.write(buffer, index, currentSize); 
     index += currentSize; 
    } 

    float currentTimes = 1.0; 
    while (currentTimes < times) 
    { 
     float timesLeft = times - currentTimes; 
     int writeBlockSize = line.available(); 
     index = 0; 

     if (timesLeft >= 1.0) 
     { 
      while (index < size) 
      { 
       currentSize = ((size - index) < writeBlockSize) ? size - index : writeBlockSize; 
       line.write(buffer, index, currentSize); 
       index += currentSize; 
      } 
      currentTimes += 1.0; 
     } 
     else 
     { 
      int partialSize = (int)(timesLeft * ((float) size) + 0.5f); 
      while (index < partialSize) 
      { 
       currentSize = ((partialSize - index) < writeBlockSize) ? partialSize - index : writeBlockSize; 
       line.write(buffer, index, currentSize); 
       index += currentSize; 
      } 
      currentTimes += timesLeft; 
     } 
    } 
} 

希望に役立ちます!

+0

これは可能ですが、私が探しているものではありません。データはプレーヤーに非同期で送信され、ファイル/サウンドの長さは分かりません。 – Tim

+0

状況の詳細についてもう少し情報を教えてください。指定されていないものがいくつかあります(例えば、ファイル/サウンドの長さと再生する時間を知っている人、プレーヤーであればプレーヤーは上記のキャッシング方法を実行できます)。 –

0

私はこれを理解するために、オーディオ入力ストリームの1秒あたりのフレーム数とフレームサイズ情報を使用します。その他の有用な情報は、SourceDataLineオブジェクトのgetMicrosecondPosition()メソッドにあり、これまでに再生された時間/継続時間を決定します。

これは、オーディオ入力ストリーム内のマークとリセットメソッドと一緒に、おそらくそれをすべて処理します。

関連する問題