1
package org.herac.tuxguitar.io.pt;
3
import java.io.DataInputStream;
5
import java.io.FileInputStream;
6
import java.io.FileNotFoundException;
7
import java.io.IOException;
8
import java.util.ArrayList;
9
import java.util.Iterator;
10
import java.util.List;
12
import org.herac.tuxguitar.song.managers.SongManager;
13
import org.herac.tuxguitar.song.models.Duration;
14
import org.herac.tuxguitar.song.models.Measure;
15
import org.herac.tuxguitar.song.models.MeasureHeader;
16
import org.herac.tuxguitar.song.models.Note;
17
import org.herac.tuxguitar.song.models.NoteEffect;
18
import org.herac.tuxguitar.song.models.RGBColor;
19
import org.herac.tuxguitar.song.models.Song;
20
import org.herac.tuxguitar.song.models.SongChannel;
21
import org.herac.tuxguitar.song.models.SongTrack;
22
import org.herac.tuxguitar.song.models.Tempo;
23
import org.herac.tuxguitar.song.models.TimeSignature;
24
import org.herac.tuxguitar.song.models.effects.BendEffect;
26
public abstract class PTBInputStream {
27
protected static final int TRACK_TYPE_GUITAR = 1;
29
protected static final int TRACK_TYPE_BASS = 2;
31
private static final int ERROR_MARGIN = 50;
33
private static final BendEffect[] DEFAULT_BENDS = makeDefaultBends();
35
private DataInputStream dataInputStream;
37
protected String version;
38
protected List headers;
39
protected List tracks;
40
protected List trackInfos;
41
protected int lastUsedChannel = 0;
43
public PTBInputStream(FileInputStream file) throws FileNotFoundException {
44
this.dataInputStream = new DataInputStream(file);
45
this.headers = new ArrayList();
46
this.tracks = new ArrayList();
47
this.trackInfos = new ArrayList();
50
public PTBInputStream(String fileName) throws FileNotFoundException {
51
this(new FileInputStream(new File(fileName)));
54
public abstract boolean isSupportedVersion(String version);
56
public abstract boolean isSupportedVersion();
59
protected SongTrack getTrack(int number,int trackType){
60
Iterator it = this.tracks.iterator();
62
SongTrack track = (SongTrack)it.next();
63
if(track.getNumber() == number){
67
lastUsedChannel = (lastUsedChannel < (SongManager.MAX_CHANNELS - 1))?lastUsedChannel+1:lastUsedChannel;
68
lastUsedChannel = (lastUsedChannel == SongChannel.DEFAULT_PERCUSION_CHANNEL)?lastUsedChannel+1:lastUsedChannel;
70
SongChannel channel = new SongChannel((short)lastUsedChannel,(short)lastUsedChannel,(short)0);
71
SongTrack track = new SongTrack(number,new String(),channel,new ArrayList(),new ArrayList(),0,(RGBColor)RGBColor.RED);
72
TrackInfo trackInfo = null;
74
//pongo por defecto el primer track info.
75
it = trackInfos.iterator();
77
TrackInfo info = (TrackInfo)it.next();
78
//if(info.trackInfoNumber == 0 && info.type == trackType){
79
if(info.type == trackType && (trackInfo == null || info.trackInfoNumber < trackInfo.trackInfoNumber)){
83
if(trackInfo != null){
84
track.setName(trackInfo.getName());
85
track.setStrings(trackInfo.getStrings());
86
track.getChannel().setInstrument((short)trackInfo.getChannel().getInstrument());
87
track.getChannel().setVolume((short)trackInfo.getChannel().getVolume());
88
track.getChannel().setBalance((short)trackInfo.getChannel().getBalance());
97
protected MeasureHeader getHeader(long start){
98
start += ERROR_MARGIN;
99
if(this.headers == null){
100
this.headers = new ArrayList();
103
Iterator it = headers.iterator();
105
MeasureHeader header = (MeasureHeader)it.next();
106
//if((start + ERROR_MARGIN) >= header.getStart() && (start + ERROR_MARGIN) < header.getStart() + header.getLength()){
107
if(start >= header.getStart() && start < header.getStart() + header.getLength()){
111
MeasureHeader last = getLastHeader();
112
int nextNumber = (last != null)?last.getNumber() + 1:1;
113
long nextStart = (last != null)?(last.getStart() + last.getLength()):1000;
114
TimeSignature nextTimeSignature = (last != null)?(TimeSignature)last.getTimeSignature().clone():new TimeSignature(4,new Duration(Duration.QUARTER));
115
Tempo nextTempo = (last != null)?(Tempo)last.getTempo().clone():new Tempo(120);
116
int nextTripletFeel = MeasureHeader.TRIPLET_FEEL_NONE;
117
MeasureHeader header = new MeasureHeader(nextNumber,nextStart,nextTimeSignature,nextTempo,null,nextTripletFeel,false,0);
119
this.headers.add(header);
121
if(header.getStart() + header.getLength() <= start){
124
return getHeader(start);
127
protected MeasureHeader getLastHeader(){
128
if(this.headers != null && !this.headers.isEmpty()){
129
return (MeasureHeader)this.headers.get(this.headers.size() - 1);
134
protected Measure getMeasure(SongTrack track,long start){
135
start += ERROR_MARGIN;
137
Iterator it = track.getMeasures().iterator();
139
Measure measure = (Measure)it.next();
140
//if((start + ERROR_MARGIN) >= measure.getStart() && (start + ERROR_MARGIN) < measure.getStart() + measure.getLength()){
141
if(start >= measure.getStart() && start < measure.getStart() + measure.getLength()){
146
getHeader(start - ERROR_MARGIN);
147
for(int i = 0;i < headers.size();i++){
148
boolean exist = false;
149
MeasureHeader header = (MeasureHeader)headers.get(i);
150
for(int j = 0;j < track.getMeasures().size();j++){
151
Measure measure = (Measure)track.getMeasures().get(j);
152
if(measure.getHeader().equals(header)){
157
track.getMeasures().add(new Measure(header,new ArrayList(),new ArrayList(),1,0));
160
return getMeasure(track,start);
163
protected void makeTrackChannels(int fromNumber,int trackType,/*List trackInfoHelpers,*/List guitarInHelpers){
164
Iterator it = guitarInHelpers.iterator();
166
GuitarInHelper guitarIn = (GuitarInHelper)it.next();
167
for(int i = 0;i < trackInfos.size();i ++){
168
TrackInfo info = (TrackInfo)trackInfos.get(i);
169
if(info.getTrackInfoNumber() == guitarIn.getTrackInfo() && info.getType() == trackType){
170
SongTrack track = getTrack(guitarIn.staff + fromNumber,trackType);
171
track.setName(info.getName());
172
track.setStrings(info.getStrings());
173
track.getChannel().setInstrument((short)info.getChannel().getInstrument());
174
track.getChannel().setVolume((short)info.getChannel().getVolume());
175
track.getChannel().setBalance((short)info.getChannel().getBalance());
181
protected long makeSectionNotes(long start,List trackHelpers,List barHelpers,List tempoHelpers){
183
for(int i = 0;i < trackHelpers.size();i ++){
184
TrackHelper track = (TrackHelper)trackHelpers.get(i);
185
long length = makeTrackNotes(start,track,barHelpers,tempoHelpers);
186
maxStart = Math.max(maxStart, length);
191
private long makeTrackNotes(long start,TrackHelper track,List barHelpers,List tempoHelpers){
194
for(int z = 0;z < barHelpers.size();z ++){
195
BarHelper bar = (BarHelper)barHelpers.get(z);
196
int nextPosition = (((z + 1)< barHelpers.size())?((BarHelper)barHelpers.get(z + 1)).getPosition():-1);
200
makeTimeSignature(bar,start, track.getTrackNumber());
201
makeTempoMarker(bar.getPosition(),start,track.getTrackNumber(),tempoHelpers);
203
for(int j = 0;j < track.getVoice1().size();j ++){
204
BeatHelper beat = (BeatHelper)track.getVoice1().get(j);
205
makeTempoMarker(beat.getPosition(),start + length1,track.getTrackNumber(),tempoHelpers);
206
length1 += makeBeatNotes(start + length1,track,beat,bar.getPosition(),nextPosition);
209
for(int j = 0;j < track.getVoice2().size();j ++){
210
BeatHelper beat = (BeatHelper)track.getVoice2().get(j);
211
makeTempoMarker(beat.getPosition(),start + length2,track.getTrackNumber(),tempoHelpers);
212
length2 += makeBeatNotes(start + length2,track,beat,bar.getPosition(),nextPosition);
214
start += Math.max(length1,length2);
216
//lastBar = bar.getPosition();
217
//start += Math.max(length1,length2);
224
for(int j = 0;j < track.getVoice1().size();j ++){
225
BeatHelper beat = (BeatHelper)track.getVoice1().get(j);
226
makeTempoMarker(beat.getPosition(),start + length1,track.getTrackNumber(),tempoHelpers);
227
length1 += makeBeatNotes(start + length1,track,beat,lastBar,-1);
230
for(int j = 0;j < track.getVoice2().size();j ++){
231
BeatHelper beat = (BeatHelper)track.getVoice2().get(j);
232
makeTempoMarker(beat.getPosition(),start + length2,track.getTrackNumber(),tempoHelpers);
233
length2 += makeBeatNotes(start + length2,track,beat,lastBar,-1);
236
start += Math.max(length1,length2);
241
private long makeBeatNotes(long start,TrackHelper track,BeatHelper beat,int position,int nextPosition){
244
for(int i = 0; i < beat.getMultiBarRest(); i++){
246
//if(!beat.isAcciaccatura() && beat.getPosition() > minPos && (beat.getPosition() < maxPos || maxPos < 0)){
247
if(!beat.isAcciaccatura() && beat.getPosition() >= position && ( beat.getPosition() < nextPosition || nextPosition < 0 )){
248
Measure measure = getMeasure(getTrack(track.getTrackNumber(),track.getTrackType()),(start + length));
249
long realStart = getRealStart(measure, (start + length) );
251
for(int k = 0;k < beat.getNotes().size();k++){
252
NoteHelper helper = (NoteHelper)beat.getNotes().get(k);
255
int value = helper.getValue();
256
int string = helper.getString();
258
boolean tied = helper.isTied();
259
Duration duration = (Duration)beat.getDuration().clone();
260
NoteEffect effect = new NoteEffect();
261
effect.setVibrato(beat.isVibrato());
262
effect.setDeadNote(helper.isDead());
263
effect.setHammer(helper.isHammer());
264
effect.setSlide(helper.isSlide());
265
effect.setBend((!tied && helper.getBend() > 0 && helper.getBend() < DEFAULT_BENDS.length)?(BendEffect)DEFAULT_BENDS[helper.getBend() - 1].clone():null);
267
addNote(measure,new Note(value,realStart,duration,velocity,string,tied,effect));
270
length += (getRealLength(measure.getTimeSignature(),beat.getDuration().getTime()) + (realStart - (start + length)));
277
private long getRealLength(TimeSignature ts,long length){
278
for(int i = 1;i <= ts.getNumerator();i ++){
279
long time = (i * (ts.getDenominator().getTime()));
281
if(length < time && (length + ERROR_MARGIN >= time ) ){
284
else if(length > time && (length - ERROR_MARGIN <= time ) ){
291
private long getRealStart(Measure measure,long start){
292
for(int i = 0;i < measure.getTimeSignature().getNumerator();i ++){
293
long time = (i * (measure.getTimeSignature().getDenominator().getTime()));
295
if(start < (measure.getStart() + time) && (start + ERROR_MARGIN >= (measure.getStart() + time) ) ){
296
return (measure.getStart() + time);
298
else if(start > (measure.getStart() + time) && (start - ERROR_MARGIN <= (measure.getStart() + time) ) ){
299
return (measure.getStart() + time);
305
private void addNote(Measure measure,Note note){
306
Iterator it = measure.getNotes().iterator();
308
Note n = (Note)it.next();
309
if(n.getStart() < note.getStart() && (n.getStart() + ERROR_MARGIN) > note.getStart()){
310
note.setStart(n.getStart());
311
}else if(n.getStart() > note.getStart() && (n.getStart() - ERROR_MARGIN) < note.getStart()){
312
note.setStart(n.getStart());
315
measure.addNote(note);
318
private void makeTimeSignature(BarHelper bar,long start,int track){
319
//solo si es la primer pista
321
MeasureHeader lastHeader = getLastHeader();
322
if(lastHeader != null){
323
start += lastHeader.getLength();
325
//MeasureHeader header = getHeader(start + getLastHeader().getLength());
326
MeasureHeader header = getHeader(start);
327
header.getTimeSignature().setNumerator(bar.getTimeSignature().getNumerator());
328
header.getTimeSignature().setDenominator((Duration)bar.getTimeSignature().getDenominator().clone());
332
private void makeTempoMarker(int position,long start,int track,List tempoHelpers){
333
//solo si es la primer pista
335
Iterator it = tempoHelpers.iterator();
337
TempoHelper helper = (TempoHelper)it.next();
338
if(helper.getPosition() == position){
339
MeasureHeader header = getHeader(start);
340
header.getTempo().setValue(helper.getTempo());
341
header.setTripletFeel(helper.getTripletFeel());
349
private void openRepeat(int track,long start){
350
repeats.add(new RepeatHelper(track,start));
352
private void closeRepeat(int track,long end,int number){
353
for(int i = 0; i < repeats.size();i ++){
354
RepeatHelper helper = (RepeatHelper)repeats.get(i);
355
if(helper.getTrack() == track && helper.getEnd() < 0){
357
helper.setRepeats(number);
362
private void doRepeats(RepeatHelper helper){
363
List measures = ((SongTrack)this.tracks.get(helper.getTrack() - 1)).getMeasures();
368
protected Song checkSong(Song song)throws IOException{
369
return new SongAdjuster().process(song);
373
private static BendEffect[] makeDefaultBends(){
374
BendEffect[] defaultBends = new BendEffect[8];
376
defaultBends[0] = new BendEffect();
377
defaultBends[0].addPoint(0,0);
378
defaultBends[0].addPoint(6,(BendEffect.SEMITONE_LENGTH * 2));
379
defaultBends[0].addPoint(12,(BendEffect.SEMITONE_LENGTH * 2));
381
defaultBends[1] = new BendEffect();
382
defaultBends[1].addPoint(0,0);
383
defaultBends[1].addPoint(3,(BendEffect.SEMITONE_LENGTH * 2));
384
defaultBends[1].addPoint(6,(BendEffect.SEMITONE_LENGTH * 2));
385
defaultBends[1].addPoint(9,0);
386
defaultBends[1].addPoint(12,0);
388
defaultBends[2] = new BendEffect();
389
defaultBends[2].addPoint(0,0);
390
defaultBends[2].addPoint(6,(BendEffect.SEMITONE_LENGTH * 2));
391
defaultBends[2].addPoint(12,(BendEffect.SEMITONE_LENGTH * 2));
393
defaultBends[3] = new BendEffect();
394
defaultBends[3].addPoint(0,(BendEffect.SEMITONE_LENGTH * 2));
395
defaultBends[3].addPoint(12,(BendEffect.SEMITONE_LENGTH * 2));
397
defaultBends[4] = new BendEffect();
398
defaultBends[4].addPoint(0,(BendEffect.SEMITONE_LENGTH * 2));
399
defaultBends[4].addPoint(4,(BendEffect.SEMITONE_LENGTH * 2));
400
defaultBends[4].addPoint(8,0);
401
defaultBends[4].addPoint(12,0);
403
defaultBends[5] = new BendEffect();
404
defaultBends[5].addPoint(0,8);
405
defaultBends[5].addPoint(12,8);
407
defaultBends[6] = new BendEffect();
408
defaultBends[6].addPoint(0,(BendEffect.SEMITONE_LENGTH * 2));
409
defaultBends[6].addPoint(4,(BendEffect.SEMITONE_LENGTH * 2));
410
defaultBends[6].addPoint(8,0);
411
defaultBends[6].addPoint(12,0);
413
defaultBends[7] = new BendEffect();
414
defaultBends[7].addPoint(0,(BendEffect.SEMITONE_LENGTH * 2));
415
defaultBends[7].addPoint(4,(BendEffect.SEMITONE_LENGTH * 2));
416
defaultBends[7].addPoint(8,0);
417
defaultBends[7].addPoint(12,0);
425
protected int readByte(){
427
return this.dataInputStream.read();
428
} catch (IOException e) {
434
protected String readString(int length){
436
byte[] bytes = new byte[length];
437
for(int i = 0;i < bytes.length; i++){
438
bytes[i] = this.dataInputStream.readByte();
440
return new String(bytes);
441
} catch (IOException e) {
448
protected String readString(){
450
int length = this.dataInputStream.read();
451
return readString(((length < 255)?length:readUInt()));
452
} catch (IOException e) {
459
protected int readUCType(){
463
protected boolean readUChar(){
465
return this.dataInputStream.readBoolean();
466
} catch (IOException e) {
472
protected int readUInt(){
475
this.dataInputStream.read(b);
476
return ((b[1] & 0xff) << 8) | (b[0] & 0xff);
477
} catch (IOException e) {
483
protected int readULong(){
485
//return this.dataInputStream.readInt();
487
byte[] b = new byte[4];
488
this.dataInputStream.read(b);
489
return ((b[3] & 0xff) << 24) | ((b[2] & 0xff) << 16) | ((b[1] & 0xff) << 8) | (b[0] & 0xff);
490
} catch (IOException e) {
497
protected void debug(int i){
498
System.out.println(i);
501
protected void debug(String s){
502
System.out.println(s);
519
protected class TrackHelper{
520
private int trackNumber;
521
private int trackType;
522
private List voice1 = new ArrayList();
523
private List voice2 = new ArrayList();
525
public TrackHelper(int trackNumber,int trackType){
526
this.trackNumber = trackNumber;
527
this.trackType = trackType;
528
this.voice1 = new ArrayList();
529
this.voice2 = new ArrayList();
532
public int getTrackNumber() {
536
public int getTrackType() {
540
public List getVoice1() {
544
public List getVoice2() {
550
protected class BeatHelper{
551
private int position;
552
private Duration duration;
554
private int multiBarRest;
555
private boolean acciaccatura;
556
private boolean vibrato;
559
this.notes = new ArrayList();
560
this.multiBarRest = 1;
563
public Duration getDuration() {
567
public void setDuration(Duration duration) {
568
this.duration = duration;
571
public int getPosition() {
575
public void setPosition(int position) {
576
this.position = position;
579
public void addNote(NoteHelper note){
580
this.notes.add(note);
583
public List getNotes(){
587
public boolean isAcciaccatura() {
591
public void setAcciaccatura(boolean acciaccatura) {
592
this.acciaccatura = acciaccatura;
595
public boolean isVibrato() {
599
public void setVibrato(boolean vibrato) {
600
this.vibrato = vibrato;
603
public int getMultiBarRest() {
607
public void setMultiBarRest(int multiBarRest) {
608
this.multiBarRest = multiBarRest;
615
protected class NoteHelper{
618
private boolean tied;
619
private boolean dead;
620
private boolean hammer;
621
private boolean slide;
628
public int getString() {
631
public void setString(int string) {
632
this.string = string;
634
public int getValue() {
637
public void setValue(int value) {
641
public boolean isDead() {
645
public void setDead(boolean dead) {
649
public boolean isTied() {
653
public void setTied(boolean tied) {
657
public int getBend() {
661
public void setBend(int bend) {
665
public boolean isHammer() {
669
public void setHammer(boolean hammer) {
670
this.hammer = hammer;
673
public boolean isSlide() {
677
public void setSlide(boolean slide) {
684
protected class BarHelper{
685
private int position;
686
private int numberOfRepetitions;
687
private boolean repeatStart;
688
private TimeSignature timeSignature;
690
public BarHelper(int position){
691
this.position = position;
694
public int getPosition() {
698
public TimeSignature getTimeSignature() {
699
return timeSignature;
702
public void setTimeSignature(TimeSignature timeSignature){
703
this.timeSignature = timeSignature;
706
public int getNumberOfRepetitions() {
707
return numberOfRepetitions;
710
public void setNumberOfRepetitions(int numberOfRepetitions) {
711
this.numberOfRepetitions = numberOfRepetitions;
714
public boolean isRepeatStart() {
718
public void setRepeatStart(boolean repeatStart) {
719
this.repeatStart = repeatStart;
724
protected class TempoHelper{
729
public TempoHelper(int position,int tempo,int tripletFeel){
730
this.position = position;
732
this.tripletFeel = tripletFeel;
735
public int getPosition() {
739
public int getTempo() {
743
public int getTripletFeel() {
749
protected class TrackInfo{
751
private int trackInfoNumber;
752
private SongChannel channel;
753
private List strings;
760
public SongChannel getChannel() {
764
public void setChannel(SongChannel channel) {
765
this.channel = channel;
768
public List getStrings() {
772
public void setStrings(List strings) {
773
this.strings = strings;
776
public int getTrackInfoNumber() {
777
return trackInfoNumber;
780
public void setTrackInfoNumber(int trackInfoNumber) {
781
this.trackInfoNumber = trackInfoNumber;
784
public int getType() {
788
public void setType(int type) {
792
public String getName() {
796
public void setName(String name) {
801
protected class GuitarInHelper{
803
private int trackInfo;
805
public GuitarInHelper(int staff,int trackInfo){
807
this.trackInfo = trackInfo;
810
public int getStaff() {
814
public int getTrackInfo() {
819
protected class SongInfo{
821
private String interpret;
822
private String album;
823
private String author;
828
public String getAlbum() {
831
public void setAlbum(String album) {
834
public String getAuthor() {
837
public void setAuthor(String author) {
838
this.author = author;
840
public String getInterpret() {
843
public void setInterpret(String interpret) {
844
this.interpret = interpret;
846
public String getName() {
849
public void setName(String name) {
854
private class SongAdjuster{
855
public SongAdjuster(){
858
public Song process(Song song)throws IOException{
859
completeMeasures(song);
860
adjustDurations(song);
865
public void completeMeasures(Song song)throws IOException{
866
int headerCount = song.getMeasureHeaders().size();
867
for(int i = 0;i < song.getTracks().size();i ++){
868
SongTrack track = (SongTrack)song.getTracks().get(i);
869
while(track.getMeasures().size() < headerCount){
870
long start = Duration.QUARTER_TIME;
871
Measure lastMeasure = (Measure)((!track.getMeasures().isEmpty())?track.getMeasures().get(track.getMeasures().size() - 1) :null);
872
if(lastMeasure != null){
873
start = (lastMeasure.getStart() + lastMeasure.getLength());
875
track.getMeasures().add(new Measure(getHeader(start),new ArrayList(),new ArrayList(),1,0));
878
if(song.getMeasureHeaders().isEmpty() || song.getTracks().isEmpty()){
879
throw new IOException("Empty Song");
883
public void adjustDurations(Song song){
884
for(int i = 0;i < song.getTracks().size();i ++){
885
SongTrack track = (SongTrack)song.getTracks().get(i);
886
for(int j = 0;j < track.getMeasures().size();j ++){
887
Measure measure = (Measure)track.getMeasures().get(j);
888
if(!measure.getNotes().isEmpty()){
890
long start = ((Note)measure.getNotes().get(0)).getStart();
891
long measureStart = measure.getStart();
892
long measureLength = measure.getLength();
893
while(start < (measureStart + measureLength)){
894
List notesAtBeat = getNotesAtBeat(measure,start);
895
long maxLength = getMaxLength(measure,start);
896
normalizeNotes(notesAtBeat,maxLength);
904
private void normalizeNotes(List notes,long maxLength){
905
Duration beatDuration = null;
907
Iterator it = notes.iterator();
909
Note note = (Note)it.next();
910
long noteDuration = note.getDuration().getTime();
911
if(noteDuration <= maxLength && (beatDuration == null || noteDuration > beatDuration.getTime())){
912
beatDuration = note.getDuration();
915
if(beatDuration == null){
916
beatDuration = Duration.fromTime(maxLength);
918
if(beatDuration != null){
919
it = notes.iterator();
921
Note note = (Note)it.next();
922
note.setDuration((Duration)beatDuration.clone());
928
private List getNotesAtBeat(Measure measure,long start){
929
List notes = new ArrayList();
930
Iterator it = measure.getNotes().iterator();
932
Note note = (Note)it.next();
933
if(note.getStart() == start){
940
private long getMaxLength(Measure measure,long start){
942
Iterator it = measure.getNotes().iterator();
944
Note note = (Note)it.next();
945
if(note.getStart() > start && (nextStart < 0 || note.getStart() < nextStart)){
946
nextStart = note.getStart();
950
nextStart = (measure.getStart() + measure.getLength());
952
return (nextStart - start);
955
private void orderNotes(Measure measure){
956
int noteCount = measure.getNotes().size();
957
for(int i = 0;i < noteCount;i++){
959
for(int noteIdx = i;noteIdx < noteCount;noteIdx++){
960
Note note = (Note)measure.getNotes().get(noteIdx);
963
}else if(note.getStart() < minNote.getStart()){
965
}else if(note.getStart() == minNote.getStart() && note.getString() < minNote.getString()){
969
measure.getNotes().remove(minNote);
970
measure.getNotes().add(i,minNote);