~ubuntu-branches/ubuntu/oneiric/tuxguitar/oneiric

« back to all changes in this revision

Viewing changes to src/org/herac/tuxguitar/io/pt/PTBInputStream.java

  • Committer: Bazaar Package Importer
  • Author(s): Philippe Coval
  • Date: 2008-06-19 00:30:30 UTC
  • mto: (5.1.2 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20080619003030-h719szrhsngou7c6
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.herac.tuxguitar.io.pt;
2
 
 
3
 
import java.io.DataInputStream;
4
 
import java.io.File;
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;
11
 
 
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;
25
 
 
26
 
public abstract class PTBInputStream {
27
 
        protected static final int TRACK_TYPE_GUITAR = 1;
28
 
        
29
 
        protected static final int TRACK_TYPE_BASS = 2;
30
 
        
31
 
        private static final int ERROR_MARGIN = 50;     
32
 
        
33
 
        private static final BendEffect[] DEFAULT_BENDS = makeDefaultBends();
34
 
        
35
 
    private DataInputStream dataInputStream;
36
 
    
37
 
    protected String version;    
38
 
    protected List headers;
39
 
    protected List tracks;
40
 
    protected List trackInfos;
41
 
    protected int lastUsedChannel = 0;
42
 
    
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();
48
 
    }
49
 
 
50
 
    public PTBInputStream(String fileName) throws FileNotFoundException {        
51
 
        this(new FileInputStream(new File(fileName)));             
52
 
    }          
53
 
    
54
 
    public abstract boolean isSupportedVersion(String version);
55
 
 
56
 
    public abstract boolean isSupportedVersion();
57
 
        
58
 
        
59
 
    protected SongTrack getTrack(int number,int trackType){
60
 
        Iterator it = this.tracks.iterator();
61
 
        while(it.hasNext()){
62
 
                SongTrack track = (SongTrack)it.next();
63
 
                if(track.getNumber() == number){
64
 
                        return track;
65
 
                }
66
 
        }
67
 
        lastUsedChannel = (lastUsedChannel < (SongManager.MAX_CHANNELS - 1))?lastUsedChannel+1:lastUsedChannel;
68
 
        lastUsedChannel = (lastUsedChannel == SongChannel.DEFAULT_PERCUSION_CHANNEL)?lastUsedChannel+1:lastUsedChannel;
69
 
        
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;
73
 
        
74
 
        //pongo por defecto el primer track info.
75
 
        it = trackInfos.iterator();
76
 
        while(it.hasNext()){
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)){
80
 
                        trackInfo = info;
81
 
                }
82
 
        }       
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());
89
 
        }
90
 
        tracks.add(track);
91
 
        
92
 
        return track;
93
 
    }
94
 
    
95
 
    
96
 
        
97
 
    protected MeasureHeader getHeader(long start){
98
 
        start += ERROR_MARGIN;
99
 
                if(this.headers == null){
100
 
                        this.headers = new ArrayList();
101
 
                }
102
 
                
103
 
                Iterator it = headers.iterator();
104
 
                while(it.hasNext()){
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()){
108
 
                                return header;
109
 
                        }
110
 
                }               
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);
118
 
                
119
 
                this.headers.add(header);
120
 
                
121
 
                if(header.getStart() + header.getLength() <= start){            
122
 
                        return header;
123
 
                }
124
 
                return getHeader(start);
125
 
        }
126
 
        
127
 
        protected MeasureHeader getLastHeader(){
128
 
                if(this.headers != null && !this.headers.isEmpty()){
129
 
                        return (MeasureHeader)this.headers.get(this.headers.size() - 1);
130
 
                }               
131
 
                return null;
132
 
        }
133
 
        
134
 
        protected Measure getMeasure(SongTrack track,long start){
135
 
                start += ERROR_MARGIN;
136
 
                
137
 
                Iterator it = track.getMeasures().iterator();
138
 
                while(it.hasNext()){
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()){
142
 
                                return measure;
143
 
                        }
144
 
                }                               
145
 
                //getHeader(start);
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)){
153
 
                                        exist = true;
154
 
                                }
155
 
                        }
156
 
                        if(!exist){
157
 
                                track.getMeasures().add(new Measure(header,new ArrayList(),new ArrayList(),1,0));               
158
 
                        }
159
 
                }
160
 
                return getMeasure(track,start);
161
 
        }       
