Alles hängt, wenn ein Sound abgespielt wird

Hallo,

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

Java:
        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

Bekanntes Mitglied
"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?
 

Fu3L

Top Contributor
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.
 

Fu3L

Top Contributor
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^^

Java:
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;
	}

}
 
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:
Java:
AudioClip a = Applet.newAudioClip(getClass().getClassLoader().getResource("zombie1.wav"));
Könntest du noch kurz eins zwei Sätze zur Bedienung sagen? :D
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;
 
S

SlaterB

Gast
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
 
Jetzt gibts ne Nullpointer bei play()

so wirds aufgerufen:

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

so sieht jetzt mein preload() aus:

Java:
    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 :D
 

Fu3L

Top Contributor
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:

Java:
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:

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

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

und schlussendlich der Aufruf in den einzelnen Klassen per:

Java:
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^^
 

Ähnliche Java Themen

Neue Themen


Oben