/* * 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.util.Vector; import java.util.Iterator; import javax.sound.sampled.AudioSystem; /** * * @author keith */ public class RepeatingPlayer implements AudioPlayer, AudioPlayListener { // don't make the source buffer too big, since it controls the resolution // with which one can pause clips private final static int SOURCE_LINE_BUFFER = 17640; // 0.1 seconds private InputLineController inputController = null; private OutputLineController outputController = null; private Vector<AudioPlayListener> listeners = null; private LineController lineController = null; /** Creates a new instance of RepeatingPlayer */ public RepeatingPlayer(LineController lineController) { listeners = new Vector<AudioPlayListener>(); this.lineController = lineController; } public void addPlayListener(AudioPlayListener listener) { listeners.add(listener); } public boolean close() { boolean closed = true; if (inputController != null) inputController.stopThread(); if (outputController != null) closed = outputController.close(); return closed; } public void fastForward(long amount) { if (inputController != null) inputController.seek(amount); } public java.io.File getCurrentFile() { if (inputController != null) return inputController.getAudioFile(); else return null; } public long getDurationMs() { if (inputController != null) return inputController.getDurationMs(); return 0; } public long getStartMs() { if (inputController != null) return inputController.getStartMs(); return 0; } public boolean isInitialised() { if (inputController != null && outputController.open()) return true; else return false; } public boolean open(java.io.File file) { return open(file, AudioSystem.NOT_SPECIFIED, false); } public boolean open(java.io.File file, long msLengthHint, boolean forceReopen) { if (inputController != null) { if (forceReopen || !file.equals(inputController.getAudioFile())) { inputController.stop(); inputController.stopThread(); inputController.setOutputController(null); inputController.setListener(null); inputController = null; } } if (inputController == null) { inputController = new InputLineController(file, msLengthHint, lineController); // now create output controller if there isn't already one if (outputController == null) { outputController = new OutputLineController(lineController, SOURCE_LINE_BUFFER); outputController.setListener(this); new Thread(outputController).start(); } inputController.setOutputController(outputController); inputController.setListener(this); // now that all pointers are initialised, start the thread // (If thread started before outputController set, some commands // may be lost) new Thread(inputController).start(); } return true; } public void pause() { if (inputController != null) inputController.pause(); } public void play() { if (inputController != null) inputController.play(); } public void rewind(long amount) { if (inputController != null) inputController.seek(-amount); } public void setBounds(long start, long duration) { if (inputController != null) inputController.setBounds(start, duration); } public void stop() { if (inputController != null) inputController.stop(); } /** Method calls the playPosition method on each registered * AudioPlayListener. */ public synchronized void playPosition(long position, long length) { Iterator<AudioPlayListener> l = listeners.iterator(); while (l.hasNext()) { ((AudioPlayListener)l.next()) .playPosition(position, length); } } public synchronized void initialisationProgress(int percent) { int percentToShow = percent; Iterator<AudioPlayListener> l = listeners.iterator(); if (outputController != null) { if (outputController.isOpen() == false) percentToShow = -1; while (l.hasNext()) { ((AudioPlayListener)l.next()) .initialisationProgress(percentToShow); } } } public boolean isActive() { if (outputController != null) { return outputController.isActive(); } return false; } }