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

« back to all changes in this revision

Viewing changes to TuxGuitar-gtp/src/org/herac/tuxguitar/io/gtp/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.gtp;
 
2
 
 
3
import java.io.IOException;
 
4
import java.util.ArrayList;
 
5
import java.util.Iterator;
 
6
import java.util.List;
 
7
 
 
8
import org.herac.tuxguitar.io.base.TGFileFormat;
 
9
import org.herac.tuxguitar.io.base.TGInputStreamBase;
 
10
import org.herac.tuxguitar.song.models.TGBeat;
 
11
import org.herac.tuxguitar.song.models.TGChannel;
 
12
import org.herac.tuxguitar.song.models.TGChord;
 
13
import org.herac.tuxguitar.song.models.TGColor;
 
14
import org.herac.tuxguitar.song.models.TGDuration;
 
15
import org.herac.tuxguitar.song.models.TGLyric;
 
16
import org.herac.tuxguitar.song.models.TGMarker;
 
17
import org.herac.tuxguitar.song.models.TGMeasure;
 
18
import org.herac.tuxguitar.song.models.TGMeasureHeader;
 
19
import org.herac.tuxguitar.song.models.TGNote;
 
20
import org.herac.tuxguitar.song.models.TGNoteEffect;
 
21
import org.herac.tuxguitar.song.models.TGSong;
 
22
import org.herac.tuxguitar.song.models.TGString;
 
23
import org.herac.tuxguitar.song.models.TGTempo;
 
24
import org.herac.tuxguitar.song.models.TGText;
 
25
import org.herac.tuxguitar.song.models.TGTimeSignature;
 
26
import org.herac.tuxguitar.song.models.TGTrack;
 
27
import org.herac.tuxguitar.song.models.TGVelocities;
 
28
import org.herac.tuxguitar.song.models.effects.TGEffectBend;
 
29
import org.herac.tuxguitar.song.models.effects.TGEffectGrace;
 
30
import org.herac.tuxguitar.song.models.effects.TGEffectHarmonic;
 
31
import org.herac.tuxguitar.song.models.effects.TGEffectTremoloBar;
 
32
import org.herac.tuxguitar.song.models.effects.TGEffectTremoloPicking;
 
33
import org.herac.tuxguitar.song.models.effects.TGEffectTrill;
 
