LCOV - code coverage report
Current view: top level - src/importexport/guitarpro/internal/gtp - gp7dombuilder.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 97.9 % 96 94
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : #include "gp7dombuilder.h"
       2              : 
       3              : #include <vector>
       4              : 
       5              : #include "global/log.h"
       6              : 
       7              : using namespace muse;
       8              : 
       9              : namespace mu::iex::guitarpro {
      10          157 : std::pair<int, std::unique_ptr<GPTrack> > GP7DomBuilder::createGPTrack(XmlDomNode* trackNode, XmlDomNode* versionNode)
      11              : {
      12              :     static const std::set<String> sUnused = {
      13              :         u"Color", u"SystemsDefautLayout", u"SystemsLayout", u"AutoBrush",
      14              :         u"PalmMute", u"AutoAccentuation", u"PlayingStyle",
      15              :         u"UseOneChannelPerString", u"IconId", u"InstrumentSet",
      16              :         u"ForcedSound", u"PlaybackState", u"AudioEngineState",
      17              :         u"Automations"
      18          157 :     };
      19              : 
      20          157 :     int trackIdx = trackNode->toElement().attribute("id").value().toInt();
      21          157 :     auto track = std::make_unique<GPTrack>(trackIdx);
      22          157 :     XmlDomNode trackChildNode = trackNode->firstChild();
      23          157 :     String version = versionNode->toElement().text();
      24              : 
      25         3350 :     while (!trackChildNode.isNull()) {
      26         3193 :         String nodeName = trackChildNode.nodeName();
      27         3193 :         if (nodeName == u"Name") {
      28          157 :             track->setName(trackChildNode.toElement().text());
      29         3036 :         } else if (nodeName == u"RSE") {
      30          156 :             GPTrack::RSE rse = readTrackRSE(&trackChildNode);
      31          156 :             track->setRSE(rse);
      32         2880 :         } else if (nodeName == u"MidiConnection") {
      33          157 :             int midiChannel = readMidiChannel(&trackChildNode);
      34          157 :             track->setMidiChannel(midiChannel);
      35         2723 :         } else if (nodeName == u"ShortName") {
      36          157 :             track->setShortName(trackChildNode.toElement().text());
      37         2566 :         } else if (nodeName == u"Sounds") {
      38          157 :             int programm = readMidiProgramm(&trackChildNode);
      39          157 :             auto soundNode = trackChildNode.firstChild();
      40          317 :             while (!soundNode.isNull()) {
      41          160 :                 GPTrack::Sound sound = readSounds(&soundNode);
      42          160 :                 track->addSound(sound);
      43              : 
      44          160 :                 soundNode = soundNode.nextSibling();
      45          160 :             }
      46          157 :             track->setProgramm(programm);
      47         2566 :         } else if (nodeName == u"Staves") {
      48          157 :             auto staffNode = trackChildNode.firstChild();
      49          157 :             int staffCount = 0;
      50          316 :             while (!staffNode.isNull()) {
      51          159 :                 auto propertyNode = staffNode.firstChild();
      52              :                 // there is a bug in gp v 7.0.0
      53              :                 // All parts marked to use flat for tuning string,
      54              :                 // but in real world gp uses tuning presets
      55              :                 // so we have to ignore <Flats/> and <TuningFlat> props
      56          159 :                 readTrackProperties(&propertyNode, track.get(), version == "7");
      57          159 :                 staffNode = staffNode.nextSibling();
      58          159 :                 staffCount++;
      59          159 :             }
      60          157 :             track->setStaffCount(staffCount);
      61         2409 :         } else if (nodeName == u"NotationPatch") {
      62            3 :             auto innerNode = trackChildNode.firstChildElement("LineCount");
      63            3 :             if (!innerNode.isNull()) {
      64            3 :                 track->setLineCount(innerNode.toElement().text().toInt());
      65              :             }
      66         2252 :         } else if (nodeName == u"Transpose") {
      67          157 :             auto octaveNode = trackChildNode.firstChildElement("Octave");
      68          157 :             int octave = octaveNode.toElement().text().toInt();
      69          157 :             auto chromaticNode = trackChildNode.firstChildElement("Chromatic");
      70          157 :             int chromatic = chromaticNode.toElement().text().toInt();
      71          157 :             int transpose = 12 * octave + chromatic;
      72          157 :             track->setTranspose(transpose);
      73         2249 :         } else if (nodeName == u"Lyrics") {
      74          156 :             readLyrics(trackChildNode, track.get());
      75         1936 :         } else if (nodeName == u"Automations") {
      76          115 :             auto automationNode = trackChildNode.firstChild();
      77          238 :             while (!automationNode.isNull()) {
      78          123 :                 GPTrack::SoundAutomation automation =  readTrackAutomation(&automationNode);
      79          123 :                 if (!automation.type.isEmpty()) {
      80          123 :                     track->addSoundAutomation(automation);
      81              :                 }
      82          123 :                 automationNode = automationNode.nextSibling();
      83          123 :             }
      84         1936 :         } else if (sUnused.find(nodeName) != sUnused.end()) {
      85              :             // Ignored nodes
      86              :         }
      87              : 
      88         3193 :         trackChildNode = trackChildNode.nextSibling();
      89         3193 :     }
      90              : 
      91          314 :     return std::make_pair(trackIdx, std::move(track));
      92          157 : }
      93              : 
      94          157 : int GP7DomBuilder::readMidiChannel(XmlDomNode* trackChildNode) const
      95              : {
      96              :     int channel
      97          314 :         =trackChildNode->firstChildElement("PrimaryChannel")
      98          157 :           .text().toInt();
      99              : 
     100          157 :     return channel;
     101              : }
     102              : 
     103          157 : int GP7DomBuilder::readMidiProgramm(XmlDomNode* trackChildNode) const
     104              : {
     105          314 :     int programm = trackChildNode->firstChild()
     106          314 :                    .firstChildElement("MIDI")
     107          314 :                    .firstChildElement("Program")
     108          157 :                    .text().toInt();
     109              : 
     110          157 :     return programm;
     111              : }
     112              : 
     113          160 : GPTrack::Sound GP7DomBuilder::readSounds(XmlDomNode* soundNode) const
     114              : {
     115          160 :     GPTrack::Sound result;
     116              : 
     117          320 :     result.programm = soundNode->firstChildElement("MIDI")
     118          320 :                       .firstChildElement("Program")
     119          160 :                       .text().toInt();
     120          160 :     result.name = soundNode->firstChildElement("Name").text();
     121          160 :     result.label = soundNode->firstChildElement("Label").text();
     122          160 :     result.path = soundNode->firstChildElement("Path").text();
     123          160 :     result.role = soundNode->firstChildElement("Role").text();
     124              : 
     125          160 :     return result;
     126            0 : }
     127              : 
     128          123 : GPTrack::SoundAutomation GP7DomBuilder::readTrackAutomation(XmlDomNode* automationNode) const
     129              : {
     130          123 :     GPTrack::SoundAutomation result;
     131              : 
     132          123 :     String type = automationNode->firstChildElement("Type").text();
     133          123 :     if (type != u"Sound") {
     134            0 :         return result;
     135              :     }
     136              : 
     137          123 :     result.type = type;
     138          123 :     result.linear = automationNode->firstChildElement("Linear").text() == u"true";
     139          123 :     result.bar = automationNode->firstChildElement("Bar").text().toInt();
     140          123 :     result.value = automationNode->firstChildElement("Value").text();
     141          123 :     result.position = automationNode->firstChildElement("Position").text().toFloat();
     142              : 
     143          123 :     return result;
     144          123 : }
     145              : } // namespace mu::iex::guitarpro
        

Generated by: LCOV version 2.0-1