package org.herac.tuxguitar.player.impl.sequencer; import org.apache.log4j.Logger; import org.herac.tuxguitar.player.base.MidiPlayerException; import org.herac.tuxguitar.player.base.MidiSequenceHandler; import org.herac.tuxguitar.player.base.MidiSequencer; import org.herac.tuxguitar.player.base.MidiTransmitter; import org.herac.tuxguitar.player.impl.jsa.midiport.MidiPortSynthesizer; public class MidiSequencerImpl implements MidiSequencer { /** The Logger for this class. */ public static final transient Logger LOG = Logger .getLogger(MidiSequencerImpl.class); private class MidiTimer extends Thread { private static final int TIMER_DELAY = 15; private MidiSequencerImpl sequencer; public MidiTimer(MidiSequencerImpl sequencer) { this.sequencer = sequencer; } public void run() { try { synchronized (this.sequencer) { while (this.sequencer.process()) { this.sequencer.wait(TIMER_DELAY); } } } catch (Throwable throwable) { LOG.error(throwable); } } } private MidiEventDispacher midiEventDispacher; private MidiEventPlayer midiEventPlayer; private MidiTickPlayer midiTickPlayer; private MidiTrackController midiTrackController; private boolean reset; private boolean running; private boolean stopped; private MidiTransmitter transmitter; public MidiSequencerImpl() { this.running = false; this.stopped = true; this.midiTickPlayer = new MidiTickPlayer(); this.midiEventPlayer = new MidiEventPlayer(this); this.midiEventDispacher = new MidiEventDispacher(this); this.midiTrackController = new MidiTrackController(this); } public synchronized void addEvent(MidiEvent event) { this.midiEventPlayer.addEvent(event); this.midiTickPlayer.notifyTick(event.getTick()); } public void check() { // Not implemented } public synchronized void close() throws MidiPlayerException { if (isRunning()) { this.stop(); } } public synchronized MidiSequenceHandler createSequence(int tracks) throws MidiPlayerException { return new MidiSequenceHandlerImpl(this, tracks); } public String getKey() { return "tuxguitar.sequencer"; } public synchronized MidiTrackController getMidiTrackController() { return this.midiTrackController; } public String getName() { return "TuxGuitar Sequencer"; } public synchronized long getTickLength() { return this.midiTickPlayer.getTickLength(); } public synchronized long getTickPosition() { return this.midiTickPlayer.getTick(); } public synchronized MidiTransmitter getTransmitter() { return this.transmitter; } public synchronized boolean isRunning() { return this.running; } public synchronized void open() { // not implemented } protected synchronized boolean process() throws MidiPlayerException { boolean running = this.isRunning(); if (running) { if (this.reset) { this.reset(false); this.reset = false; this.midiEventPlayer.reset(); } this.stopped = false; this.midiTickPlayer.process(); this.midiEventPlayer.process(); if (this.getTickPosition() > this.getTickLength()) { this.stop(); } } else if (!this.stopped) { this.stopped = true; this.midiEventPlayer.clearEvents(); this.midiTickPlayer.clearTick(); this.reset(true); } return running; } public synchronized void reset(boolean systemReset) throws MidiPlayerException { this.getTransmitter().sendAllNotesOff(); for (int channel = 0; channel < 16; channel++) { this.getTransmitter().sendPitchBend(channel, 64); } if (systemReset) { this.getTransmitter().sendSystemReset(); } } public synchronized void sendEvent(MidiEvent event) throws MidiPlayerException { if (!this.reset) { this.midiEventDispacher.dispatch(event); } } public synchronized void setMute(int index, boolean mute) throws MidiPlayerException { this.getMidiTrackController().setMute(index, mute); } public synchronized void setRunning(boolean running) throws MidiPlayerException { this.running = running; if (this.running) { this.setTempo(120); this.setTickPosition(this.getTickPosition()); new MidiTimer(this).start(); } else { this.process(); } } public synchronized void setSolo(int index, boolean solo) throws MidiPlayerException { this.getMidiTrackController().setSolo(index, solo); } public synchronized void setTempo(int tempo) { this.midiTickPlayer.setTempo(tempo); } public synchronized void setTickPosition(long tickPosition) { this.reset = true; this.midiTickPlayer.setTick(tickPosition); } public synchronized void setTransmitter(MidiTransmitter transmitter) { this.transmitter = transmitter; } public synchronized void start() throws MidiPlayerException { this.setRunning(true); } public synchronized void stop() throws MidiPlayerException { this.setRunning(false); } }