package mage.client.util.audio; import java.awt.List; import java.io.File; import java.util.concurrent.TimeUnit; import javax.sound.sampled.*; import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; import org.apache.log4j.Logger; /** * * @author renli */ public class MusicPlayer { private static final Logger log = Logger.getLogger(AudioManager.class); String filepath; String filename; final List filelist = new List(); static MusicPlayer player = null; //open file and add list private boolean open() { String path = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SOUNDS_MATCH_MUSIC_PATH, "true"); filepath = path + File.separator; if (path == null) { filepath = Constants.BASE_MUSICS_PATH; } filelist.removeAll(); File filedir = new File(filepath); File[] fileread = filedir.listFiles(); if (fileread == null) { return false; } if (fileread.length == 0) { return false; } String filename; for (File f : fileread) { filename = f.getName().toLowerCase(); if (filename.endsWith(".mp3") || filename.endsWith(".wav")) { filelist.add(filename); } } if (filelist.getItemCount() == 0) { return false; } return true; } public static void playBGM() { stopBGM(); if (player == null) { player = new MusicPlayer(); } if (player.open()) { player.play(); } } public void play() { String soundsOn = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SOUNDS_MATCH_MUSIC_ON, "true"); if (soundsOn.equals("true")) { player.breaked = false; player.breaked_out = false; player.stopped = false; Thread player = new Thread(new playerThread()); player.start(); } } public static void stopBGM() { if (player != null) { player.stopped = true; player.breaked_out = true; player.breaked = true; try { TimeUnit.MILLISECONDS.sleep(100); } catch (Exception e) { log.error("Thread error: " + e); } } } public volatile boolean breaked = false; public volatile boolean breaked_out = false; public volatile boolean stopped = false; public volatile FloatControl volume; AudioInputStream audioInputStream; AudioFormat audioFormat; SourceDataLine sourceDataLine; class playerThread extends Thread { private void load(File file) { try { audioInputStream = AudioSystem.getAudioInputStream(file); audioFormat = audioInputStream.getFormat(); // mp3 decode if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) { audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, audioFormat.getSampleRate(), 16, audioFormat.getChannels(), audioFormat.getChannels() * 2, audioFormat.getSampleRate(), false); audioInputStream = AudioSystem.getAudioInputStream(audioFormat, audioInputStream); } //output DataLine.Info dataLineInfo = new DataLine.Info( SourceDataLine.class, audioFormat, AudioSystem.NOT_SPECIFIED); sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo); sourceDataLine.open(audioFormat); volume = (FloatControl) sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN); sourceDataLine.start(); } catch (Exception e) { log.error("Couldn't load file: " + file + ' ' + e); } } public void run() { try { TimeUnit.MILLISECONDS.sleep(100); } catch (Exception e) { } while (!stopped) { int it = (int) Math.abs(Math.random() * (filelist.getItemCount())); File file = new File(filepath + filelist.getItem(it)); load(file); Thread PlayThread = new Thread(new PlayThread()); PlayThread.start(); while (!(breaked || breaked_out)) { try { TimeUnit.MILLISECONDS.sleep(10); } catch (Exception e) { log.error("Thread error: " + e); } } breaked = false; } } } class PlayThread extends Thread { final byte[] tempBuffer = new byte[320]; public void run() { try { sourceDataLine.flush(); int len; while ((len = audioInputStream.read(tempBuffer, 0, tempBuffer.length)) != -1) { if (breaked_out) { break; } if (len > 0) { sourceDataLine.write(tempBuffer, 0, len); } } //breaked or stopped sourceDataLine.flush(); sourceDataLine.close(); breaked = true; } catch (Exception e) { log.error("Thread error: " + e); } } } }