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

« back to all changes in this revision

Viewing changes to src/org/herac/tuxguitar/io/gp/GP4InputStream.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.gp;
2
 
 
3
 
import java.io.File;
4
 
import java.io.FileInputStream;
5
 
import java.io.FileNotFoundException;
6
 
import java.io.IOException;
7
 
import java.io.InputStream;
8
 
import java.util.ArrayList;
9
 
import java.util.List;
10
 
 
11
 
import org.herac.tuxguitar.song.models.Duration;
12
 
import org.herac.tuxguitar.song.models.InstrumentString;
13
 
import org.herac.tuxguitar.song.models.Lyric;
14
 
import org.herac.tuxguitar.song.models.Marker;
15
 
import org.herac.tuxguitar.song.models.Measure;
16
 
import org.herac.tuxguitar.song.models.MeasureHeader;
17
 
import org.herac.tuxguitar.song.models.Note;
18
 
import org.herac.tuxguitar.song.models.NoteEffect;
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.RGBColor;
25
 
import org.herac.tuxguitar.song.models.VelocityValues;
26
 
import org.herac.tuxguitar.song.models.effects.BendEffect;
27
 
import org.herac.tuxguitar.song.models.effects.GraceEffect;
28
 
import org.herac.tuxguitar.song.models.effects.HarmonicEffect;
29
 
import org.herac.tuxguitar.song.models.effects.TremoloBarEffect;
30
 
import org.herac.tuxguitar.song.models.effects.TremoloPickingEffect;
31
 
import org.herac.tuxguitar.song.models.effects.TrillEffect;
32
 
 
33
 
public class GP4InputStream extends InputStream {
34
 
    private static final String supportedVersions[] = { "FICHIER GUITAR PRO v4.00", "FICHIER GUITAR PRO v4.06", "FICHIER GUITAR PRO L4.06" };    
35
 
    private static final int GP_BEND_SEMITONE = 50;    
36
 
    private static final int GP_BEND_POSITION = 60;
37
 
    
38
 
    private InputStream inputStream;
39
 
    private String version;
40
 
    private int tripletFeel;
41
 
    
42
 
    //private int offset;
43
 
 
44
 
    public GP4InputStream(InputStream inputStream) {
45
 
        super();
46
 
        this.inputStream = inputStream;
47
 
        //this.offset = 0;
48
 
    }
49
 
 
50
 
    public GP4InputStream(String fileName) throws FileNotFoundException {
51
 
        this(new FileInputStream(new File(fileName)));
52
 
    }
53
 
 
54
 
    public void close() throws IOException {
55
 
        this.inputStream.close();
56
 
    }
57
 
 
58
 
    public int read() throws IOException {
59
 
        //this.offset++;
60
 
        return this.inputStream.read();
61
 
    }
62
 
 
63
 
    private void readVersion(){
64
 
                try {
65
 
                        if(this.version == null){
66
 
                                this.version = readStringByte(30);
67
 
                        }
68
 
                } catch (IOException e) {
69
 
                        this.version = "NOT_SUPPORTED";
70
 
                }       
71
 
    }    
72
 
    
73
 
    public static boolean isSupportedVersion(String version) {
74
 
        for (int i = 0; i < supportedVersions.length; i++) {
75
 
            if (version.equals(supportedVersions[i])) {
76
 
                return true;
77
 
            }
78
 
        }
79
 
        return false;
80
 
    }
81
 
 
82
 
    public boolean isSupportedVersion(){    
83
 
        try{
84
 
                readVersion();
85
 
                return isSupportedVersion(version);
86
 
        }catch(Exception e){
87
 
                return false;
88
 
        }catch(Error e){
89
 
                return false;
90
 
        }                       
91
 
    }    
92
 
    
93
 
