diff --git a/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java b/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java index 639c84fdbc7..831dc2806c6 100644 --- a/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java +++ b/forge-gui-desktop/src/main/java/forge/sound/AudioClip.java @@ -37,6 +37,7 @@ import java.util.function.Supplier; public class AudioClip implements IAudioClip { private Clip clip; private boolean started; + private boolean looping; public static boolean fileExists(String fileName) { File fSound = new File(ForgeConstants.SOUND_DIR, fileName); @@ -76,7 +77,16 @@ public class AudioClip implements IAudioClip { return; } synchronized (this) { + if (clip.isRunning()) { + // introduce small delay to make a batch sounds more granular, + // e.g. when you auto-tap 4 lands the 4 tap sounds should + // not become completely merged + waitSoundSystemDelay(); + } clip.setMicrosecondPosition(0); + if (!this.looping && clip.isRunning()) { + return; + } this.started = false; clip.start(); wait(() -> this.started); @@ -90,9 +100,13 @@ public class AudioClip implements IAudioClip { } synchronized (this) { clip.setMicrosecondPosition(0); + if (this.looping && clip.isRunning()) { + return; + } this.started = false; clip.loop(Clip.LOOP_CONTINUOUSLY); wait(() -> this.started); + this.looping = true; } } @@ -103,6 +117,7 @@ public class AudioClip implements IAudioClip { } synchronized (this) { clip.stop(); + this.looping = false; } } @@ -117,18 +132,22 @@ public class AudioClip implements IAudioClip { private void wait(Supplier completed) { final int attempts = 5; for (int i = 0; i < attempts; i++) { - if (completed.get()) { - break; - } - try { - Thread.sleep(SoundSystem.DELAY); - } catch (InterruptedException ex) { - ex.printStackTrace(); + if (completed.get() || !waitSoundSystemDelay()) { break; } } } + private boolean waitSoundSystemDelay() { + try { + Thread.sleep(SoundSystem.DELAY); + return true; + } catch (InterruptedException ex) { + ex.printStackTrace(); + return false; + } + } + private void lineStatusChanged(LineEvent line) { LineEvent.Type status = line.getType(); this.started |= status == LineEvent.Type.START;