# Alles hängt, wenn ein Sound abgespielt wird



## Chickenwarrior (10. Jan 2012)

Hallo,

Ich hab ein Problemchen, denn mein Programm laggt, wenn ein Sound abgespielt wird!


```
File soundFile = new File("zombie1.wav");
        if (!soundFile.exists()) { 
            System.err.println("Wave file not found: " + "zombie1.wav");
            return;
        } 
 
        AudioInputStream audioInputStream = null;
        try { 
            audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        } catch (UnsupportedAudioFileException e1) { 
            e1.printStackTrace();
            return;
        } catch (IOException e1) { 
            e1.printStackTrace();
            return;
        }
 
        AudioFormat format = audioInputStream.getFormat();
        SourceDataLine auline = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
 
        try { 
            auline = (SourceDataLine) AudioSystem.getLine(info);
            auline.open(format);
        } catch (LineUnavailableException e) { 
            e.printStackTrace();
            return;
        } catch (Exception e) { 
            e.printStackTrace();
            return;
        } 
 
        auline.start();
        int nBytesRead = 0;
        byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
 
        try { 
            while (nBytesRead != -1) { 
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0) 
                    auline.write(abData, 0, nBytesRead);
            } 
        } catch (IOException e) { 
            e.printStackTrace();
            return;
        } finally { 
            auline.drain();
            auline.close();
        }
```

Ich hoffe, jemand kann das überblicken und mir sagen, wieso es hängt


----------



## Bile Demon (10. Jan 2012)

"Laggt" oder hängt?

Ohne jetzt genau zu wissen woran es liegt: Hast du den Code zum Abspielen der Audiodatei in einen eigenen Thread gelegt?


----------



## Chickenwarrior (10. Jan 2012)

Nope, hab ich nicht. Anfängerfehler ^^

Ist nun in eigenem Thread, hängt immernoch


----------



## Fu3L (10. Jan 2012)

Zumindest beim AudioClip wird's automatisch von 'nem eigenen Thread abgespielt.

Ich vermute, dass du den Sound jedes Mal neu lädst, wenn er abgespielt werden soll und das laggt dann halt.


----------



## Chickenwarrior (10. Jan 2012)

Mit Audioclip hab ichs nicht hinbekommen, die Anleitungen sind alle kacke, deswegen ist das eine Blaupause ausm indernet. Wie kann man das beheben?


----------



## Fu3L (10. Jan 2012)

Für deine Lösung mit dem AudioInputStream kann ich leider nichts beitragen, weil ich immer AudioClip auf sehr bequeme Art und Weise nutzen konnte.

So sieht meine Soundklasse in etwa aus und die funktioniert ziemlich gut. Bei 1000 verschiedenen Sounds sollte man sich dann aber doch was besser skalierbares ausdenken^^


```
public class Sound {

	public final static Sound instance = new Sound();
	private boolean loaded = false;
	private boolean playSound = true;

	private Map<String, AudioClip> clips = new HashMap<String, AudioClip>();

	private Sound() {
	}

	public static Sound get() {
		return instance;
	}

	public void preLoad() {
		if(!loaded) {
			AudioClip a = Applet.newAudioClip(getClass().getClassLoader().getResource("sounds/paddle.wav"));
			clips.put("paddle", a);
			loaded = true;
		}
	} 

	public void playPaddleCollision() {
		this.play("paddle");
	}

	public void play(String sound) {
		if(playSound) {
			clips.get(sound).play();
		}
	}

	public void playSound(boolean playSound) {
		this.playSound = playSound;
	}

	public boolean isMute() {
		return !playSound;
	}

}
```


----------



## Chickenwarrior (11. Jan 2012)

Danke, dass du deine gesamte Sound-Klasse zur Verfügung stellst. Ich kriege jedoch stets eine NullPointerException auf Zeile 18.
Ich hab die .wav soundfile so angegeben:

```
AudioClip a = Applet.newAudioClip(getClass().getClassLoader().getResource("zombie1.wav"));
```
Könntest du noch kurz eins zwei Sätze zur Bedienung sagen? 
PS: Mit meiner Klasse kann ich den Sound so abspielen, indem ich ich mit "zombie.wav" angebe.

Ich hab folgende Imports eingefügt:

import java.applet.Applet;
import java.applet.AudioClip;
import java.util.HashMap;
import java.util.Map;


----------



## SlaterB (11. Jan 2012)

getClass().getClassLoader().getResource() sucht im ClassPath des Programms,
nicht unbedingt im Grundverzeichnis des Programms, welches bei relativen Dateipfaden zum Tragen kommt,
wenn du mit File schon Erfolg hast geht vielleicht der Weg

Javabeginners - FilezuURL


----------



## Chickenwarrior (11. Jan 2012)

Jetzt gibts ne Nullpointer bei play()

so wirds aufgerufen:

zomb.preLoad();
zomb.play("zombie1.wav");

so sieht jetzt mein preload() aus:


```
public void preLoad() {
        if(!loaded) {
            AudioClip a = Applet.newAudioClip(getClass().getClassLoader().getResource("zombie1.wav"));
            clips.put("zombie", a);
            loaded = true;
        }
    }
```

play() ist unverändert. Da kein Fehler in Zeile 3, denke ich, dass er zombie1.wav nun findet...

HILFE


----------



## Fu3L (12. Jan 2012)

Die Art wie du es aufrufst deutet auf eine Nutzung hin, wie sie nicht gedacht ist^^
Erstmal zum Konkreten: Die play()-Methode erwartet den String, unter dem der Sound in der HashMap gespeichert ist, also "zombie".

Zur beabsichtigten Nutzen:
Du solltest mehrere verschiedene Sounds in der Klasse Sound laden (einfach copy&paste der loadzeilen:


```
AudioClip a = Applet.newAudioClip(getClass().getClassLoader().getResource("zombie1.wav"));
clips.put("zombie", a);
a = Applet.newAudioClip(getClass().getClassLoader().getResource("blubb.wav"));
clips.put("blubb", a);
loaded = true;
```
) dann hinzufügen mehrerer Methoden:


```
public void playZombieBreath() {
this.play("zombie");
}

public void playBlubbdiblubb() {
this.play("blubb");
}
```

und schlussendlich der Aufruf in den einzelnen Klassen per:


```
public class DieBlubbMacht {
  public void hierPassiertWas() {
     Sound.get().playBlubbdieblubb();
  }
}
```

Besser skalierbar wäre es natürlich schon, wenn jede Art von Wesen seinen eigenen Sound per Soundklasse verwalten und abspielen lassen würde. Für 10-20 Sounds sollte es aber schon reichen^^

Das Abwandeln wäre dann auch nicht mehr sooo schwer. Da ich sowieso grad meine Hilfsklassen mal geordnet neuschreibe, wird sowas vllt in den nächsten Tagen entstehen^^


----------