    public Song readSong() throws IOException, GPFormatException {
94
 
        readVersion();
95
 
        if (!isSupportedVersion(version)) {
96
 
            throw new GPFormatException("Unsuported Version");
97
 
        }
98
 
 
99
 
        String title = readStringIntegerPlusOne();
100
 
 
101
 
        String subtitle = readStringIntegerPlusOne();
102
 
 
103
 
        String interpret = readStringIntegerPlusOne();
104
 
 
105
 
        String album = readStringIntegerPlusOne();
106
 
 
107
 
        String songAuthor = readStringIntegerPlusOne();
108
 
 
109
 
        String copyright = readStringIntegerPlusOne();
110
 
 
111
 
        String pieceAuthor = readStringIntegerPlusOne();
112
 
 
113
 
        String instructions = readStringIntegerPlusOne();
114
 
 
115
 
        int nbNotes = readInt();
116
 
        String note = "";
117
 
        for (int i = 0; i < nbNotes; i++) {
118
 
            note += readStringIntegerPlusOne();
119
 
            note += "\n";
120
 
        }
121
 
 
122
 
        //boolean tripletFeel = readBoolean();
123
 
        this.tripletFeel = ((readBoolean())?MeasureHeader.TRIPLET_FEEL_EIGHTH:MeasureHeader.TRIPLET_FEEL_NONE);
124
 
        
125
 
        
126
 
        //----lyrics----
127
 
        int lyricTrack = readInt();
128
 
        Lyric lyric = new Lyric(readInt(),readStringInteger());                
129
 
        for (int i = 0; i < 4; i++) {
130
 
            int measureNumber = readInt();
131
 
            String lines = readStringInteger();
132
 
        }
133
 
        //--------------
134
 
        
135
 
        int tempoValue = readInt();
136
 
 
137
 
        int key = readByte();
138
 
 
139
 
        int octave = readInt();
140
 
 
141
 
        List channels = new ArrayList();
142
 
        int[] instruments = new int[64];
143
 
        for (int i = 0; i < 64; i++) {
144
 
                channels.add(new SongChannel((short)i,
145
 
                                        (short)i, 
146
 
                                        (short)readInt(),
147
 
                                        toChannelShort(readByte()),
148
 
                                        toChannelShort(readByte()),
149
 
                                        toChannelShort(readByte()),
150
 
                                        toChannelShort(readByte()),
151
 
                                        toChannelShort(readByte()),
152
 
                                        toChannelShort(readByte()),
153
 
                                        false,
154
 
                                        false));       
155
 
            byte[] b = { 0, 0 };
156
 
            read(b);
157
 
        }
158
 
 
159
 
        TimeSignature timeSignature = new TimeSignature(4, new Duration(4));
160
 
 
161
 
        int numberOfMeasures = readInt();
162
 
        int numberOfTracks = readInt();
163
 
 
164
 
        List headers = new ArrayList();
165
 
        if (numberOfMeasures > 0) {
166
 
            for (int i = 0; i < numberOfMeasures; i++) {
167
 
                MeasureHeader header = createMeasureHeader((i + 1),timeSignature);
168
 
                headers.add(header);
169
 
            }
170
 
        }
171
 
 
172
 
        List tracks = new ArrayList();
173
 
        for (int number = 1; number <= numberOfTracks; number++) {
174
 
                SongTrack track = createTrack(number, channels,(number == lyricTrack)?lyric:new Lyric());               
175
 
            tracks.add(track);
176
 
        }
177
 
 
178
 
        long nextMeasureStart = 1000;
179
 
        for (int i = 0; i < numberOfMeasures; i++) {
180
 
            MeasureHeader currHeader = (MeasureHeader) headers.get(i);
181
 
            Tempo tempo = new Tempo(tempoValue);
182
 
            currHeader.setStart(nextMeasureStart);
183
 
            for (int j = 0; j < numberOfTracks; j++) {
184
 
                SongTrack track = (SongTrack) tracks.get(j);
185
 
                Measure measure = new Measure(currHeader,new ArrayList(),new ArrayList(),1,0);
186
 
                addMeasureComponents(track.getStrings(), measure, track.getMeasures(), tempo);
187
 
                currHeader.setTempo(tempo);      
188
 
                track.getMeasures().add(measure);
189
 
            }
190
 
            tempoValue = tempo.getValue();
191
 
            nextMeasureStart += currHeader.getLength();
192
 
        }
193
 
 
194
 
        return new Song(title,interpret,album,songAuthor,tracks,headers,Song.MAX_VOLUME);
195
 
    }
196
 
 
197
 
