package org.herac.tuxguitar.player.base; import org.herac.tuxguitar.song.models.TGDuration; import org.herac.tuxguitar.song.models.TGMeasureHeader; import org.herac.tuxguitar.song.models.TGSong; import org.herac.tuxguitar.song.models.TGVelocities; public class MidiPlayerCountDown { public static final int DEFAULT_TEMPO_PERCENT = 100; private MidiPlayer player; private boolean enabled; private boolean running; private int tempoPercent; public MidiPlayerCountDown(MidiPlayer player){ this.player = player; this.enabled = false; this.tempoPercent = DEFAULT_TEMPO_PERCENT; } public void start(){ try { this.running = true; int channelId = this.player.getPercussionChannelId(); if( channelId >= 0 ){ TGMeasureHeader header = this.findMeasureHeader(); if( header != null ){ Object timerLock = new Object(); int tgTempo = ((header.getTempo().getValue() * this.getTempoPercent()) / DEFAULT_TEMPO_PERCENT); long tgLength = header.getTimeSignature().getDenominator().getTime(); long tickLength = (long)(1000.00 * (60.00 / tgTempo * tgLength) / TGDuration.QUARTER_TIME); long tickStart = System.currentTimeMillis(); int tickIndex = 0; int tickCount = header.getTimeSignature().getNumerator(); while( this.isRunning() && tickIndex <= tickCount ){ long currentTime = System.currentTimeMillis(); if( tickStart <= currentTime ){ tickStart += tickLength; tickIndex ++; if( tickIndex <= tickCount ){ this.player.getOutputTransmitter().sendNoteOn(channelId, 37, TGVelocities.DEFAULT, -1, false); synchronized (timerLock) { timerLock.wait( 1 ); } this.player.getOutputTransmitter().sendNoteOff(channelId, 37, TGVelocities.DEFAULT, -1, false); } } synchronized (timerLock) { timerLock.wait( 10 ); } } } } this.running = false; } catch (Throwable throwable) { throwable.printStackTrace(); } } public TGMeasureHeader findMeasureHeader(){ long tick = this.player.getTickPosition(); long startPoint = this.player.getLoopSPosition(); long start = startPoint; long length = 0; TGSong song = this.player.getSongManager().getSong(); MidiRepeatController controller = new MidiRepeatController(song, this.player.getLoopSHeader() , this.player.getLoopEHeader() ); while(!controller.finished()){ TGMeasureHeader header = song.getMeasureHeader(controller.getIndex()); controller.process(); if(controller.shouldPlay()){ start += length; length = header.getLength(); //verifico si es el compas correcto if(tick >= start && tick < (start + length )){ return header; } } } return null; } public boolean isRunning() { return (this.enabled && this.running && this.player.isRunning() && !this.player.isChangeTickPosition()); } public boolean isEnabled() { return this.enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public int getTempoPercent() { return tempoPercent; } public void setTempoPercent(int tempoPercent) { this.tempoPercent = tempoPercent; } }