1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2011 Werner Schweer
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2
9 //  as published by the Free Software Foundation and appearing in
10 //  the file LICENCE.GPL
11 //=============================================================================
12 
13 #include "importgtp.h"
14 
15 #include <libmscore/score.h>
16 #include <libmscore/measurebase.h>
17 #include <libmscore/text.h>
18 #include <libmscore/box.h>
19 #include <libmscore/staff.h>
20 #include <libmscore/part.h>
21 #include <libmscore/measure.h>
22 #include <libmscore/timesig.h>
23 #include <libmscore/tremolo.h>
24 #include <libmscore/chordline.h>
25 #include <libmscore/glissando.h>
26 #include <libmscore/rest.h>
27 #include <libmscore/chord.h>
28 #include <libmscore/note.h>
29 #include <libmscore/stringdata.h>
30 #include <libmscore/clef.h>
31 #include <libmscore/lyrics.h>
32 #include <libmscore/tempotext.h>
33 #include <libmscore/slur.h>
34 #include <libmscore/tie.h>
35 #include <libmscore/tuplet.h>
36 #include <libmscore/barline.h>
37 #include <libmscore/excerpt.h>
38 #include <libmscore/stafftype.h>
39 #include <libmscore/bracket.h>
40 #include <libmscore/articulation.h>
41 #include <libmscore/keysig.h>
42 #include <libmscore/harmony.h>
43 #include <libmscore/bend.h>
44 #include <libmscore/tremolobar.h>
45 #include <libmscore/segment.h>
46 #include <libmscore/rehearsalmark.h>
47 #include <libmscore/dynamic.h>
48 #include <libmscore/arpeggio.h>
49 #include <libmscore/volta.h>
50 #include <libmscore/instrtemplate.h>
51 #include <libmscore/fingering.h>
52 #include <libmscore/notedot.h>
53 #include <libmscore/stafftext.h>
54 #include <libmscore/sym.h>
55 #include <libmscore/instrtemplate.h>
56 
57 namespace Ms {
58 
59 //---------------------------------------------------------
60 //   readMixChange
61 //---------------------------------------------------------
62 
readMixChange(Measure * measure)63 bool GuitarPro4::readMixChange(Measure* measure)
64       {
65       /*char patch   =*/ readChar();
66       signed char volume  = readChar();
67       signed char pan     = readChar();
68       signed char chorus  = readChar();
69       signed char reverb  = readChar();
70       signed char phase   = readChar();
71       signed char tremolo = readChar();
72       int temp    = readInt();
73 
74       bool tempoEdited = false;
75 
76       if (volume >= 0)
77             readChar();
78       if (pan >= 0)
79             readChar();
80       if (chorus >= 0)
81             readChar();
82       if (reverb >= 0)
83             readChar();
84       if (phase >= 0)
85             readChar();
86       if (tremolo >= 0)
87             readChar();
88       if (temp >= 0) {
89             if (last_segment) {
90                   score->setTempo(last_segment->tick(), double(temp) / 60.0f);
91                   last_segment = nullptr;
92                   }
93             if (temp != previousTempo) {
94                   previousTempo = temp;
95                   setTempo(temp, measure);
96                   }
97             readChar();
98             tempoEdited = true;
99             }
100 
101       readChar();       // bitmask: what should be applied to all tracks
102       return tempoEdited;
103       }
104 
105 //---------------------------------------------------------
106 //   readBeatEffects
107 //---------------------------------------------------------
108 
readBeatEffects(int track,Segment * segment)109 int GuitarPro4::readBeatEffects(int track, Segment* segment)
110       {
111       int effects = 0;
112       uchar fxBits1 = readUChar();
113       uchar fxBits2 = readUChar();
114       if (fxBits1 & BEAT_FADE)
115             effects = 4; // fade in
116       if (fxBits1 & BEAT_EFFECT) {
117             effects = readUChar();      // effect 1-tapping, 2-slapping, 3-popping
118             }
119       if (fxBits2 & BEAT_TREMOLO)
120             readTremoloBar(track,segment);
121       if (fxBits1 & BEAT_ARPEGGIO) {
122             int strokeup = readUChar();            // up stroke length
123             int strokedown = readUChar();            // down stroke length
124 
125             Arpeggio* a = new Arpeggio(score);
126             if( strokeup > 0 ) {
127                   a->setArpeggioType(ArpeggioType::UP_STRAIGHT);
128                   }
129             else if( strokedown > 0 ) {
130                   a->setArpeggioType(ArpeggioType::DOWN_STRAIGHT);
131                   }
132             else {
133                   delete a;
134                   a = 0;
135                   }
136 
137             if(a) {
138                   ChordRest* cr = new Chord(score);
139                   cr->setTrack(track);
140                   cr->add(a);
141                   segment->add(cr);
142                   }
143             }
144       if (fxBits2 & BEAT_STROKE_DIR) {
145             effects = readUChar();            // stroke pick direction
146             effects += 4;    //1 or 2 for effects becomes 4 or 5
147             }
148       if (fxBits1 & 0x01) {         // GP3 column-wide vibrato
149             }
150       if (fxBits1 & 0x2) {          // GP3 column-wide wide vibrato (="tremolo" in GP3)
151             }
152       return effects;
153       }
154 
155 //---------------------------------------------------------
156 //   readNote
157 //---------------------------------------------------------
158 
readNote(int string,int staffIdx,Note * note)159 bool GuitarPro4::readNote(int string, int staffIdx, Note* note)
160       {
161       uchar noteBits = readUChar();
162 
163       //
164       // noteBits:
165       //   80 - Right hand or left hand fingering;
166       //   40 - Accentuated note
167       //   20 - Note type (rest, empty note, normal note);
168       //   10 - note dynamic;
169       //    8 - Presence of effects linked to the note;
170       //    4 - Ghost note;
171       //    2 - Dotted note;  ?
172       //    1 - Time-independent duration
173 
174       if (noteBits & BEAT_TREMOLO) {
175             //note->setHeadGroup(NoteHead::Group::HEAD_CROSS);
176             note->setGhost(true);
177             }
178 
179       bool tieNote = false;
180       uchar variant = 1;
181       if (noteBits & BEAT_EFFECT) {       // 0x20
182             variant = readUChar();
183             if (variant == 1) {     // normal note
184                   }
185             else if (variant == 2) {
186                   /* guitar pro 4 bundles tied notes with slides in the representation
187                    * we take note when we see ties and do not create slides for these notes. */
188                   slides[staffIdx * VOICES] = -2;
189                   tieNote = true;
190                   }
191             else if (variant == 3) {                 // dead notes = ghost note
192                   note->setHeadGroup(NoteHead::Group::HEAD_CROSS);
193                   note->setGhost(true);
194                   }
195             else
196                   qDebug("unknown note variant: %d", variant);
197             }
198 
199       if (noteBits & 0x1) {               // note != beat
200             int a = readUChar();          // length
201             int b = readUChar();          // t
202             qDebug("          Time independent note len, len %d t %d", a, b);
203             }
204       if (noteBits & 0x2) {               // note is dotted
205             //readUChar();
206             }
207 
208       // set dynamic information on note if different from previous note
209       if (noteBits & NOTE_DYNAMIC) {            // 0x10
210             int d = readChar();
211             if (previousDynamic != d) {
212                   previousDynamic = d;
213                   // addDynamic(note, d);    // velocity? TODO-ws ??
214                   }
215             }
216       else if (previousDynamic) {
217             previousDynamic = 0;
218             //addDynamic(note, 0);
219             }
220 
221       int fretNumber = -1;
222       if (noteBits & NOTE_FRET) {                 // 0x20
223             // TODO: special case if note is tied
224             fretNumber = readUChar();
225             }
226 
227       // check if a note is supposed to be accented, and give it the sforzato type
228       if (noteBits & NOTE_SFORZATO) {           // 0x40
229             Articulation* art = new Articulation(note->score());
230             art->setSymId(SymId::articAccentAbove);
231             if (!note->score()->addArticulation(note, art))
232                   delete art;
233             }
234 
235       if (noteBits & NOTE_FINGERING) {          // 0x80
236             int leftFinger  = readUChar();
237             int rightFinger = readUChar();
238             Fingering* fi   = new Fingering(score);
239             QString finger;
240             // if there is a valid left hand fingering
241             if (leftFinger < 5) {
242                   if (leftFinger == 0)
243                         finger = "T";
244                   else if (leftFinger == 1)
245                         finger = "1";
246                   else if (leftFinger == 2)
247                         finger = "2";
248                   else if (leftFinger == 3)
249                         finger = "3";
250                   else if (leftFinger == 4)
251                         finger = "4";
252                   }
253             else  {
254                   if (rightFinger == 0)
255                         finger = "T";
256                   else if (rightFinger == 1)
257                         finger = "I";
258                   else if (rightFinger == 2)
259                         finger = "M";
260                   else if (rightFinger == 3)
261                         finger = "A";
262                   else if (rightFinger == 4)
263                         finger = "O";
264                   }
265             fi->setPlainText(finger);
266             note->add(fi);
267             fi->reset();
268             }
269       bool slur = false;
270       uchar modMask2{ 0 };
271       if (noteBits & BEAT_EFFECTS) {
272             uchar modMask1 = readUChar();
273             modMask2 = readUChar();
274             if (modMask1 & EFFECT_BEND) {
275                   readBend(note);
276                   }
277             if (modMask1 & EFFECT_HAMMER) {
278                   slur = true;
279                   }
280             if (modMask1 & EFFECT_LET_RING) {
281                   addLetRing(note);
282                   //note->setLetRing(true);
283                   }
284             if (modMask2 & 0x40)
285                   addVibrato(note);
286             if (modMask1 & EFFECT_GRACE) {
287                   int fret = readUChar();             // grace fret
288                   int dynamic = readUChar();          // grace dynamic
289                   int transition = readUChar();       // grace transition
290                   int duration = readUChar();         // grace duration
291 
292                   int grace_len = MScore::division/8;
293                   if (duration == 1)
294                         grace_len = MScore::division/8; //32th
295                   else if (duration == 2)
296                         grace_len = MScore::division/6; //24th
297                   else if (duration == 3)
298                         grace_len = MScore::division/4; //16th
299 
300                   Note* gn = new Note(score);
301 
302                   if (fret == 255) {
303                         gn->setHeadGroup(NoteHead::Group::HEAD_CROSS);
304                         gn->setGhost(true);
305                         }
306                   if (fret == 255)
307                         fret = 0;
308                   gn->setFret(fret);
309                   gn->setString(string);
310                   int grace_pitch = note->part()->instrument()->stringData()->getPitch(string, fret, nullptr, Fraction(0,1));
311                   gn->setPitch(grace_pitch);
312                   gn->setTpcFromPitch();
313 
314                   Chord* gc = new Chord(score);
315                   gc->setTrack(note->chord()->track());
316                   gc->add(gn);
317                   gc->setParent(note->chord());
318 
319                   TDuration d;
320                   d.setVal(grace_len);
321                   if(grace_len == MScore::division/6)
322                         d.setDots(1);
323                   gc->setDurationType(d);
324                   gc->setTicks(d.fraction());
325                   gc->setNoteType(NoteType::ACCIACCATURA);
326                   gc->setMag(note->chord()->staff()->mag(Fraction(0,1)) * score->styleD(Sid::graceNoteMag));
327                   note->chord()->add(gc);
328                   addDynamic(gn, dynamic);
329 
330                   if (transition == 0) {
331                         // no transition
332                         }
333                   else if(transition == 1) {
334                         //TODO: Add a 'slide' guitar effect when implemented
335                         //TODO-ws				note->setSlideNote(gn);
336                         }
337                   else if (transition == 2 && fretNumber>=0 && fretNumber<=255 && fretNumber!=gn->fret()) {
338 #if 0
339                         QList<PitchValue> points;
340                         points.append(PitchValue(0,0, false));
341                         points.append(PitchValue(60,(fretNumber-gn->fret())*100, false));
342 
343                         Bend* b = new Bend(note->score());
344                         b->setPoints(points);
345                         b->setTrack(gn->track());
346                         gn->add(b);
347 #endif
348                         }
349                   else if (transition == 3) {
350                         // TODO:
351                         //     major: replace with a 'hammer-on' guitar effect when implemented
352                         //     minor: make slurs for parts
353 
354                         ChordRest* cr1 = toChord(gc);
355                         ChordRest* cr2 = toChord(note->chord());
356 
357                         Slur* slur1 = new Slur(score);
358                         slur1->setAnchor(Spanner::Anchor::CHORD);
359                         slur1->setStartElement(cr1);
360                         slur1->setEndElement(cr2);
361                         slur1->setTick(cr1->tick());
362                         slur1->setTick2(cr2->tick());
363                         slur1->setTrack(cr1->track());
364                         slur1->setTrack2(cr2->track());
365                         // this case specifies only two-note slurs, don't set a parent
366                         score->undoAddElement(slur1);
367                         }
368                   }
369             if (modMask2 & EFFECT_STACATTO) {   // staccato
370                   Chord* chord = note->chord();
371                   Articulation* a = new Articulation(chord->score());
372                   a->setSymId(SymId::articStaccatoAbove);
373                   chord->add(a);
374                   }
375             if (modMask2 & EFFECT_PALM_MUTE) {
376                   //note->setPalmMute(true);
377                   addPalmMute(note);
378                   }
379 
380             if (modMask2 & EFFECT_TREMOLO) {    // tremolo picking length
381                   int tremoloDivision = readUChar();
382                   Chord* chord = note->chord();
383                   Tremolo* t = new Tremolo(chord->score());
384                   if (tremoloDivision == 1) {
385                         t->setTremoloType(TremoloType::R8);
386                         chord->add(t);
387                         }
388                   else if (tremoloDivision == 2) {
389                         t->setTremoloType(TremoloType::R16);
390                         chord->add(t);
391                         }
392                   else if (tremoloDivision == 3) {
393                         t->setTremoloType(TremoloType::R32);
394                         chord->add(t);
395                         }
396                   else
397                         qDebug("Unknown tremolo value");
398                   }
399             if (modMask2 & EFFECT_SLIDE) {
400                   int slideKind = readUChar();
401                   // if slide >= 4 then we are not dealing with legato slide nor shift slide
402                   if (slideKind >= 3 || slideKind == 254 || slideKind == 255) {
403                         slide = slideKind;
404                         }
405                   else
406                         //slides[note->chord()->track()] = slideKind;
407                         slideList.push_back(note);
408                   if (slideKind == 2)
409                         slur = true;
410                   }
411 
412             if (modMask2 & EFFECT_TRILL) {
413                   /* unsigned char a = */ readUChar();
414                   //TODO-ws                  note->setTrillFret(a);      // trill fret
415                   /*int period =*/ readUChar();      // trill length
416 
417                   // add the trill articulation to the note
418                   Articulation* art = new Articulation(note->score());
419                   art->setSymId(SymId::ornamentTrill);
420                   if (!note->score()->addArticulation(note, art))
421                         delete art;
422 
423                   }
424             }
425       if (fretNumber == -1) {
426             qDebug("Note: no fret number, tie %d", tieNote);
427             }
428       Staff* staff = note->staff();
429       if (fretNumber == 255) {
430             fretNumber = 0;
431             note->setHeadGroup(NoteHead::Group::HEAD_CROSS);
432             note->setGhost(true);
433             }
434       // dead note represented as high numbers - fix to zero
435       if (fretNumber > 99 || fretNumber == -1)
436             fretNumber = 0;
437       int pitch = staff->part()->instrument()->stringData()->getPitch(string, fretNumber, nullptr, Fraction(0,1));
438       note->setFret(fretNumber);
439       note->setString(string);
440       note->setPitch(std::min(pitch, 127));
441 
442       if (modMask2 & 0x10) {
443             int type = readUChar();      // harmonic kind
444             if (type == 1) //Natural
445                   ; // TODO-ws note->setHarmonic(false);
446             else if (type == 3) // Tapped
447                   addTextToNote("T.H.", Align::CENTER, note);
448             else if (type == 4) //Pinch
449                   addTextToNote("P.H.", Align::CENTER, note);
450             else if (type == 5) //semi
451                   addTextToNote("S.H.", Align::CENTER, note);
452             else { //Artificial
453                   addTextToNote("A.H.", Align::CENTER, note);
454                   int harmonicFret = note->fret();
455                   harmonicFret += type - 10;
456                   Note* harmonicNote = new Note(score);
457                   note->chord()->add(harmonicNote);
458                   harmonicNote->setFret(harmonicFret);
459                   harmonicNote->setString(note->string());
460                   //TODO-ws			harmonicNote->setHarmonic(true);
461                   harmonicNote->setPitch(note->staff()->part()->instrument()->stringData()->getPitch(note->string(), harmonicFret, nullptr, Fraction(0,1)));
462                   harmonicNote->setTpcFromPitch();
463                   }
464             }
465 
466       if (tieNote) {
467             int si = note->staffIdx();
468             if (slurs[si]) {
469                   score->removeSpanner(slurs[si]);
470                   delete slurs[si];
471                   slurs[si] = 0;
472                   }
473             bool found = false;
474             Chord* chord = note->chord();
475             Segment* segment = chord->segment()->prev1(SegmentType::ChordRest);
476             int track = note->track();
477             std::vector<ChordRest*> chords;
478             Note* true_note = 0;
479             while (segment) {
480                   Element* e = segment->element(track);
481                   if (e) {
482                         if (e->isChord()) {
483                               Chord* chord2 = toChord(e);
484                               foreach (Note* note2, chord2->notes()) {
485                                     if (note2->string() == string) {
486                                           if (chords.empty()) {
487                                                 Tie* tie = new Tie(score);
488                                                 tie->setEndNote(note);
489                                                 note2->add(tie);
490                                                 }
491                                           note->setFret(note2->fret());
492                                           note->setPitch(note2->pitch());
493                                           true_note = note2;
494                                           found = true;
495                                           break;
496                                           }
497                                     }
498                               }
499                         if (found)
500                               break;
501                         else {
502                               if (e)
503                                     chords.push_back(toChordRest(e));
504                               }
505                         }
506                   segment = segment->prev1(SegmentType::ChordRest);
507                   }
508             if (true_note && chords.size()) {
509                   Note* end_note = note;
510                   for (unsigned int i = 0; i < chords.size(); ++i) {
511                         Chord* chord1 = nullptr;
512                         auto cr = chords.at(i);
513                         if (cr->isChord())
514                               chord1 = toChord(cr);
515                         else {
516                               Rest* rest = toRest(cr);
517                               auto dur = rest->ticks();
518                               auto dut = rest->durationType();
519                               auto seg = rest->segment();
520                               seg->remove(rest);
521                               auto tuplet = rest->tuplet();
522                               if (tuplet)
523                                     tuplet->remove(rest);
524                               delete rest;
525                               chord1 = new Chord(score);
526                               chord1->setTrack(note->track());
527                               chord1->setTicks(dur);
528                               chord1->setDurationType(dut);
529                               seg->add(chord1);
530                               if (tuplet)
531                                     tuplet->add(chord1);
532                               }
533 
534                         Note* note2 = new Note(score);
535                         note2->setString(true_note->string());
536                         note2->setFret(true_note->fret());
537                         note2->setPitch(true_note->pitch());
538                         note2->setTpcFromPitch();
539                         chord1->setNoteType(true_note->noteType());
540                         chord1->add(note2);
541                         Tie* tie = new Tie(score);
542                         tie->setEndNote(end_note);
543                         //TODO-ws			end_note->setHarmonic(true_note->harmonic());
544                         end_note = note2;
545                         note2->add(tie);
546                         }
547                   Tie* tie = new Tie(score);
548                   tie->setEndNote(end_note);
549                   //TODO-ws		end_note->setHarmonic(true_note->harmonic());
550                   true_note->add(tie);
551                   }
552             if (!found) {
553                   qDebug("tied note not found, pitch %d fret %d string %d", note->pitch(), note->fret(), note->string());
554                   return false;
555                   }
556             }
557       return slur;
558       }
559 
560 //---------------------------------------------------------
561 //   readInfo
562 //---------------------------------------------------------
563 
readInfo()564 void GuitarPro4::readInfo()
565       {
566       title        = readDelphiString();
567       subtitle     = readDelphiString();
568       artist       = readDelphiString();
569       album        = readDelphiString();
570       composer     = readDelphiString();
571       QString copyright = readDelphiString();
572       if (!copyright.isEmpty())
573             score->setMetaTag("copyright", QString("%1").arg(copyright));
574 
575       transcriber  = readDelphiString();
576       instructions = readDelphiString();
577       int n = readInt();
578       for (int i = 0; i < n; ++i)
579             comments.append(readDelphiString());
580       }
581 
582 //---------------------------------------------------------
583 //   convertGP4SlideNum
584 //---------------------------------------------------------
585 
convertGP4SlideNum(int sl)586 int GuitarPro4::convertGP4SlideNum(int sl)
587       {
588       switch (sl) {
589             case 1:
590                   return SHIFT_SLIDE;
591             case 2:
592                   return LEGATO_SLIDE;
593             case 3:     // slide out downwards
594                   return SLIDE_OUT_DOWN;
595             case 4:     // slide out upwards
596                   return SLIDE_OUT_UP;
597             case 254:   // slide in from above
598                   return SLIDE_IN_ABOVE;
599             case 255:   // slide in from below
600                   return SLIDE_IN_BELOW;
601             }
602       return sl;
603       }
604 
605 //---------------------------------------------------------
606 //   read
607 //---------------------------------------------------------
608 
read(QFile * fp)609 bool GuitarPro4::read(QFile* fp)
610       {
611       f      = fp;
612       curPos = 30;
613 
614       readInfo();
615       readUChar();      // triplet feeling
616       readLyrics();
617 
618       int temp   = readInt();
619       key        = readInt();
620       /*int octave =*/ readUChar();    // octave
621 
622       //previousDynamic = new int [staves * VOICES];
623       // initialise the dynamics to 0
624       //for (int i = 0; i < staves * VOICES; i++)
625       //      previousDynamic[i] = 0;
626       previousDynamic = -1;
627       previousTempo = -1;
628 
629       readChannels();
630       measures = readInt();
631       staves   = readInt();
632 
633       curDynam.resize(staves * VOICES);
634       for (auto& i : curDynam)
635             i = -1;
636 
637       int tnumerator   = 4;
638       int tdenominator = 4;
639       for (int i = 0; i < measures; ++i) {
640             GpBar bar;
641             uchar barBits = readUChar();
642             if (barBits & SCORE_TIMESIG_NUMERATOR)
643                   tnumerator = readUChar();
644             if (barBits & SCORE_TIMESIG_DENOMINATOR)
645                   tdenominator = readUChar();
646             if (barBits & SCORE_REPEAT_START)
647                   bar.repeatFlags = bar.repeatFlags | Repeat::START;
648             if (barBits & SCORE_REPEAT_END) {                // number of repeats
649                   bar.repeatFlags = bar.repeatFlags | Repeat::END;
650                   bar.repeats = readUChar() + 1;
651                   }
652             if (barBits & SCORE_VOLTA) {                      // a volta
653                   uchar voltaNumber = readUChar();
654                   while (voltaNumber > 0) {
655                         // volta information is represented as a binary number
656                         bar.volta.voltaType = GP_VOLTA_BINARY;
657                         bar.volta.voltaInfo.append(voltaNumber & 1);
658                         voltaNumber >>= 1;
659                         }
660                   }
661             if (barBits & SCORE_MARKER) {
662                   bar.marker = readDelphiString();     // new section?
663                   /*int color = */ readInt();    // color?
664                   }
665             if (barBits & SCORE_KEYSIG) {
666                   int currentKey = readUChar();
667                   /* key signatures are specified as
668                    * 1# = 1, 2# = 2, ..., 7# = 7
669                    * 1b = 255, 2b = 254, ... 7b = 249 */
670                   bar.keysig = currentKey <= 7 ? currentKey : -256+currentKey;
671                   readUChar();        // specifies major/minor mode
672                   }
673             if (barBits & SCORE_DOUBLE_BAR)
674                   bar.barLine = BarLineType::DOUBLE;
675             bar.timesig = Fraction(tnumerator, tdenominator);
676             bars.append(bar);
677             }
678 
679       //
680       // create a part for every staff
681       //
682       for (int staffIdx = 0; staffIdx < staves; ++staffIdx) {
683             Part* part = new Part(score);
684             Staff* s = new Staff(score);
685             s->setPart(part);
686             part->insertStaff(s, 0);
687             score->staves().push_back(s);
688             score->appendPart(part);
689             }
690 
691       createMeasures();
692 
693       setTempo(temp, score->firstMeasure());
694 
695       for (int i = 0; i < staves; ++i) {
696             int tuning[GP_MAX_STRING_NUMBER];
697 
698             uchar c = readUChar();   // simulations bitmask
699             if (c & 0x2) {                // 12 stringed guitar
700                   }
701             if (c & 0x4) {                // banjo track
702                   }
703             QString name = readPascalString(40);
704             int strings  = readInt();
705             if (strings <= 0 || strings > GP_MAX_STRING_NUMBER)
706                   return false;
707             for (int j = 0; j < strings; ++j)
708                   tuning[j] = readInt();
709             for (int j = strings; j < GP_MAX_STRING_NUMBER; ++j)
710                   readInt();
711             int midiPort     = readInt() - 1;
712             int midiChannel  = readInt() - 1;
713             /*int midiChannel2 =*/ readInt(); // - 1;
714             int frets        = readInt();
715 
716             int capo         = readInt();
717             /*int color        =*/ readInt();
718 
719             std::vector<int> tuning2(strings);
720             //int tuning2[strings];
721             for (int k = 0; k < strings; ++k)
722                   tuning2[strings-k-1] = tuning[k];
723             StringData stringData(frets, strings, &tuning2[0]);
724             createTuningString(strings, &tuning2[0]);
725             Part* part = score->staff(i)->part();
726             Instrument* instr = part->instrument();
727             instr->setStringData(stringData);
728             instr->setSingleNoteDynamics(false);
729             part->setPartName(name);
730             part->setPlainLongName(name);
731 
732             //
733             // determine clef
734             //
735             Staff* staff = score->staff(i);
736             int patch = channelDefaults[midiChannel].patch;
737             ClefType clefId = ClefType::G;
738             if (midiChannel == GP_DEFAULT_PERCUSSION_CHANNEL) {
739                   clefId = ClefType::PERC;
740                   // instr->setUseDrumset(DrumsetKind::GUITAR_PRO);
741                   instr->setDrumset(gpDrumset);
742                   staff->setStaffType(Fraction(0,1), *StaffType::preset(StaffTypes::PERC_DEFAULT));
743                   }
744             else
745                   clefId = defaultClef(patch);
746             Measure* measure = score->firstMeasure();
747             Clef* clef = new Clef(score);
748             clef->setClefType(clefId);
749             clef->setTrack(i * VOICES);
750             Segment* segment = measure->getSegment(SegmentType::HeaderClef, Fraction(0,1));
751             segment->add(clef);
752 
753             if (capo > 0) {
754                   Segment* s = measure->getSegment(SegmentType::ChordRest, measure->tick());
755                   StaffText* st = new StaffText(score);
756                   st->setPlainText(QString("Capo. fret ") + QString::number(capo));
757                   st->setTrack(i * VOICES);
758                   s->add(st);
759                   }
760 
761             Channel* ch = instr->channel(0);
762             if (midiChannel == GP_DEFAULT_PERCUSSION_CHANNEL) {
763                   ch->setProgram(0);
764                   ch->setBank(128);
765                   }
766             else {
767                   ch->setProgram(patch);
768                   ch->setBank(0);
769                   }
770             ch->setVolume(channelDefaults[midiChannel].volume);
771             ch->setPan(channelDefaults[midiChannel].pan);
772             ch->setChorus(channelDefaults[midiChannel].chorus);
773             ch->setReverb(channelDefaults[midiChannel].reverb);
774             staff->part()->setMidiChannel(midiChannel, midiPort);
775             // missing: phase, tremolo
776             }
777 
778       slurs = new Slur*[staves];
779       tupleKind.resize(staves);
780       for (auto& i : tupleKind)
781             i = 0;
782       for (int i = 0; i < staves; ++i)
783             slurs[i] = 0;
784 
785       Measure* measure = score->firstMeasure();
786       bool mixChange = false;
787       bool lastSlurAdd = false;
788       for (int bar = 0; bar < measures; ++bar, measure = measure->nextMeasure()) {
789             if (!f->isReadable())
790                   break;
791             const GpBar& gpbar = bars[bar];
792             if (!gpbar.marker.isEmpty()) {
793                   RehearsalMark* s = new RehearsalMark(score);
794                   s->setPlainText(gpbar.marker.trimmed());
795                   s->setTrack(0);
796                   Segment* segment = measure->getSegment(SegmentType::ChordRest, measure->tick());
797                   segment->add(s);
798                   }
799 
800             std::vector<Tuplet*> tuplets(staves);
801             for (int staffIdx = 0; staffIdx < staves; ++staffIdx)
802                   tuplets[staffIdx] = 0;
803 
804             for (int staffIdx = 0; staffIdx < staves; ++staffIdx) {
805                   Fraction measureLen = {0,1};
806                   Fraction tick  = measure->tick();
807                   int beats = readInt();
808                   int track = staffIdx * VOICES;
809 
810                   if (!f->isReadable())
811                         break;
812                   for (int beat = 0; beat < beats; ++beat) {
813                         slide = -1;
814                         if (slides.contains(track))
815                               slide = slides.take(track);
816 
817                         uchar beatBits = readUChar();
818                         bool dotted = beatBits & 0x1;
819                         int pause = -1;
820                         if (beatBits & BEAT_PAUSE)
821                               pause = readUChar();
822                         int len = readChar();
823                         int tuple = 0;
824                         if (beatBits & BEAT_TUPLET) {
825                               tuple = readInt();
826 #if 0 // TODO: ws
827                               if (tupleKind[staffIdx])
828                                     --tupleKind[staffIdx];
829                               else {
830                                     tupleKind[staffIdx] = tuple - 1;
831                                     curTuple = tuple;
832                                     }
833 #endif
834                               }
835                         else if (tupleKind[staffIdx]) {
836                               //TODO: ws                              tuple = curTuple;
837                               //					--tupleKind[staffIdx];
838                               }
839                         Segment* segment = measure->getSegment(SegmentType::ChordRest, tick);
840                         if (beatBits & BEAT_CHORD) {
841                               int numStrings = score->staff(staffIdx)->part()->instrument()->stringData()->strings();
842                               int header = readUChar();
843                               QString name;
844                               if ((header & 1) == 0) {
845                                     name = readDelphiString();
846                                     readChord(segment, staffIdx * VOICES, numStrings, name, false);
847                                     }
848                               else  {
849                                     skip(16);
850                                     name = readPascalString(21);
851                                     skip(4);
852                                     readChord(segment, staffIdx * VOICES, numStrings, name, true);
853                                     skip(32);
854                                     }
855                               }
856 
857                         Lyrics* lyrics = 0;
858                         if (beatBits & BEAT_LYRICS) {
859                               lyrics = new Lyrics(score);
860                               auto  str = readDelphiString();
861                               //TODO-ws					str.erase(std::remove_if(str.begin(), str.end(), [](char c){return c == '_'; }), str.end());
862                               lyrics->setPlainText(str);
863                               }
864                         gpLyrics.beatCounter++;
865                         if (gpLyrics.beatCounter >= gpLyrics.fromBeat && gpLyrics.lyricTrack == staffIdx + 1) {
866                               int index = gpLyrics.beatCounter - gpLyrics.fromBeat;
867                               if (index < gpLyrics.lyrics.size()) {
868                                     lyrics = new Lyrics(score);
869                                     lyrics->setPlainText(gpLyrics.lyrics[index]);
870                                     }
871                               }
872                         int beatEffects = 0;
873                         if (beatBits & BEAT_EFFECTS)
874                               beatEffects = readBeatEffects(track, segment);
875                         last_segment = segment;
876                         if (beatBits & BEAT_MIX_CHANGE) {
877                               readMixChange(measure);
878                               mixChange = true;
879                               }
880 #if 0
881                         else  {
882                               if (bar == 0)
883                                     setTempo(tempo, measure);
884                               }
885 #endif
886                         int strings = readUChar();   // used strings mask
887                         Fraction l  = len2fraction(len);
888 
889                         // Some beat effects could add a Chord before this
890                         ChordRest* cr = segment->cr(track);
891 
892                         if (strings == 0) {
893                               if(segment->cr(track)){
894                                     segment->remove(segment->cr(track));
895                                     delete cr;
896                                     cr = 0;
897                                     }
898                               cr = new Rest(score);
899                               }
900                         else {
901                               if(!segment->cr(track))
902                                     cr = new Chord(score);
903                               }
904                         cr->setParent(segment);
905                         cr->setTrack(track);
906                         if (lyrics)
907                               cr->add(lyrics);
908 
909                         TDuration d(l);
910                         d.setDots(dotted ? 1 : 0);
911 
912                         if (dotted)
913                               l = l + (l * Fraction(1,2));
914                         if (tuple) {
915                               Tuplet* tuplet = tuplets[staffIdx];
916                               if ((tuplet == 0) || (tuplet->elementsDuration() == tuplet->baseLen().fraction() * tuplet->ratio().numerator())) {
917                                     tuplet = new Tuplet(score);
918                                     tuplet->setTick(tick);
919                                     tuplet->setTrack(cr->track());
920                                     tuplets[staffIdx] = tuplet;
921                                     setTuplet(tuplet, tuple);
922                                     tuplet->setParent(measure);
923                                     }
924                               tuplet->setTrack(track);
925                               tuplet->setBaseLen(l);
926                               tuplet->setTicks(l * tuplet->ratio().denominator());
927                               cr->setTuplet(tuplet);
928                               tuplet->add(cr);
929                               }
930                         else
931                               tuplets[staffIdx] = 0;  // needed?
932 
933                         cr->setTicks(l);
934                         if (cr->isRest() && (pause == 0 || l >= measure->ticks())) {
935                               cr->setDurationType(TDuration::DurationType::V_MEASURE);
936                               cr->setTicks(measure->ticks());
937                               }
938                         else
939                               cr->setDurationType(d);
940                         if (!segment->cr(track))
941                               segment->add(cr);
942                         Staff* staff   = cr->staff();
943                         int numStrings = staff->part()->instrument()->stringData()->strings();
944                         bool hasSlur   = false;
945                         int dynam      = -1;
946                         if (cr && cr->isChord()) {    // TODO::ws  crashes without if
947                               for (int i = 6; i >= 0; --i) {
948                                     if (strings & (1 << i) && ((6-i) < numStrings)) {
949                                           Note* note = new Note(score);
950                                           // apply dotted notes to the note
951                                           if (dotted) {
952                                                 // there is at most one dotted note in this guitar pro version
953                                                 NoteDot* dot = new NoteDot(score);
954                                                 dot->setParent(note);
955                                                 dot->setTrack(track);  // needed to know the staff it belongs to (and detect tablature)
956                                                 dot->setVisible(true);
957                                                 note->add(dot);
958                                                 }
959                                           toChord(cr)->add(note);
960 
961                                           hasSlur = readNote(6-i, staffIdx, note);
962                                           dynam = std::max(dynam, previousDynamic);
963                                           note->setTpcFromPitch();
964                                           }
965                                     }
966                               } //ws
967                         if (cr && cr->isChord()) {
968                               applyBeatEffects(toChord(cr), beatEffects);
969                               if (dynam != curDynam[track]) {
970                                     curDynam[track] = dynam;
971                                     addDynamic(toChord(cr)->notes().front(), dynam);
972                                     }
973                               }
974 
975                         // if we see that a tied note has been constructed do not create the tie
976                         if (slides[track] == -2) {
977                               slide = 0;
978                               slides[track] = -1;
979                               }
980                         bool slurSwap = true;
981                         if (slide != 2) {
982                               if (hasSlur && (slurs[staffIdx] == 0)) {
983                                     Slur* slur = new Slur(score);
984                                     slur->setParent(0);
985                                     slur->setTrack(track);
986                                     slur->setTrack2(track);
987                                     slur->setTick(cr->tick());
988                                     slur->setTick2(cr->tick());
989                                     slurs[staffIdx] = slur;
990                                     score->addElement(slur);
991                                     }
992                               else if (slurs[staffIdx] && !hasSlur) {
993                                     // TODO: check slur
994                                     Slur* s = slurs[staffIdx];
995                                     slurs[staffIdx] = 0;
996                                     s->setTick2(cr->tick());
997                                     s->setTrack2(cr->track());
998                                     if (cr->isChord()) {
999                                           lastSlurAdd = true;
1000                                           slurSwap = false;
1001                                           }
1002                                     //TODO-ws                           cr->has_slur = true;
1003                                     }
1004                               else if (slurs[staffIdx] && hasSlur) {
1005                                     }
1006                               }
1007                         if (cr && (cr->isChord()) && slide > 0) {
1008                               auto chord = toChord(cr);
1009                               auto effect = convertGP4SlideNum(slide);
1010                               if (slide > 2)
1011                                     createSlide(convertGP4SlideNum(slide), cr, staffIdx);
1012                               if (slide < 3 || effect == SLIDE_OUT_UP) {
1013                                     Note* last = chord->upNote();
1014                                     auto seg = chord->segment();
1015                                     Measure* mes = seg->measure();
1016                                     while ((seg = seg->prev()) || (mes = mes->prevMeasure())) {
1017                                           if (!seg)
1018                                                 break;//seg = mes->last();
1019                                           if (seg->segmentType() == SegmentType::ChordRest) {
1020                                                 bool br = false;
1021                                                 Chord* cr1 = toChord(seg->cr(chord->track()));
1022                                                 if (cr1) {
1023                                                       for (auto n : cr1->notes()) {
1024                                                             if (n->string() == last->string()) {
1025                                                                   Glissando* s = new Glissando(score);
1026                                                                   s->setAnchor(Spanner::Anchor::NOTE);
1027                                                                   s->setStartElement(n);
1028                                                                   s->setTick(seg->tick());
1029                                                                   s->setTrack(chord->track());
1030                                                                   s->setParent(n);
1031                                                                   s->setGlissandoType(GlissandoType::STRAIGHT);
1032                                                                   s->setEndElement(last);
1033                                                                   s->setTick2(chord->segment()->tick());
1034                                                                   s->setTrack2(chord->track());
1035                                                                   score->addElement(s);
1036                                                                   if (slide == 2 || effect == SLIDE_OUT_UP) {
1037                                                                         if (!lastSlurAdd) {
1038                                                                               createSlur(true, chord->staffIdx(), cr1);
1039                                                                               createSlur(false, chord->staffIdx(), chord);
1040                                                                               }
1041                                                                         }
1042                                                                   br = true;
1043                                                                   break;
1044                                                                   }
1045                                                             }
1046                                                       }
1047                                                 if (br)
1048                                                       break;
1049                                                 }
1050                                           }
1051                                     }
1052                               }
1053                         if (slurSwap)
1054                               lastSlurAdd = false;
1055                         restsForEmptyBeats(segment, measure, cr, l, track, tick);
1056                         createSlur(hasSlur, staffIdx, cr);
1057                         tick += cr->actualTicks();
1058                         measureLen += cr->actualTicks();
1059                         }
1060                   if (measureLen < measure->ticks()) {
1061                         score->setRest(tick, track, measure->ticks() - measureLen, false, nullptr, false);
1062                         }
1063                   }
1064 
1065             if (bar == 1 && !mixChange)
1066                   setTempo(temp, score->firstMeasure());
1067             }
1068 
1069       for (auto n : slideList) {
1070             Segment* segment = n->chord()->segment();
1071             Measure* measure1 = segment->measure();
1072             int segment_counter = 0;
1073             while ((segment = segment->next1(SegmentType::ChordRest)) || ((measure1 = measure1->nextMeasure()) && (segment = measure1->first()))) {
1074                   if (!segment->isChordRestType())
1075                         continue;
1076                   bool br = false;
1077                   ChordRest* cr = segment->cr(n->track());
1078                   if (cr && cr->isChord()) {
1079                         Chord* c = toChord(cr);
1080                         ++segment_counter;
1081                         if (segment_counter > 2)
1082                               break;
1083                         for (Note* nt : c->notes()) {
1084                               if (nt->string() == n->string()) {
1085                                     for (auto e : nt->el()) {
1086                                           if (e->isChordLine()) {
1087                                                 auto cl = toChordLine(e);
1088                                                 if (cl->chordLineType() == ChordLineType::PLOP || cl->chordLineType() == ChordLineType::SCOOP) {
1089                                                       br = true;
1090                                                       break;
1091                                                       }
1092                                                 }
1093                                           }
1094                                     if (br)
1095                                           break;
1096 #if 1  // TODO-ws: crash
1097                                     Glissando* s = new Glissando(score);
1098                                     s->setAnchor(Spanner::Anchor::NOTE);
1099                                     s->setStartElement(n);
1100                                     s->setTick(n->chord()->segment()->tick());
1101                                     s->setTrack(n->track());
1102                                     s->setParent(n);
1103                                     s->setGlissandoType(GlissandoType::STRAIGHT);
1104                                     s->setEndElement(nt);
1105                                     s->setTick2(nt->chord()->segment()->tick());
1106                                     s->setTrack2(n->track());
1107                                     score->addElement(s);
1108 #endif
1109                                     br = true;
1110                                     break;
1111                                     }
1112                               }
1113                         if (br)
1114                               break;
1115                         }
1116                   }
1117             }
1118 
1119       return true;
1120       }
1121 
1122 }
1123