    private long addNotes(long start, List notes, List trackStrings, List currTrackMeasures, Tempo tempo) throws IOException,GPFormatException {
198
 
        NoteEffect effect = new NoteEffect();
199
 
        
200
 
        int header = readUnsignedByte();
201
 
 
202
 
        if ((header & 0x40) != 0) {
203
 
            int beatStatus = readUnsignedByte();
204
 
            boolean emptyBeat = (beatStatus == 0x00);
205
 
            boolean restBeat = (beatStatus == 0x02);
206
 
        }
207
 
 
208
 
        boolean dottedNotes = ((header & 0x01) != 0);
209
 
 
210
 
        Duration duration = parseDuration(readByte());
211
 
        duration.setDotted(dottedNotes);
212
 
 
213
 
        if ((header & 0x20) != 0) {
214
 
            int tuplet = readInt();
215
 
            //-------Verifico el tupleto--------------------
216
 
            switch (tuplet) {
217
 
            case 3:
218
 
                duration.getTupleto().setEnters(3);
219
 
                duration.getTupleto().setTimes(2);
220
 
                break;
221
 
            case 5:
222
 
                duration.getTupleto().setEnters(5);
223
 
                duration.getTupleto().setTimes(4);
224
 
                break;                
225
 
            case 6:
226
 
                duration.getTupleto().setEnters(6);
227
 
                duration.getTupleto().setTimes(4);
228
 
                break;
229
 
            case 7:
230
 
                duration.getTupleto().setEnters(7);
231
 
                duration.getTupleto().setTimes(4);
232
 
                break;
233
 
            case 9:
234
 
                duration.getTupleto().setEnters(9);
235
 
                duration.getTupleto().setTimes(8);
236
 
                break;
237
 
            case 10:
238
 
                duration.getTupleto().setEnters(10);
239
 
                duration.getTupleto().setTimes(8);
240
 
                break;
241
 
            case 11:
242
 
                duration.getTupleto().setEnters(11);
243
 
                duration.getTupleto().setTimes(8);
244
 
                break;
245
 
            case 12:
246
 
                duration.getTupleto().setEnters(12);
247
 
                duration.getTupleto().setTimes(8);
248
 
                break;                  
249
 
            }
250
 
        }
251
 
 
252
 
        if ((header & 0x02) != 0) {
253
 
            readChordDiagram();
254
 
        }
255
 
 
256
 
        if ((header & 0x04) != 0) {
257
 
            String text = readStringIntegerPlusOne();
258
 
        }
259
 
 
260
 
        if ((header & 0x08) != 0) {
261
 
                readBeatEffects(effect,duration);
262
 
        }
263
 
 
264
 
        if ((header & 0x10) != 0) {
265
 
            readMixChange(tempo);
266
 
        }
267
 
 
268
 
        int stringsPlayed = readUnsignedByte();
269
 
        List strings = getPlayedStrings(stringsPlayed, trackStrings);
270
 
 
271
 
        for (int i = strings.size() - 1; i >= 0; i--) {
272
 
            InstrumentString string = (InstrumentString) strings.get(i);
273
 
            Note note = parseNote(start, string, duration, notes, currTrackMeasures,(NoteEffect)effect.clone());
274
 
            if (note != null) {
275
 
                notes.add(note);
276
 
            }
277
 
        }
278
 
 
279
 
        return duration.getTime();
280
 
    }
281
 
 
282
 
    private List getPlayedStrings(int stringsPlayed, List trackStrings) {
283
 
        List strings = new ArrayList();
284
 
        if ((stringsPlayed & (1 << 0)) != 0 && trackStrings.size() > 6) {
285
 
            strings.add(((InstrumentString) trackStrings.get(6)).clone());
286
 
        }
287
 
        if ((stringsPlayed & (1 << 1)) != 0 && trackStrings.size() > 5) {
288
 
            strings.add(((InstrumentString) trackStrings.get(5)).clone());
289
 
        }
290
 
        if ((stringsPlayed & (1 << 2)) != 0 && trackStrings.size() > 4) {
291
 
            strings.add(((InstrumentString) trackStrings.get(4)).clone());
292
 
        }
293
 
        if ((stringsPlayed & (1 << 3)) != 0 && trackStrings.size() > 3) {
294
 
            strings.add(((InstrumentString) trackStrings.get(3)).clone());
295
 
        }
296
 
        if ((stringsPlayed & (1 << 4)) != 0 && trackStrings.size() > 2) {
297
 
            strings.add(((InstrumentString) trackStrings.get(2)).clone());
298
 
        }
299
 
        if ((stringsPlayed & (1 << 5)) != 0 && trackStrings.size() > 1) {
300
 
            strings.add(((InstrumentString) trackStrings.get(1)).clone());
301
 
        }
302
 
        if ((stringsPlayed & (1 << 6)) != 0 && trackStrings.size() > 0) {
303
 
            strings.add(((InstrumentString) trackStrings.get(0)).clone());
304
 
        }
305
 
        return strings;
306
 
    }
307
 
 
308
 
    private Duration parseDuration(byte value) {
309
 
        Duration duration = null;
310
 
        switch (value) {
311
 
        case -2:
312
 
            duration = new Duration(Duration.WHOLE);
313
 
            break;
314
 
        case -1:
315
 
            duration = new Duration(Duration.HALF);
316
 
            break;
317
 
        case 0:
318
 
            duration = new Duration(Duration.QUARTER);
319
 
            break;
320
 
        case 1:
321
 
            duration = new Duration(Duration.EIGHTH);
322
 
            break;
323
 
        case 2:
324
 
            duration = new Duration(Duration.SIXTEENTH);
325
 
            break;
326
 
        case 3:
327
 
            duration = new Duration(Duration.THIRTY_SECOND);
328
 
            break;
329
 
        case 4:
330
 
            duration = new Duration(Duration.SIXTY_FOURTH);
331
 
            break;
332
 
        }
333
 
        if(duration == null){
334
 
                duration = new Duration(Duration.QUARTER);
335
 
                System.err.println("Incorrect Duration. Forcing duration Quarter as Default.");
336
 
        }        
337
 
        return duration;
338
 
    }
339
 
 
340
 
