|  | @@ -1,207 +1,101 @@
 | 
	
		
			
				|  |  |  package me.hammerle.supersnuvi.util;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import java.io.File;
 | 
	
		
			
				|  |  | -import java.util.Arrays;
 | 
	
		
			
				|  |  | -import javafx.scene.media.Media;
 | 
	
		
			
				|  |  | -import javafx.scene.media.MediaPlayer;
 | 
	
		
			
				|  |  | +import java.io.IOException;
 | 
	
		
			
				|  |  | +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 javax.sound.sampled.LineUnavailableException;
 | 
	
		
			
				|  |  | +import javax.sound.sampled.UnsupportedAudioFileException;
 | 
	
		
			
				|  |  |  import me.hammerle.supersnuvi.gamelogic.StateRenderer;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  public class SoundUtils 
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    private static SoundPlayer soundPlayer;
 | 
	
		
			
				|  |  | -            
 | 
	
		
			
				|  |  | -    public static void initSounds()
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        soundPlayer = new SoundPlayer(!StateRenderer.isSoundEnabled());
 | 
	
		
			
				|  |  | -        //new Thread(soundPlayer).start();
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +    private static final AudioFormat WAV = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100.0f, 24, 1, 3, 44100.0f, false);
 | 
	
		
			
				|  |  | +    private static final DataLine.Info INFO = new DataLine.Info(Clip.class, WAV);
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  |      public enum Sound
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        COLLECT(true), 
 | 
	
		
			
				|  |  | -        JUMP(true), 
 | 
	
		
			
				|  |  | -        JUMP_ON_BOUNCE_SHROOM(false), 
 | 
	
		
			
				|  |  | -        STONE_CRUMBLING(true), 
 | 
	
		
			
				|  |  | -        WALK(false), 
 | 
	
		
			
				|  |  | -        WALK_WATER(false),
 | 
	
		
			
				|  |  | -        MENU_MUSIC(false), 
 | 
	
		
			
				|  |  | -        SONG_1(false);
 | 
	
		
			
				|  |  | +        COLLECT("collect", true), 
 | 
	
		
			
				|  |  | +        JUMP("jump", true), 
 | 
	
		
			
				|  |  | +        JUMP_ON_BOUNCE_SHROOM("jump_on_bounce_shroom", false), 
 | 
	
		
			
				|  |  | +        STONE_CRUMBLING("stone_crumbling", true), 
 | 
	
		
			
				|  |  | +        WALK("walk", false), 
 | 
	
		
			
				|  |  | +        WALK_WATER("walk_water", false),
 | 
	
		
			
				|  |  | +        MENU_MUSIC("menu_music", false), 
 | 
	
		
			
				|  |  | +        SONG_1("song1", false);
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  |          private final boolean reset;
 | 
	
		
			
				|  |  | +        private Clip clip;
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  | -        Sound(boolean reset)
 | 
	
		
			
				|  |  | +        Sound(String path, boolean reset)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              this.reset = reset;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        public boolean shouldReset()
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            return reset;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | -    private static class SoundPlayer implements Runnable
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        private final MediaPlayer collect;
 | 
	
		
			
				|  |  | -        private final MediaPlayer jump;
 | 
	
		
			
				|  |  | -        private final MediaPlayer jumpOnBounceShroom;
 | 
	
		
			
				|  |  | -        private final MediaPlayer stoneCrumbling;
 | 
	
		
			
				|  |  | -        private final MediaPlayer walk;
 | 
	
		
			
				|  |  | -        private final MediaPlayer walkWater;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        private final MediaPlayer menuMusic;
 | 
	
		
			
				|  |  | -        private final MediaPlayer song1;
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        private final boolean noSound;
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        private final boolean[] playState;
 | 
	
		
			
				|  |  | -        private boolean shouldRun;
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        public SoundPlayer(boolean noSound)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            this.noSound = noSound;
 | 
	
		
			
				|  |  | -            shouldRun = false;
 | 
	
		
			
				|  |  | -            
 | 
	
		
			
				|  |  | -            collect = getMedia("collect");
 | 
	
		
			
				|  |  | -            jump = getMedia("jump");
 | 
	
		
			
				|  |  | -            jumpOnBounceShroom = getMedia("jump_on_bounce_shroom");
 | 
	
		
			
				|  |  | -            stoneCrumbling = getMedia("stone_crumbling");
 | 
	
		
			
				|  |  | -            walk = getMedia("walk");
 | 
	
		
			
				|  |  | -            walkWater = getMedia("walk_water");
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            menuMusic = getMedia("menu_music", true);
 | 
	
		
			
				|  |  | -            song1 = getMedia("song1", true);
 | 
	
		
			
				|  |  | -            
 | 
	
		
			
				|  |  | -            playState = new boolean[Sound.values().length];
 | 
	
		
			
				|  |  | -            Arrays.fill(playState, false);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        private MediaPlayer getMedia(String path, boolean loop)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            if(noSound)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                return null;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            Media sound = new Media(new File("sounds/" + path + ".wav").toURI().toString());
 | 
	
		
			
				|  |  | -            MediaPlayer mp = new MediaPlayer(sound);
 | 
	
		
			
				|  |  | -            mp.setCycleCount(MediaPlayer.INDEFINITE);
 | 
	
		
			
				|  |  | -            if(loop)
 | 
	
		
			
				|  |  | +            try
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                mp.setCycleCount(MediaPlayer.INDEFINITE);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                mp.setOnEndOfMedia(() -> 
 | 
	
		
			
				|  |  | +                AudioInputStream stream = AudioSystem.getAudioInputStream(WAV, 
 | 
	
		
			
				|  |  | +                        AudioSystem.getAudioInputStream(new File("sounds/" + path + ".wav")));
 | 
	
		
			
				|  |  | +                this.clip = (Clip) AudioSystem.getLine(INFO);
 | 
	
		
			
				|  |  | +                clip.open(stream);
 | 
	
		
			
				|  |  | +                clip.addLineListener((e) -> 
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  | -                    mp.stop();
 | 
	
		
			
				|  |  | +                    if(e.getFramePosition() > 0)
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                        clip.stop();
 | 
	
		
			
				|  |  | +                        clip.setMicrosecondPosition(0);
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  |                  });
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            return mp;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        private MediaPlayer getMedia(String path)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            return getMedia(path, false);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        public synchronized void playSound(Sound sound)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            if(noSound)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                return;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            shouldRun = true;
 | 
	
		
			
				|  |  | -            playState[sound.ordinal()] = true;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        public synchronized void playSounds()
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            if(!noSound && shouldRun)
 | 
	
		
			
				|  |  | +            catch(IOException | LineUnavailableException | UnsupportedAudioFileException ex)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                this.notifyAll();
 | 
	
		
			
				|  |  | +                System.err.println("error with 'sounds/" + path + ".wav'");
 | 
	
		
			
				|  |  | +                System.err.println(ex);
 | 
	
		
			
				|  |  | +                this.clip = null;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  | -        public void stopSound(Sound sound)
 | 
	
		
			
				|  |  | +        private void play()
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            if(noSound)
 | 
	
		
			
				|  |  | +            if(clip != null)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                return;
 | 
	
		
			
				|  |  | +                if(reset)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    clip.stop();
 | 
	
		
			
				|  |  | +                    clip.setMicrosecondPosition(0);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                clip.start();
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            getMediaPlayer(sound).stop();
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  | -        private MediaPlayer getMediaPlayer(Sound sound)
 | 
	
		
			
				|  |  | +        private void stop()
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            switch(sound)
 | 
	
		
			
				|  |  | +            if(clip != null)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                case COLLECT: return collect;
 | 
	
		
			
				|  |  | -                case JUMP: return jump;
 | 
	
		
			
				|  |  | -                case JUMP_ON_BOUNCE_SHROOM: return jumpOnBounceShroom;
 | 
	
		
			
				|  |  | -                case MENU_MUSIC: return menuMusic;
 | 
	
		
			
				|  |  | -                case SONG_1: return song1;
 | 
	
		
			
				|  |  | -                case STONE_CRUMBLING: return stoneCrumbling;
 | 
	
		
			
				|  |  | -                case WALK: return walk;
 | 
	
		
			
				|  |  | -                case WALK_WATER: return walkWater;
 | 
	
		
			
				|  |  | +                clip.stop();
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            return null;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        @Override
 | 
	
		
			
				|  |  | -        public void run() 
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            /*while(GameWindow.isRunning)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                final boolean[] states;
 | 
	
		
			
				|  |  | -                synchronized(this)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    states = Arrays.copyOf(soundPlayer.playState, soundPlayer.playState.length);
 | 
	
		
			
				|  |  | -                    Arrays.fill(soundPlayer.playState, false);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                Sound sound;
 | 
	
		
			
				|  |  | -                MediaPlayer mp;
 | 
	
		
			
				|  |  | -                for(int i = 0; i < states.length; i++)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    if(states[i])
 | 
	
		
			
				|  |  | -                    {
 | 
	
		
			
				|  |  | -                        states[i] = false;
 | 
	
		
			
				|  |  | -                        sound = Sound.values()[i];
 | 
	
		
			
				|  |  | -                        mp = soundPlayer.getMediaPlayer(sound);
 | 
	
		
			
				|  |  | -                        if(sound.shouldReset())
 | 
	
		
			
				|  |  | -                        {
 | 
	
		
			
				|  |  | -                            mp.seek(mp.getStartTime());
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | -                        mp.play();
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                
 | 
	
		
			
				|  |  | -                synchronized(this)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    try
 | 
	
		
			
				|  |  | -                    {
 | 
	
		
			
				|  |  | -                        this.wait();
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    catch(InterruptedException ex)
 | 
	
		
			
				|  |  | -                    {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }*/
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  | -    public static void playSounds()
 | 
	
		
			
				|  |  | +    public static void playSound(Sound sound)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        soundPlayer.playSounds();
 | 
	
		
			
				|  |  | +        if(StateRenderer.isSoundEnabled())
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            sound.play();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  | -    public static void playSound(Sound sound)
 | 
	
		
			
				|  |  | +    public static void stopSound(Sound sound)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        soundPlayer.playSound(sound);
 | 
	
		
			
				|  |  | +        sound.stop();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  | -    public static void stopSound(Sound sound)
 | 
	
		
			
				|  |  | +    public static void turnSoundOff()
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        soundPlayer.stopSound(sound);
 | 
	
		
			
				|  |  | +        for(Sound sound : Sound.values())
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            sound.stop();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |