Эх сурвалжийг харах

sound system rewritten, sound tests on windows and linux

Kajetan Johannes Hammerle 5 жил өмнө
parent
commit
521bf0f31d

+ 1 - 1
options.txt

@@ -12,4 +12,4 @@ key.left=263
 key.right=262
 key.run=340
 key.up=265
-sound=false
+sound=true

+ 6 - 0
src/me/hammerle/supersnuvi/Game.java

@@ -657,4 +657,10 @@ public class Game extends Engine
         }
         end.run();
     }
+
+    @Override
+    public void onStop()
+    {
+        SoundUtils.closeSounds();
+    }
 }

+ 1 - 1
src/me/hammerle/supersnuvi/entity/components/DefaultMovement.java

@@ -46,7 +46,7 @@ public class DefaultMovement extends Movement
     {
         if(ent.isOnGround())
         {
-            ent.setMotionY(ent.getMotionY() - getJumpPower());
+            ent.setMotionY((ent.getMotionY() < 0.0f ? ent.getMotionY() : 0.0f) - getJumpPower());
             return true;
         }
         return false;

+ 3 - 0
src/me/hammerle/supersnuvi/entity/components/ai/HumanController.java

@@ -5,6 +5,7 @@ import me.hammerle.snuviengine.api.Texture;
 import me.hammerle.supersnuvi.Keys;
 import me.hammerle.supersnuvi.entity.Entity;
 import me.hammerle.supersnuvi.util.Face;
+import me.hammerle.supersnuvi.util.SoundUtils;
 import me.hammerle.supersnuvi.util.Utils;
 
 public class HumanController extends Controller
@@ -102,11 +103,13 @@ public class HumanController extends Controller
         if(Keys.LEFT.isDown())
         {
             ent.setMotionX(-speed);
+            SoundUtils.playSound(SoundUtils.Sound.WALK);
         }
         
         if(Keys.RIGHT.isDown())
         {
             ent.setMotionX(speed);
+            SoundUtils.playSound(SoundUtils.Sound.WALK);
         }
         
         if(Keys.JUMP.isDown())

+ 162 - 62
src/me/hammerle/supersnuvi/util/SoundUtils.java

@@ -4,98 +4,190 @@ import java.io.File;
 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.SourceDataLine;
 import me.hammerle.supersnuvi.Game;
 
 public class SoundUtils 
-{
-    private static AudioFormat WAV;
-    private static DataLine.Info INFO;
-    
-    static
-    {
-        try
-        {
-            WAV = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100f, 24, 1, 3, 44100.0f, false);
-            INFO = new DataLine.Info(Clip.class, WAV);
-        }
-        catch(Exception ex)
-        {
-            WAV = null;
-            INFO = null;
-            ex.printStackTrace();
-        }
-    }
-    
+{    
     public enum Sound
     {
-        DASH("dash", true),
-        DODGE("dodge", true), 
-        LONDONER_JUMP("londoner_jump", true), 
-        MIRROR_BREAK("mirror_break", true), 
-        MIRROR_CRACK("mirror_crack", true), 
-        SWORD_PULL("sword_pull", true),
-        SWORD_SHEATH("sword_sheath", true), 
-        SWORD_SLASH("sword_slash", true), 
+        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);
         
-        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 boolean isLooping = true;
+        private volatile boolean isRunning = false;
+
+        private SourceDataLine line = null;
+
+        private AudioFormat format = null;
+        private File f;
+        private Thread thread = null;
         
-        private final boolean reset;
-        private Clip clip;
+        private byte[] cache = null;
         
-        Sound(String path, boolean reset)
+        private boolean reset;
+
+        Sound(String sound, boolean reset)
         {
             this.reset = reset;
+            f = new File(sound);
             try
             {
-                AudioInputStream stream = AudioSystem.getAudioInputStream(WAV, 
-                        AudioSystem.getAudioInputStream(new File("sounds/" + path + ".wav")));
-                this.clip = (Clip) AudioSystem.getLine(INFO);
-                clip.open(stream);
-                clip.addLineListener((e) -> 
+                AudioFormat oldFormat = AudioSystem.getAudioFileFormat(f).getFormat();
+                AudioFormat.Encoding[] encodings = AudioSystem.getTargetEncodings(oldFormat);
+                if(encodings.length == 0)
+                {
+                    return;
+                }
+                else
                 {
-                    if(e.getFramePosition() > 0)
+                    AudioFormat[] formats = AudioSystem.getTargetFormats(encodings[0], oldFormat);
+                    if(formats.length == 0)
                     {
-                        clip.stop();
-                        clip.setMicrosecondPosition(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.err.println("error with 'sounds/" + path + ".wav'");
-                System.err.println(ex);
-                this.clip = null;
+                System.out.println("Sound '" + f + "' failed.");
+                ex.printStackTrace();
             }
         }
         
-        private void play()
+        private void run()
         {
-            if(clip != null)
+            try
             {
-                if(reset)
+                while(isLooping)
                 {
-                    clip.stop();
-                    clip.setMicrosecondPosition(0);
+                    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();
                 }
-                clip.start();
+            }
+            catch(Exception ex)
+            {
+                System.out.println("Sound '" + f + "' failed.");
+                ex.printStackTrace();
             }
         }
-        
-        private void stop()
+
+        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(clip != null)
+            if(thread == null)
             {
-                clip.stop();
+                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();
         }
     }
     
@@ -123,4 +215,12 @@ public class SoundUtils
             sound.stop();
         }
     }
+    
+    public static void closeSounds()
+    {
+        for(Sound sound : Sound.values())
+        {
+            sound.close();
+        }
+    }
 }