package org.herac.tuxguitar.io.midi; import java.io.IOException; import java.io.OutputStream; import org.herac.tuxguitar.gm.GMChannelRoute; import org.herac.tuxguitar.gm.GMChannelRouter; import org.herac.tuxguitar.io.midi.base.MidiEvent; import org.herac.tuxguitar.io.midi.base.MidiSequence; import org.herac.tuxguitar.io.midi.base.MidiTrack; import org.herac.tuxguitar.player.base.MidiSequenceHandler; import org.herac.tuxguitar.song.models.TGDuration; import org.herac.tuxguitar.song.models.TGTimeSignature; public class MidiSequenceHandlerImpl extends MidiSequenceHandler{ private OutputStream stream; private MidiSequence sequence; private GMChannelRouter router; public MidiSequenceHandlerImpl(int tracks, GMChannelRouter router, OutputStream stream){ super(tracks); this.router = router; this.stream = stream; this.init(); } private void init(){ this.sequence = new MidiSequence(MidiSequence.PPQ,(int)TGDuration.QUARTER_TIME); for (int i = 0; i < getTracks(); i++) { this.sequence.addTrack(new MidiTrack()); } } public MidiSequence getSequence(){ return this.sequence; } private int resolveChannel(GMChannelRoute gmChannel, boolean bendMode){ return (bendMode ? gmChannel.getChannel2() : gmChannel.getChannel1()); } public void addEvent(int track, MidiEvent event) { if(track >= 0 && track < getSequence().countTracks()){ getSequence().getTrack(track).add(event); } } @Override public void addNoteOff(long tick,int track,int channelId, int note, int velocity, int voice, boolean bendMode) { GMChannelRoute gmChannel = this.router.getRoute(channelId); if( gmChannel != null ){ addEvent(track,new MidiEvent(MidiMessageUtils.noteOff(resolveChannel(gmChannel,bendMode), note, velocity), tick )); } } @Override public void addNoteOn(long tick,int track,int channelId, int note, int velocity, int voice, boolean bendMode) { GMChannelRoute gmChannel = this.router.getRoute(channelId); if( gmChannel != null ){ addEvent(track,new MidiEvent(MidiMessageUtils.noteOn(resolveChannel(gmChannel,bendMode), note, velocity), tick )); } } @Override public void addPitchBend(long tick,int track,int channelId, int value, int voice, boolean bendMode) { GMChannelRoute gmChannel = this.router.getRoute(channelId); if( gmChannel != null ){ addEvent(track,new MidiEvent(MidiMessageUtils.pitchBend(resolveChannel(gmChannel,bendMode), value), tick )); } } @Override public void addControlChange(long tick,int track,int channelId, int controller, int value) { GMChannelRoute gmChannel = this.router.getRoute(channelId); if( gmChannel != null ){ addEvent(track,new MidiEvent(MidiMessageUtils.controlChange(gmChannel.getChannel1(), controller, value), tick )); if( gmChannel.getChannel1() != gmChannel.getChannel2() ){ addEvent(track,new MidiEvent(MidiMessageUtils.controlChange(gmChannel.getChannel2(), controller, value), tick )); } } } @Override public void addProgramChange(long tick,int track,int channelId, int instrument) { GMChannelRoute gmChannel = this.router.getRoute(channelId); if( gmChannel != null ){ addEvent(track,new MidiEvent(MidiMessageUtils.programChange(gmChannel.getChannel1(), instrument), tick )); if( gmChannel.getChannel1() != gmChannel.getChannel2() ){ addEvent(track,new MidiEvent(MidiMessageUtils.programChange(gmChannel.getChannel2(), instrument), tick )); } } } @Override public void addTempoInUSQ(long tick,int track,int usq) { addEvent(track,new MidiEvent(MidiMessageUtils.tempoInUSQ(usq), tick )); } @Override public void addTimeSignature(long tick,int track,TGTimeSignature ts) { addEvent(track,new MidiEvent(MidiMessageUtils.timeSignature(ts), tick )); } @Override public void notifyFinish() { try { getSequence().finish(); new MidiFileWriter().write(getSequence(),1,this.stream); } catch (IOException e) { e.printStackTrace(); } } }