Java Abspielen von Wave-Dateien

chrian

Grünschnabel
Hi Leute,
nach zahlreichen Tutorials habe ich nun folgendes Programm gebastelt.
ich würde da gerne mehrere Sounds je nach aufruf wiedergeben, aber genau das geht leider nicht :-(
Es ist immer nach dem ersten Sound Schluss.... (_awful und das sind integerwerte aus dem Interface)
Java:
package sound;

import java.io.InputStream;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;

import org.apache.log4j.Logger;

public class Sound implements SoundList {
	Logger logger = Logger.getLogger(Sound.class);
	ClassLoader classLoader = getClass().getClassLoader();
	private InputStream fi;
	
	public void makeSound(int sound){
		if (sound==_awful){
			fi = classLoader.getResourceAsStream("sound/awful.wav");
		}
		else if (sound==_awh_man){
			fi = classLoader.getResourceAsStream("sound/awh_man.wav");
		}
		else if (sound==_boing){
			fi = classLoader.getResourceAsStream("sound/boing.wav");
		}
		else if (sound==_burp){
			fi = classLoader.getResourceAsStream("sound/burp.wav");
		}
		else if (sound==_excuse_me){
			fi = classLoader.getResourceAsStream("sound/excuse_me.wav");
		}
		else if (sound==_hiho){
			fi = classLoader.getResourceAsStream("sound/hiho.wav");
		}
		else if (sound==_nein){
			fi = classLoader.getResourceAsStream("sound/nein.wav");
		}
		else if (sound==_soundgood){
			fi = classLoader.getResourceAsStream("sound/soundgood.wav");
		}
		else if (sound==_troubles){
			fi = classLoader.getResourceAsStream("sound/troubles.wav");
		}
		try{
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(fi);
            AudioFormat af     = audioInputStream.getFormat();
            int size      = (int) (af.getFrameSize() * audioInputStream.getFrameLength());
            byte[] audio       = new byte[size];
            DataLine.Info info      = new DataLine.Info(Clip.class, af, size);
            audioInputStream.read(audio, 0, size);
            Clip clip = (Clip) AudioSystem.getLine(info);
            clip.open(af, audio, 0, size);
            System.out.println("------------->start musik");

                clip.start();
                while (clip.isActive()){
                }

                clip.stop();
                clip.close();
        }
        catch (Exception e){
        	logger.warn(e);
        }
	}
	
	public static void main(String[] args){
		System.out.println("hi");
		Sound sound = new Sound();
		//sound.makeSound(_awh_man);
		sound.makeSound(_awful);
		System.out.println("sound1");
		sound.makeSound(_soundgood);
		System.out.println("sound1");
		sound.makeSound(_boing);
		System.out.println("sound1");
		sound.makeSound(_burp);
		sound.makeSound(_excuse_me);
		sound.makeSound(_hiho);
		sound.makeSound(_nein);
		sound.makeSound(_troubles);
	
	}




}
 
Moin,

bitte verdeutliche Dein Problem noch mal ...

Heißt dass, dass Du in der Main-Methode nicht über folgende Zeile hinaus kommst :confused:
Java:
Sound sound = new Sound();
//sound.makeSound(_awh_man);
sound.makeSound(_awful);  // ist hier Schluß ? ?

// dies kommt nicht mehr
System.out.println("sound1");
sound.makeSound(_soundgood);

Oder hast Du ein Problem in der If-Anweisung in "makeSound()" :confused:
Java:
if (sound==_awful)
{
    fi = classLoader.getResourceAsStream("sound/awful.wav");
}
// also dieser Teil wird nie durchlaufen   :confused:
// else if (sound==_awh_man)  
// {
//     fi = classLoader.getResourceAsStream("sound/awh_man.wav");
//}
// usw.

Gruß
Klaus
 
Zuletzt bearbeitet:
Moin,

ah, die while-Schleife ...
Code:
while( clip.isActive() )
{
}

Sieht verdächtig nach einer Endlosschleife aus ;)

Was soll die überhaupt bewirken?
Willst Du damit Deiner Programm solange anhalten, bis der Clip zuende ist ?

Gruß
Klaus
 
*schäm*
so bei anderem Beispiel kopiert...
dachte man braucht die, damit der Sound ned sofort tot ist...
*Teste schnell und Editiere dann*

