package org.herac.tuxguitar.player.impl.sequencer; 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; public class MidiSequencerImpl implements MidiSequencer{ private boolean reset; private boolean running; private MidiTransmitter transmitter; private MidiTickPlayer midiTickPlayer; private MidiEventPlayer midiEventPlayer; private MidiEventDispacher midiEventDispacher; private MidiTrackController midiTrackController; public MidiSequencerImpl(){ this.running = false; this.midiTickPlayer = new MidiTickPlayer(); this.midiEventPlayer = new MidiEventPlayer(this); this.midiEventDispacher = new MidiEventDispacher(this); this.midiTrackController = new MidiTrackController(this); } public synchronized MidiTrackController getMidiTrackController(){ return this.midiTrackController; } public synchronized void setTempo(int tempo){ this.midiTickPlayer.setTempo(tempo); } public synchronized long getTickPosition(){ return this.midiTickPlayer.getTick(); } public synchronized void setTickPosition(long tickPosition){ this.reset = true; this.midiTickPlayer.setTick(tickPosition); } public synchronized long getTickLength(){ return this.midiTickPlayer.getTickLength(); } public synchronized void sendEvent(MidiEvent event) throws MidiPlayerException{ if(!this.reset){ this.midiEventDispacher.dispatch(event); } } public synchronized void addEvent(MidiEvent event){ this.midiEventPlayer.addEvent(event); this.midiTickPlayer.notifyTick(event.getTick()); } public synchronized boolean isRunning() { return this.running; } 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 stop() throws MidiPlayerException{ this.setRunning(false); } public synchronized void start() throws MidiPlayerException{ this.setRunning(true); } 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(); } } 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.midiTickPlayer.process(); this.midiEventPlayer.process(); if(this.getTickPosition() > this.getTickLength()){ this.stop(); } } else{ this.midiEventPlayer.clearEvents(); this.midiTickPlayer.clearTick(); this.reset( true ); } return running; } public synchronized MidiTransmitter getTransmitter() { return this.transmitter; } public synchronized void setTransmitter(MidiTransmitter transmitter) { this.transmitter = transmitter; } public synchronized void open() { //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 synchronized void setSolo(int index,boolean solo) throws MidiPlayerException{ this.getMidiTrackController().setSolo(index, solo); } public synchronized void setMute(int index,boolean mute) throws MidiPlayerException{ this.getMidiTrackController().setMute(index, mute); } public String getKey() { return "tuxguitar.sequencer"; } public String getName() { return "TuxGuitar Sequencer"; } 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) { throwable.printStackTrace(); } } } }