162
 
        
163
 
        protected void makeTrackChannels(int fromNumber,int trackType,/*List trackInfoHelpers,*/List guitarInHelpers){
164
 
                Iterator it = guitarInHelpers.iterator();
165
 
                while(it.hasNext()){
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());                                   
176
 
                                }
177
 
                        }
178
 
                }
179
 
        }
180
 
        
181
 
        protected long makeSectionNotes(long start,List trackHelpers,List barHelpers,List tempoHelpers){
182
 
                long maxStart = 0;
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);
187
 
                }
188
 
                return maxStart;
189
 
        }
190
 
        
191
 
        private long makeTrackNotes(long start,TrackHelper track,List barHelpers,List tempoHelpers){
192
 
                //int lastBar = -1;
193
 
                
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);
197
 
                        int length1 = 0;
198
 
                        int length2 = 0;
199
 
                                                        
200
 
                        makeTimeSignature(bar,start, track.getTrackNumber());
201
 
                        makeTempoMarker(bar.getPosition(),start,track.getTrackNumber(),tempoHelpers);
202
 
                        
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);
207
 
                        }
208
 
 
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);
213
 
                        }
214
 
                        start += Math.max(length1,length2);
215
 
                        
216
 
                        //lastBar = bar.getPosition();
217
 
                        //start += Math.max(length1,length2);                   
218
 
                        
219
 
                        
220
 
                }
221
 
                /*
222
 
                int length1 = 0;
223
 
                int length2 = 0;                
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);                        
228
 
                }
229
 
 
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);
234
 
                }               
235
 
                
236
 
                start += Math.max(length1,length2);     
237
 
                */
238
 
                return start;
239
 
        }
240
 
 
241
 
        private long makeBeatNotes(long start,TrackHelper track,BeatHelper beat,int position,int nextPosition){
242
 
                long length = 0;
243
 
                
244
 
                for(int i = 0; i < beat.getMultiBarRest(); i++){
245
 
                
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) );
250
 
                        
251
 
                        for(int k = 0;k < beat.getNotes().size();k++){
252
 
                                NoteHelper helper = (NoteHelper)beat.getNotes().get(k);
253
 
                                
254
 
                                
255
 
                                int value = helper.getValue();
256
 
                                int string = helper.getString();
257
 
                                int velocity = 64;
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);
266
 
                                
267
 
                                addNote(measure,new Note(value,realStart,duration,velocity,string,tied,effect));
268
 
                        }       
269
 
 
270
 
                        length += (getRealLength(measure.getTimeSignature(),beat.getDuration().getTime()) + (realStart - (start + length)));
271
 
                }               
272
 
                }
273
 
                
274
 
                return length;
275
 
        }
276
 
        
277
 
        private long getRealLength(TimeSignature ts,long length){
278
 
                for(int i = 1;i <= ts.getNumerator();i ++){
279
 
                        long time = (i * (ts.getDenominator().getTime()));
280
 
                        
281
 
                        if(length < time && (length + ERROR_MARGIN >= time ) ){
282
 
                                return time;                            
283
 
                        }
284
 
                        else if(length > time && (length - ERROR_MARGIN <= time ) ){
285
 
                                return time;
286
 
                        }
287
 
                }       
288
 
                return length;
289
 
        }
290
 
        
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()));
294
 
                        
295
 
                        if(start < (measure.getStart() + time) && (start + ERROR_MARGIN >= (measure.getStart() + time) ) ){
296
 
                                return (measure.getStart() + time);                             
297
 
                        }
298
 
                        else if(start > (measure.getStart() + time) && (start - ERROR_MARGIN <= (measure.getStart() + time) ) ){
299
 
                                return (measure.getStart() + time);
300
 
                        }
301
 
                }       
302
 
                return start;
303
 
        }
304
 
        
305
 
        private void addNote(Measure measure,Note note){
306
 
                Iterator it = measure.getNotes().iterator();
307
 
                while(it.hasNext()){
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());
313
 
                        }
314
 
                }
315
 
                measure.addNote(note);
316
 
        }
317
 
        
318
 
        private void makeTimeSignature(BarHelper bar,long start,int track){
319
 
                //solo si es la primer pista
320
 
                if(track == 1){
321
 
                        MeasureHeader lastHeader = getLastHeader();
322
 
                        if(lastHeader != null){
323
 
                                start += lastHeader.getLength();
324
 
                        }
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());            
329
 
                }
330
 
        }       
