package org.herac.tuxguitar.io.gtp;
import org.herac.tuxguitar.song.factory.TGFactory;
import org.herac.tuxguitar.song.models.TGBeat;
import org.herac.tuxguitar.song.models.TGDuration;
import org.herac.tuxguitar.song.models.TGMeasure;
import org.herac.tuxguitar.song.models.TGNote;
import org.herac.tuxguitar.song.models.TGVoice;
public class GTPVoiceJoiner {
private TGFactory factory;
private TGMeasure measure;
public GTPVoiceJoiner(TGFactory factory,TGMeasure measure){
this.factory = factory;
this.measure = measure.clone(factory, measure.getHeader());
this.measure.setTrack( measure.getTrack() );
}
public TGMeasure process(){
this.orderBeats();
this.joinBeats();
return this.measure;
}
public void joinBeats(){
TGBeat previous = null;
boolean finish = true;
long measureStart = this.measure.getStart();
long measureEnd = (measureStart + this.measure.getLength());
for(int i = 0;i < this.measure.countBeats();i++){
TGBeat beat = this.measure.getBeat( i );
TGVoice voice = beat.getVoice(0);
for(int v = 1; v < beat.countVoices(); v++ ){
TGVoice currentVoice = beat.getVoice(v);
if(!currentVoice.isEmpty()){
for(int n = 0 ; n < currentVoice.countNotes() ; n++ ){
TGNote note = currentVoice.getNote( n );
voice.addNote( note );
}
}
}
if( voice.isEmpty() ){
this.measure.removeBeat(beat);
finish = false;
break;
}
long beatStart = beat.getStart();
if(previous != null){
long previousStart = previous.getStart();
TGDuration previousBestDuration = null;
for(int v = /*1*/0; v < previous.countVoices(); v++ ){
TGVoice previousVoice = previous.getVoice(v);
if(!previousVoice.isEmpty()){
long length = previousVoice.getDuration().getTime();
if( (previousStart + length) <= beatStart){
if( previousBestDuration == null || length > previousBestDuration.getTime() ){
previousBestDuration = previousVoice.getDuration();
}
}
}
}
if(previousBestDuration != null){
previousBestDuration.copy( previous.getVoice(0).getDuration() );
}else{
if(voice.isRestVoice()){
this.measure.removeBeat(beat);
finish = false;
break;
}
TGDuration duration = TGDuration.fromTime(this.factory, (beatStart - previousStart) );
duration.copy( previous.getVoice(0).getDuration() );
}
}
TGDuration beatBestDuration = null;
for(int v = /*1*/0; v < beat.countVoices(); v++ ){
TGVoice currentVoice = beat.getVoice(v);
if(!currentVoice.isEmpty()){
long length = currentVoice.getDuration().getTime();
if( (beatStart + length) <= measureEnd ){
if( beatBestDuration == null || length > beatBestDuration.getTime() ){
beatBestDuration = currentVoice.getDuration();
}
}
}
}
if(beatBestDuration == null){
if(voice.isRestVoice()){
this.measure.removeBeat(beat);
finish = false;
break;
}
TGDuration duration = TGDuration.fromTime(this.factory, (measureEnd - beatStart) );
duration.copy( voice.getDuration() );
}
previous = beat;
}
if(!finish){
joinBeats();
}
}
public void orderBeats(){
for(int i = 0;i < this.measure.countBeats();i++){
TGBeat minBeat = null;
for(int j = i;j < this.measure.countBeats();j++){
TGBeat beat = this.measure.getBeat(j);
if(minBeat == null || beat.getStart() < minBeat.getStart()){
minBeat = beat;
}
}
this.measure.moveBeat(i, minBeat);
}
}
}