package me.hammerle.supersnuvi.util; import java.io.File; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.SourceDataLine; import me.hammerle.supersnuvi.Game; public class SoundUtils { public enum Sound { DASH("sounds/dash.wav", true), DODGE("sounds/dodge.wav", true), LONDONER_JUMP("sounds/londoner_jump.wav", true), MIRROR_BREAK("sounds/mirror_break.wav", true), MIRROR_CRACK("sounds/mirror_crack.wav", true), SWORD_PULL("sounds/sword_pull.wav", true), SWORD_SHEATH("sounds/sword_sheath.wav", true), SWORD_SLASH("sounds/sword_slash.wav", true), COLLECT("sounds/collect.wav", true), JUMP("sounds/jump.wav", true), JUMP_ON_BOUNCE_SHROOM("sounds/jump_on_bounce_shroom.wav", false), STONE_CRUMBLING("sounds/stone_crumbling.wav", true), WALK("sounds/walk.wav", false), WALK_WATER("sounds/walk_water.wav", false), MENU_MUSIC("sounds/menu_music.wav", false), SONG_1("sounds/song1.wav", false); private boolean isLooping = true; private volatile boolean isRunning = false; private SourceDataLine line = null; private AudioFormat format = null; private File f; private Thread thread = null; private byte[] cache = null; private boolean reset; Sound(String sound, boolean reset) { this.reset = reset; f = new File(sound); try { AudioFormat oldFormat = AudioSystem.getAudioFileFormat(f).getFormat(); AudioFormat.Encoding[] encodings = AudioSystem.getTargetEncodings(oldFormat); if(encodings.length == 0) { return; } else { AudioFormat[] formats = AudioSystem.getTargetFormats(encodings[0], oldFormat); if(formats.length == 0) { return; } else { format = new AudioFormat( formats[0].getEncoding(), oldFormat.getSampleRate(), formats[0].getSampleSizeInBits(), formats[0].getChannels(), formats[0].getFrameSize(), oldFormat.getFrameRate(), formats[0].isBigEndian()); line = AudioSystem.getSourceDataLine(format); } } thread = new Thread(() -> run()); thread.start(); } catch(Exception ex) { System.out.println("Sound '" + f + "' failed."); //ex.printStackTrace(); } } private void run() { try { while(isLooping) { if(!isRunning) { synchronized(this) { wait(); if(!isLooping) { return; } } } isRunning = false; line.open(format); line.start(); if(cache != null) { line.write(cache, 0, cache.length); } else { AudioInputStream stream = AudioSystem.getAudioInputStream(format, AudioSystem.getAudioInputStream(f)); byte[] buffer = new byte[1024 * 1024]; int read = stream.read(buffer); if(read < buffer.length) { cache = new byte[read]; System.arraycopy(buffer, 0, cache, 0, read); line.write(cache, 0, cache.length); } else { while(read > 0) { line.write(buffer, 0, read); read = stream.read(buffer); } } } line.drain(); line.close(); } } catch(Exception ex) { System.out.println("Sound '" + f + "' failed."); //ex.printStackTrace(); } } public void play() { if(reset) { stop(); } if(thread == null) { System.out.println("Playing sound '" + f + "' failed."); return; } isRunning = true; synchronized(this) { notify(); } } public void stop() { if(thread == null) { System.out.println("Stopping sound '" + f + "' failed."); return; } isRunning = false; line.stop(); } public void close() { if(thread == null) { System.out.println("Closing sound '" + f + "' failed."); return; } isLooping = false; synchronized(this) { notify(); } line.close(); } } public static void playSound(Sound sound) { if(Game.get().isSoundEnabled() && sound != null) { /*if(sound != Sound.MENU_MUSIC && sound != Sound.SONG_1 && sound != Sound.WALK) { System.out.println("PLAYING " + sound); }*/ sound.play(); } } public static void stopSound(Sound sound) { sound.stop(); } public static void turnSoundOff() { for(Sound sound : Sound.values()) { sound.stop(); } } public static void closeSounds() { for(Sound sound : Sound.values()) { sound.close(); } } }