/*
* JFugue, an Application Programming Interface (API) for Music Programming
* http://www.jfugue.org
*
* Copyright (C) 2003-2014 David Koelle
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jfugue.player;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;
import jp.kshoji.javax.sound.midi.InvalidMidiDataException;
import jp.kshoji.javax.sound.midi.MidiUnavailableException;
import jp.kshoji.javax.sound.midi.Sequence;
/**
* This is player that can be "managed" - e.g., started, stopped, paused, resumed, seeked, and finished.
* Additionally, the state of this player can be requested.
* If you want to create a player that you can control like any standard media player, this is your class.
*/
public class ManagedPlayer implements EndOfTrackListener
{
private SequencerManager common;
private boolean started;
private boolean finished;
private boolean paused;
private CopyOnWriteArrayList<ManagedPlayerListener> playerListeners;
public ManagedPlayer() {
playerListeners = new CopyOnWriteArrayList<ManagedPlayerListener>();
try {
common = SequencerManager.getInstance();
} catch (MidiUnavailableException e) {
Logger.getLogger("org.jfugue").severe(e.getLocalizedMessage());
}
}
public void addManagedPlayerListener(ManagedPlayerListener listener) {
playerListeners.add(listener);
}
public void removeManagedPlayerListener(ManagedPlayerListener listener) {
playerListeners.add(listener);
}
public List<ManagedPlayerListener> getManagedPlayerListeners() {
return playerListeners;
}
/**
* This method opens the sequencer (if it is not already open - @see PlayerCommon),
* sets the sequence, tells listeners that play is starting, and starts the sequence.
* @param sequence
*/
public void start(Sequence sequence) throws InvalidMidiDataException, MidiUnavailableException {
common.openSequencer();
common.addEndOfTrackListener(this);
common.getSequencer().setSequence(sequence);
fireOnStarted();
this.started = true;
this.paused = false;
this.finished = false;
common.getSequencer().start();
}
/**
* To resume play, @see resume()
*/
public void pause() {
fireOnPaused();
this.paused = true;
common.getSequencer().stop();
}
/**
* To pause play, @see pause()
*/
public void resume() {
fireOnResumed();
this.paused = false;
common.getSequencer().start();
}
public void seek(long tick) {
fireOnSeek(tick);
common.getSequencer().setTickPosition(tick);
}
public void finish() {
common.close();
this.finished = true;
fireOnFinished();
}
public long getTickLength() {
return common.getSequencer().getTickLength();
}
public long getTickPosition() {
return common.getSequencer().getTickPosition();
}
public boolean isStarted() {
return this.started;
}
public boolean isFinished() {
return this.finished;
}
public boolean isPaused() {
return this.paused;
}
public boolean isPlaying() {
return common.getSequencer().isRunning();
}
@Override
public void onEndOfTrack() {
finish();
}
protected void fireOnStarted() {
List<ManagedPlayerListener> listeners = getManagedPlayerListeners();
for (ManagedPlayerListener listener : listeners) {
listener.onStarted();
}
}
protected void fireOnFinished() {
List<ManagedPlayerListener> listeners = getManagedPlayerListeners();
for (ManagedPlayerListener listener : listeners) {
listener.onFinished();
}
}
protected void fireOnPaused() {
List<ManagedPlayerListener> listeners = getManagedPlayerListeners();
for (ManagedPlayerListener listener : listeners) {
listener.onPaused();
}
}
protected void fireOnResumed() {
List<ManagedPlayerListener> listeners = getManagedPlayerListeners();
for (ManagedPlayerListener listener : listeners) {
listener.onResumed();
}
}
protected void fireOnSeek(long tick) {
List<ManagedPlayerListener> listeners = getManagedPlayerListeners();
for (ManagedPlayerListener listener : listeners) {
listener.onSeek(tick);
}
}
}