Line data Source code
1 : #include "gp6dombuilder.h"
2 :
3 : #include <set>
4 :
5 : #include "global/log.h"
6 :
7 : using namespace muse;
8 :
9 : namespace mu::iex::guitarpro {
10 82 : std::pair<int, std::unique_ptr<GPTrack> > GP6DomBuilder::createGPTrack(XmlDomNode* trackNode, XmlDomNode* versionNode)
11 : {
12 : UNUSED(versionNode);
13 : static const std::set<String> sUnusedNodes = {
14 : u"Color", // we don't use icon color for the tracks
15 : u"SystemsDefaultLayout", u"SystemsLayout", // we have our own layout algorithms
16 : u"SystemsDefautLayout", // GP has a typo here :)
17 : u"PalmMute", // currently our synthesizer is unable to simulate this feature
18 : u"AutoAccentuation", // currently our synthesizer is unable to simulate this feature
19 : u"PlayingStyle", // currently we ignore playing style
20 : u"UseOneChannelPerString", // we have our own channel management system in synth
21 : u"PartSounding", // don't know what this is
22 : u"PlaybackState" // ignored
23 82 : };
24 :
25 82 : int trackIdx = trackNode->toElement().attribute("id").value().toInt();
26 82 : auto track = std::make_unique<GPTrack>(trackIdx);
27 82 : XmlDomNode trackChildNode = trackNode->firstChild();
28 :
29 1200 : while (!trackChildNode.isNull()) {
30 1118 : String nodeName = trackChildNode.nodeName();
31 1118 : if (nodeName == u"Name") {
32 82 : track->setName(trackChildNode.toElement().text());
33 1036 : } else if (nodeName == u"RSE") {
34 82 : GPTrack::RSE rse = readTrackRSE(&trackChildNode);
35 82 : track->setRSE(rse);
36 :
37 82 : XmlDomNode bankChangesNode = trackChildNode.firstChildElement("BankChanges");
38 82 : if (!bankChangesNode.isNull()) {
39 40 : XmlDomNode bankChange = bankChangesNode.firstChild();
40 88 : while (!bankChange.isNull()) {
41 48 : GPTrack::SoundAutomation automation = readRsePickUp(bankChange);
42 48 : track->addSoundAutomation(automation);
43 48 : bankChange = bankChange.nextSibling();
44 48 : }
45 40 : }
46 1036 : } else if (nodeName == u"GeneralMidi") {
47 82 : if (trackChildNode.hasChildNodes()) {
48 82 : auto programm = trackChildNode.firstChildElement("Program").text().toInt();
49 82 : track->setProgramm(programm);
50 82 : int midiChannel = trackChildNode.firstChildElement("PrimaryChannel").text().toInt();
51 82 : track->setMidiChannel(midiChannel);
52 : }
53 872 : } else if (nodeName == u"ShortName") {
54 82 : track->setShortName(trackChildNode.toElement().text());
55 790 : } else if (nodeName == u"Properties") {
56 82 : readTrackProperties(&trackChildNode, track.get(), false);
57 708 : } else if (nodeName == u"Instrument") {
58 82 : setUpInstrument(&trackChildNode, track.get());
59 626 : } else if (nodeName == u"Lyrics") {
60 82 : readLyrics(trackChildNode, track.get());
61 544 : } else if (sUnusedNodes.find(nodeName) != sUnusedNodes.end()) {
62 : // these nodes are not used (see comment to the sUnusedNodes variable)
63 : }
64 :
65 1118 : trackChildNode = trackChildNode.nextSibling();
66 1118 : }
67 :
68 164 : return std::make_pair(trackIdx, std::move(track));
69 82 : }
70 :
71 82 : void GP6DomBuilder::setUpInstrument(XmlDomNode* trackChildNode, GPTrack* track)
72 : {
73 82 : String ref = trackChildNode->toElement().attribute("ref").value();
74 82 : track->setInstrument(ref);
75 82 : if (ref.endsWith(u"-gs") || ref.startsWith(u'2')) { // grand staff
76 1 : track->setStaffCount(2);
77 : }
78 :
79 82 : if (ref.contains(u"gtr") || ref.contains(u"bass")) {
80 : //! NOTE Guitar notation is transposed to octave by default (see music grammar)
81 80 : track->setTranspose(-12);
82 :
83 80 : track->setIsGuitar(true);
84 : }
85 82 : }
86 :
87 48 : GPTrack::SoundAutomation GP6DomBuilder::readRsePickUp(XmlDomNode& bankChangesNode) const
88 : {
89 48 : GPTrack::SoundAutomation result;
90 :
91 48 : result.bar = bankChangesNode.toElement().attribute("barIndex").value().toInt();
92 48 : result.value = bankChangesNode.toElement().attribute("bankId").value();
93 48 : result.position = bankChangesNode.toElement().attribute("tickOffset").value().toFloat();
94 :
95 48 : return result;
96 0 : }
97 : } // namespace mu::iex::guitarpro
|