package org.herac.tuxguitar.player.impl.jsa.sequencer; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; import javax.sound.midi.Track; import javax.sound.midi.Transmitter; import org.apache.log4j.Logger; import org.herac.tuxguitar.gui.TuxGuitar; 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, MidiSequenceLoader { /** The Logger for this class. */ public static final transient Logger LOG = Logger .getLogger(MidiSequencerImpl.class); private static final int TICK_MOVE = 1; private Object lock; private Sequencer sequencer; private Transmitter sequencerTransmitter; private MidiTransmitter transmitter; public MidiSequencerImpl(Sequencer sequencer) { this.lock = new Object(); this.sequencer = sequencer; } public void check() throws MidiPlayerException { this.getSequencer(true); if (this.sequencer == null || !this.sequencer.isOpen()) { throw new MidiPlayerException(TuxGuitar .getProperty("jsa.error.midi.unavailable")); } } public synchronized void close() { try { if (this.sequencer.isOpen()) { this.sequencer.close(); this.closeTransmitter(); } } catch (Throwable throwable) { LOG.error(throwable); } } public void closeTransmitter() { try { if (this.sequencerTransmitter != null) { this.sequencerTransmitter.close(); this.sequencerTransmitter = null; } } catch (Throwable throwable) { LOG.error(throwable); } } public MidiSequenceHandler createSequence(int tracks) { this.resetTracks(); return new MidiSequenceHandlerImpl(this, tracks); } public String getKey() { return this.sequencer.getDeviceInfo().getName(); } public String getName() { return this.sequencer.getDeviceInfo().getName(); } protected Sequencer getSequencer() { return this.getSequencer(true); } protected Sequencer getSequencer(boolean open) { if (open) { this.open(); } return this.sequencer; } public long getTickLength() { try { return getSequencer().getTickLength(); } catch (Throwable throwable) { LOG.error(throwable); } return 0; } public long getTickPosition() { try { return (getSequencer().getTickPosition() + TICK_MOVE); } catch (Throwable throwable) { LOG.error(throwable); } return 0; } public synchronized MidiTransmitter getTransmitter() { return this.transmitter; } public boolean isRunning() { try { return (getSequencer(false) != null && getSequencer(false).isRunning()); } catch (Throwable throwable) { LOG.error(throwable); } return false; } public synchronized void open() { try { if (!this.sequencer.isOpen()) { this.sequencer.open(); this.closeTransmitter(); this.openTransmitter(); } } catch (Throwable throwable) { LOG.error(throwable); } } public void openTransmitter() { try { this.sequencerTransmitter = getSequencer().getTransmitter(); this.sequencerTransmitter.setReceiver(new MidiReceiverImpl(this)); } catch (Throwable throwable) { LOG.error(throwable); } } public void reset(boolean systemReset) { try { this.getTransmitter().sendAllNotesOff(); for (int channel = 0; channel < 16; channel++) { this.getTransmitter().sendPitchBend(channel, 64); } if (systemReset) { this.getTransmitter().sendSystemReset(); } } catch (Throwable throwable) { LOG.error(throwable); } } public void resetTracks() { try { Sequence sequence = this.getSequencer().getSequence(); if (sequence != null) { Track[] tracks = sequence.getTracks(); if (tracks != null) { int count = tracks.length; for (int i = 0; i < count; i++) { this.setSolo(i, false); this.setMute(i, false); } } } } catch (Throwable throwable) { LOG.error(throwable); } } public void setMute(int index, boolean mute) { try { getSequencer().setTrackMute(index, mute); } catch (Throwable throwable) { LOG.error(throwable); } } public void setRunning(boolean running) { try { synchronized (this.lock) { if (running && !this.isRunning()) { this.getSequencer().start(); } else if (!running && this.isRunning()) { this.getSequencer().stop(); this.reset(true); } } } catch (Throwable throwable) { LOG.error(throwable); } } public void setSequence(Sequence sequence) { try { getSequencer().setSequence(sequence); } catch (Throwable throwable) { LOG.error(throwable); } } public void setSolo(int index, boolean solo) { try { getSequencer().setTrackSolo(index, solo); } catch (Throwable throwable) { LOG.error(throwable); } } public void setTickPosition(long tickPosition) { try { this.getSequencer().setTickPosition(tickPosition - TICK_MOVE); this.reset(false); } catch (Throwable throwable) { LOG.error(throwable); } } public synchronized void setTransmitter(MidiTransmitter transmitter) { this.transmitter = transmitter; } public void start() { try { this.setRunning(true); } catch (Throwable throwable) { LOG.error(throwable); } } public void stop() { try { this.setRunning(false); } catch (Throwable throwable) { LOG.error(throwable); } } }