34
 
 
35
public class GP4InputStream extends GTPInputStream implements TGInputStreamBase {
 
36
        private static final String SUPPORTED_VERSIONS[] = { "FICHIER GUITAR PRO v4.00", "FICHIER GUITAR PRO v4.06", "FICHIER GUITAR PRO L4.06" };
 
37
        private static final float GP_BEND_SEMITONE = 25f;
 
38
        private static final float GP_BEND_POSITION = 60f;
 
39
        
 
40
        private int tripletFeel;
 
41
        
 
42
        public GP4InputStream(){
 
43
                super(SUPPORTED_VERSIONS);
 
44
        }
 
45
        
 
46
        public TGFileFormat getFileFormat(){
 
47
                return new TGFileFormat("Guitar Pro 4","*.gp4");
 
48
        }
 
49
        
 
50
        public TGSong readSong() throws IOException, GTPFormatException {
 
51
                readVersion();
 
52
                if (!isSupportedVersion(getVersion())) {
 
53
                        this.close();
 
54
                        throw new GTPFormatException("Unsuported Version");
 
55
                }
 
56
                TGSong song = getFactory().newSong();
 
57
                
 
58
                readInfo(song);
 
59
                
 
60
                this.tripletFeel = ((readBoolean())?TGMeasureHeader.TRIPLET_FEEL_EIGHTH:TGMeasureHeader.TRIPLET_FEEL_NONE);
 
61
                
 
62
                int lyricTrack = readInt();
 
63
                TGLyric lyric = readLyrics();
 
64
                
 
65
                int tempoValue = readInt();
 
66
                
 
67
                readInt(); //key
 
68
                
 
69
                readByte(); //octave
 
70
                
 
71
                List channels = readChannels();
 
72
                
 
73
                int measures = readInt();
 
74
                int tracks = readInt();
 
75
                
 
76
                readMeasureHeaders(song, measures);
 
77
                readTracks(song, tracks, channels, lyric, lyricTrack);
 
78
                readMeasures(song, measures, tracks, tempoValue);
 
79
                
 
80
                this.close();
 
81
                
 
82
                return song;
 
83
        }
 
84
        
 
85
        private void readInfo(TGSong song) throws IOException{
 
86
                song.setName(readStringByteSizeOfInteger());
 
87
                readStringByteSizeOfInteger();
 
88
                song.setArtist(readStringByteSizeOfInteger());
 
89
                song.setAlbum(readStringByteSizeOfInteger());
 
90
                song.setAuthor(readStringByteSizeOfInteger());
 
91
                readStringByteSizeOfInteger();
 
92
                readStringByteSizeOfInteger();
 
93
                readStringByteSizeOfInteger();
 
94
                int notes = readInt();
 
95
                for (int i = 0; i < notes; i++) {
 
96
                        readStringByteSizeOfInteger();
 
97
                }
 
98
        }
 
99
        
 
100
        private void readMeasureHeaders(TGSong song, int count) throws IOException{
 
101
                TGTimeSignature timeSignature = getFactory().newTimeSignature();
 
102
                for (int i = 0; i < count; i++) {
 
103
                        song.addMeasureHeader(readMeasureHeader((i + 1),song,timeSignature));
 
104
                }
 
105
        }
 
106
        
 
107
        private void readTracks(TGSong song, int count, List channels,TGLyric lyric, int lyricTrack) throws IOException{
 
108
                for (int number = 1; number <= count; number++) {
 
109
                        song.addTrack(readTrack(number, channels,(number == lyricTrack)?lyric:getFactory().newLyric()));
 
110
                }
 
111
        }
 
112
        
 
113
        private void readMeasures(TGSong song, int measures, int tracks, int tempoValue) throws IOException{
 
114
                TGTempo tempo = getFactory().newTempo();
 
115
                tempo.setValue(tempoValue);
 
116
                long start = TGDuration.QUARTER_TIME;
 
117
                for (int i = 0; i < measures; i++) {
 
118
                        TGMeasureHeader header = song.getMeasureHeader(i);
 
119
                        header.setStart(start);
 
120
                        for (int j = 0; j < tracks; j++) {
 
121
                                TGTrack track = song.getTrack(j);
 
122
                                TGMeasure measure = getFactory().newMeasure(header);
 
123
                                track.addMeasure(measure);
 
124
                                readMeasure(measure, track, tempo);
 
125
                        }
 
126
                        tempo.copy(header.getTempo());
 
127
                        start += header.getLength();
 
128
                }
 
129
        }
 
130
        
 
131
        private TGLyric readLyrics() throws IOException{
 
132
                TGLyric lyric = getFactory().newLyric();
 
133
                lyric.setFrom(readInt());
 
134
                lyric.setLyrics(readStringInteger());
 
135
                for (int i = 0; i < 4; i++) {
 
136
                        readInt();
 
137
                        readStringInteger();
 
138
                }
 
139
                return lyric;
 
140
        }
 
141
        
 
142
        private List readChannels() throws IOException{
 
143
                List channels = new ArrayList();
 
144
                for (int i = 0; i < 64; i++) {
 
145
                        TGChannel channel = getFactory().newChannel();
 
146
                        channel.setChannel((short)i);
 
147
                        channel.setEffectChannel((short)i);
 
148
                        channel.setInstrument((short)readInt());
 
149
                        channel.setVolume(toChannelShort(readByte()));
 
150
                        channel.setBalance(toChannelShort(readByte()));
 
151
                        channel.setChorus(toChannelShort(readByte()));
 
152
                        channel.setReverb(toChannelShort(readByte()));
 
153
                        channel.setPhaser(toChannelShort(readByte()));
 
154
                        channel.setTremolo(toChannelShort(readByte()));
 
155
                        channel.setSolo(false);
 
156
                        channel.setMute(false);
 
157
                        channels.add(channel);
 
158
                        skip(2);
 
159
                }
 
160
                return channels;
 
161
        }
 
162
        
 
163
        private long readBeat(long start, TGMeasure measure,TGTrack track, TGTempo tempo) throws IOException {
 
164
                int flags = readUnsignedByte();
 
165
                if((flags & 0x40) != 0){
 
166
                        readUnsignedByte();
 
167
                }
 
168
                
 
169
                TGBeat beat = getFactory().newBeat();
 
170
                TGDuration duration = readDuration(flags);
 
171
                TGNoteEffect effect = getFactory().newEffect();
 
172
                if ((flags & 0x02) != 0) {
 
173
                        readChord(track.stringCount(), beat);
 
174
                }
 
175
                if ((flags & 0x04) != 0) {
 
176
                        readText(beat);
 
177
                }
 
178
                if ((flags & 0x08) != 0) {
 
179
                        readBeatEffects(effect);
 
180
                }
 
181
                if ((flags & 0x10) != 0) {
 
182
                        readMixChange(tempo);
 
183
                }
 
184
                int stringFlags = readUnsignedByte();
 
185
                for (int i = 6; i >= 0; i--) {
 
186
                        if ((stringFlags & (1 << i)) != 0 && (6 - i) < track.stringCount()) {
 
187
                                TGString string = track.getString( (6 - i) + 1 ).clone(getFactory());
 
188
                                TGNote note = readNote(string, track,effect.clone(getFactory()));
 
189
                                beat.addNote(note);
 
190
                        }
 
191
                }
 
192
                beat.setStart(start);
 
193
                duration.copy(beat.getDuration());
 
194
                measure.addBeat(beat);
 
195
                
 
196
                return duration.getTime();
 
197
        }
 
198
        
 
199
        private void readText(TGBeat beat) throws IOException{
 
200
                TGText text = getFactory().newText();
 
201
                text.setValue(readStringByteSizeOfInteger());
 
202
                beat.setText(text);
 
203
        }
 
204
        
 
205
        private TGDuration readDuration(int flags) throws IOException {
 
206
                TGDuration duration = getFactory().newDuration();
 
207
                duration.setValue( (int) (Math.pow( 2 , (readByte() + 4) ) / 4 ) );
 
208
                duration.setDotted(((flags & 0x01) != 0));
 
209
                if ((flags & 0x20) != 0) {
 
210
                        int tuplet = readInt();
 
211
                        switch (tuplet) {
 
212
                        case 3:
 
213
                                duration.getTupleto().setEnters(3);
 
214
                                duration.getTupleto().setTimes(2);
 
215
                                break;
 
216
                        case 5:
 
217
                                duration.getTupleto().setEnters(5);
 
218
                                duration.getTupleto().setTimes(4);
 
219
                                break;
 
220
                        case 6:
 
221
                                duration.getTupleto().setEnters(6);
 
222
                                duration.getTupleto().setTimes(4);
 
223
                                break;
 
224
                        case 7:
 
225
                                duration.getTupleto().setEnters(7);
 
226
                                duration.getTupleto().setTimes(4);
 
227
                                break;
 
228
                        case 9:
 
229
                                duration.getTupleto().setEnters(9);
 
230
                                duration.getTupleto().setTimes(8);
 
231
                                break;
 
232
                        case 10:
 
233
                                duration.getTupleto().setEnters(10);
 
234
                                duration.getTupleto().setTimes(8);
 
235
                                break;
 
236
                        case 11:
 
237
                                duration.getTupleto().setEnters(11);
 
238
                                duration.getTupleto().setTimes(8);
 
239
                                break;
 
240
                        case 12:
 
241
                                duration.getTupleto().setEnters(12);
 
242
                                duration.getTupleto().setTimes(8);
 
243
                                break;
 
244
                        }
 
245
                }
 
246
                return duration;
 
247
        }
 
248
        
 
249
        private int getTiedNoteValue(int string, TGTrack track) {
 
250
                int measureCount = track.countMeasures();
 
251
                if (measureCount > 0) {
 
252
                        for (int m = measureCount - 1; m >= 0; m--) {
 
253
                                TGMeasure measure = track.getMeasure( m );
 
254
                                for (int b = measure.countBeats() - 1; b >= 0; b--) {
 
255
                                        TGBeat beat = measure.getBeat( b );
 
256
                                        for (int n = 0; n < beat.countNotes(); n ++) {
 
257
                                                TGNote note = beat.getNote( n );
 
258
                                                if (note.getString() == string) {
 
259
                                                        return note.getValue();
 
260
                                                }
 
261
                                        }
 
262
                                }
 
263
                        }
 
264
                }
 
265
                return -1;
 
266
        }
 
267
        
 
268
        private void readColor(TGColor color) throws IOException {
 
269
                color.setR(readUnsignedByte());
 
270
                color.setG(readUnsignedByte());
 
271
                color.setB(readUnsignedByte());
 
272
                read();
 
273
        }
 
274
        
 
275
        private TGMarker readMarker(int measure) throws IOException {
 
276
                TGMarker marker = getFactory().newMarker();
 
277
                marker.setMeasure(measure);
 
278
                marker.setTitle(readStringByteSizeOfInteger());
 
279
                readColor(marker.getColor());
 
280
                return marker;
 
281
        }
 
282
        
 
283
        private TGMeasureHeader readMeasureHeader(int number,TGSong song,TGTimeSignature timeSignature) throws IOException {
 
284
                int flags = readUnsignedByte();
 
285
                TGMeasureHeader header = getFactory().newHeader();
 
286
                header.setNumber(number);
 
287
                header.setStart(0);
 
288
                header.getTempo().setValue(120);
 
289
                header.setTripletFeel(this.tripletFeel);
 
290
                header.setRepeatOpen( ((flags & 0x04) != 0) );
 
291
                if ((flags & 0x01) != 0) {
 
292
                        timeSignature.setNumerator(readByte());
 
293
                }
 
294
                if ((flags & 0x02) != 0) {
 
295
                        timeSignature.getDenominator().setValue(readByte());
 
296
                }
 
297
                timeSignature.copy(header.getTimeSignature());
 
298
                if ((flags & 0x08) != 0) {
 
299
                        header.setRepeatClose(readByte());
 
300
                }
 
301
                if ((flags & 0x10) != 0) {
 
302
                        header.setRepeatAlternative(parseRepeatAlternative(song, number, readUnsignedByte()));
 
303
                }
 
304
                if ((flags & 0x20) != 0) {
 
305
                        header.setMarker(readMarker(number));
 
306
                }
 
307
                if ((flags & 0x40) != 0) {
 
308
                        readByte();
 
309
                        readByte();
 
310
                }
 
311
                return header;
 
312
        }
 
313
        
 
314
        private void readMeasure(TGMeasure measure,TGTrack track, TGTempo tempo) throws IOException{
 
315
                long nextNoteStart = measure.getStart();
 
316
                int numberOfBeats = readInt();
 
317
                for (int i = 0; i < numberOfBeats; i++) {
 
318
                        nextNoteStart += readBeat(nextNoteStart, measure, track, tempo);
 
319
                }
 
320
        }
 
321
        
 
322
        private TGNote readNote(TGString string, TGTrack track,TGNoteEffect effect)throws IOException {
 
323
                int flags = readUnsignedByte();
 
324
                TGNote note = getFactory().newNote();
 
325
                note.setString(string.getNumber());
 
326
                note.setEffect(effect);
 
327
                note.getEffect().setAccentuatedNote(((flags & 0x40) != 0));
 
328
                note.getEffect().setGhostNote(((flags & 0x04) != 0));
 
329
                if ((flags & 0x20) != 0) {
 
330
                        int noteType = readUnsignedByte();
 
331
                        note.setTiedNote( (noteType == 0x02) );
 
332
                        note.getEffect().setDeadNote((noteType == 0x03));
 
333
                }
 
334
                if ((flags & 0x01) != 0) {
 
335
                        skip(2);
 
336
                }
 
337
                if ((flags & 0x10) != 0) {
 
338
                        note.setVelocity((TGVelocities.MIN_VELOCITY + (TGVelocities.VELOCITY_INCREMENT * readByte())) - TGVelocities.VELOCITY_INCREMENT);
 
339
                }
 
340
                if ((flags & 0x20) != 0) {
 
341
                        int fret = readByte();
 
342
                        int value = ( note.isTiedNote() ? getTiedNoteValue(string.getNumber(), track) : fret );
 
343
                        note.setValue( value >= 0 && value < 100 ? value : 0 );
 
344
                }
 
345
                if ((flags & 0x80) != 0) {
 
346
                        skip(2);
 
347
                }
 
348
                if ((flags & 0x08) != 0) {
 
349
                        readNoteEffects(note.getEffect());
 
350
                }
 
351
                return note;
 
352
        }
 
353
        
 
354
        private TGTrack readTrack(int number, List channels,TGLyric lyrics) throws IOException {
 
355
                TGTrack track = getFactory().newTrack();
 
356
                track.setNumber(number);
 
357
                track.setLyrics(lyrics);
 
358
                readUnsignedByte();
 
359
                track.setName(readStringByte(40));
 
360
                int stringCount = readInt();
 
361
                for (int i = 0; i < 7; i++) {
 
362
                        int tuning = readInt();
 
363
                        if (stringCount > i) {
 
364
                                TGString string = getFactory().newString();
 
365
                                string.setNumber(i + 1);
 
366
                                string.setValue(tuning);
 
367
                                track.getStrings().add(string);
 
368
                        }
 
369
                }
 
370
                readInt();
 
371
                readChannel(track.getChannel(), channels);
 
372
                readInt();
 
373
                track.setOffset(readInt());
 
374
                readColor(track.getColor());
 
375
                return track;
 
376
        }
 
377
        
 
378
        private void readChannel(TGChannel channel,List channels) throws IOException {
 
379
                int index = (readInt() - 1);
 
380
                int effectChannel = (readInt() - 1);
 
381
                if(index >= 0 && index < channels.size()){
 
382
                        ((TGChannel) channels.get(index)).copy(channel);
 
383
                        if (channel.getInstrument() < 0) {
 
384
                                channel.setInstrument((short)0);
 
385
                        }
 
386
                        if(!channel.isPercussionChannel()){
 
387
                                channel.setEffectChannel((short)effectChannel);
 
388
                        }
 
389
                }
 
390
        }
 
391
        
 
392
        private int parseRepeatAlternative(TGSong song,int measure,int value){
 
393
                int repeatAlternative = 0;
 
394
                int existentAlternatives = 0;
 
395
                Iterator it = song.getMeasureHeaders();
 
396
                while(it.hasNext()){
 
397
                        TGMeasureHeader header = (TGMeasureHeader)it.next();
 
398
                        if(header.getNumber() == measure){
 
399
                                break;
 
400
                        }
 
401
                        if(header.isRepeatOpen()){
 
402
                                existentAlternatives = 0;
 
403
                        }
 
404
                        existentAlternatives |= header.getRepeatAlternative();
 
405
                }
 
406
                
 
407
                for(int i = 0; i < 8; i ++){
 
408
                        if(value > i && (existentAlternatives & (1 << i)) == 0){
 
409
                                repeatAlternative |= (1 << i);
 
410
                        }
 
411
                }
 
412
                return repeatAlternative;
 
413
        }
 
414
        
 
415
        private void readChord(int strings,TGBeat beat) throws IOException {
 
416
                TGChord chord = getFactory().newChord(strings);
 
417
                if ((readUnsignedByte() & 0x01) == 0) {
 
418
                        chord.setName( readStringByteSizeOfInteger() );
 
419
                        chord.setFirstFret(readInt());
 
420
                        if(chord.getFirstFret() != 0){
 
421
                                for (int i = 0; i < 6; i++) {
 
422
                                        int fret = readInt();
 
423
                                        if(i < chord.countStrings()){
 
424
                                                chord.addFretValue(i,fret);
 
425
                                        }
 
426
                                }
 
427
                        }
 
428
                }
 
429
                else{
 
430
                        skip(16);
 
431
                        chord.setName(readStringByte(21));
 
432
                        skip(4);
 
433
                        chord.setFirstFret(readInt());
 
434
                        for (int i = 0; i < 7; i++) {
 
435
                                int fret = readInt();
 
436
                                if(i < chord.countStrings()){
 
437
                                        chord.addFretValue(i,fret);
 
438
                                }
 
439
                        }
 
440
                        skip(32);
 
441
                }
 
442
                if(chord.countNotes() > 0){
 
443
                        beat.setChord(chord);
 
444
                }
 
445
        }
 
446
        
 
447
        private void readGrace(TGNoteEffect effect) throws IOException {
 
448
                int fret = readUnsignedByte();
 
449
                TGEffectGrace grace = getFactory().newEffectGrace();
 
450
                grace.setOnBeat(false);
 
451
                grace.setDead( (fret == 255) );
 
452
                grace.setFret( ((!grace.isDead())?fret:0) );
 
453
                grace.setDynamic( (TGVelocities.MIN_VELOCITY + (TGVelocities.VELOCITY_INCREMENT * readUnsignedByte())) - TGVelocities.VELOCITY_INCREMENT );
 
454
                int transition = readUnsignedByte();
 
455
                if(transition == 0){
 
456
                        grace.setTransition( TGEffectGrace.TRANSITION_NONE );
 
457
                }
 
458
                else if(transition == 1){
 
459
                        grace.setTransition(  TGEffectGrace.TRANSITION_SLIDE );
 
460
                }
 
461
                else if(transition == 2){
 
462
                        grace.setTransition(  TGEffectGrace.TRANSITION_BEND );
 
463
                }
 
464
                else if(transition == 3){
 
465
                        grace.setTransition(  TGEffectGrace.TRANSITION_HAMMER );
 
466
                }
 
467
                grace.setDuration(readUnsignedByte());
 
468
                effect.setGrace(grace);
 
469
        }
 
470
        
 
471
        private void readBend(TGNoteEffect effect) throws IOException {
 
472
                TGEffectBend bend = getFactory().newEffectBend();
 
473
                skip(5);
 
474
                int points = readInt();
 
475
                for (int i = 0; i < points; i++) {
 
476
                        int position = readInt();
 
477
                        int value = readInt();
 
478
                        readByte();
 
479
                        
 
480
                        int pointPosition = Math.round(position * TGEffectBend.MAX_POSITION_LENGTH / GP_BEND_POSITION);
 
481
                        int pointValue = Math.round(value * TGEffectBend.SEMITONE_LENGTH / GP_BEND_SEMITONE);
 
482
                        bend.addPoint(pointPosition,pointValue);
 
483
                }
 
484
                if(!bend.getPoints().isEmpty()){
 
485
                        effect.setBend(bend);
 
486
                }
 
487
        }
 
488
        
 
489
        private void readTremoloBar(TGNoteEffect effect) throws IOException {
 
490
                TGEffectTremoloBar tremoloBar = getFactory().newEffectTremoloBar();
 
491
                skip(5);
 
492
                int points = readInt();
 
493
                for (int i = 0; i < points; i++) {
 
494
                        int position = readInt();
 
495
                        int value = readInt();
 
496
                        readByte();
 
497
                        
 
498
                        int pointPosition = Math.round(position * TGEffectTremoloBar.MAX_POSITION_LENGTH / GP_BEND_POSITION);
 
499
                        int pointValue = Math.round(value / (GP_BEND_SEMITONE * 2f));
 
500
                        tremoloBar.addPoint(pointPosition,pointValue);
 
501
                }
 
502
                if(!tremoloBar.getPoints().isEmpty()){
 
503
                        effect.setTremoloBar(tremoloBar);
 
504
                }
 
505
        }
 
506
        
 
507
        public void readTremoloPicking(TGNoteEffect effect) throws IOException{
 
508
                int value = readUnsignedByte();
 
509
                TGEffectTremoloPicking tp = getFactory().newEffectTremoloPicking();
 
510
                if(value == 1){
 
511
                        tp.getDuration().setValue(TGDuration.EIGHTH);
 
512
                        effect.setTremoloPicking(tp);
 
513
                }else if(value == 2){
 
514
                        tp.getDuration().setValue(TGDuration.SIXTEENTH);
 
515
                        effect.setTremoloPicking(tp);
 
516
                }else if(value == 3){
 
517
                        tp.getDuration().setValue(TGDuration.THIRTY_SECOND);
 
518
                        effect.setTremoloPicking(tp);
 
519
                }
 
520
        }
 
521
        
 
522
        private void readNoteEffects(TGNoteEffect noteEffect) throws IOException {
 
523
                int flags1 = readUnsignedByte();
 
524
                int flags2 = readUnsignedByte();
 
525
                noteEffect.setHammer(((flags1 & 0x02) != 0));
 
526
                noteEffect.setVibrato(((flags2 & 0x40) != 0) || noteEffect.isVibrato());
 
527
                noteEffect.setPalmMute(((flags2 & 0x02) != 0));
 
528
                noteEffect.setStaccato(((flags2 & 0x01) != 0));
 
529
                if ((flags1 & 0x01) != 0) {
 
530
                        readBend(noteEffect);
 
531
                }
 
532
                if ((flags1 & 0x10) != 0) {
 
533
                        readGrace(noteEffect);
 
534
                }
 
535
                if ((flags2 & 0x04) != 0) {
 
536
                        readTremoloPicking(noteEffect);
 
537
                }
 
538
                if ((flags2 & 0x08) != 0) {
 
539
                        noteEffect.setSlide(true);
 
540
                        readByte();
 
541
                }
 
542
                if ((flags2 & 0x10) != 0) {
 
543
                        TGEffectHarmonic harmonic = getFactory().newEffectHarmonic();
 
544
                        int type = readByte();
 
545
                        if(type == 1){
 
546
                                harmonic.setType(TGEffectHarmonic.TYPE_NATURAL);
 
547
                        }else if(type == 3){
 
548
                                harmonic.setType(TGEffectHarmonic.TYPE_TAPPED);
 
549
                        }else if(type == 4){
 
550
                                harmonic.setType(TGEffectHarmonic.TYPE_PINCH);
 
551
                        }else if(type == 5){
 
552
                                harmonic.setType(TGEffectHarmonic.TYPE_SEMI);
 
553
                        }else if(type == 15){
 
554
                                harmonic.setType(TGEffectHarmonic.TYPE_ARTIFICIAL);
 
555
                                harmonic.setData(2);
 
556
                        }else if(type == 17){
 
557
                                harmonic.setType(TGEffectHarmonic.TYPE_ARTIFICIAL);
 
558
                                harmonic.setData(3);
 
559
                        }else if(type == 22){
 
560
                                harmonic.setType(TGEffectHarmonic.TYPE_ARTIFICIAL);
 
561
                                harmonic.setData(0);
 
562
                        }
 
563
                        noteEffect.setHarmonic(harmonic);
 
564
                }
 
565
                if ((flags2 & 0x20) != 0) {
 
566
                        byte fret = readByte();
 
567
                        byte period = readByte();
 
568
                        TGEffectTrill trill = getFactory().newEffectTrill();
 
569
                        trill.setFret(fret);
 
570
                        if(period == 1){
 
571
                                trill.getDuration().setValue(TGDuration.SIXTEENTH);
 
572
                                noteEffect.setTrill(trill);
 
573
                        }else if(period == 2){
 
574
                                trill.getDuration().setValue(TGDuration.THIRTY_SECOND);
 
575
                                noteEffect.setTrill(trill);
 
576
                        }else if(period == 3){
 
577
                                trill.getDuration().setValue(TGDuration.SIXTY_FOURTH);
 
578
                                noteEffect.setTrill(trill);
 
579
                        }
 
580
                }
 
581
        }
 
582
        
 
583
        private void readBeatEffects(TGNoteEffect noteEffect) throws IOException {
 
584
                int flags1 = readUnsignedByte();
 
585
                int flags2 = readUnsignedByte();
 
586
                noteEffect.setFadeIn(((flags1 & 0x10) != 0));
 
587
                noteEffect.setVibrato(((flags1  & 0x02) != 0));
 
588
                if ((flags1 & 0x20) != 0) {
 
589
                        int effect = readUnsignedByte();
 
590
                        noteEffect.setTapping(effect == 1);
 
591
                        noteEffect.setSlapping(effect == 2);
 
592
                        noteEffect.setPopping(effect == 3);
 
593
                }
 
594
                if ((flags2 & 0x04) != 0) {
 
595
                        readTremoloBar(noteEffect);
 
596
                }
 
597
                if ((flags1 & 0x40) != 0) {
 
598
                        readByte();
 
599
                        readByte();
 
600
                }
 
601
                if ((flags2 & 0x02) != 0) {
 
602
                        readByte();
 
603
                }
 
604
        }
 
605
        
 
606
        private void readMixChange(TGTempo tempo) throws IOException {
 
607
                readByte();
 
608
                int volume = readByte();
 
609
                int pan = readByte();
 
610
                int chorus = readByte();
 
611
                int reverb = readByte();
 
612
                int phaser = readByte();
 
613
                int tremolo = readByte();
 
614
                int tempoValue = readInt();
 
615
                if(volume >= 0){
 
616
                        readByte();
 
617
                }
 
618
                if(pan >= 0){
 
619
                        readByte();
 
620
                }
 
621
                if(chorus >= 0){
 
622
                        readByte();
 
623
                }
 
624
                if(reverb >= 0){
 
625
                        readByte();
 
626
                }
 
627
                if(phaser >= 0){
 
628
                        readByte();
 
629
                }
 
630
                if(tremolo >= 0){
 
631
                        readByte();
 
632
                }
 
633
                if(tempoValue >= 0){
 
634
                        tempo.setValue(tempoValue);
 
635
                        readByte();
 
636
                }
 
637
                readByte();
 
638
        }
 
639
        
 
640
        private short toChannelShort(byte b){
 
641
                short value = (short)(( b * 8 ) - 1);
 
642
                return (short)Math.max(value,0);
 
643
        }
 
644
}