331
 
        
332
 
        private void makeTempoMarker(int position,long start,int track,List tempoHelpers){
333
 
                //solo si es la primer pista
334
 
                if(track == 1){
335
 
                        Iterator it = tempoHelpers.iterator();
336
 
                        while(it.hasNext()){
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());
342
 
                                }
343
 
                        }
344
 
                }
345
 
        }
346
 
 
347
 
        
348
 
        /*
349
 
        private void openRepeat(int track,long start){
350
 
                repeats.add(new RepeatHelper(track,start));
351
 
        }
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){
356
 
                                helper.setEnd(end);
357
 
                                helper.setRepeats(number);
358
 
                                break;
359
 
                        }
360
 
                }
361
 
        }
362
 
        private void doRepeats(RepeatHelper helper){
363
 
                List measures = ((SongTrack)this.tracks.get(helper.getTrack() - 1)).getMeasures();
364
 
                
365
 
        }
366
 
        */
367
 
                
368
 
        protected Song checkSong(Song song)throws IOException{
369
 
                return new SongAdjuster().process(song);
370
 
        }    
371
 
    
372
 
 
373
 
    private static BendEffect[] makeDefaultBends(){
374
 
        BendEffect[] defaultBends = new BendEffect[8];
375
 
        
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));               
380
 
        
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);
387
 
        
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));         
392
 
                
393
 
        defaultBends[3] = new BendEffect();
394
 
        defaultBends[3].addPoint(0,(BendEffect.SEMITONE_LENGTH * 2));
395
 
        defaultBends[3].addPoint(12,(BendEffect.SEMITONE_LENGTH * 2));
396
 
 
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);
402
 
        
403
 
        defaultBends[5] = new BendEffect();
404
 
        defaultBends[5].addPoint(0,8);
405
 
        defaultBends[5].addPoint(12,8);
406
 
        
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);
412
 
        
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);
418
 
        
419
 
        return defaultBends;
420
 
    }       
421
 
        
422
 
        
423
 
    
424
 
        
425
 
    protected int readByte(){
426
 
        try {
427
 
            return this.dataInputStream.read();
428
 
        } catch (IOException e) {
429
 
            e.printStackTrace();
430
 
        }
431
 
        return 0;
432
 
    }
433
 
    
434
 
    protected String readString(int length){
435
 
        try {
436
 
            byte[] bytes = new byte[length];
437
 
            for(int i = 0;i < bytes.length; i++){
438
 
                bytes[i] = this.dataInputStream.readByte();
439
 
            }
440
 
            return new String(bytes);
441
 
        } catch (IOException e) {            
442
 
            e.printStackTrace();
443
 
        }
444
 
        return null;
445
 
        
446
 
    }        
447
 
    
448
 
    protected String readString(){
449
 
        try {           
450
 
                int length = this.dataInputStream.read();               
451
 
                return readString(((length < 255)?length:readUInt()));
452
 
        } catch (IOException e) {            
453
 
            e.printStackTrace();
454
 
        }
455
 
        return null;
456
 
        
457
 
    }   
458
 
    
459
 
    protected int readUCType(){
460
 
        return readByte();
461
 
    }
462
 
    
463
 
    protected boolean readUChar(){
464
 
        try {
465
 
            return this.dataInputStream.readBoolean();
466
 
        } catch (IOException e) {            
467
 
            e.printStackTrace();
468
 
        }
469
 
        return false;
470
 
    }
471
 
    
472
 
    protected int readUInt(){
473
 
        try {
474
 
                byte[] b = {0, 0};
475
 
                this.dataInputStream.read(b);
476
 
                return ((b[1] & 0xff) << 8) | (b[0] & 0xff);
477
 
        } catch (IOException e) {
478
 
            e.printStackTrace();
479
 
        }
480
 
        return 0;
481
 
    }
482
 
    
483
 
    protected int readULong(){
484
 
        try {
485
 
                //return this.dataInputStream.readInt(); 
486
 
                
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) {
491
 
            e.printStackTrace();
492
 
        }
493
 
        return 0;
494
 
    }
495
 
    
496
 
    
497
 
    protected void debug(int i){
498
 
        System.out.println(i);
499
 
    }
500
 
    
501
 
    protected void debug(String s){
502
 
        System.out.println(s);
503
 
    }
