# Java Abspielen von Wave-Dateien



## chrian (17. Januar 2011)

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)

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




}
```


----------



## vfl_freak (17. Januar 2011)

Moin,

bitte verdeutliche Dein Problem noch mal ...

Heißt dass, dass Du in der Main-Methode nicht über folgende Zeile hinaus kommst 

```
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()" 

```
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


----------



## chrian (17. Januar 2011)

hi,
ich komme nicht über den ersten sound hinaus.
die whileschleife läuft auch, keine Ahnung warum, mehr als 20 Sec, obwohl der Sound nur 5 Sec hat :-(

Also:
Der 1. Sound wird immer korrekt ausgegeben, aber dann ist schluss.
ich exportier mal alles:
http://www.file-upload.net/download-3137407/Archiv.zip.html


----------



## vfl_freak (17. Januar 2011)

Moin,

ah, die while-Schleife ...

```
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


----------



## chrian (17. Januar 2011)

*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 :-(


----------



## darkmagic2002 (6. Februar 2011)

Hallo chrian,
versuche doch einmal, die Anweisungen in der _makeSound_-Methode in einem temporären Thread auszuführen:

```
public void makeSound(int sound)
{
    new Thread(new Runnable()
    {
        // hier die Anweisungen
    }.start();
}
```
Bei mir hat das damals geklappt.

Grüße kevin


----------



## wakoz (12. Februar 2011)

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


----------



## darkmagic2002 (12. Februar 2011)

Hallo wakoz,


wakoz hat gesagt.:


> Ich Schätze das mit dem Thread wird neue Probleme Bringen


Schon ausprobiert?



wakoz hat gesagt.:


> 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


----------



## wakoz (14. Februar 2011)

darkmagic2002 hat gesagt.:


> Hallo wakoz,
> 
> Schon ausprobiert?
> 
> ...


 
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 sound*s* 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


----------

