/* * ----------------------------------------------------------------------- * File: $Source: /home/keith/cvsroot/projects/LanguageAids/uk/co/dabsol/stribley/sound/ClipPlayer.java,v $ * Version: $Revision: 852 $ * Last Modified: $Date: 2007-06-09 16:02:23 +0700 (Sat, 09 Jun 2007) $ * ----------------------------------------------------------------------- * Copyright (C) 2004 Keith Stribley <tech@thanlwinsoft.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA * ----------------------------------------------------------------------- */ package org.thanlwinsoft.languagetest.sound; import java.io.File; import java.io.IOException; import javax.sound.sampled.*; /** * * @author keith */ public class ClipPlayer implements LineListener, AudioPlayer { private AudioInputStream input = null; private Clip clip = null; private int startFrame = 0; private int endFrame = -1; private long microSecPerFrame; private File currentFile = null; //private static final long STEP_SIZE = 100000; // 0.1sec private LineListener listener = null; boolean userStop = false; /** Creates a new instance of ClipPlayer */ public ClipPlayer(LineListener listener) { this.listener = listener; } public void play() { if (clip == null) return; System.out.println("Frame Pos: " + clip.getFramePosition()); if (clip.getFramePosition() == clip.getFrameLength() || clip.getFramePosition() == endFrame) { // rewind to start if clip finished //clip.setFramePosition(startFrame); } clip.start(); } public boolean open(File file, long msLengthHint, boolean forceReopen) { if (currentFile != null) { // clip already loaded if (!forceReopen && file.compareTo(currentFile)==0) return true; else close(); // unload previous clip } try { input = AudioSystem.getAudioInputStream(file); } catch (UnsupportedAudioFileException uafe) { System.out.println(uafe); return false; } catch (IOException ioe) { System.out.println(ioe); return false; } DataLine.Info info = new DataLine.Info(Clip.class, input.getFormat()); // format is an AudioFormat object if (!AudioSystem.isLineSupported(info)) { // Handle the error. return false; } // Obtain and open the output line. try { clip = (Clip) AudioSystem.getLine(info); clip.addLineListener(this); clip.open(input); } catch (LineUnavailableException ex) { // Handle the error. //... System.out.println(ex); return false; } catch (IOException e) { System.out.println(e); return false; } clip.loop(0); microSecPerFrame = clip.getMicrosecondLength() / (long)clip.getFrameLength(); startFrame = 0; endFrame = -1; return true; } public boolean close() { if (clip != null) { clip.drain(); clip.stop(); clip.close(); clip.removeLineListener(this); clip = null; currentFile = null; try { input.close(); input = null; } catch (IOException e) { System.out.println(e); return false; } } return true; } public void setBounds(long start, long duration) { if (clip == null) return; if (start > 0) { startFrame = (int)(start / microSecPerFrame); } else startFrame = 0; if (duration > 0) { endFrame = startFrame + (int)(duration / microSecPerFrame); if (endFrame > clip.getFrameLength()) endFrame = -1; } else endFrame = -1; clip.setLoopPoints(startFrame, endFrame); } public void rewind(long amount) { if (clip == null) return ; int newPosition = clip.getFramePosition() - (int)(amount / microSecPerFrame); if (newPosition < 0) newPosition = 0; clip.setFramePosition(newPosition); //return clip.getMicrosecondPosition(); } public void fastForward(long amount) { if (clip == null) return ; int newPosition = clip.getFramePosition() + (int)(amount / microSecPerFrame); if (newPosition < 0) newPosition = 0; clip.setFramePosition(newPosition); //return clip.getMicrosecondPosition(); } /** * Returns position play stopped/started at */ public void pause() { if (clip == null) return ; //long position = 0; if (clip.isRunning()) { userStop = true; clip.stop(); //clip.flush(); //position = clip.getMicrosecondPosition(); } else { //position = clip.getMicrosecondPosition(); clip.start(); } //return position; } public void stop() { if (clip == null) return; userStop = true; clip.stop(); clip.setFramePosition(startFrame); } public long clipLength() { if (clip == null) return 0; return clip.getFrameLength() * microSecPerFrame; } synchronized public void update(javax.sound.sampled.LineEvent lineEvent) { if (lineEvent.getType() == LineEvent.Type.STOP) { System.out.println("Stopped at:" + clip.getFramePosition()); // if userStop not set then must have played to end if (!userStop) { clip.stop(); clip.setFramePosition(startFrame); } userStop = false; } if (listener != null) // call listener on gui { listener.update(lineEvent); } } synchronized public long getPlayPosition() { return clip.getMicrosecondPosition(); } public void addPlayListener(AudioPlayListener listener) { } public File getCurrentFile() { return currentFile; } public long getDurationMs() { return (long)(endFrame - startFrame) * microSecPerFrame; } public long getStartMs() { return (long)startFrame * microSecPerFrame; } public boolean isInitialised() { return (clip == null) ? false : true; } public boolean open(File file) { return open(file, AudioSystem.NOT_SPECIFIED, false); } public boolean isActive() { return clip.isActive(); } }