504
 
    
505
 
    
506
 
    
507
 
    
508
 
    
509
 
    
510
 
    
511
 
    
512
 
    
513
 
    
514
 
    
515
 
    
516
 
    
517
 
    
518
 
 
519
 
    protected class TrackHelper{
520
 
        private int trackNumber;
521
 
        private int trackType;
522
 
        private List voice1 = new ArrayList();
523
 
        private List voice2 = new ArrayList();
524
 
        
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();
530
 
        }
531
 
 
532
 
                public int getTrackNumber() {
533
 
                        return trackNumber;
534
 
                }
535
 
 
536
 
                public int getTrackType() {
537
 
                        return trackType;
538
 
                }
539
 
                
540
 
                public List getVoice1() {
541
 
                        return voice1;
542
 
                }
543
 
 
544
 
                public List getVoice2() {
545
 
                        return voice2;
546
 
                }
547
 
        
548
 
    }
549
 
        
550
 
        protected class BeatHelper{
551
 
                private int position;           
552
 
                private Duration duration;
553
 
                private List notes;
554
 
                private int multiBarRest;
555
 
                private boolean acciaccatura;
556
 
                private boolean vibrato;
557
 
                
558
 
        public BeatHelper(){ 
559
 
                this.notes = new ArrayList();
560
 
                this.multiBarRest = 1;
561
 
        }
562
 
 
563
 
                public Duration getDuration() {
564
 
                        return duration;
565
 
                }
566
 
 
567
 
                public void setDuration(Duration duration) {
568
 
                        this.duration = duration;
569
 
                }
570
 
 
571
 
                public int getPosition() {
572
 
                        return position;
573
 
                }
574
 
 
575
 
                public void setPosition(int position) {
576
 
                        this.position = position;
577
 
                }
578
 
 
579
 
                public void addNote(NoteHelper note){
580
 
                        this.notes.add(note);
581
 
                }
582
 
                
583
 
                public List getNotes(){
584
 
                        return this.notes;
585
 
                }
586
 
 
587
 
                public boolean isAcciaccatura() {
588
 
                        return acciaccatura;
589
 
                }
590
 
 
591
 
                public void setAcciaccatura(boolean acciaccatura) {
592
 
                        this.acciaccatura = acciaccatura;
593
 
                }
594
 
 
595
 
                public boolean isVibrato() {
596
 
                        return vibrato;
597
 
                }
598
 
 
599
 
                public void setVibrato(boolean vibrato) {
600
 
                        this.vibrato = vibrato;
601
 
                }
602
 
 
603
 
                public int getMultiBarRest() {
604
 
                        return multiBarRest;
605
 
                }
606
 
 
607
 
                public void setMultiBarRest(int multiBarRest) {
608
 
                        this.multiBarRest = multiBarRest;
609
 
                }
610
 
                
611
 
                
612
 
                
613
 
        }
614
 
        
615
 
        protected class NoteHelper{
616
 
                private int value;
617
 
                private int string;
618
 
                private boolean tied;
619
 
                private boolean dead;
620
 
                private boolean hammer;
621
 
                private boolean slide;
622
 
                private int bend;
623
 
                
624
 
                
625
 
                public NoteHelper(){
626
 
                }
627
 
                
628
 
                public int getString() {
629
 
                        return string;
630
 
                }
631
 
                public void setString(int string) {
632
 
                        this.string = string;
633
 
                }
634
 
                public int getValue() {
635
 
                        return value;
636
 
                }
637
 
                public void setValue(int value) {
638
 
                        this.value = value;
639
 
                }
640
 
 
641
 
                public boolean isDead() {
642
 
                        return dead;
643
 
                }
644
 
 
645
 
                public void setDead(boolean dead) {
646
 
                        this.dead = dead;
647
 
                }
648
 
 
649
 
                public boolean isTied() {
650
 
                        return tied;
651
 
                }
652
 
 
653
 
                public void setTied(boolean tied) {
654
 
                        this.tied = tied;
655
 
                }
656
 
 
657
 
                public int getBend() {
658
 
                        return bend;
659
 
                }
660
 
 
661
 
                public void setBend(int bend) {
662
 
                        this.bend = bend;
663
 
                }
664
 
 
665
 
                public boolean isHammer() {
666
 
                        return hammer;
667
 
                }
668
 
 
669
 
                public void setHammer(boolean hammer) {
670
 
                        this.hammer = hammer;
671
 
                }
672
 
 
673
 
                public boolean isSlide() {
674
 
                        return slide;
675
 
                }
676
 
 
677
 
                public void setSlide(boolean slide) {
678
 
                        this.slide = slide;
679
 
                }               
680
 
                
681
 
                
682
 
        }
