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

« back to all changes in this revision

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