2011-10-18 8 views
1

に私のゲームは、通常のメソッドを介して音を再生ハングSourceDataLine.drainは()OSX

sdl.stop(); 

このキャンセルがうまく動作しますWindowsでは、しかし、Java 6でOSX 10.5.8を実行している1人のユーザにとって、プログラムはハングします。 Threaddumpは、再生スレッドがdrain()内にあることを示します:com.sun.media.sound.MixerSourceLine.nDrain。ユーザーがサウンドを中断しない場合は、正常に完了し、アプリケーションは続行されます。

私の質問は以下のとおりです。

  • これはOSXのJavaのバグですか?
  • 停止の代わりにsdl.close()を使用しますか?
  • 回避策に関するご提案またはご経験がありますか?

編集:私は、同様の効果を持つthisバグレポートを見つけましたが、ページには、それが固定されていると言います。参考

+0

この[例](http://stackoverflow.com/questions/2064066/does-java-have-built-in-library-for-audio-synthesis/2065693#2065693)はMac OSX 10.5.8で正常終了します、Java 6. – trashgod

+0

@trashgodこの例は非同期に閉じられません。私は、中断しないと、音がうまく再生されるという質問に言及しました。 – akarnokd

+0

[BigClip](http://stackoverflow.com/questions/5667454/playing-audio-file-in-java-application/5668510#5668510)を使用して同じ動作をしますか? –

答えて

1

lineは既に上に正常に閉じられていない限り、EDTハングのJava 5と6の両方ではなくclose()よりstop()を、起動通常のJava 5または6

いずれか下close()出口を使用して、この例最初のスレッド。停止した回線が切断されないので、これはブロックdrain()の予期された結果のようです。

import java.awt.EventQueue; 
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 
import javax.swing.JOptionPane; 

/** 
* @see https://stackoverflow.com/questions/7803310 
* @see https://stackoverflow.com/questions/2065693 
*/ 
public class Tone { 

    public static void main(String[] args) throws LineUnavailableException { 
     final AudioFormat af = 
      new AudioFormat(Note.SAMPLE_RATE, 8, 1, true, true); 
     final SourceDataLine line = AudioSystem.getSourceDataLine(af); 
     EventQueue.invokeLater(new Runnable() { 

      public void run() { 
       JOptionPane.showMessageDialog(null, "Halt"); 
       //line.stop(); // stops and hangs on drain 
       line.close(); 
      } 
     }); 
     line.open(af, Note.SAMPLE_RATE); 
     line.start(); 
     for (Note n : Note.values()) { 
      play(line, n, 500); 
      play(line, Note.REST, 10); 
     } 
     line.drain(); 
     line.close(); 
    } 

    private static void play(SourceDataLine line, Note note, int ms) { 
     ms = Math.min(ms, Note.SECONDS * 1000); 
     int length = Note.SAMPLE_RATE * ms/1000; 
     int count = line.write(note.data(), 0, length); 
    } 
} 

Noteが必要です。

+0

ありがとうございました。 Windows JREが仕様に準拠していないようです。私は、これらの変更でゲームを試してみるようにユーザーに依頼します。 – akarnokd

+1

変更が反映されました。ありがとう。 – akarnokd