    private int getTiedNoteValue(int string, List notes, List measures) {
341
 
        if (!notes.isEmpty()) {
342
 
            for (int nIdx = notes.size() - 1; nIdx >= 0; nIdx--) {
343
 
                Note note = (Note) notes.get(nIdx);
344
 
                if (note.getString() == string) {
345
 
                    return note.getValue();
346
 
                }
347
 
            }
348
 
        }
349
 
        if (!measures.isEmpty()) {
350
 
            for (int mIdx = measures.size() - 1; mIdx >= 0; mIdx--) {
351
 
                Measure measure = (Measure) measures.get(mIdx);
352
 
                for (int nIdx = measure.getNotes().size() - 1; nIdx >= 0; nIdx--) {
353
 
                    Note note = (Note) measure.getNotes().get(nIdx);
354
 
                    if (note.getString() == string) {
355
 
                        return note.getValue();
356
 
                    }
357
 
                }
358
 
            }
359
 
        }
360
 
        return -1;
361
 
    }
362
 
 
363
 
    private boolean readBoolean() throws IOException {
364
 
        return (read() == 1);
365
 
    }
366
 
 
367
 
    private byte readByte() throws IOException {
368
 
        return (byte) read();
369
 
    }
370
 
 
371
 
    private RGBColor readColor() throws IOException {
372
 
        int r = readUnsignedByte();
373
 
        int g = readUnsignedByte();
374
 
        int b = readUnsignedByte();
375
 
        read();
376
 
        
377
 
        return new RGBColor(r,g,b);
378
 
    }
379
 
 
380
 
    private int readInt() throws IOException {
381
 
        int integer = 0;
382
 
        byte[] b = { 0, 0, 0, 0 };
383
 
 
384
 
        read(b);
385
 
        integer = ((b[3] & 0xff) << 24) | ((b[2] & 0xff) << 16) | ((b[1] & 0xff) << 8) | (b[0] & 0xff);
386
 
 
387
 
        return integer;
388
 
    }
389
 
 
390
 
    private Marker readMarker(int measure) throws IOException {
391
 
        String name = readStringIntegerPlusOne();
392
 
        RGBColor color = readColor();
393
 
        
394
 
        return new Marker(measure,name,color);
395
 
    }
396
 
 
397
 
    private MeasureHeader createMeasureHeader(int number,TimeSignature currTimeSignature) throws IOException {
398
 
        int header = readUnsignedByte();
399
 
 
400
 
        int numerator = 0;
401
 
        if ((header & 0x01) != 0) {
402
 
            numerator = readByte();
403
 
        }
404
 
 
405
 
        int denominator = 0;
406
 
        if ((header & 0x02) != 0) {
407
 
            denominator = readByte();
408
 
        }
409
 
 
410
 
        boolean repeatStart = ((header & 0x04) != 0);
411
 
 
412
 
        int numberOfRepetitions = 0;
413
 
        if ((header & 0x08) != 0) {
414
 
            numberOfRepetitions = readByte();
415
 
        }
416
 
 
417
 
        int NumberOfAlternateEnding = 0;
418
 
        if ((header & 0x10) != 0) {
419
 
            NumberOfAlternateEnding = readByte();
420
 
        }
421
 
 
422
 
        Marker marker = null;
423
 
        if ((header & 0x20) != 0) {
424
 
                marker = readMarker(number);
425
 
        }
426
 
 
427
 
        if ((header & 0x40) != 0) {
428
 
            int type = readByte();
429
 
            readByte();
430
 
        }
431
 
 
432
 
        if ((header & 0x80) != 0) {
433
 
        }
434
 
        
435
 
        boolean doubleBar = ((header & 0x80) != 0);
436
 
 
437
 
        if (numerator > 0) {
438
 
            currTimeSignature.setNumerator(numerator);
439
 
        }
440
 
        if (denominator > 0) {
441
 
            currTimeSignature.setDenominator(new Duration(denominator));
442
 
        }
443
 
        
444
 
        return new MeasureHeader(number,0,(TimeSignature) currTimeSignature.clone(), new Tempo(120),marker,tripletFeel,repeatStart,numberOfRepetitions);
445
 
    }
446
 
 
447
 
    private void addMeasureComponents(List trackStrings, Measure measure, List currTrackMeasures, Tempo tempo) throws IOException,
448
 
            GPFormatException {
449
 
        long nextNoteStart = measure.getStart();
450
 
        int numberOfBeats = readInt();
451
 
        for (int i = 0; i < numberOfBeats; i++) {
452
 
            nextNoteStart += addNotes(nextNoteStart, measure.getNotes(), trackStrings, currTrackMeasures, tempo);
453
 
        }
454
 
 
455
 
    }
456
 
 
457
 
    private Note parseNote(long start, InstrumentString string, Duration currDuration, List currMeasureNotes, List currTrackMeasures,NoteEffect effect)
458
 
