--- /dev/null
+package tim.prune.function;
+
+import java.io.File;
+import java.io.IOException;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+
+import tim.prune.App;
+import tim.prune.GenericFunction;
+
+/**
+ * Class to play the current audio file
+ */
+public class PlayAudioFunction extends GenericFunction implements Runnable
+{
+ /** Audio clip used for playing within java */
+ private Clip _clip = null;
+
+
+ /**
+ * Constructor
+ * @param inApp app object
+ */
+ public PlayAudioFunction(App inApp) {
+ super(inApp);
+ }
+
+ /**
+ * @return name key
+ */
+ public String getNameKey() {
+ return "function.playaudio";
+ }
+
+ /**
+ * Perform function
+ */
+ public void begin()
+ {
+ // Launch new thread if clip isn't currently playing
+ if (_clip == null) {
+ new Thread(this).start();
+ }
+ }
+
+ /**
+ * Play the audio in a new thread
+ */
+ public void run()
+ {
+ File audioFile = _app.getTrackInfo().getCurrentAudio().getFile();
+ boolean played = false;
+ if (audioFile.exists() && audioFile.isFile() && audioFile.canRead())
+ {
+ // First choice is to play using java
+ played = playClip(audioFile);
+ // Second choice is to try the Desktop library from java 6, if available
+ if (!played) {
+ try {
+ Class<?> d = Class.forName("java.awt.Desktop");
+ d.getDeclaredMethod("open", new Class[] {File.class}).invoke(
+ d.getDeclaredMethod("getDesktop").invoke(null), new Object[] {audioFile});
+ //above code mimics: Desktop.getDesktop().open(audioFile);
+ played = true;
+ }
+ catch (Exception ignore) {
+ played = false;
+ }
+ }
+ // If the Desktop call failed, need to try backup methods
+ if (!played)
+ {
+ // If system looks like a Mac, try open command
+ String osName = System.getProperty("os.name").toLowerCase();
+ boolean isMacOsx = osName.indexOf("mac os") >= 0 || osName.indexOf("darwin") >= 0;
+ if (isMacOsx) {
+ String[] command = new String[] {"open", audioFile.getAbsolutePath()};
+ try {
+ Runtime.getRuntime().exec(command);
+ played = true;
+ }
+ catch (IOException ioe) {}
+ }
+ }
+ }
+ if (!played)
+ {
+ // If still not worked, show error message
+ _app.showErrorMessage(getNameKey(), "error.playaudiofailed");
+ }
+ }
+
+ /**
+ * Try to play the sound file using built-in java libraries
+ * @return true if play was successful
+ */
+ private boolean playClip(File inFile)
+ {
+ boolean success = false;
+ AudioInputStream audioInputStream = null;
+ _clip = null;
+ try
+ {
+ audioInputStream = AudioSystem.getAudioInputStream(inFile);
+ _clip = AudioSystem.getClip();
+ _clip.open(audioInputStream);
+ // play the clip
+ _clip.start();
+ _clip.drain();
+ success = true;
+ } catch (Exception e) {
+ } finally {
+ // close the stream to clean up
+ try {
+ _clip.close();
+ audioInputStream.close();
+ } catch (Exception e) {}
+ _clip = null;
+ }
+ return success;
+ }
+
+ /**
+ * Try to stop a currently playing clip
+ */
+ public void stopClip()
+ {
+ if (_clip != null && _clip.isActive()) {
+ try {
+ _clip.stop();
+ _clip.flush();
+ }
+ catch (Exception e) {}
+ }
+ }
+
+ /**
+ * @return percentage of clip currently played, or -1 if not playing
+ */
+ public int getPercentage()
+ {
+ int percent = -1;
+ if (_clip != null && _clip.isActive())
+ {
+ long clipLen = _clip.getMicrosecondLength();
+ if (clipLen > 0) {
+ percent = (int) (_clip.getMicrosecondPosition() * 100.0 / clipLen);
+ }
+ }
+ return percent;
+ }
+}