package engine;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
import org.newdawn.easyogg.OggClip;
public class Sounds {
public static HashMap<String, Sound> musics = new HashMap<String, Sound>();
public static ArrayList<Sound> sfxs = new ArrayList<Sound>(16);
// musaks
public static final String[] AMBIENT = {"Dark Fog.ogg", "Decline.ogg", "Private Reflection.ogg", "The Complex.ogg",
"The Path of the Goblin King.ogg", "The Snow Queen.ogg", "Unpromised.ogg"};
// sound affects
private static Sound initMusic(String sound) {
sound = "assets/audio/" + sound;
Sound s = musics.get(sound);
if (s != null)
return musics.get(sound);
return initNewSound(sound);
}
public static boolean isPlayingMusic() {
for(Sound s : musics.values())
if(!s.stopped())
return true;
return false;
}
private static Sound initNewSound(String sound) {
if (isOgg(sound)) {
return new OggSound(sound);
} else if (isWav(sound))
return new WavSound(sound);
return null;
}
public static boolean loadMusic(String sound) {
if (musics.containsKey(sound))
return true;
Sound s = initMusic(sound);
if (s == null)
return false;
musics.put(sound, s);
return true;
}
public static void playMusic(String sound) {
loadMusic(sound);
musics.get(sound).play();
}
public static void loopMusic(String sound) {
loadMusic(sound);
musics.get(sound).loop();
}
private static void updateSfxs() {
for (int i = 0; i < sfxs.size();) {
if (sfxs.get(i).stopped())
sfxs.remove(i);
else
i++;
}
}
public static void playSoundEffect(String sound) {
Sound s = initNewSound(sound);
updateSfxs();
sfxs.add(s);
s.play();
}
public static void loopSoundEffect(String sound) {
Sound s = initNewSound(sound);
updateSfxs();
sfxs.add(s);
s.loop();
}
public static void stopSoundEffect(String sound) {
for (Sound s : sfxs) {
if (s.getLocation().equals(sound)) {
s.stop();
sfxs.remove(s);
}
}
}
public static void stopMusic(String sound) {
for (Entry<String, Sound> entry : musics.entrySet())
if (entry.getKey().equals(sound))
entry.getValue().stop();
}
public static void stopAllSoundEffects() {
updateSfxs();
for (Sound s : sfxs)
s.stop();
sfxs.clear();
}
public static void stopAllMusic() {
for (Entry<String, Sound> entry : musics.entrySet())
entry.getValue().stop();
}
public static void setVolume(float f) {
setMusicVolume(f);
// setSoundEffectsVolume(f);
}
public static void setMusicVolume(float f) {
for (Entry<String, Sound> entry : musics.entrySet())
entry.getValue().setVolume(f);
}
public static void setSoundEffectsVolume(float f) {
updateSfxs();
for (Sound s : sfxs)
s.setVolume(f);
sfxs.clear();
}
public static void stopAll() {
stopAllMusic();
stopAllSoundEffects();
}
public static boolean isOgg(String sound) {
return sound.endsWith(".ogg");
}
public static boolean isWav(String sound) {
return sound.endsWith(".wav");
}
}
interface Sound {
public void play();
public void stop();
public void loop();
public void setVolume(float vol);
public void resetVolume();
public String getLocation();
public boolean stopped();
}
class WavSound implements Sound {
private Clip clip;
public String location;
public WavSound(String sound) {
location = sound;
try {
clip = AudioSystem.getClip();
// java.net.URL soundURL = Sprites.class.getClassLoader().getResource(sound);
// clip.open(AudioSystem.getAudioInputStream(soundURL));
InputStream ins = Settings.class.getClassLoader().getResourceAsStream(sound);
clip.open(AudioSystem.getAudioInputStream(ins));
// clip.open(AudioSystem.getAudioInputStream(new File(sound)));
} catch (Exception e) {
System.out.println("sound clip not found or had error");
}
}
@Override
public void play() {
clip.start();
}
@Override
public void stop() {
clip.stop();
}
@Override
public void loop() {
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
@Override
public void setVolume(float vol) {
if (vol > 1)
vol = 1.0f;
else if (vol < 0)
vol = 0.0f;
FloatControl volume = (FloatControl) clip
.getControl(FloatControl.Type.VOLUME);
volume.setValue(vol);
}
@Override
public void resetVolume() {
setVolume(1.0f);
}
@Override
public String getLocation() {
return location;
}
@Override
public boolean stopped() {
return clip.isRunning();
}
}
class OggSound implements Sound {
private OggClip clip;
public String location;
public OggSound(String sound) {
location = sound;
try {
// java.net.URL soundURL = Sprites.class.getClassLoader().getResource(sound);
// InputStream fis = soundURL.openStream();
InputStream fis = Settings.class.getClassLoader().getResourceAsStream(sound);
// InputStream fis = new FileInputStream(sound);
clip = new OggClip(fis);
} catch (IOException e) {
e.printStackTrace();
System.out.println("sound clip not found or had error");
}
}
@Override
public void play() {
clip.play();
}
@Override
public void stop() {
clip.stop();
}
@Override
public void loop() {
clip.loop();
}
@Override
public void setVolume(float vol) {
if (vol > 1)
vol = 1.0f;
else if (vol < 0)
vol = 0.0f;
clip.setGain(vol);
}
@Override
public void resetVolume() {
setVolume(1.0f);
}
@Override
public String getLocation() {
return location;
}
@Override
public boolean stopped() {
return clip.stopped();
}
}