            throws IOException {
459
 
        int header = readUnsignedByte();
460
 
                        
461
 
        //boolean accentuated = ((header & 0x40) != 0);        
462
 
        //boolean ghostNote = ((header & 0x04) != 0);
463
 
        boolean dotted = ((header & 0x02) != 0);
464
 
        
465
 
        effect.setAccentuatedNote(((header & 0x40) != 0));
466
 
        effect.setGhostNote(((header & 0x04) != 0));
467
 
        
468
 
        boolean tiedNote = false;
469
 
        boolean deadNote = false;
470
 
        if ((header & 0x20) != 0) {             
471
 
            int noteType = readUnsignedByte();
472
 
            tiedNote = (noteType == 0x02);
473
 
            effect.setDeadNote((noteType == 0x03));                        
474
 
        }
475
 
 
476
 
        if ((header & 0x01) != 0) {             
477
 
            byte duration = readByte();
478
 
            byte tuplet = readByte();
479
 
        }
480
 
 
481
 
        int velocity = VelocityValues.DEFAULT;
482
 
        if ((header & 0x10) != 0) {
483
 
                velocity = (VelocityValues.MIN_VELOCITY + (VelocityValues.VELOCITY_INCREMENT * readByte())) - VelocityValues.VELOCITY_INCREMENT;            
484
 
        }
485
 
 
486
 
        byte numberOfFret = 0;
487
 
        if ((header & 0x20) != 0) {
488
 
            numberOfFret = readByte();
489
 
        }
490
 
 
491
 
        if ((header & 0x80) != 0) {
492
 
            byte fingeringLeftHand = readByte();
493
 
            byte fingeringRightHand = readByte();
494
 
        }
495
 
 
496
 
        if ((header & 0x08) != 0) {
497
 
            readNoteEffects(effect,currDuration);
498
 
        }
499
 
 
500
 
        int value = numberOfFret;
501
 
        if (numberOfFret >= 0 || tiedNote) {
502
 
            if (tiedNote) {
503
 
                value = getTiedNoteValue(string.getNumber(), currMeasureNotes, currTrackMeasures);
504
 
            }
505
 
 
506
 
            return new Note(value, start, (Duration) currDuration.clone(), velocity, string.getNumber(),tiedNote,effect);
507
 
        }
508
 
 
509
 
        return null;
510
 
    }
511
 
 
512
 
    private String readStringByte(int expectedLength) throws IOException {
513
 
        byte[] bytes;
514
 
        int realLength = readUnsignedByte();
515
 
 
516
 
        if (expectedLength != 0) {
517
 
                bytes = new byte[expectedLength];
518
 
        } else {
519
 
                bytes = new byte[realLength];
520
 
        }
521
 
        read(bytes);
522
 
        
523
 
        realLength = (realLength >= 0)?realLength:expectedLength;
524
 
        return new String(bytes, 0, realLength); 
525
 
    }
526
 
 
527
 
    private String readStringInteger() throws IOException {
528
 
        byte[] b;
529
 
        String str;
530
 
        int length = readInt();
531
 
 
532
 
        b = new byte[length];
533
 
        read(b);
534
 
 
535
 
        str = new String(b);
536
 
        return str;
537
 
    }
538
 
 
539
 
    private String readStringIntegerPlusOne() throws IOException {
540
 
        byte[] b;
541
 
        String str;
542
 
        int lengthPlusOne = readInt();
543
 
        int length = lengthPlusOne - 1;
544
 
 
545
 
        if (length != read()) {
546
 
            throw new IOException();
547
 
        }
548
 
 
549
 
        b = new byte[length];
550
 
        read(b);
551
 
 
552
 
        str = new String(b);
553
 
        return str;
554
 
    }
555
 
 
556
 
    private SongTrack createTrack(int number, List channels,Lyric lyrics) throws IOException {
557
 
        int header = readUnsignedByte();
558
 
 
559
 
        boolean isDrumsTrack = ((header & 0x01) != 0);
560
 
        boolean is12StringedGuitarTrack = ((header & 0x02) != 0);
561
 
        boolean isBanjoTrack = ((header & 0x04) != 0);
562
 
 
563
 
        String name = readStringByte(40);
564
 
 
565
 
        int numberOfStrings = readInt();
566
 
 
567
 
        List strings = new ArrayList(numberOfStrings);
568
 
 
569
 
        for (int i = 0; i < 7; i++) {
570
 
            int tunning = readInt();
571
 
            if (numberOfStrings > i) {
572
 
                strings.add(new InstrumentString(i + 1, tunning));
573
 
            }
574
 
        }
575
 
 
576
 
        int port = readInt();
577
 
 
578
 
        int channelIndex = readInt();
579
 
 
580
 
        int effects = readInt();
581
 
 
582
 
        int numberOfFrets = readInt();
583
 
 
584
 
        int capo = readInt();
585
 
 
586
 
        RGBColor color = readColor();
587
 
        
588
 
        return new SongTrack(number,name,parseChannel(channels,channelIndex,effects), new ArrayList(), strings,capo,color,lyrics);
589
 
    }
590
 
    
591
 
