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/rest.h>
25 #include <libmscore/chord.h>
26 #include <libmscore/note.h>
27 #include <libmscore/stringdata.h>
28 #include <libmscore/clef.h>
29 #include <libmscore/lyrics.h>
30 #include <libmscore/tempotext.h>
31 #include <libmscore/glissando.h>
32 #include <libmscore/slur.h>
33 #include <libmscore/tie.h>
34 #include <libmscore/tuplet.h>
35 #include <libmscore/barline.h>
36 #include <libmscore/excerpt.h>
37 #include <libmscore/stafftype.h>
38 #include <libmscore/bracket.h>
39 #include <libmscore/articulation.h>
40 #include <libmscore/keysig.h>
41 #include <libmscore/harmony.h>
42 #include <libmscore/bend.h>
43 #include <libmscore/tremolobar.h>
44 #include <libmscore/segment.h>
45 #include <libmscore/rehearsalmark.h>
46 #include <libmscore/dynamic.h>
47 #include <libmscore/arpeggio.h>
48 #include <libmscore/volta.h>
49 #include <libmscore/instrtemplate.h>
50 #include <libmscore/fingering.h>
51 #include <libmscore/notedot.h>
52 #include <libmscore/stafftext.h>
53 #include <libmscore/sym.h>
54 #include <libmscore/chordline.h>
55 
56 
57 namespace Ms {
58 
59 //---------------------------------------------------------
60 //   readInfo
61 //---------------------------------------------------------
62 
readInfo()63 void GuitarPro5::readInfo()
64       {
65       title        = readDelphiString();
66       subtitle     = readDelphiString();
67       artist       = readDelphiString();
68       album        = readDelphiString();
69       composer     = readDelphiString();
70       readDelphiString();
71       QString copyright = readDelphiString();
72       if (!copyright.isEmpty())
73             score->setMetaTag("copyright", QString("%1").arg(copyright));
74 
75       transcriber  = readDelphiString();
76       instructions = readDelphiString();
77       int n = readInt();
78       for (int i = 0; i < n; ++i)
79             comments.append(readDelphiString());
80       }
81 
82 //---------------------------------------------------------
83 //   readBeatEffects
84 //---------------------------------------------------------
85 
readBeatEffects(int track,Segment * segment)86 int GuitarPro5::readBeatEffects(int track, Segment* segment)
87       {
88       int effects = 0;
89 
90       uchar fxBits1 = readUChar();
91       uchar fxBits2 = readUChar();
92       if (fxBits1 & BEAT_FADE)
93              effects = 4; // fade in
94       if (fxBits1 & BEAT_EFFECT) {
95             int k = readUChar();
96 		effects = k + effects * 100;// &effects;
97 	      }
98       if (fxBits1 & BEAT_VIBRATO_TREMOLO) {
99             effects = 7 + effects * 100;
100             }
101       if (fxBits2 & BEAT_TREMOLO)
102             readTremoloBar(track, segment);       // readBend();
103       if (fxBits2 & 0x01) { // Rasgueado effect
104             StaffText* st = new StaffText(score);
105 		st->setXmlText("rasg.");
106 		st->setParent(segment);
107 		st->setTrack(track);
108 		score->addElement(st);
109 	      }
110       if (fxBits1 & BEAT_ARPEGGIO) {
111             int strokeup = readUChar();            // up stroke length
112             int strokedown = readUChar();            // down stroke length
113 
114             Arpeggio* a = new Arpeggio(score);
115             // representation is different in guitar pro 5 - the up/down order below is correct
116             if (strokeup > 0) {
117                   a->setArpeggioType(ArpeggioType::UP_STRAIGHT);
118                   }
119             else if (strokedown > 0) {
120                   a->setArpeggioType(ArpeggioType::DOWN_STRAIGHT);
121                   }
122             else {
123                   delete a;
124                   a = 0;
125                   }
126             if (a) {
127                   ChordRest* cr = new Chord(score);
128                   cr->setTrack(track);
129                   cr->add(a);
130                   segment->add(cr);
131                   }
132             }
133       if (fxBits2 & BEAT_STROKE_DIR) {
134             effects = readChar();            // stroke pick direction
135             effects += 4; //1 or 2 for effects becomes 4 or 5
136             }
137       return effects;
138       }
139 
140 //---------------------------------------------------------
141 //   readPageSetup
142 //---------------------------------------------------------
143 
readPageSetup()144 void GuitarPro5::readPageSetup()
145       {
146       skip(version > 500 ? 49 : 30);
147       for (int i = 0; i < 11; ++i) {
148             skip(4);
149             readBytePascalString();
150             }
151       }
152 
153 //---------------------------------------------------------
154 //   readBeat
155 //---------------------------------------------------------
156 
readBeat(const Fraction & tick,int voice,Measure * measure,int staffIdx,Tuplet ** tuplets,bool)157 Fraction GuitarPro5::readBeat(const Fraction& tick, int voice, Measure* measure, int staffIdx, Tuplet** tuplets,
158    bool /*mixChange*/)
159       {
160       uchar beatBits = readUChar();
161       bool dotted    = beatBits & BEAT_DOTTED;
162 
163       slide = -1;
164       int track = staffIdx * VOICES + voice;
165       if (slides.contains(track))
166             slide = slides.take(track);
167 
168       int pause = -1;
169       if (beatBits & BEAT_PAUSE)
170             pause = readUChar();
171 
172       // readDuration
173       int len   = readChar();
174       int tuple = 0;
175       if (beatBits & BEAT_TUPLET)
176             tuple = readInt();
177 
178       Segment* segment = measure->getSegment(SegmentType::ChordRest, tick);
179       if (beatBits & BEAT_CHORD) {
180             int numStrings = score->staff(staffIdx)->part()->instrument()->stringData()->strings();
181             skip(17);
182 #if 0
183             uchar header = readUChar(); //1
184 		uchar sharp = readUChar(); //2
185 		skip(3); //5
186 		char root = readChar(); //6
187 		uchar chordtype = readUChar();//7
188 		uchar nines = readUChar();//8
189 		int bass = readInt();//12
190 		int aug = readInt(); //16
191 		char add = readChar(); //17
192 #endif
193             QString name;
194             {
195 		      /*auto len =*/ readUChar();
196 			char c[21];
197 			f->read(c, 21);
198 			// if (len > 20)
199 			//      skip(len - 20);
200                   //skip(len - 20);
201 			c[20] = 0;
202 			name = c;
203 			}
204             //QString name = readPascalString(21);
205             skip(4);
206             // no header to be read in the GP5 format - default to true.
207             readChord(segment, staffIdx * VOICES, numStrings, name, true);
208             skip(32);
209             }
210       Lyrics* lyrics = 0;
211       QString free_text;
212       if (beatBits & BEAT_LYRICS) {
213             //free_text = readDelphiString();
214 		QString qs = readDelphiString();
215             std::string txt = qs.toUtf8().constData();
216      	      txt.erase(std::remove_if(txt.begin(), txt.end(), [](char c) {return c == '_'; }), txt.end());
217 //		auto pos = txt.find('-');
218 		auto buffer = txt;
219 		txt.resize(0);
220 		const char* c = buffer.c_str();
221             while (*c) {
222                   if (*c == ' ') {
223                         while (*c == ' ')
224                               ++c;
225                         if (*c == '-') {
226 				      txt += '-';
227                               ++c;
228 					while (*c == ' ')
229                                     ++c;
230 				      }
231                         else if (*c)
232                               txt += '-';
233 			      }
234                   else
235                         txt += *(c++);
236 		      }
237             if (gpLyrics.lyrics.size() == 0 || (gpLyrics.lyrics.size() == 1 && gpLyrics.lyrics[0].isEmpty())) {
238 //			gpLyrics.lyrics.resize(0);
239                   gpLyrics.lyrics.clear();
240 			gpLyrics.fromBeat = _beat_counter;
241 			gpLyrics.lyricTrack = track;
242 		      }
243             while (txt.size() && txt[txt.size() - 1] == '-')
244                   txt.resize(txt.size() - 1);
245 //		  gpLyrics.lyrics.append(txt);
246             gpLyrics.lyrics.append(QString::fromUtf8(txt.data(), int(txt.size())));
247 		gpLyrics.segments.push_back(segment);
248             }
249 #if 0
250       gpLyrics.beatCounter++;
251       if (false && gpLyrics.beatCounter >= gpLyrics.fromBeat && gpLyrics.lyricTrack == staffIdx+1) {
252             int index = gpLyrics.beatCounter - gpLyrics.fromBeat;
253             if (index < gpLyrics.lyrics.size()) {
254 		      lyrics = new Lyrics(score);
255 			lyrics->setPlainText(gpLyrics.lyrics[index]);
256                   }
257             }
258 #endif
259       int beatEffects = 0;
260       if (beatBits & BEAT_EFFECTS)
261             beatEffects = readBeatEffects(track, segment);
262       last_segment = segment;
263       if (beatBits & BEAT_MIX_CHANGE)
264             readMixChange(measure);
265 
266       int strings = readUChar();   // used strings mask
267 
268       Fraction l  = len2fraction(len);
269 
270       // Some beat effects could add a Chord before this
271       ChordRest* cr = segment->cr(track);
272       if (voice != 0 && pause == 0 && strings == 0)
273             cr = 0;
274       else {
275             if (strings == 0) {
276                   if (cr) {
277                         segment->remove(cr);
278                         delete cr;
279                         cr = 0;
280                         }
281                   cr = new Rest(score);
282                   }
283             else  {
284                   if (!cr)
285                         cr = new Chord(score);
286                   }
287             cr->setParent(segment);
288             cr->setTrack(track);
289 
290             TDuration d(l);
291             d.setDots(dotted ? 1 : 0);
292 
293             if (dotted)
294                   l = l + (l * Fraction(1,2));
295 
296             if (tuple) {
297                   Tuplet* tuplet = tuplets[staffIdx * 2 + voice];
298                   if ((tuplet == 0) || (tuplet->elementsDuration() == tuplet->baseLen().fraction() * tuplet->ratio().numerator())) {
299                         tuplet = new Tuplet(score);
300                         tuplet->setTick(tick);
301                         // int track = staffIdx * 2 + voice;
302                         tuplets[staffIdx * 2 + voice] = tuplet;
303                         tuplet->setTrack(cr->track());
304                         setTuplet(tuplet, tuple);
305                         tuplet->setParent(measure);
306                         }
307                   tuplet->setTrack(cr->track());
308                   tuplet->setBaseLen(l);
309                   tuplet->setTicks(l * tuplet->ratio().denominator());
310                   cr->setTuplet(tuplet);
311                   tuplet->add(cr);
312                   }
313 
314             cr->setTicks(l);
315             if (cr->isRest() && (pause == 0 || l >= measure->ticks())) {
316                   cr->setDurationType(TDuration::DurationType::V_MEASURE);
317                   cr->setTicks(measure->ticks());
318                   }
319             else
320                   cr->setDurationType(d);
321 
322             if (!segment->cr(track))
323                   segment->add(cr);
324 
325             Staff* staff = cr->staff();
326             int numStrings = staff->part()->instrument()->stringData()->strings();
327             bool hasSlur = false;
328 		Note* _note{ nullptr };
329 		std::vector<Note*> delnote;
330             for (int i = 6; i >= 0; --i) {
331                   if (strings & (1 << i) && ((6-i) < numStrings)) {
332                         Note* note = new Note(score);
333 				_note = note;
334                         if (dotted) {
335                               // there is at most one dotted note in this guitar pro version
336                               NoteDot* dot = new NoteDot(score);
337                               dot->setParent(note);
338                               dot->setTrack(track);  // needed to know the staff it belongs to (and detect tablature)
339                               dot->setVisible(true);
340                               note->add(dot);
341                               }
342                         toChord(cr)->add(note);
343 
344                         hasSlur = (readNote(6-i, note) || hasSlur);
345                         if (slideList.size() && slideList.back() == nullptr) {
346                               slideList.back() = note;
347 					hasSlur = true;
348 					}
349                         if (note->fret() == -20) {
350                               delnote.push_back(note);
351 #if 0
352 					Chord* chord = toChord(cr);
353 					chord->remove(note);
354                               delete note;
355 					if (chord->notes().empty()) {
356                                     chord->segment()->remove(chord);
357 						delete chord;
358 						cr = nullptr;
359 						}
360 #endif
361 				      }
362 			      else
363 				      note->setTpcFromPitch();
364                         }
365                   }
366             if (delnote.size()) {
367                   Chord* chord = toChord(cr);
368                   for (auto n : delnote) {
369                         chord->remove(n);
370                         delete n;
371                         }
372                   if (chord->notes().empty()) {
373                         if (chord->tuplet())
374                               chord->tuplet()->remove(chord);
375                         chord->segment()->remove(chord);
376                         delete chord;
377 				cr = nullptr;
378 				}
379                   delnote.clear();
380 			}
381             createSlur(hasSlur, staffIdx, cr);
382             if (lyrics)
383                   cr->add(lyrics);
384 			if (free_text.length() && _note) {
385 				addTextToNote(free_text, Align::CENTER, _note);
386 			      }
387 
388             }
389       int rr = readChar();
390       if (cr && cr->isChord()) {
391             Chord* chord = toChord(cr);
392             do {
393                   applyBeatEffects(chord, beatEffects % 100);
394             } while (beatEffects /= 100);
395             if (rr == ARPEGGIO_DOWN)
396                   chord->setStemDirection(Direction::DOWN);
397             else if (rr == ARPEGGIO_UP)
398                   chord->setStemDirection(Direction::UP);
399             }
400       int r = readChar();
401       if (r & 0x8) {
402             int rrr = readChar();
403 qDebug("  3beat read 0x%02x", rrr);
404            }
405       if (cr && cr->isChord()) {
406 	      if (toChord(cr)->notes().size() == 0) {
407                   segment->remove(cr);
408                   delete cr;
409 			cr = 0;
410 		      }
411             else if (slide > 0)
412                   createSlide(slide, cr, staffIdx);
413 	      }
414       restsForEmptyBeats(segment, measure, cr, l, track, tick);
415       return cr ? cr->actualTicks() : measure->ticks();
416       }
417 
418 //---------------------------------------------------------
419 //   readMeasure
420 //---------------------------------------------------------
421 
readMeasure(Measure * measure,int staffIdx,Tuplet ** tuplets,bool mixChange)422 void GuitarPro5::readMeasure(Measure* measure, int staffIdx, Tuplet** tuplets, bool mixChange)
423       {
424       for (int voice = 0; voice < 2; ++voice) {
425             Fraction measureLen = { 0,1 };
426             Fraction tick       = measure->tick();
427             int beats           = readInt();
428             if (beats > 100)
429                   return;
430             for (int beat = 0; beat < beats; ++beat) {
431                   Fraction ticks = readBeat(tick, voice, measure, staffIdx, tuplets, mixChange);
432 			++_beat_counter;
433                   tick += ticks;
434                   measureLen += ticks;
435                   }
436             if (measureLen < measure->ticks()) {
437                   score->setRest(tick, staffIdx * VOICES + voice, measure->ticks() - measureLen, false, nullptr, false);
438                   }
439             }
440       }
441 
442 //---------------------------------------------------------
443 //   readMixChange
444 //---------------------------------------------------------
445 
readMixChange(Measure * measure)446 bool GuitarPro5::readMixChange(Measure* measure)
447       {
448       /*char patch   =*/ readChar();
449       skip(16);
450       signed char volume  = readChar();
451       signed char pan     = readChar();
452       signed char chorus  = readChar();
453       signed char reverb  = readChar();
454       signed char phase   = readChar();
455       signed char tremolo = readChar();
456       readDelphiString();                 // tempo name
457 
458       int temp = readInt();
459       bool editedTempo = false;
460       if (volume >= 0)
461             readChar();
462       if (pan >= 0)
463             readChar();
464       if (chorus >= 0)
465             readChar();
466       if (reverb >= 0)
467             readChar();
468       //qDebug("read reverb: %d", reverb);
469       if (phase >= 0)
470             readChar();
471       if (tremolo >= 0)
472             readChar();
473       if (temp >= 0) {
474             if (last_segment) {
475                   score->setTempo(last_segment->tick(), double(temp) / 60.0);
476 			last_segment = nullptr;
477 		      }
478             if (temp != previousTempo) {
479                   previousTempo = temp;
480                   setTempo(temp, measure);
481                   editedTempo = true;
482                   }
483             readChar();
484             if (version > 500)
485                  readChar();
486             }
487       readChar();
488       readChar();
489       if (version > 500) {
490             readDelphiString();
491             readDelphiString();
492             }
493       return editedTempo;
494       }
495 
496 //---------------------------------------------------------
497 //   readTracks
498 //---------------------------------------------------------
499 
readTracks()500 bool GuitarPro5::readTracks()
501       {
502       for (int i = 0; i < staves; ++i) {
503             int tuning[GP_MAX_STRING_NUMBER];
504             Staff* staff = score->staff(i);
505             Part* part = staff->part();
506 
507             uchar c = readUChar();   // simulations bitmask
508             if (c & 0x2) {           // 12 stringed guitar
509                   }
510             if (c & 0x4) {           // banjo track
511                   }
512             if (i == 0 || version == 500)
513                   skip(1);
514             QString name = readPascalString(40);
515 
516             int strings  = readInt();
517             if (strings <= 0 || strings > GP_MAX_STRING_NUMBER)
518                 return false;
519             for (int j = 0; j < strings; ++j) {
520                   tuning[j] = readInt();
521                   }
522             for (int j = strings; j < GP_MAX_STRING_NUMBER; ++j)
523                   readInt();
524             int midiPort     = readInt() -1;
525             int midiChannel  = readInt() - 1;
526             /*int midiChannel2 =*/ readInt();   // -1
527 
528             int frets        = readInt();
529             int capo         = readInt();
530             /*int color        =*/ readInt();
531 
532             skip(version > 500 ? 49 : 44);
533             if (version > 500) {
534                   //  british stack clean / amp tone
535                   readDelphiString();
536                   readDelphiString();
537                   }
538 			std::vector<int> tuning2(strings);
539             //int tuning2[strings];
540             for (int k = 0; k < strings; ++k)
541                   tuning2[strings-k-1] = tuning[k];
542             StringData stringData(frets, strings, &tuning2[0]);
543 			createTuningString(strings, &tuning2[0]);
544             Instrument* instr = part->instrument();
545             instr->setStringData(stringData);
546             instr->setSingleNoteDynamics(false);
547             part->setPartName(name);
548             part->setPlainLongName(name);
549 
550             //
551             // determine clef
552             //
553             int patch = channelDefaults[midiChannel].patch;
554             ClefType clefId = ClefType::G;
555             if (midiChannel == GP_DEFAULT_PERCUSSION_CHANNEL) {
556                   clefId = ClefType::PERC;
557                   // instr->setUseDrumset(DrumsetKind::GUITAR_PRO);
558                   instr->setDrumset(gpDrumset);
559                   staff->setStaffType(Fraction(0,1), *StaffType::preset(StaffTypes::PERC_DEFAULT));
560                   }
561             else
562                   clefId = defaultClef(patch);
563             Measure* measure = score->firstMeasure();
564             Clef* clef = new Clef(score);
565             clef->setClefType(clefId);
566             clef->setTrack(i * VOICES);
567             Segment* segment = measure->getSegment(SegmentType::HeaderClef, Fraction(0,1));
568             segment->add(clef);
569 
570             if (capo > 0) {
571                   Segment* s = measure->getSegment(SegmentType::ChordRest, measure->tick());
572                   StaffText* st = new StaffText(score);
573                   st->setPlainText(QString("Capo. fret ") + QString::number(capo));
574                   st->setTrack(i * VOICES);
575                   s->add(st);
576                   }
577 
578             Channel* ch = instr->channel(0);
579             if (midiChannel == GP_DEFAULT_PERCUSSION_CHANNEL) {
580                   ch->setProgram(0);
581                   ch->setBank(128);
582                   }
583             else {
584                   ch->setProgram(patch);
585                   ch->setBank(0);
586                   }
587             ch->setVolume(channelDefaults[midiChannel].volume);
588             ch->setPan(channelDefaults[midiChannel].pan);
589             ch->setChorus(channelDefaults[midiChannel].chorus);
590             ch->setReverb(channelDefaults[midiChannel].reverb);
591             staff->part()->setMidiChannel(midiChannel, midiPort);
592 
593             //qDebug("default2: %d", channelDefaults[i].reverb);
594             // missing: phase, tremolo
595             }
596       skip(version == 500 ? 2 : 1);
597 
598       return true;
599       }
600 
601 //---------------------------------------------------------
602 //   readMeasures
603 //---------------------------------------------------------
604 
readMeasures(int)605 void GuitarPro5::readMeasures(int /*startingTempo*/)
606       {
607       Measure* measure = score->firstMeasure();
608       bool mixChange = false;
609       for (int bar = 0; bar < measures; ++bar, measure = measure->nextMeasure()) {
610             const GpBar& gpbar = bars[bar];
611 
612             if (!gpbar.marker.isEmpty()) {
613                   RehearsalMark* s = new RehearsalMark(score);
614                   s->setPlainText(gpbar.marker.trimmed());
615                   s->setTrack(0);
616                   Segment* segment = measure->getSegment(SegmentType::ChordRest, measure->tick());
617                   segment->add(s);
618                   }
619 
620 			std::vector<Tuplet*> tuplets(staves * 2);
621             //Tuplet* tuplets[staves * 2];     // two voices
622             for (int track = 0; track < staves*2; ++track)
623                   tuplets[track] = 0;
624 
625             for (int staffIdx = 0; staffIdx < staves; ++staffIdx) {
626                   _beat_counter = 0;
627                   readMeasure(measure, staffIdx, &tuplets[0], mixChange);
628                   if (!(((bar == (measures-1)) && (staffIdx == (staves-1))))) {
629                         /*int a = */  readChar();
630                         // qDebug("    ======skip %02x", a);
631                         }
632                   }
633             if (bar == 1 && !mixChange)
634                   setTempo(tempo, score->firstMeasure());
635             }
636 
637       if (gpLyrics.segments.size()) {
638             auto size = std::min(int(gpLyrics.segments.size()), int(gpLyrics.lyrics.size()));
639 		for (int i = 0; i < size; ++i) {
640                   std::string str = gpLyrics.lyrics[i].toUtf8().constData();
641 			auto seg = gpLyrics.segments[i];
642 			auto mes = seg->measure();
643 			while (str.size() && seg && seg->segmentType() == SegmentType::ChordRest) {
644                         auto cr = seg->cr(gpLyrics.lyricTrack);
645 				if (cr) {
646                               if (str[0] != '-') {
647                                     auto lyr = new Lyrics(score);
648 
649 						std::string text;
650 						auto pos = str.find('-');
651 						auto pos2 = str.find('\n');
652 						if (pos2 < pos)
653                                           pos = pos2;
654 					      if (pos != std::string::npos) {
655                                           const char* c = &str.c_str()[pos + 1];
656 							if (*c == 0) {
657                                                 pos = std::string::npos;
658 								text = str;
659                                                 }
660                                           else {
661                                                 text = str.substr(0, pos);
662                                                 str = str.substr(pos + 1);
663                                                 }
664                                           }
665                                     else
666                                           text = str;
667                                     if (pos == std::string::npos)
668                                           str.resize(0);
669                                     lyr->setPlainText(QString::fromUtf8(text.data(), int(text.size())));
670                                     cr->add(lyr);
671                                     }
672                               else {
673                                     str = str.substr(1);
674                                     }
675                               }
676                         seg = seg->next();
677                         if (!seg) {
678                               mes = mes->nextMeasure();
679                               if (!mes)
680                                     break;
681                               seg = mes->first();
682                               }
683                         }
684                   }
685             }
686       else {
687             int counter = 0;
688 //            int index = 0;
689 //TODO-ws ???		gpLyrics.lyricTrack -= 1;
690 		auto mes = score->firstMeasure();
691 		auto beg = mes->first();
692 
693 		do {
694 		      if (beg->isChordRestType() && beg->cr(gpLyrics.lyricTrack)) {
695                         ChordRest* cr = beg->cr(gpLyrics.lyricTrack);
696 				++counter;
697 				if (!cr->isChord())
698                               continue;
699                         bool is_tied = false;
700 				Chord* chord = toChord(cr);
701 				for (auto n : chord->notes()) {
702 				      if (n->tiedNotes().size() > 1 && n->tiedNotes()[0] != n) {
703                                     is_tied = true;
704 						break;
705 					      }
706                               }
707                         if (is_tied)
708                               continue;
709 #if 0 // TODO-ws
710                         if (counter >= gpLyrics.fromBeat) {
711                               if (gpLyrics.lyrics[index][0] != '-') {
712                                     auto lyr = new Lyrics(score);
713 
714                                     std::string text;
715 						auto pos  = gpLyrics.lyrics[index].find('-');
716 						auto pos2 = gpLyrics.lyrics[index].find('\n');
717 						if (pos2 < pos)
718                                           pos = pos2;
719 						if (pos != std::string::npos) {
720                                           const char* c = &gpLyrics.lyrics[index].c_str()[pos + 1];
721 							if (*c == 0) {
722                                                 pos = std::string::npos;
723 								text = gpLyrics.lyrics[index];
724 							      }
725                                           else {
726                                                 text = gpLyrics.lyrics[index].substr(0, pos);
727 								auto str = gpLyrics.lyrics[index].substr(pos + 1);
728 								gpLyrics.lyrics[index] = str;
729 								if (str.length())
730 								      gpLyrics.lyrics[index][0] = str[0];
731 							      }
732 						      }
733 						else
734                                           text = gpLyrics.lyrics[index];
735                                     if (pos == std::string::npos)
736                                           ++index;
737                                     lyr->setPlainText(text);
738 						cr->add(lyr);
739 						if (index >= gpLyrics.lyrics.size())
740 							  break;
741 					      }
742                               else {
743                                     //TODO: Need studio new release, bug here
744 						std::string s = &gpLyrics.lyrics[index].c_str()[1];
745 						gpLyrics.lyrics[index] = s;
746 						if (s.length())
747                                           gpLyrics.lyrics[index][0] = s[0];
748 					      }
749 				      }
750 #endif
751 			      }
752 		      } while ((beg = beg->next()) || ((mes = toMeasure(mes->next())) && (beg = mes->first())));
753             }
754       }
755 
756 //---------------------------------------------------------
757 //   read
758 //---------------------------------------------------------
759 
read(QFile * fp)760 bool GuitarPro5::read(QFile* fp)
761       {
762       f = fp;
763 
764       readInfo();
765       readLyrics();
766       readPageSetup();
767 
768       previousDynamic = -1;
769       previousTempo = -1;
770       //previousDynamic = new int [staves * VOICES];
771       // initialise the dynamics to 0
772       //for (int i = 0; i < staves * VOICES; i++)
773       //      previousDynamic[i] = 0;
774 
775       tempo = readInt();
776       if (version > 500)
777             skip(1);
778 
779       key    = readInt();
780       /* int octave =*/ readChar();    // octave
781 
782       readChannels();
783 
784       std::vector<unsigned int> articulations;
785 	articulations.resize(19);
786 	{
787             unsigned int r; unsigned char x;
788 		for (int i = 0; i < 19; ++i) {
789                   x = readUChar();
790 			r = x;
791 			x = readUChar();
792 			r += x << 8;
793 
794 			articulations[i] = r;
795 		      }
796 	      }
797 
798       //skip(42);
799       skip(4);
800 
801       measures = readInt();
802       staves  = readInt();
803 
804 	for (int str = 0; str < 7; ++str) {
805 	      for (int staff = 0; staff < staves; ++staff)
806 		      dead_end[{staff, str}] = true;
807             }
808 
809       slurs = new Slur*[staves];
810       for (int i = 0; i < staves; ++i)
811             slurs[i] = 0;
812 
813       int tnumerator   = 4;
814       int tdenominator = 4;
815       for (int i = 0; i < measures; ++i) {
816             if (i > 0)
817                   skip(1);
818             GpBar bar;
819             uchar barBits = readUChar();
820             if (barBits & SCORE_TIMESIG_NUMERATOR)
821                   tnumerator = readUChar();
822             if (barBits & SCORE_TIMESIG_DENOMINATOR)
823                   tdenominator = readUChar();
824             if (barBits & SCORE_REPEAT_START)
825                   bar.repeatFlags = bar.repeatFlags | Repeat::START;
826             if (barBits & SCORE_REPEAT_END) {                // number of repeats
827                   bar.repeatFlags = bar.repeatFlags |Repeat::END;
828                   bar.repeats = readUChar();
829                   }
830             if (barBits & SCORE_MARKER) {
831                   bar.marker = readDelphiString();     // new section?
832                   /*int color =*/ readInt();    // color?
833                   }
834             if (barBits & SCORE_VOLTA) {                      // a volta
835                   uchar voltaNumber = readUChar();
836                   while (voltaNumber > 0) {
837                         // voltas are represented as flags
838                         bar.volta.voltaType = GP_VOLTA_FLAGS;
839                         bar.volta.voltaInfo.append(voltaNumber & 1);
840                         voltaNumber >>= 1;
841                         }
842                   }
843             if (barBits & SCORE_KEYSIG) {
844                   int currentKey = readUChar();
845                   /* key signatures are specified as
846                    * 1# = 1, 2# = 2, ..., 7# = 7
847                    * 1b = 255, 2b = 254, ... 7b = 249 */
848                   bar.keysig = currentKey <= 7 ? currentKey : -256+currentKey;
849                   readUChar();        // specified major/minor mode
850                   }
851             if (barBits & SCORE_DOUBLE_BAR)
852                   bar.barLine = BarLineType::DOUBLE;
853             if (barBits & 0x3) {
854                   skip(4);
855                   }
856             if ((barBits & 0x10) == 0) {
857                   skip(1);
858 			}
859 
860             readChar();             // triple feel  (none, 8, 16)
861             bar.timesig = Fraction(tnumerator, tdenominator);
862             bars.append(bar);
863             }
864 
865       //
866       // create a part for every staff
867       //
868       for (int staffIdx = 0; staffIdx < staves; ++staffIdx) {
869             Part* part = new Part(score);
870             Staff* s = new Staff(score);
871             s->setPart(part);
872             part->insertStaff(s, -1);
873             score->staves().push_back(s);
874             score->appendPart(part);
875             }
876 
877       createMeasures();
878       if (!readTracks()) {
879             return false;
880             }
881       readMeasures(tempo);
882       for (auto n : slideList) {
883 //		Note* next = nullptr;
884             auto segment = n->chord()->segment();
885 		auto measure = segment->measure();
886 		while ((segment = segment->next1(SegmentType::ChordRest)) || ((measure = measure->nextMeasure() ) && (segment = measure->first()))) {
887                   if (segment->segmentType() != SegmentType::ChordRest)
888 			      continue;
889                   bool br = false;
890 			ChordRest* cr = toChordRest(segment->cr(n->track()));
891 			if (cr && cr->isChord()) {
892                         Chord* c = toChord(cr);
893 			      for (auto nt : c->notes()) {
894 				      if (nt->string() == n->string()) {
895                                     for (auto e : nt->el())
896 						      if (e->isChordLine()) {
897                                                 ChordLine* cl = toChordLine(e);
898 								if (cl->chordLineType() == ChordLineType::PLOP || cl->chordLineType() == ChordLineType::SCOOP) {
899                                                       br = true;
900 									break;
901 								      }
902 							      }
903 				            if (br)
904                                           break;
905                                     Glissando* s = new Glissando(score);
906 						s->setAnchor(Spanner::Anchor::NOTE);
907 						s->setStartElement(n);
908 						s->setTick(n->chord()->segment()->tick());
909 						s->setTrack(n->track());
910 						s->setParent(n);
911 						s->setGlissandoType(GlissandoType::STRAIGHT);
912 						s->setEndElement(nt);
913 						s->setTick2(nt->chord()->segment()->tick());
914 						s->setTrack2(n->track());
915 						score->addElement(s);
916 						br = true;
917 						break;
918                                     }
919                               }
920                         }
921 			if (br)
922                         break;
923 		      }
924             }
925 
926 	  std::map<int, int> counter;
927 	  for (int i = 0; i < 19; ++i) {
928 		  if (articulations[i] != 0xFFFF) {
929                   Measure* measure = toMeasure(score->measure(articulations[i] - 1));
930 			if (i < 4) {
931                         Segment* segment = measure->getSegment(SegmentType::BarLine, measure->tick());
932                         Symbol* sym = new Symbol(score);
933 				if (i == 0)
934                               sym->setSym(SymId::coda);
935                         else if (i == 1) {
936 #if 0
937 				      sym->setSym(SymId::coda);
938 					Symbol* s2 = new Symbol(score);
939 					s2->setSym(SymId::coda);
940 					s2->setXoffset(5.5f);
941 					auto iter = counter.find(articulations[i]);
942 					if (iter != counter.end())
943 					      s2->setElYOffset(-7.0f * iter->second);
944                               s2->setParent(measure);
945 				      s2->setTrack(0);
946 					segment->add(s2);
947 #endif
948 					sym->setSym(SymId::codaSquare);
949 				      }
950 				else if (i == 2)
951                               sym->setSym(SymId::segno);
952 				else {
953 #if 0
954 					sym->setSym(SymId::segno);
955                               Symbol* s2 = new Symbol(score);
956 					s2->setSym(SymId::segno);
957 					s2->setXoffset(5.5f);
958 					auto iter = counter.find(articulations[i]);
959 					if (iter != counter.end())
960 						  s2->setElYOffset(-7.0f * iter->second);
961 					s2->setParent(measure);
962 					s2->setTrack(0);
963 					segment->add(s2);
964 #endif
965 					sym->setSym(SymId::segnoSerpent2);
966 				      }
967 
968 
969                         sym->setParent(measure);
970 				sym->setTrack(0);
971 				segment->add(sym);
972 				auto iter = counter.find(articulations[i]);
973 				if (iter == counter.end())
974 				      counter[articulations[i]] = 1;
975                         else {
976 //TODO-ws		            sym->setElYOffset(-7.0f * counter[articulations[i]]);
977 					counter[articulations[i]] += 1;
978 				      }
979                         }
980                   else {
981                         Segment* s = measure->getSegment(SegmentType::KeySig, measure->tick());
982 				StaffText* st = new StaffText(score);
983 				static constexpr char text[][22] = {
984 					"fine", "Da Capo", "D.C. al Coda", "D.C. al Double Coda",
985 					"D.C. al Fine", "Da Segno", "D.S. al Coda", "D.S. al Double Coda",
986 					"D.S. al Fine", "Da Segno Segno", "D.S.S. al Coda", "D.S.S. al Double Coda",
987 					"D.S.S. al Fine", "Da Coda", "Da Double Coda"
988 				      };
989 			      st->setPlainText(text[i - 4]);
990 				st->setParent(s);
991 				st->setTrack(0);
992 //TODO-ws			st->_measureEnd = true;
993 				auto iter = counter.find(articulations[i]);
994 				if (iter == counter.end())
995 				      counter[articulations[i]] = 1;
996                         else {
997 //TODO-ws                     st->setElYOffset(-7.0f * counter[articulations[i]]);
998 					counter[articulations[i]] += 1;
999 				      }
1000                         score->addElement(st);
1001 			      }
1002 		      }
1003 	      }
1004       return true;
1005       }
1006 
1007 //---------------------------------------------------------
1008 //   readNoteEffects
1009 //---------------------------------------------------------
1010 
readNoteEffects(Note * note)1011 bool GuitarPro5::readNoteEffects(Note* note)
1012       {
1013       uchar modMask1 = readUChar();
1014       uchar modMask2 = readUChar();
1015       bool slur = false;
1016 
1017       if (modMask1 & EFFECT_BEND) {
1018             readBend(note);
1019             }
1020       if (modMask1 & EFFECT_HAMMER) {
1021             slur = true;
1022 #if 0
1023 		Symbol* s = new Symbol(score);
1024 		s->setSym(SymId::articLaissezVibrerBelow);
1025 		s->setParent(note);
1026 		note->add(s);
1027 #endif
1028 	      }
1029       if (modMask1 & EFFECT_LET_RING)
1030 	      addLetRing(note);
1031 		//note->setLetRing(true);
1032 
1033       if (modMask1 & EFFECT_GRACE) {
1034             int fret = readUChar();            // grace fret
1035             /*int dynamic =*/ readUChar();            // grace dynamic
1036             int transition = readUChar();            // grace transition
1037             /*int duration =*/ readUChar();            // grace duration
1038             int gflags = readUChar();
1039 
1040 		NoteType note_type = NoteType::ACCIACCATURA;
1041 
1042             if (gflags & NOTE_APPOGIATURA) //on beat
1043                   note_type = NoteType::APPOGGIATURA;
1044 
1045 #if 0
1046             int grace_len = MScore::division/8;
1047             if (duration == 1)
1048                   grace_len = MScore::division/8; //32th
1049             else if (duration == 2)
1050                   grace_len = MScore::division/6; //24th
1051             else if (duration == 3)
1052                   grace_len = MScore::division/4; //16th
1053             Note* gn = new Note(score);
1054 
1055             if (gflags & EFFECT_GHOST) {
1056                   gn->setHeadGroup(NoteHead::Group::HEAD_CROSS);
1057                   gn->setGhost(true);
1058                   }
1059             gn->setFret(fret);
1060             gn->setString(note->string());
1061 #endif
1062             int grace_pitch = note->staff()->part()->instrument()->stringData()->getPitch(note->string(), fret, nullptr, Fraction(0,1));
1063 #if 0
1064             gn->setPitch(grace_pitch);
1065             gn->setTpcFromPitch();
1066 
1067             Chord* gc = new Chord(score);
1068             gc->setTrack(note->chord()->track());
1069             gc->add(gn);
1070             gc->setParent(note->chord());
1071 
1072             TDuration d;
1073             d.setVal(grace_len);
1074             if (grace_len == MScore::division/6)
1075                   d.setDots(1);
1076             gc->setDurationType(d);
1077             gc->setTicks(d.fraction());
1078             gc->setNoteType(note_type);
1079             gc->setMag(note->chord()->staff()->mag(0) * score->styleD(Sid::graceNoteMag));
1080             note->chord()->add(gc);
1081             addDynamic(gn, dynamic);
1082 #endif
1083 		auto gnote = score->setGraceNote(note->chord(), grace_pitch, note_type, MScore::division / 2);
1084 		gnote->setString(note->string());
1085 		auto sd = note->part()->instrument()->stringData();
1086 		gnote->setFret(grace_pitch - sd->stringList().at(sd->stringList().size() - note->string() - 1).pitch);
1087             if (transition == 0) {
1088                   // no transition
1089                   }
1090             else if (transition == 1) {
1091 			}
1092 	      else if (transition == 3) {
1093 		      Slur* slur1 = new Slur(score);
1094 			slur1->setAnchor(Spanner::Anchor::CHORD);
1095 			slur1->setStartElement(gnote->chord());
1096 			slur1->setEndElement(note->chord());
1097 			slur1->setParent(0);
1098 			slur1->setTrack(note->staffIdx());
1099 			slur1->setTrack2(note->staffIdx());
1100 			slur1->setTick(gnote->chord()->tick());
1101 			slur1->setTick2(note->chord()->tick());
1102 //TODO-ws		note->chord()->has_slur = true;
1103 			score->addElement(slur1);
1104                   //TODO: Add a 'slide' guitar effect when implemented
1105 			//note->setSlideNote(gn);
1106                   }
1107 #if 0
1108             else if (transition == 2 && note->fret()>=0 && note->fret()<=255 && note->fret()!=gn->fret()) {
1109                   QList<PitchValue> points;
1110                   points.append(PitchValue(0,0, false));
1111                   points.append(PitchValue(60,(note->fret()-gn->fret())*100, false));
1112 
1113                   Bend* b = new Bend(note->score());
1114                   b->setPoints(points);
1115                   b->setTrack(gn->track());
1116                   gn->add(b);
1117                   }
1118              else if (transition == 3) {
1119                    // TODO:
1120                    //     major: replace with a 'hammer-on' guitar effect when implemented
1121                    //     minor: make slurs for parts
1122 
1123                    ChordRest* cr1 = toChord(gc);
1124                    ChordRest* cr2 = toChord(note->chord());
1125 
1126                    Slur* slur = new Slur(score);
1127                    slur->setAnchor(Spanner::Anchor::CHORD);
1128                    slur->setStartElement(cr1);
1129                    slur->setEndElement(cr2);
1130                    slur->setTick(cr1->tick());
1131                    slur->setTick2(cr2->tick());
1132                    slur->setTrack(cr1->track());
1133                    slur->setTrack2(cr2->track());
1134                    // this case specifies only two-note slurs, don't set a parent
1135                    score->undoAddElement(slur);
1136                    }
1137 #endif
1138             }
1139       if (modMask2 & EFFECT_STACATTO) {
1140             Chord* chord = note->chord();
1141             Articulation* a = new Articulation(chord->score());
1142             a->setSymId(SymId::articStaccatoAbove);
1143 		bool add = true;
1144 		for (auto a1 : chord->articulations()) {
1145 		      if (a1->symId() == SymId::articStaccatoAbove) {
1146 			      add = false;
1147 				break;
1148 				}
1149                   }
1150             if (add)
1151                   chord->add(a);
1152             }
1153       if (modMask2 & EFFECT_PALM_MUTE)
1154 	      addPalmMute(note);
1155 		//note->setPalmMute(true);
1156 
1157       if (modMask2 & EFFECT_TREMOLO) {    // tremolo picking length
1158             int tremoloDivision = readUChar();
1159             Chord* chord = note->chord();
1160             Tremolo* t = new Tremolo(score);
1161             if (tremoloDivision == 1) {
1162                   t->setTremoloType(TremoloType::R8);
1163                   chord->add(t);
1164                   }
1165             else if (tremoloDivision == 2) {
1166                   t->setTremoloType(TremoloType::R16);
1167                   chord->add(t);
1168                   }
1169             else if (tremoloDivision == 3) {
1170                   t->setTremoloType(TremoloType::R32);
1171                   chord->add(t);
1172                   }
1173             else
1174                   qDebug("Unknown tremolo value");
1175             }
1176 //      bool skip = false;
1177       if (modMask2 & EFFECT_SLIDE) {
1178             int slideKind = readUChar();
1179 		if (slideKind & SLIDE_OUT_DOWN) {
1180 		      slideKind &= ~SLIDE_OUT_DOWN;
1181 			ChordLine* cl = new ChordLine(score);
1182 			cl->setChordLineType(ChordLineType::FALL);
1183 			cl->setStraight(true);
1184 			note->add(cl);
1185 //			skip = true;
1186 			}
1187 	      // slide out upwards (doit)
1188 		if (slideKind & SLIDE_OUT_UP) {
1189 		      slideKind &= ~SLIDE_OUT_UP;
1190 			ChordLine* cl = new ChordLine(score);
1191 			cl->setChordLineType(ChordLineType::DOIT);
1192 			cl->setStraight(true);
1193 			note->add(cl);
1194 //			skip = true;
1195 			}
1196             // slide in from below (plop)
1197 		if (slideKind & SLIDE_IN_BELOW) {
1198 		      slideKind &= ~SLIDE_IN_BELOW;
1199 			ChordLine* cl = new ChordLine(score);
1200 			cl->setChordLineType(ChordLineType::PLOP);
1201 			cl->setStraight(true);
1202 			note->add(cl);
1203 //			skip = true;
1204 			}
1205 	      // slide in from above (scoop)
1206 		if (slideKind & SLIDE_IN_ABOVE) {
1207 		      slideKind &= ~SLIDE_IN_ABOVE;
1208 			ChordLine* cl = new ChordLine(score);
1209 			cl->setChordLineType(ChordLineType::SCOOP);
1210 			cl->setStraight(true);
1211 			note->add(cl);
1212 //			skip = true;
1213 			}
1214 
1215 	      if (false && !slideList.empty() && slideList.back()->chord()->segment() != note->chord()->segment()) {
1216                   Note* start = slideList.front();
1217 			slideList.pop_front();
1218 			bool skip = false;
1219 			for (auto e : start->el()) {
1220 			      if (e->isChordLine())
1221                               skip = true;
1222                         }
1223                   if (!skip) {
1224 			      Glissando* s = new Glissando(score);
1225 				s->setAnchor(Spanner::Anchor::NOTE);
1226 				s->setStartElement(start);
1227 				s->setTick(start->chord()->segment()->tick());
1228 				s->setTrack(start->staffIdx());
1229 				s->setParent(start);
1230 				s->setGlissandoType(GlissandoType::STRAIGHT);
1231 				s->setEndElement(note);
1232 				s->setTick2(note->chord()->segment()->tick());
1233 				s->setTrack2(note->staffIdx());
1234 				score->addElement(s);
1235 				}
1236 			}
1237             if (slideKind & LEGATO_SLIDE) {
1238                   slideKind &= ~LEGATO_SLIDE;
1239 			slideList.push_back(nullptr);
1240 			createSlur(true, note->staffIdx(), note->chord());
1241 			}
1242 	      if (slideKind & SHIFT_SLIDE) {
1243                   slideKind &= ~SHIFT_SLIDE;
1244 			slideList.push_back(note);
1245 			}
1246 #if 0
1247             if (slideKind)
1248 		      int k = 1;
1249             if (slideKind > 4)
1250                   int k = 1;
1251             // if slide >= 4 then we are not dealing with legato slide nor shift slide
1252             if (slideKind >= 4)
1253                   slide = slideKind;
1254             else
1255                   slides[note->chord()->track()] = slideKind;
1256 #endif
1257             }
1258 
1259       if (modMask2 & EFFECT_ARTIFICIAL_HARMONIC) {
1260             int type = readArtificialHarmonic();
1261 		if (type == 2) {
1262                   auto harmNote = readUChar();
1263 			/*auto sharp =*/ readChar();
1264 			auto octave = readUChar();
1265 
1266 			auto harmonicNote = new Note(score);
1267 //TODO-ws		harmonicNote->setHarmonic(true);
1268 			note->chord()->add(harmonicNote);
1269 			auto staff = note->staff();
1270 //			int string = staff->part()->instrument()->stringData()->strings() - 1 - note->string();
1271 			int fret = note->fret();
1272 			switch (harmNote) {
1273                         case 0: fret += 24; break;
1274 			      case 2: fret += 34; break;
1275 			      case 4: fret += 38; break;
1276 			      case 5: fret += 12; break;
1277 			      case 7: fret += 32; break;
1278 			      case 9: fret += 28; break;
1279 			      default: fret += octave * 12;
1280 			      }
1281 		      harmonicNote->setString(note->string());
1282 			harmonicNote->setFret(fret);
1283 			harmonicNote->setPitch(staff->part()->instrument()->stringData()->getPitch(note->string(), fret, nullptr, Fraction(0,1)));
1284 			harmonicNote->setTpcFromPitch();
1285 			addTextToNote("A.H.", Align::CENTER, harmonicNote);
1286 		      }
1287             if (type == 1 || type == 4 || type == 5) {
1288                   //TextStyle textStyle;
1289 			//textStyle.setAlign(Align::CENTER);
1290 			//addTextToNote("N.H.", textStyle, note);
1291 //TODO-ws		note->setHarmonic(true);
1292 		      }
1293 	      }
1294 
1295             if (modMask2 & 0x40)
1296                   addVibrato(note);
1297 
1298       if (modMask2 & EFFECT_TRILL) {
1299 //TODO-ws            note->setTrillFret(readUChar());      // trill fret
1300             readUChar();      // trill fret
1301 
1302             int period = readUChar();      // trill length
1303 
1304             // add the trill articulation to the note
1305             Articulation* art = new Articulation(note->score());
1306             art->setSymId(SymId::ornamentTrill);
1307             if (!note->score()->addArticulation(note, art))
1308                   delete art;
1309 
1310             switch(period) {
1311                   case 1:           // 16
1312                         break;
1313                   case 2:           // 32
1314                         break;
1315                   case 3:           // 64
1316                         break;
1317                   default:
1318                         qDebug("unknown trill period %d", period);
1319                         break;
1320                   }
1321             }
1322       return slur;
1323       }
1324 
1325 //---------------------------------------------------------
1326 //   readNote
1327 //---------------------------------------------------------
1328 
readNote(int string,Note * note)1329 bool GuitarPro5::readNote(int string, Note* note)
1330       {
1331       uchar noteBits = readUChar();
1332       //
1333       // noteBits:
1334       //    7 - Right hand or left hand fingering;
1335       //    6 - Accentuated note
1336       //    5 - Note type (rest, empty note, normal note);
1337       //    4 - note dynamic;
1338       //    3 - Presence of effects linked to the note;
1339       //    2 - Ghost note;
1340       //    1 - Dotted note;  ?
1341       //    0 - Time-independent duration
1342 
1343       if (noteBits & NOTE_GHOST) {
1344             note->setHeadGroup(NoteHead::Group::HEAD_CROSS);
1345             note->setGhost(true);
1346             }
1347 
1348       bool tieNote = false;
1349 
1350       if (noteBits & NOTE_DEAD) {
1351             uchar noteType = readUChar();
1352             if (noteType == 1) {} //standard note
1353             else if (noteType == 2) {
1354                   tieNote = true;
1355                   }
1356             else if (noteType == 3) {                 // dead notes
1357                   note->setHeadGroup(NoteHead::Group::HEAD_CROSS);
1358                   note->setGhost(true);
1359                   }
1360             else
1361                   qDebug("unknown note type: %d", noteType);
1362             }
1363 
1364       if (noteBits & NOTE_DYNAMIC) {          // velocity
1365             int d = readChar();
1366             if (previousDynamic != d) {
1367                   previousDynamic = d;
1368                   addDynamic(note, d);
1369                   }
1370             }
1371 
1372       int fretNumber = 0;
1373       if (noteBits & NOTE_FRET) {
1374 	      fretNumber = readChar();
1375             }
1376 
1377       if (noteBits & NOTE_FINGERING) {
1378             int leftFinger = readUChar();
1379             int rightFinger = readUChar();
1380             Fingering* fi = new Fingering(score);
1381             QString finger;
1382             // if there is a valid left hand fingering
1383             if (leftFinger < 5) {
1384                   if (leftFinger == 0)
1385                         finger = "T";
1386                   else if (leftFinger == 1)
1387                         finger = "1";
1388                   else if (leftFinger == 2)
1389                         finger = "2";
1390                   else if (leftFinger == 3)
1391                         finger = "3";
1392                   else if (leftFinger == 4)
1393                         finger = "4";
1394                   }
1395             else  {
1396                   if (rightFinger == 0)
1397                         finger = "T";
1398                   else if (rightFinger == 1)
1399                         finger = "I";
1400                   else if (rightFinger == 2)
1401                         finger = "M";
1402                   else if (rightFinger == 3)
1403                         finger = "A";
1404                   else if (rightFinger == 4)
1405                         finger = "O";
1406                   }
1407             fi->setPlainText(finger);
1408             note->add(fi);
1409             fi->reset();
1410             }
1411 
1412       if (noteBits & 0x1)     // Time independent duration
1413             skip(8);
1414 
1415       // check if a note is supposed to be accented, and give it the marcato type
1416       if (noteBits & NOTE_MARCATO) {
1417             Articulation* art = new Articulation(note->score());
1418             art->setSymId(SymId::articMarcatoAbove);
1419             if (!note->score()->addArticulation(note, art))
1420                   delete art;
1421             }
1422 
1423       // check if a note is supposed to be accented, and give it the sforzato type
1424       if (noteBits & NOTE_SFORZATO) {
1425             Articulation* art = new Articulation(note->score());
1426             art->setSymId(SymId::articAccentAbove);
1427 			note->add(art);
1428             // if (!note->score()->addArticulation(note, art))
1429             //      delete art;
1430             }
1431 
1432       readUChar(); //skip
1433 
1434       Staff* staff = note->staff();
1435       if (fretNumber == 255 || fretNumber < 0) {
1436             fretNumber = 0;
1437             note->setHeadGroup(NoteHead::Group::HEAD_CROSS);
1438             note->setGhost(true);
1439             }
1440       int pitch = staff->part()->instrument()->stringData()->getPitch(string, fretNumber, nullptr, Fraction(0,1));
1441       note->setFret(fretNumber);
1442       note->setString(string);
1443       note->setPitch(pitch);
1444 
1445       // This function uses string and fret number, so it should be set before this
1446       bool slur = false;
1447       if (noteBits & NOTE_SLUR) {
1448             slur = readNoteEffects(note);
1449 	      }
1450 
1451       if (tieNote) {
1452             auto staffIdx = note->staffIdx();
1453 		if (dead_end[{staffIdx, string}]) {
1454 		      note->setFret(-20);
1455 			return false;
1456 		      }
1457             if (slurs[staffIdx]) {
1458                   score->removeSpanner(slurs[staffIdx]);
1459 			delete slurs[staffIdx];
1460 			slurs[staffIdx] = 0;
1461 		      }
1462             bool found = false;
1463             Chord* chord     = note->chord();
1464             Segment* segment = chord->segment()->prev1(SegmentType::ChordRest);
1465             int track        = note->track();
1466 		std::vector<ChordRest*> chords;
1467 		Note* true_note = nullptr;
1468             while (segment) {
1469                   Element* e = segment->element(track);
1470                   if (e) {
1471                         if (e->isChord()) {
1472                               Chord* chord2 = toChord(e);
1473                               foreach (Note* note2, chord2->notes()) {
1474                                     if (note2->string() == string) {
1475 					            if (chords.empty()) {
1476                                                 Tie* tie = new Tie(score);
1477 	      						tie->setEndNote(note);
1478 		      					note2->add(tie);
1479 			      				}
1480                                           note->setFret(note2->fret());
1481                                           note->setPitch(note2->pitch());
1482 						      true_note = note2;
1483                                           found = true;
1484                                           break;
1485                                           }
1486                                     }
1487                               }
1488                         if (found)
1489                               break;
1490                         else {
1491 				      if (e)
1492                                     chords.push_back(toChordRest(e));
1493                               }
1494                         }
1495                   segment = segment->prev1(SegmentType::ChordRest);
1496                   }
1497             if (true_note && chords.size()) {
1498                   Note* end_note = note;
1499 			for (unsigned int i = 0; i < chords.size(); ++i) {
1500                         Chord* chord1 = nullptr;
1501 				auto cr = chords.at(i);
1502 				if (cr->isChord())
1503                               chord1 = toChord(cr);
1504                         else {
1505 				      auto rest = toRest(cr);
1506 					auto dur = rest->ticks();
1507 					auto dut = rest->durationType();
1508 					auto seg = rest->segment();
1509 					seg->remove(rest);
1510 					auto tuplet = rest->tuplet();
1511 					if (tuplet)
1512                                     tuplet->remove(rest);
1513 					delete rest;
1514 					chord1 = new Chord(score);
1515 					chord1->setTrack(note->track());
1516 					chord1->setTicks(dur);
1517 					chord1->setDurationType(dut);
1518 					seg->add(chord1);
1519 					if (tuplet)
1520                                     tuplet->add(chord1);
1521 					}
1522 
1523 			      Note* note2 = new Note(score);
1524 				note2->setString(true_note->string());
1525 				note2->setFret(true_note->fret());
1526 				note2->setPitch(true_note->pitch());
1527 				note2->setTpcFromPitch();
1528 				chord1->setNoteType(true_note->noteType());
1529 				chord1->add(note2);
1530 				Tie* tie = new Tie(score);
1531 				tie->setEndNote(end_note);
1532 //TODO-ws			end_note->setHarmonic(true_note->harmonic());
1533 				end_note = note2;
1534 				note2->add(tie);
1535 				}
1536 		      Tie* tie = new Tie(score);
1537 			tie->setEndNote(end_note);
1538 //TODO-ws		end_note->setHarmonic(true_note->harmonic());
1539 			true_note->add(tie);
1540 			}
1541             if (!found) {
1542 		      note->setFret(-20);
1543 			dead_end[{staffIdx, string}] = true;
1544 			qDebug("tied note not found, pitch %d fret %d string %d", note->pitch(), note->fret(), note->string());
1545 			return false;
1546 			}
1547             }
1548       dead_end[{note->staffIdx(), string}] = false;
1549       return slur;
1550       }
1551 
1552 //---------------------------------------------------------
1553 //   readArtificialHarmonic
1554 //---------------------------------------------------------
1555 
readArtificialHarmonic()1556 int GuitarPro5::readArtificialHarmonic()
1557       {
1558       int type = readChar();
1559       switch(type) {
1560             case 1:           // natural
1561                   break;
1562             case 2:           // artificial
1563                   //skip(3);
1564                   break;
1565             case 3:           // tapped
1566                   skip(1);
1567                   break;
1568             case 4:           // pinch
1569                   break;
1570             case 5:           // semi
1571                   break;
1572             }
1573 	  return type;
1574       }
1575 
1576 }
1577