683
 
        
684
 
        protected class BarHelper{
685
 
                private int position;           
686
 
                private int numberOfRepetitions;
687
 
                private boolean repeatStart;
688
 
                private TimeSignature timeSignature;
689
 
                
690
 
                public BarHelper(int position){
691
 
                        this.position = position;
692
 
                }
693
 
                
694
 
                public int getPosition() {
695
 
                        return position;
696
 
                }
697
 
                
698
 
                public TimeSignature getTimeSignature() {
699
 
                        return timeSignature;
700
 
                }
701
 
                
702
 
                public void setTimeSignature(TimeSignature timeSignature){
703
 
                        this.timeSignature = timeSignature;
704
 
                }
705
 
 
706
 
                public int getNumberOfRepetitions() {
707
 
                        return numberOfRepetitions;
708
 
                }
709
 
 
710
 
                public void setNumberOfRepetitions(int numberOfRepetitions) {
711
 
                        this.numberOfRepetitions = numberOfRepetitions;
712
 
                }
713
 
 
714
 
                public boolean isRepeatStart() {
715
 
                        return repeatStart;
716
 
                }
717
 
 
718
 
                public void setRepeatStart(boolean repeatStart) {
719
 
                        this.repeatStart = repeatStart;
720
 
                }
721
 
                
722
 
        }       
723
 
        
724
 
        protected class TempoHelper{
725
 
                int position;
726
 
                int tempo;
727
 
                int tripletFeel;
728
 
                
729
 
                public TempoHelper(int position,int tempo,int tripletFeel){
730
 
                        this.position = position;
731
 
                        this.tempo = tempo;
732
 
                        this.tripletFeel = tripletFeel;
733
 
                }
734
 
 
735
 
                public int getPosition() {
736
 
                        return position;
737
 
                }
738
 
 
739
 
                public int getTempo() {
740
 
                        return tempo;
741
 
                }
742
 
                
743
 
                public int getTripletFeel() {
744
 
                        return tripletFeel;
745
 
                }
746
 
                
747
 
        }
748
 
    
749
 
    protected class TrackInfo{          
750
 
        private int type;
751
 
        private int trackInfoNumber;
752
 
        private SongChannel channel;
753
 
        private List strings;
754
 
        private String name;
755
 
        
756
 
        public TrackInfo(){             
757
 
        }
758
 
        
759
 
        
760
 
                public SongChannel getChannel() {
761
 
                        return channel;
762
 
                }
763
 
 
764
 
                public void setChannel(SongChannel channel) {
765
 
                        this.channel = channel;
766
 
                }
767
 
 
768
 
                public List getStrings() {
769
 
                        return strings;
770
 
                }
771
 
 
772
 
                public void setStrings(List strings) {
773
 
                        this.strings = strings;
774
 
                }
775
 
 
776
 
                public int getTrackInfoNumber() {
777
 
                        return trackInfoNumber;
778
 
                }
779
 
 
780
 
                public void setTrackInfoNumber(int trackInfoNumber) {
781
 
                        this.trackInfoNumber = trackInfoNumber;
782
 
                }
783
 
 
784
 
                public int getType() {
785
 
                        return type;
786
 
                }
787
 
 
788
 
                public void setType(int type) {
789
 
                        this.type = type;
790
 
                }
791
 
 
792
 
                public String getName() {
793
 
                        return name;
794
 
                }
795
 
 
796
 
                public void setName(String name) {
797
 
                        this.name = name;
798
 
                }       
799
 
    }
800
 
    
801
 
    protected class GuitarInHelper{
802
 
        private int staff;
803
 
        private int trackInfo;
804
 
        
805
 
        public GuitarInHelper(int staff,int trackInfo){
806
 
                this.staff = staff;
807
 
                this.trackInfo = trackInfo;
808
 
        }
809
 
 
810
 
                public int getStaff() {
811
 
                        return staff;
812
 
                }
813
 
 
814
 
                public int getTrackInfo() {
815
 
                        return trackInfo;
816
 
                }       
817
 
    }
