|
@@ -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();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|