Sound/Thread Problem

Flokati

Grünschnabel
Hi!

Ich möchte gerne etwas Sound in meinem Programm abspielen.
Klappt leider noch nicht so ganz, wie ich mir das vorstelle. Ich kann ca. eine halbe Sekunde was hören und dann ist finito.
Das Problem ist wohl, das das Programm beendet wird, bevor das Sound komplett abgespielt wurde.

Code:
import java.applet.Applet;
import java.applet.AudioClip;
import java.io.File;

public class PlaySound extends Thread {

  public static void main(String[] args) throws InterruptedException {
    PlaySound playSound = new PlaySound();
    playSound.start();
  }

  public void run() {
    // Sound File
    String file = "Ee_rev.wav";
    String path = "C:\\WINDOWS\\Media\\";
    String soundFileName = path + file;
    File soundFile = new File(soundFileName);

    // play Sound
    try {
      AudioClip sound = Applet.newAudioClip(soundFile.toURL());
      sound.play();
    } catch (Exception tmpE) {
      System.err.println(tmpE);
    }
  }
}

Ich vermute mal, das ich am Ende meiner main()-Methode einfach nur einen Befehl a la "Warte, bis alle Threads beendet sind" einbauen muss.
 
Dann tue es doch einfach. Schleife rein und immer abfragen. Aber ich würde das eigendlich am Ende der Run machen, bzw. dafür nichtmal einen Thread verwenden. Ich habe bis jetzt nur einen Sequenzer für diese Aufgabe genommen, da lautet die Methode .isRunning() (wer hätts gedacht?).
Allerdings ist Musik doch immer ein Thread, oder? Wäre doch blöd wenn nicht.
Also sollte es meines erachtends automatisch gehen.

JavaDoc hat gesagt.:
isRunning
boolean isRunning()
Indicates whether the Sequencer is currently running. The default is false. The Sequencer starts running when either start() or startRecording() is called. isRunning then returns true until playback of the sequence completes or stop() is called.

Returns:
true if the Sequencer is running, otherwise false


Die Methode, die ich immer verwende:

Java:
package title;

import java.io.File;

import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequencer;
import javax.swing.JOptionPane;

public final class Musikplayer extends Object
{
	private boolean playable;
	private Sequencer sequencer;
	
	public Musikplayer(String s)
	{
		super();
		
		this.playable = false;		
		this.sequencer = this.getSequencer();

		if(this.sequencer == null)
			return;
		this.sequencer = this.openAndLoad(s, this.sequencer);
	}
	public final void startPlay(Float tempoRate)
	{
		if(!this.playable)
			return;
		this.sequencer.setTempoFactor(tempoRate);
		this.sequencer.start();
	}
	
	private final Sequencer getSequencer()
	{
		Sequencer sequencer = null;
		
		try
		{
			sequencer = MidiSystem.getSequencer();
		}
		catch(Exception e)
		{
			JOptionPane.showMessageDialog(null,
					"Konnte Midi-Sequencer nicht intialisieren.\n" +
					"Es wird keine Musik gespielt werden.",
					"Warnung",
					JOptionPane.WARNING_MESSAGE);
		}
		return(sequencer);
	}
	private final Sequencer openAndLoad(String s, Sequencer sequ)
	{
		try
		{
			sequ.open();
		}
		catch(Exception e1)
		{
			JOptionPane.showMessageDialog(null,
					"Konnte Midi-Sequencer nicht öffnen.\n" +
					"Es wird keine Musik gespielt werden.",
					"Warnung",
					JOptionPane.WARNING_MESSAGE);
			return(null);
		}
		
		File f = new File(s);
		
		if(!f.exists())
		{
			JOptionPane.showMessageDialog(null,
					"Konnte Datei " + s + " nicht finden.\n" +
					"Programm wird nun beendetet.",
					"Fehler",
					JOptionPane.ERROR_MESSAGE);
			System.exit(0);
		}
		
	    try
	    {
			this.sequencer.setSequence(MidiSystem.getSequence(f));
		}
	    catch(Exception e)
	    {
			JOptionPane.showMessageDialog(null,
					"Konnte Musikdatei nicht laden\n" +
					"Es wird keine Musik gespielt werden.",
					"Warnung",
					JOptionPane.WARNING_MESSAGE);
			return(null);
	    }
		
	    this.playable = true;
		return(sequ);
	}
}

Wie man prüft ob alle Threads beendet sind weiß ich nicht, man könnte event. einen globalen Counter am Beginn der run() hochzählen, und am Ende wieder abziehen.
Aber ich bin immer davon ausgegangen, dass ein Programm erst beendet, wenn alle Threads, die keine Dämone sind beendet wurden.
 
Zuletzt bearbeitet:
Aber ich bin immer davon ausgegangen, dass ein Programm erst beendet, wenn alle Threads, die keine Dämone sind beendet wurden.
Jepp, davon bin ich auch ausgegangen, aber anscheinend passiert hier irgendwas anderes.

Ich habe meiner main() am Ende folgenden Code angefügt:
Code:
while(playSound.isAlive()) {      
      Thread.sleep(1000);
    }
Es sollte also jede Sekunde gecheckt werden, ob die Musik noch läuft und danach ist dann Ende.
Tatsächlich läuft die Musik eine Sekunde und dann ist Schluß, obwohl der Sample länger als eine Sekunde ist.

Ich lasse jetzt einfach stumpf 10 Sekunden warten, bevor das Programm beendet wird, das reicht, um den kleinen Soundschnippsel abzuspielen, ist aber natürlich keine "elegante" Lösung.
 

Neue Beiträge

Zurück