Man braucht die Whileschleife, weil der Sound sonst unmittelbar beendet wird :-(
 
Zuletzt bearbeitet:
Hallo chrian,
versuche doch einmal, die Anweisungen in der makeSound-Methode in einem temporären Thread auszuführen:
Java:
public void makeSound(int sound)
{
    new Thread(new Runnable()
    {
        // hier die Anweisungen
    }.start();
}
Bei mir hat das damals geklappt.

Grüße kevin
 
Ich Schätze das mit dem Thread wird neue Probleme Bringen ;)

ich habe bei derart verschachtelten if anweisungen bemerkt das Java die nicht immer korreckt durch arbeitet ;)

ersetze den if else Baum mal durch ein switch, ich vermute ein problem beim setzen von fi


while (clip.isActive()){]

sorgt dafür das der Code der Klasse nicht weiter durchlaufen wird solange die wav datei noch gespielt wird. Ist der Sound abgespielt worden wird clip.isActive() = fals
 
Hallo wakoz,
Ich Schätze das mit dem Thread wird neue Probleme Bringen ;)
Schon ausprobiert?;)

while (clip.isActive()){]

sorgt dafür das der Code der Klasse nicht weiter durchlaufen wird solange die wav datei noch gespielt wird. Ist der Sound abgespielt worden wird clip.isActive() = fals
Ja, stimmt genau, allerdings ist die Thread-Variante besser (Performance), da nicht ständig eine Schleife durchgearbeitet werden muss (vor allem bei längeren Sounds sehr rechenaufwendig), sondern sich ein eigener Thread um den Sound kümmert, bis der vollständig abgespielt worden ist. Außerdem ist das Programm während der Soundwiedergabe "ansprechbar"; vor allem bei Swing-Apps sinnvoll.

Grüße,
kevin
 
Hallo wakoz,

Schon ausprobiert?;)


Ja, stimmt genau, allerdings ist die Thread-Variante besser (Performance), da nicht ständig eine Schleife durchgearbeitet werden muss (vor allem bei längeren Sounds sehr rechenaufwendig), sondern sich ein eigener Thread um den Sound kümmert, bis der vollständig abgespielt worden ist. Außerdem ist das Programm während der Soundwiedergabe "ansprechbar"; vor allem bei Swing-Apps sinnvoll.

Grüße,
kevin

Natürlich hast du recht wegen der Verfügbarkeit von GUI und Program wenn es im Sound teil der anwendung läuft.

Aber!!

Ein eigener Thread für die Wiedergabe führt dazu das Sounds nicht immer zu dem gewünschten zeitpunkt abgespielt werden.

Wenn er für jedem Sound einen Thread startet werden die Sound nicht in der Gewünschten reihenfolge abgespielt oder auch mal gar nicht.

so wie er es derzeit gepostet hat wird er das problem bekommen das während der Sound Thread gerade versucht den ersten sound abzuspielen, bereits neue sounds abgespielt werden sollen. Mit anderen worten der Thread kommt nicht hinterher.

Die While schleife wird im Thread auch noch benötigt, ich habe noch kein beispiel gesehen wo es anders geht. Schließlich wird mit dem clip.stop() und dem clip.close() das Abspielen beendet. Also wenn die WAV gestartet wird dürfen die beiden Metoden nicht aufgerufen werden solange die WAV noch abgespielt werden soll, dieses verhindert die schleife derzeit.
Ich persönlichwürde es gerne sehen wenn das Clip objekt ein event schmeißt wenn der Sound abgespielt worden ist, so könnte da der Listener der auf das Event hört den Clip schließen.


Ich habe mich im Vergangendem jahr intensiv mit Java und Sound ausgaben beschäftigt und bin auf die von mir genannten Probleme gestoßen. Wobei ich für das abspielen meiner Sounds auch was änliches wie Threads verwendet hab.

Edit:
in der Schleife könnt man ein Thread sleep(2 sek) einsetzen, schließlich arbeitet der Java Clip im Hintergrund mit einem separaten Thread oder so. zumindest wird das abspielen der Sounds nicht beeinflusst wenn die Klasse/Thread schlafen gelegt wird ;)
Wichtig ist eins in dem beispiel code von chrian darf der code nicht weiter durchlaufen werden, ohne die von mir beschrieben Problematiken zu beachten und zu umschiffen
 
Zuletzt bearbeitet:
Zurück