818
 
    
819
 
    protected class SongInfo{
820
 
            private String name;    
821
 
            private String interpret;
822
 
            private String album;
823
 
            private String author;
824
 
            
825
 
            public SongInfo(){          
826
 
            }
827
 
            
828
 
                public String getAlbum() {
829
 
                        return album;
830
 
                }
831
 
                public void setAlbum(String album) {
832
 
                        this.album = album;
833
 
                }
834
 
                public String getAuthor() {
835
 
                        return author;
836
 
                }
837
 
                public void setAuthor(String author) {
838
 
                        this.author = author;
839
 
                }
840
 
                public String getInterpret() {
841
 
                        return interpret;
842
 
                }
843
 
                public void setInterpret(String interpret) {
844
 
                        this.interpret = interpret;
845
 
                }
846
 
                public String getName() {
847
 
                        return name;
848
 
                }
849
 
                public void setName(String name) {
850
 
                        this.name = name;
851
 
                }                           
852
 
    }
853
 
    
854
 
    private class SongAdjuster{         
855
 
        public SongAdjuster(){                  
856
 
        }
857
 
        
858
 
        public Song process(Song song)throws IOException{               
859
 
                completeMeasures(song);
860
 
                adjustDurations(song);
861
 
                
862
 
                return song;
863
 
        }       
864
 
        
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());
874
 
                                }
875
 
                                track.getMeasures().add(new Measure(getHeader(start),new ArrayList(),new ArrayList(),1,0));
876
 
                        }
877
 
                }               
878
 
                if(song.getMeasureHeaders().isEmpty() || song.getTracks().isEmpty()){
879
 
                        throw new IOException("Empty Song");
880
 
                }
881
 
        }               
882
 
        
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()){
889
 
                                        orderNotes(measure);                    
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);
897
 
                                                start += maxLength;
898
 
                                        }
899
 
                                }
900
 
                        }
901
 
                }               
902
 
        }
903
 
        
904
 
        private void normalizeNotes(List notes,long maxLength){
905
 
                Duration beatDuration = null;
906
 
                
907
 
                Iterator it = notes.iterator();
908
 
                while(it.hasNext()){
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();
913
 
                        }
914
 
                }               
915
 
                if(beatDuration == null){
916
 
                        beatDuration = Duration.fromTime(maxLength);
917
 
                }
918
 
                if(beatDuration != null){                       
919
 
                        it = notes.iterator();
920
 
                        while(it.hasNext()){
921
 
                                Note note = (Note)it.next();
922
 
                                note.setDuration((Duration)beatDuration.clone());
923
 
                        }
924
 
                }
925
 
        }       
926
 
        
927
 
        
928
 
        private List getNotesAtBeat(Measure measure,long start){
929
 
                List notes = new ArrayList();
930
 
                Iterator it = measure.getNotes().iterator();
931
 
                while(it.hasNext()){
932
 
                        Note note = (Note)it.next();
933
 
                        if(note.getStart() == start){
934
 
                                notes.add(note);
935
 
                        }
936
 
                }
937
 
                return notes;
938
 
        }
939
 
                
940
 
        private long getMaxLength(Measure measure,long start){
941
 
                long nextStart = -1;
942
 
                Iterator it = measure.getNotes().iterator();
943
 
                while(it.hasNext()){
944
 
                        Note note = (Note)it.next();
945
 
                        if(note.getStart() > start && (nextStart < 0 || note.getStart() < nextStart)){
946
 
                                nextStart = note.getStart();
947
 
                        }
948
 
                }
949
 
                if(nextStart < 0){
950
 
                        nextStart = (measure.getStart() + measure.getLength());
951
 
                }
952
 
                return (nextStart - start);
953
 
        }
954
 
        
955
 
        private void orderNotes(Measure measure){
956
 
                int noteCount = measure.getNotes().size();
957
 
            for(int i = 0;i < noteCount;i++){
958
 
                Note minNote = null;
959
 
                for(int noteIdx = i;noteIdx < noteCount;noteIdx++){
960
 
                    Note note = (Note)measure.getNotes().get(noteIdx);
961
 
                    if(minNote == null){
962
 
                        minNote = note;
963
 
                    }else if(note.getStart() < minNote.getStart()){
964
 
                        minNote = note;
965
 
                    }else if(note.getStart() == minNote.getStart() && note.getString() < minNote.getString()){
966
 
                        minNote = note;
967
 
                    }
968
 
                }
969
 
                measure.getNotes().remove(minNote);
970
 
                measure.getNotes().add(i,minNote);
971
 
            }
972
 
        }
973
 
        
974
 
    }    
975
 
 
976
 
}