    private SongChannel parseChannel(List channels, int channelIndex,int effectChannel) {
592
 
        SongChannel channel = (SongChannel) channels.get(channelIndex - 1);
593
 
 
594
 
        int instrument = channel.getInstrument();
595
 
        if (instrument == -1) {
596
 
            channel.setInstrument((short)0);
597
 
        }
598
 
        if(!channel.isPercusionChannel()){
599
 
                channel.setEffectChannel((short)(effectChannel - 1));
600
 
        }
601
 
        
602
 
        return channel;
603
 
    }
604
 
 
605
 
 
606
 
    private int readUnsignedByte() throws IOException {
607
 
        return read();
608
 
    }
609
 
 
610
 
    private void readChordType() throws IOException {
611
 
        readUnsignedByte();
612
 
    }
613
 
 
614
 
    private void readRoot() throws IOException {
615
 
        readByte();
616
 
    }
617
 
 
618
 
    private void readTonalityType(int numBytes) throws IOException {
619
 
        if (numBytes == 1) {
620
 
            int type = readUnsignedByte();
621
 
        } else if (numBytes == 4) {
622
 
            int type = readInt();
623
 
        }
624
 
    }
625
 
 
626
 
    private String readChordName() throws IOException {
627
 
        byte[] nameB;
628
 
        char[] nameC;
629
 
        int i;
630
 
        int max;
631
 
 
632
 
        nameB = new byte[21];
633
 
        nameC = new char[20];
634
 
        read(nameB, 0, 21);
635
 
        max = 20;
636
 
        if (nameB[0] < max) {
637
 
            max = nameB[0];
638
 
        }
639
 
 
640
 
        for (i = 1; i <= max; i++) {
641
 
            nameC[i - 1] = (char) nameB[i];
642
 
        }
643
 
        return (String.valueOf(nameC, 0, max));
644
 
    }
645
 
 
646
 
    private void readChordDiagram() throws IOException, GPFormatException {        
647
 
        int header = readUnsignedByte();
648
 
 
649
 
        if ((header & 0x01) == 0) {
650
 
            String name = readStringIntegerPlusOne();
651
 
            int base = readInt();
652
 
 
653
 
            if (base != 0) {
654
 
                for (int i = 0; i < 6; i++) {
655
 
                    int fret = readInt();
656
 
                }
657
 
            }
658
 
            //new GPFormatException("Cannot Read Chord Diagram");         
659
 
        }else{
660
 
 
661
 
                boolean sharp = readBoolean();
662
 
 
663
 
                this.skip(3);
664
 
 
665
 
                readRoot();
666
 
 
667
 
                readChordType();
668
 
 
669
 
                int nineElevenThirteen = readUnsignedByte();
670
 
 
671
 
                int bass = readInt();
672
 
 
673
 
                readTonalityType(4);
674
 
 
675
 
                int addedNote = readUnsignedByte();
676
 
 
677
 
                String name = readChordName();
678
 
 
679
 
                this.skip(2);
680
 
 
681
 
                readTonalityType(1);
682
 
 
683
 
                readTonalityType(1);
684
 
 
685
 
                readTonalityType(1);
686
 
 
687
 
                int baseFret = readInt();
688
 
 
689
 
                for (int i = 1; i <= 7; i++) {
690
 
                        int fret = readInt();
691
 
                }
692
 
 
693
 
                int numBarres = readUnsignedByte();
694
 
 
695
 
                for (int i = 1; i <= 5; i++) {
696
 
                        int fretOfBarre = readUnsignedByte();
697
 
                }
698
 
                for (int i = 1; i <= 5; i++) {
699
 
                        int barreStart = readUnsignedByte();
700
 
                }
701
 
                for (int i = 1; i <= 5; i++) {
702
 
                        int barreEnd = readUnsignedByte();
703
 
                }
704
 
 
705
 
            this.skip(8);
706
 
                
707
 
            for (int i = 1; i <= 7; i++) {
708
 
                        int fingering = readByte();
709
 
                }
710
 
                
711
 
            boolean chordFingeringDisplayed = readBoolean();
712
 
        }
713
 
    }
714
 
 
715
 
