1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2020 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 #include "libmscore/bracketItem.h"
15 #include <libmscore/instrtemplate.h>
16 #include <libmscore/part.h>
17 #include <libmscore/staff.h>
18 #include "thirdparty/qzip/qzipreader_p.h"
19 
20 namespace Ms {
21 
22 //---------------------------------------------------------
23 //   readTracks
24 //---------------------------------------------------------
25 
readTracks(QDomNode * track)26 void GuitarPro7::readTracks(QDomNode* track)
27       {
28       QDomNode nextTrack = track->firstChild();
29       int trackCounter   = 0;
30       while (!nextTrack.isNull()) {
31             QDomNode currentNode = nextTrack.firstChild();
32             Part* part           = new Part(score);
33             bool hasTuning       = false;
34             Staff* s             = new Staff(score);
35             s->setPart(part);
36             part->insertStaff(s, -1);
37             score->staves().push_back(s);
38             while (!currentNode.isNull()) {
39                   QString nodeName = currentNode.nodeName();
40                   if (nodeName == "Name")
41                         part->setPartName(currentNode.toElement().text());
42                   else if (nodeName == "Color") {}
43                   // this is a typo is guitar pro - 'defaut' is correct here
44                   else if (nodeName == "SystemsDefautLayout") {}
45                   else if (nodeName == "SystemsLayout") {}
46                   else if (nodeName == "RSE") {}
47                   else if (nodeName == "PlaybackState") {}
48                   else if (nodeName == "PlayingStyle") {}
49                   else if (nodeName == "PageSetup") {}
50                   else if (nodeName == "MultiVoice") {}
51                   else if (nodeName == "ShortName") {}
52                   else if (nodeName == "Instrument") {
53                         QString ref = currentNode.attributes().namedItem("ref").toAttr().value();
54                         auto it     = instrumentMapping.find(ref);
55                         if (it != instrumentMapping.end()) {
56                               part->setInstrument(Instrument::fromTemplate(Ms::searchTemplate(it->second)));
57                               }
58                         else
59                               qDebug() << "Unknown instrument: " << ref;
60                         if (ref.endsWith("-gs") || ref.startsWith("2")) { // grand staff
61                               Staff* s2 = new Staff(score);
62                               s2->setPart(part);
63                               part->insertStaff(s2, -1);
64                               score->staves().push_back(s2);
65                               s->addBracket(new BracketItem(s->score(), BracketType::BRACE, 2));
66                               s->setBarLineSpan(2);
67                               }
68                         }
69                   else if (nodeName == "Transpose")
70                         part->instrument()->setTranspose(Interval(currentNode.firstChildElement("Octave").text().toInt() * 12));
71                   else if (nodeName == "Sounds")
72                         part->instrument()->channel(0)->setProgram(currentNode.firstChildElement("Sound").firstChildElement("MIDI").firstChildElement("Program").text().toInt());
73                   else if (nodeName == "MidiConnection") {
74                         part->setMidiChannel(currentNode.firstChildElement("PrimaryChannel").text().toInt());
75                         if (part->midiChannel() == GP_DEFAULT_PERCUSSION_CHANNEL) {
76                               part->instrument()->setDrumset(gpDrumset);
77                               s->setStaffType(Fraction(0, 1), *StaffType::preset(StaffTypes::PERC_DEFAULT));
78                               }
79                         }
80                   else if (nodeName == "Staves") {
81                         QDomNode staff = currentNode.firstChild();
82                         QDomNode properties = staff.firstChildElement("Properties");
83                         readTrackProperties(properties, part, trackCounter, hasTuning);
84                         }
85                   currentNode = currentNode.nextSibling();
86                   }
87 
88             // add in a new part
89             score->appendPart(part);
90             trackCounter++;
91             nextTrack = nextTrack.nextSibling();
92 
93             if (!hasTuning) {
94                   tunings.push_back("");
95                   }
96             }
97 
98       previousDynamic = new int[score->staves().length() * VOICES];
99       // initialise the dynamics to 0
100       for (int i = 0; i < score->staves().length() * VOICES; i++)
101             previousDynamic[i] = 0;
102       // set the number of staves we need
103       staves = score->staves().length();
104       }
105 
106 //---------------------------------------------------------
107 //   read
108 //---------------------------------------------------------
109 
read(QFile * fp)110 bool GuitarPro7::read(QFile* fp)
111       {
112       f = fp;
113       previousTempo = -1;
114       MQZipReader zip(fp);
115       QByteArray fileData = zip.fileData("Content/score.gpif");
116       zip.close();
117       readGpif(&fileData);
118       return true;
119       }
120 }
121