From b1f2a7e05f34b3a44b5f698a3857241d15367bbb Mon Sep 17 00:00:00 2001 From: drdev Date: Sun, 29 Jun 2014 15:56:40 +0000 Subject: [PATCH] Support playing background music for desktop game --- forge-gui-desktop/pom.xml | 5 + .../src/main/java/forge/sound/AudioMusic.java | 133 ++++++++++++------ .../src/main/java/forge/view/FFrame.java | 12 ++ forge-gui/CHANGES.txt | 8 ++ 4 files changed, 115 insertions(+), 43 deletions(-) diff --git a/forge-gui-desktop/pom.xml b/forge-gui-desktop/pom.xml index c31fbc5a50f..0daec823024 100644 --- a/forge-gui-desktop/pom.xml +++ b/forge-gui-desktop/pom.xml @@ -242,6 +242,11 @@ freemarker 2.3.20 + + com.googlecode.soundlibs + jlayer + 1.0.1-1 + diff --git a/forge-gui-desktop/src/main/java/forge/sound/AudioMusic.java b/forge-gui-desktop/src/main/java/forge/sound/AudioMusic.java index dea1d27447f..2dd932131c1 100644 --- a/forge-gui-desktop/src/main/java/forge/sound/AudioMusic.java +++ b/forge-gui-desktop/src/main/java/forge/sound/AudioMusic.java @@ -1,67 +1,114 @@ package forge.sound; -import java.io.File; -/*import java.io.IOException; +import java.io.BufferedInputStream; +import java.io.FileInputStream; -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioInputStream; -import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.DataLine.Info; -import javax.sound.sampled.LineUnavailableException; -import javax.sound.sampled.SourceDataLine; -import javax.sound.sampled.UnsupportedAudioFileException;*/ +import javazoom.jl.player.advanced.AdvancedPlayer; +import javazoom.jl.player.advanced.PlaybackEvent; +import javazoom.jl.player.advanced.PlaybackListener; public class AudioMusic implements IAudioMusic { - private final File file; + private AdvancedPlayer musicPlayer; + private FileInputStream fileStream; + private BufferedInputStream bufferedStream; + private boolean canResume; + private String filename; + private int total; + private int stopped; + private boolean valid; + private Runnable onComplete; - public AudioMusic(String filename) { - file = new File(filename); + public AudioMusic(String filename0) { + filename = filename0; } - public void play(final Runnable onComplete) { - /*try (final AudioInputStream in = AudioSystem.getAudioInputStream(file)) { - final AudioFormat outFormat = getOutFormat(in.getFormat()); - final Info info = new Info(SourceDataLine.class, outFormat); - - try (final SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info)) { - if (line != null) { - line.open(outFormat); - line.start(); - stream(AudioSystem.getAudioInputStream(outFormat, in), line); - line.drain(); - line.stop(); - } + public void play(final Runnable onComplete0) { + onComplete = onComplete0; + play(-1); + } + + private boolean play(int pos) { + valid = true; + canResume = false; + try { + fileStream = new FileInputStream(filename); + total = fileStream.available(); + if (pos > -1) { + fileStream.skip(pos); } - } catch (UnsupportedAudioFileException - | LineUnavailableException - | IOException e) { - throw new IllegalStateException(e); - }*/ + bufferedStream = new BufferedInputStream(fileStream); + musicPlayer = new AdvancedPlayer(bufferedStream); + musicPlayer.setPlayBackListener(new PlaybackListener() { + @Override + public void playbackFinished(PlaybackEvent evt) { + if (onComplete != null) { + onComplete.run(); + } + } + }); + new Thread( + new Runnable(){ + public void run(){ + try { + musicPlayer.play(); + } + catch (Exception e){ + e.printStackTrace(); + valid = false; + } + } + } + ).start(); + } + catch (Exception e) { + e.printStackTrace(); + valid = false; + } + return valid; } public void pause() { + if (musicPlayer == null) { return; } + + try { + stopped = fileStream.available(); + close(); + if (valid) { + canResume = true; + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + + private void close() { + musicPlayer.setPlayBackListener(null); //prevent firing if closed + musicPlayer.close(); + fileStream = null; + bufferedStream = null; + musicPlayer = null; } public void resume() { + if (!canResume) { return; } + + if (play(total - stopped)) { + canResume = false; + } } public void stop() { + if (musicPlayer == null) { return; } + + musicPlayer.setPlayBackListener(null); //prevent firing if stopped manually + musicPlayer.stop(); } public void dispose() { - } + if (musicPlayer == null) { return; } - /*private AudioFormat getOutFormat(AudioFormat inFormat) { - final int ch = inFormat.getChannels(); - final float rate = inFormat.getSampleRate(); - return new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, rate, 16, ch, ch * 2, rate, false); + close(); + canResume = false; } - - private void stream(AudioInputStream in, SourceDataLine line) - throws IOException { - final byte[] buffer = new byte[4096]; - for (int n = 0; n != -1; n = in.read(buffer, 0, buffer.length)) { - line.write(buffer, 0, n); - } - }*/ } diff --git a/forge-gui-desktop/src/main/java/forge/view/FFrame.java b/forge-gui-desktop/src/main/java/forge/view/FFrame.java index 8cab0161ede..964da238abc 100644 --- a/forge-gui-desktop/src/main/java/forge/view/FFrame.java +++ b/forge-gui-desktop/src/main/java/forge/view/FFrame.java @@ -1,5 +1,6 @@ package forge.view; +import forge.Singletons; import forge.gui.framework.SDisplayUtil; import forge.gui.framework.SResizingUtil; import forge.model.FModel; @@ -46,8 +47,19 @@ public class FFrame extends SkinnedFrame implements ITitleBarOwner { this.lockTitleBar = this.isMainFrame && FModel.getPreferences().getPrefBoolean(FPref.UI_LOCK_TITLE_BAR); addResizeSupport(); this.addWindowListener(new WindowAdapter() { + @Override + public void windowActivated(WindowEvent e) { + if (isMainFrame) { //resume music when main frame regains focus + Singletons.getControl().getSoundSystem().resume(); + } + } + @Override public void windowDeactivated(WindowEvent arg0) { + if (isMainFrame) { //pause music when main frame loses focus + Singletons.getControl().getSoundSystem().pause(); + } + if (fullScreen && arg0.getOppositeWindow() == null) { setMinimized(true); //minimize if switching from Full Screen Forge to outside application window } diff --git a/forge-gui/CHANGES.txt b/forge-gui/CHANGES.txt index 0cb49ae371a..852a84b1b67 100644 --- a/forge-gui/CHANGES.txt +++ b/forge-gui/CHANGES.txt @@ -8,6 +8,14 @@ Forge Beta: 0#-##-2014 ver 1.5.21 Release Notes ------------- +- Introducing Background Music - +Forge now supports playing background music!!! +There are 4 tracks for the menu screens and 4 tracks just for the match screen. +Tracks shuffle randomly as they finish, as well as when starting a new game or leaving the match screen. +A new "Enable Music" setting allows turning the music off, and toggling this setting can also be used to force a shuffle. +The music is paused automatically if you minimize or switch away from Forge, and resumed when it's activated again. + + - New Magic 2015 cards - We have added a branch to our SVN for the new cards that are currently being scripted. These cards are not yet available in this build of forge. Please be patient and they will soon become available.