    private void readGraceNote(NoteEffect effect) throws IOException {          
716
 
        int fret = readUnsignedByte();          
717
 
        int velocity = readUnsignedByte();
718
 
        int transition = readUnsignedByte();            
719
 
        int duration = readUnsignedByte();
720
 
        
721
 
        //dead
722
 
        boolean dead = (fret == 255);
723
 
        
724
 
        //fret
725
 
        fret = ((!dead)?fret:0);
726
 
        
727
 
        //velocity      
728
 
        velocity = (VelocityValues.MIN_VELOCITY + (VelocityValues.VELOCITY_INCREMENT * velocity)) - VelocityValues.VELOCITY_INCREMENT;
729
 
        
730
 
        //transition
731
 
        if(transition == 0){
732
 
                transition = GraceEffect.TRANSITION_NONE;
733
 
        }
734
 
        else if(transition == 1){
735
 
                transition = GraceEffect.TRANSITION_SLIDE;
736
 
        }
737
 
        else if(transition == 2){
738
 
                transition = GraceEffect.TRANSITION_BEND;
739
 
        }
740
 
        else if(transition == 3){
741
 
                transition = GraceEffect.TRANSITION_HAMMER;
742
 
        }
743
 
        
744
 
        effect.setGrace(new GraceEffect(fret,duration,velocity,transition,false,dead));                 
745
 
    }
746
 
 
747
 
    private void readBend(NoteEffect effect,Duration duration) throws IOException {
748
 
        byte type = readByte();
749
 
        int value = readInt();
750
 
        
751
 
        BendEffect bend = new BendEffect();        
752
 
        int numPoints = readInt();
753
 
        for (int i = 0; i < numPoints; i++) {            
754
 
            int bendPosition = readInt();
755
 
            int bendValue = readInt();
756
 
            byte bendVibrato = readByte();
757
 
 
758
 
            bend.addPoint((int)(bendPosition * BendEffect.MAX_POSITION_LENGTH / GP_BEND_POSITION),(bendValue * BendEffect.SEMITONE_LENGTH / GP_BEND_SEMITONE));           
759
 
        }
760
 
        if(!bend.getPoints().isEmpty()){
761
 
            effect.setBend(bend);
762
 
        }        
763
 
    }
764
 
 
765
 
    private void readTremoloBar(NoteEffect effect,Duration duration) throws IOException {
766
 
        byte type = readByte();
767
 
        int value = readInt();
768
 
        
769
 
        TremoloBarEffect tremoloBar = new TremoloBarEffect();        
770
 
        int numPoints = readInt();
771
 
        for (int i = 0; i < numPoints; i++) {            
772
 
            int bendPosition = readInt();
773
 
            int bendValue = readInt();
774
 
            byte bendVibrato = readByte();
775
 
 
776
 
            tremoloBar.addPoint((int)(bendPosition * TremoloBarEffect.MAX_POSITION_LENGTH / GP_BEND_POSITION),(bendValue * TremoloBarEffect.SEMITONE_LENGTH / GP_BEND_SEMITONE));           
777
 
        }
778
 
        if(!tremoloBar.getPoints().isEmpty()){
779
 
            effect.setTremoloBar(tremoloBar);
780
 
        }        
781
 
    }    
782
 
 
783
 
    public void readTremoloPicking(NoteEffect effect) throws IOException{               
784
 
        int duration = readUnsignedByte();      
785
 
        if(duration == 1){
786
 
                        effect.setTremoloPicking(new TremoloPickingEffect(new Duration(Duration.EIGHTH)));
787
 
                }else if(duration == 2){
788
 
                        effect.setTremoloPicking(new TremoloPickingEffect(new Duration(Duration.SIXTEENTH)));
789
 
                }else if(duration == 3){
790
 
                        effect.setTremoloPicking(new TremoloPickingEffect(new Duration(Duration.THIRTY_SECOND)));
791
 
                }
792
 
        }
793
 
    
794
 
    private void readNoteEffects(NoteEffect noteEffect,Duration duration) throws IOException {
795
 
        int header1;
796
 
        int header2;
797
 
        int b;
798
 
 
799
 
        header1 = readUnsignedByte();
800
 
        header2 = readUnsignedByte();
801
 
 
802
 
        if ((header1 & 0x01) != 0) {
803
 
            readBend(noteEffect,duration);
804
 
        }
805
 
 
806
 
        if ((header1 & 0x10) != 0) {            
807
 
            readGraceNote(noteEffect);
808
 
        }
809
 
 
810
 
        if ((header2 & 0x04) != 0) {
811
 
                readTremoloPicking(noteEffect);
812
 
        }
813
 
 
814
 
        if ((header2 & 0x08) != 0) {
815
 
            noteEffect.setSlide(true);
816
 
            readByte();            
817
 
        }
818
 
        
819
 
        if ((header2 & 0x10) != 0) {            
820
 
            b = readByte();
821
 
            if(b == 1){
822
 
                noteEffect.setHarmonic(new HarmonicEffect(HarmonicEffect.TYPE_NATURAL));
823
 
            }else if(b == 3){
824
 
                noteEffect.setHarmonic(new HarmonicEffect(HarmonicEffect.TYPE_TAPPED));
825
 
            }else if(b == 4){
826
 
                noteEffect.setHarmonic(new HarmonicEffect(HarmonicEffect.TYPE_PINCH));
827
 
            }else if(b == 5){
828
 
                noteEffect.setHarmonic(new HarmonicEffect(HarmonicEffect.TYPE_SEMI));
829
 
            }else if(b == 15){
830
 
                noteEffect.setHarmonic(new HarmonicEffect(HarmonicEffect.TYPE_ARTIFICIAL,19));
831
 
            }else if(b == 17){
832
 
                noteEffect.setHarmonic(new HarmonicEffect(HarmonicEffect.TYPE_ARTIFICIAL,24));
833
 
            }else if(b == 22){
834
 
                noteEffect.setHarmonic(new HarmonicEffect(HarmonicEffect.TYPE_ARTIFICIAL,12));
835
 
            }
836
 
        }
837
 
 
838
 
        //trill
839
 
        if ((header2 & 0x20) != 0) {
840
 
            byte fret = readByte();
841
 
            byte period = readByte();            
842
 
                if(period == 1){
843
 
                        noteEffect.setTrill(new TrillEffect(fret,new Duration(Duration.SIXTEENTH)));            
844
 
                }else if(period == 2){
845
 
                        noteEffect.setTrill(new TrillEffect(fret,new Duration(Duration.THIRTY_SECOND)));
846
 
                }else if(period == 3){
847
 
                        noteEffect.setTrill(new TrillEffect(fret,new Duration(Duration.SIXTY_FOURTH)));
848
 
                }                   
849
 
        }
850
 
 
851
 
        if ((header1 & 0x08) != 0) {            
852
 
        }
853
 
 
854
 
        //hammer
855
 
        noteEffect.setHammer(((header1 & 0x02) != 0));
856
 
 
857
 
        //vibrato        
858
 
        noteEffect.setVibrato(((header2 & 0x40) != 0) || noteEffect.isVibrato());
859
 
 
860
 
        //palm-mute        
861
 
        noteEffect.setPalmMute(((header2 & 0x02) != 0));
862
 
 
863
 
        //staccato
864
 
        noteEffect.setStaccato(((header2 & 0x01) != 0));
865
 
 
866
 
    }
867
 
 
868
 
    private void readBeatEffects(NoteEffect noteEffect,Duration currDuration) throws IOException {
869
 
        int header[] = { 0, 0 };
870
 
 
871
 
        header[0] = readUnsignedByte();
872
 
        header[1] = readUnsignedByte();
873
 
 
874
 
        noteEffect.setFadeIn(((header[0] & 0x10) != 0));
875
 
        noteEffect.setVibrato(((header[0]  & 0x02) != 0)); 
876
 
        
877
 
        if ((header[0] & 0x20) != 0) {
878
 
            int effect = readUnsignedByte();            
879
 
            noteEffect.setTapping(effect == 1);
880
 
            noteEffect.setSlapping(effect == 2);
881
 
            noteEffect.setPopping(effect == 3);            
882
 
        }
883
 
 
884
 
        if ((header[1] & 0x04) != 0) {          
885
 
            readTremoloBar(noteEffect,currDuration);
886
 
        }
887
 
 
888
 
        if ((header[0] & 0x40) != 0) {
889
 
                //Upstroke - Downstroke
890
 
            readByte();
891
 
            readByte();
892
 
        }
893
 
 
894
 
        if ((header[1] & 0x01) != 0) {
895
 
            //Rasgueado
896
 
        }
897
 
 
898
 
        if ((header[1] & 0x02) != 0) {
899
 
            //Pickstroke
900
 
            readByte();
901
 
        }
902
 
        
903
 
 
904
 
    }
905
 
 
906
 
    private void readMixChange(Tempo tempo) throws IOException {
907
 
        int pos[] = new int[8];
908
 
        int i;
909
 
        int n;
910
 
        int aux;
911
 
        n = 0;
912
 
        for (i = 0; i < 7; i++) {
913
 
            aux = readByte();
914
 
            if ((i != 0) && (aux != -1)) {
915
 
                pos[n] = i;
916
 
                n++;
917
 
            }
918
 
        }
919
 
        aux = readInt();
920
 
        if (aux != -1) {
921
 
            tempo.setValue(aux);
922
 
            pos[n] = i;
923
 
            n++;
924
 
        }
925
 
 
926
 
        for (i = 0; i < n; i++) {
927
 
            aux = readByte();
928
 
        }
929
 
        int applyToAllTracks = readUnsignedByte();
930
 
    }
931
 
    
932
 
    private short toChannelShort(byte b){
933
 
        short s = (short)b;
934
 
        s = (short)((s * (short)127) / (short)16);
935
 
        return (s <= 127)?s:127;
936
 
    }
937
 
 
938
 
}
939