LCOV - code coverage report
Current view: top level - src/importexport/guitarpro/internal - importgtp.h Coverage Total Hit
Test: filtered_coverage.info Lines: 78.9 % 19 15
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : 
      23              : #pragma once
      24              : 
      25              : #include <map>
      26              : #include <vector>
      27              : 
      28              : #include "io/iodevice.h"
      29              : #include "modularity/ioc.h"
      30              : #include "types/bytearray.h"
      31              : #include "types/string.h"
      32              : 
      33              : #include "engraving/dom/measurebase.h"
      34              : #include "engraving/dom/stringdata.h"
      35              : #include "engraving/engravingerrors.h"
      36              : #include "engraving/iengravingconfiguration.h"
      37              : #include "engraving/types/types.h"
      38              : 
      39              : #include "continiouselementsbuilder.h"
      40              : #include "gtp/igpdombuilder.h"
      41              : #include "guitarbendimport/guitarbendimporter.h"
      42              : 
      43              : namespace mu::engraving {
      44              : class Chord;
      45              : class ChordRest;
      46              : class Drumset;
      47              : class Instrument;
      48              : class LetRing;
      49              : class Measure;
      50              : class Note;
      51              : class PalmMute;
      52              : class Score;
      53              : class Segment;
      54              : class Tuplet;
      55              : class Vibrato;
      56              : class Volta;
      57              : class MasterScore;
      58              : class Ottava;
      59              : class Hairpin;
      60              : class Bend;
      61              : class Slur;
      62              : } // namespace mu::engraving
      63              : 
      64              : namespace mu::iex::guitarpro {
      65              : static constexpr int GP_MAX_LYRIC_LINES = 5;
      66              : static constexpr int GP_MAX_TRACK_NUMBER = 32;
      67              : static constexpr int GP_MAX_STRING_NUMBER = 7;
      68              : static constexpr int GP_DEFAULT_PERCUSSION_CHANNEL = 9;
      69              : static constexpr int GP_INVALID_KEYSIG = 127;
      70              : static constexpr int GP_VOLTA_BINARY = 1;
      71              : static constexpr int GP_VOLTA_FLAGS = 2;
      72              : 
      73              : mu::engraving::Err importGTP(mu::engraving::Score* score, const muse::String& filename, const char* data, unsigned int data_len);
      74              : 
      75              : enum class Repeat : char;
      76              : 
      77              : struct GpTrack {
      78              :     int patch;
      79              :     uint8_t volume, pan, chorus, reverb, phase, tremolo;
      80              : };
      81              : 
      82              : struct GPVolta {
      83              :     int voltaType;
      84              :     std::vector<int> voltaInfo;
      85              : };
      86              : 
      87              : /* How the fermatas are represented in Guitar Pro is two integers, the
      88              :  * first is an index value and the second is the time division that
      89              :  * index value refers to, and they are givin with respect to a
      90              :  * measure. Time division 0 means a minim, 1 is a crotchet, 2 is a
      91              :  * quaver and so on, with the index (counting from 0) referring to how
      92              :  * many time divisions occur before the fermata. These numbers are
      93              :  * separated in GP6 with a '/' character. For example, a note
      94              :  * occurring on the third beat of a measure in a 4/4 bar would be
      95              :  * represented as 2/1.
      96              :  */
      97              : 
      98              : struct GPFermata {
      99              :     int index;
     100              :     int timeDivision;
     101              :     muse::String type;
     102              : };
     103              : 
     104              : struct GPLyrics {
     105              :     muse::StringList lyrics;
     106              :     std::vector<mu::engraving::Segment*> segments;
     107              :     std::vector<size_t> lyricPos;
     108              :     size_t fromBeat = 0;
     109              :     size_t beatCounter = 0;
     110              :     size_t lyricTrack = 0;
     111              : };
     112              : 
     113              : struct GpBar {
     114              :     mu::engraving::Fraction timesig = mu::engraving::Fraction(4, 4);
     115              :     bool freeTime = false;
     116              :     int keysig = GP_INVALID_KEYSIG;
     117              :     muse::String marker;
     118              :     mu::engraving::BarLineType barLine = mu::engraving::BarLineType::NORMAL;
     119              :     mu::engraving::Repeat repeatFlags = mu::engraving::Repeat::NONE;
     120              :     int repeats = 2;
     121              :     GPVolta volta;
     122              :     muse::String direction;
     123              :     muse::String directionStyle;
     124              :     muse::String section[2];
     125              :     std::vector<muse::String> directions;
     126              : };
     127              : 
     128              : //---------------------------------------------------------
     129              : //   GuitarPro
     130              : //---------------------------------------------------------
     131              : 
     132              : class GuitarPro : public muse::Contextable
     133              : {
     134              : public:
     135              :     muse::GlobalInject<mu::engraving::IEngravingConfiguration> engravingConfiguration;
     136              : 
     137              : protected:
     138              : 
     139              :     using staff_idx_t = mu::engraving::staff_idx_t;
     140              :     using track_idx_t = mu::engraving::track_idx_t;
     141              :     using Fraction = mu::engraving::Fraction;
     142              :     using Measure = mu::engraving::Measure;
     143              :     using ChordRest = mu::engraving::ChordRest;
     144              :     using Chord = mu::engraving::Chord;
     145              :     using Note = mu::engraving::Note;
     146              : 
     147              :     enum class TabImportOption {
     148              :         STANDARD = 1,
     149              :         TAB      = 2,
     150              :         BOTH     = 3
     151              :     };
     152              : 
     153              :     struct GPProperties {
     154              :         std::vector<TabImportOption> partsImportOptions;
     155              :     };
     156              : 
     157              :     struct ReadNoteResult {
     158              :         bool slur = false;
     159              :         bool hammerOnPullOff = false;
     160              :         bool letRing = false;
     161              :         bool palmMute = false;
     162              :         bool trill = false;
     163              :         bool vibrato = false;
     164              : 
     165              :         /// harmonic marks
     166              :         bool harmonicArtificial = false;
     167              :         bool harmonicPinch = false;
     168              :         bool harmonicTap = false;
     169              :         bool harmonicSemi = false;
     170              :     };
     171              : 
     172              :     GPProperties m_properties;
     173              : 
     174              :     std::vector<Note*> slideList;   //list of start slide notes
     175              : 
     176              :     // note effect bit masks
     177              :     static const uint8_t EFFECT_BEND = 0x1;
     178              :     static const uint8_t EFFECT_STACCATO = 0x1;
     179              :     static const uint8_t EFFECT_HAMMER = 0x2;
     180              :     static const uint8_t EFFECT_PALM_MUTE = 0x2;
     181              :     static const uint8_t EFFECT_TREMOLO = 0x4;
     182              :     static const uint8_t EFFECT_LET_RING = 0x8;
     183              :     static const uint8_t EFFECT_SLIDE_OLD = 0x4;
     184              :     static const uint8_t EFFECT_SLIDE = 0x8;
     185              :     static const uint8_t EFFECT_GRACE = 0x10;
     186              :     static const uint8_t EFFECT_ARTIFICIAL_HARMONIC = 0x10;
     187              :     static const uint8_t EFFECT_TRILL = 0x20;
     188              :     static const uint8_t EFFECT_GHOST = 0x01;
     189              :     static const uint8_t EFFECT_VIBRATO = 0x40;
     190              : 
     191              :     // arpeggio direction masks
     192              :     static const uint8_t ARPEGGIO_UP = 0xa;
     193              :     static const uint8_t ARPEGGIO_DOWN = 0x2;
     194              : 
     195              :     // note bit masks
     196              :     static const uint8_t NOTE_GHOST = 0x04;   // 2
     197              :     static const uint8_t NOTE_DEAD = 0x20;   //5
     198              :     static const uint8_t NOTE_DYNAMIC = 0x10;   // 4
     199              :     static const uint8_t NOTE_FRET = 0x20;   //5
     200              :     static const uint8_t NOTE_FINGERING = 0x80;   //7
     201              :     static const uint8_t NOTE_MARCATO = 0x02;   //1
     202              :     static const uint8_t NOTE_SFORZATO = 0x40;   //6
     203              :     static const uint8_t NOTE_SLUR = 0x8;  //3
     204              :     static const uint8_t NOTE_APPOGIATURA = 0x02;  //1
     205              : 
     206              :     // beat bit masks
     207              :     static const uint8_t BEAT_RASGUEADO = 0x01;
     208              :     static const uint8_t BEAT_VIBRATO_TREMOLO = 0x02;
     209              :     static const uint8_t BEAT_FADE = 0x10;
     210              :     static const uint8_t BEAT_EFFECT = 0x20;
     211              :     static const uint8_t BEAT_TREMOLO = 0x04;
     212              :     static const uint8_t BEAT_ARPEGGIO = 0x40;
     213              :     static const uint8_t BEAT_STROKE_DIR = 0x02;
     214              :     static const uint8_t BEAT_DOTTED = 0x01;
     215              :     static const uint8_t BEAT_PAUSE = 0x40;
     216              :     static const uint8_t BEAT_TUPLET = 0x20;
     217              :     static const uint8_t BEAT_LYRICS = 0x4;
     218              :     static const uint8_t BEAT_EFFECTS = 0x8;
     219              :     static const uint8_t BEAT_MIX_CHANGE = 0x10;
     220              :     static const uint8_t BEAT_CHORD = 0x2;
     221              : 
     222              :     // score bit masks
     223              :     static const uint8_t SCORE_TIMESIG_NUMERATOR = 0x1;
     224              :     static const uint8_t SCORE_TIMESIG_DENOMINATOR = 0x2;
     225              :     static const uint8_t SCORE_REPEAT_START = 0x4;
     226              :     static const uint8_t SCORE_REPEAT_END = 0x8;
     227              :     static const uint8_t SCORE_MARKER = 0x20;
     228              :     static const uint8_t SCORE_VOLTA = 0x10;
     229              :     static const uint8_t SCORE_KEYSIG = 0x40;
     230              :     static const uint8_t SCORE_DOUBLE_BAR = 0x80;
     231              : 
     232              :     // slide kinds
     233              :     static const int SHIFT_SLIDE = 1;
     234              :     static const int LEGATO_SLIDE = 2;
     235              :     static const int SLIDE_OUT_DOWN = 4;
     236              :     static const int SLIDE_OUT_UP = 8;
     237              :     static const int SLIDE_IN_ABOVE = 16;
     238              :     static const int SLIDE_IN_BELOW = 32;
     239              : 
     240              :     // harmonic mark types
     241              :     static const int HARMONIC_MARK_NATURAL = 1;
     242              :     static const int HARMONIC_MARK_ARTIFICIAL = 2;
     243              :     static const int HARMONIC_MARK_TAP = 3;
     244              :     static const int HARMONIC_MARK_PINCH = 4;
     245              :     static const int HARMONIC_MARK_SEMI = 5;
     246              : 
     247              :     static const int MAX_PITCH = 127;
     248              :     static const char* const errmsg[];
     249              :     int version = 0;
     250              :     int key = 0;
     251              : 
     252              :     mu::engraving::Segment* last_segment = nullptr;
     253              :     Measure* last_measure = nullptr;
     254              :     int last_tempo = -1;
     255              : 
     256              :     std::vector<mu::engraving::Ottava*> ottava; /// will be removed
     257              :     mu::engraving::Hairpin** hairpins = nullptr; /// will be removed
     258              :     mu::engraving::MasterScore* score = nullptr;
     259              :     muse::io::IODevice* f = nullptr;
     260              :     int curPos = 0;
     261              :     int previousTempo = -1;
     262              :     std::vector<int> previousDynamicByTrack;
     263              :     constexpr static int INVALID_DYNAMIC = -1;
     264              :     constexpr static int DEFAULT_DYNAMIC = 0;
     265              :     int tempo = -1;
     266              :     std::map<int, int> slides;
     267              : 
     268              :     GPLyrics gpLyrics;
     269              :     int slide = 0;
     270              :     int voltaSequence = 0;
     271              :     std::vector<mu::engraving::Slur*> slurs;
     272              : 
     273              :     void skip(int64_t len);
     274              :     void read(void* p, int64_t len);
     275              :     uint8_t readUInt8();
     276              :     int readChar();
     277              :     muse::String readPascalString(int);
     278              : 
     279              :     muse::String readWordPascalString();
     280              :     muse::String readBytePascalString();
     281              :     int readInt();
     282              :     muse::String readDelphiString();
     283              :     void readVolta(GPVolta*, Measure*);
     284              :     void readBend(Note*);
     285              :     std::vector<mu::engraving::PitchValue> readBendDataFromFile();
     286              :     void createBend(Note* note, std::vector<mu::engraving::PitchValue>& bendData);
     287              :     virtual bool readMixChange(Measure* measure);
     288              :     virtual int readBeatEffects(int track, mu::engraving::Segment*) = 0;
     289              :     void readLyrics();
     290              :     void readChannels();
     291              :     void setTuplet(mu::engraving::Tuplet* tuplet, int tuple);
     292              :     void setupTupletStyle(mu::engraving::Tuplet* tuplet);
     293              :     Fraction len2fraction(int len);
     294              :     void addDynamic(Note*, int d);
     295              :     void createMeasures();
     296              :     void applyBeatEffects(mu::engraving::Chord*, int beatEffects, bool& hasVibratoLeftHand, bool& hasVibratoWTremBar);
     297              :     void readTremoloBar(int track, mu::engraving::Segment*);
     298              :     void readChord(mu::engraving::Segment* seg, int track, int numStrings, muse::String name, bool gpHeader);
     299              :     void restsForEmptyBeats(mu::engraving::Segment* seg, Measure* measure, ChordRest* cr, Fraction& l, int track, const Fraction& tick);
     300              :     void createSlur(bool hasSlur, staff_idx_t staffIdx, ChordRest* cr);
     301              :     void createSlide(int slide, ChordRest* cr, int staffIdx, Note* note = nullptr);
     302              :     void addTextToNote(muse::String text, Note* note);
     303              :     void addTextArticulation(Note* note, mu::engraving::ArticulationTextType type);
     304              :     void addPalmMute(ChordRest* cr, bool hasPalmMute);
     305              :     void addLetRing(ChordRest* cr, bool hasPalmMute);
     306              :     void addTrill(ChordRest* cr, bool hasTrill);
     307              :     void addHammerOnPullOff(ChordRest* cr, bool hasHammerOnPullOff);
     308              :     void addRasgueado(ChordRest* cr, bool hasRasgueado);
     309              :     void addVibratoLeftHand(ChordRest* cr, bool hasVibratoLeftHand);
     310              :     void addVibratoWTremBar(ChordRest* cr, bool hasVibratoWTremBar);
     311              :     void addHarmonicMarks(ChordRest* cr, bool hasHarmonicArtificial, bool hasHarmonicPinch, bool hasHarmonicTap, bool hasHarmonicSemi);
     312              :     void addTap(Chord*);
     313              :     void addSlap(Note*);
     314              :     void addPop(Note*);
     315              :     bool createTuningString(int strings, int tuning[]); // returns useFlats
     316            0 :     virtual std::unique_ptr<IGPDomBuilder> createGPDomBuilder() const { return nullptr; }
     317              :     void initDynamics(size_t stavesNum);
     318              :     void addTunings();
     319              : 
     320              : public:
     321              :     std::vector<std::string> tunings;
     322              : 
     323              :     void setTempo(int n, Measure* measure);
     324              :     muse::String title, subtitle, artist, album, composer, poet;
     325              :     muse::StringList comments;
     326              :     std::array<GpTrack, GP_MAX_TRACK_NUMBER* 2> channelDefaults;
     327              :     size_t staves = 0;
     328              :     size_t measures = 0;
     329              :     std::vector<GpBar> bars;
     330              :     std::unique_ptr<ContiniousElementsBuilder> m_continiousElementsBuilder;
     331              :     std::unique_ptr<GuitarBendImporter> m_guitarBendImporter;
     332              : 
     333              :     enum class GuitarProError : char {
     334              :         GP_NO_ERROR, GP_UNKNOWN_FORMAT,
     335              :         GP_EOF, GP_BAD_NUMBER_OF_STRINGS
     336              :     };
     337              : 
     338              :     GuitarPro(mu::engraving::MasterScore*, int v, const muse::modularity::ContextPtr& iocCtx);
     339          295 :     virtual ~GuitarPro() {}
     340              :     virtual bool read(muse::io::IODevice*) = 0;
     341              :     muse::String error(GuitarProError n) const { return muse::String::fromUtf8(errmsg[int(n)]); }
     342              : };
     343              : 
     344              : //---------------------------------------------------------
     345              : //   GuitarPro1
     346              : //---------------------------------------------------------
     347              : 
     348              : class GuitarPro1 : public GuitarPro
     349              : {
     350              : protected:
     351              :     ReadNoteResult readNote(int string, mu::engraving::Note* note);
     352              :     int readBeatEffects(int track, mu::engraving::Segment*) override;
     353              : 
     354              : public:
     355            7 :     GuitarPro1(mu::engraving::MasterScore* s, int v, const muse::modularity::ContextPtr& iocCtx)
     356            7 :         : GuitarPro(s, v, iocCtx) {}
     357              :     bool read(muse::io::IODevice*) override;
     358              : };
     359              : 
     360              : //---------------------------------------------------------
     361              : //   GuitarPro2
     362              : //---------------------------------------------------------
     363              : 
     364              : class GuitarPro2 : public GuitarPro1
     365              : {
     366              : public:
     367            0 :     GuitarPro2(mu::engraving::MasterScore* s, int v, const muse::modularity::ContextPtr& iocCtx)
     368            0 :         : GuitarPro1(s, v, iocCtx) {}
     369              :     bool read(muse::io::IODevice*) override;
     370              : };
     371              : 
     372              : //---------------------------------------------------------
     373              : //   GuitarPro3
     374              : //---------------------------------------------------------
     375              : 
     376              : class GuitarPro3 : public GuitarPro1
     377              : {
     378              :     int readBeatEffects(int track, mu::engraving::Segment* segment) override;
     379              : 
     380              : public:
     381            7 :     GuitarPro3(mu::engraving::MasterScore* s, int v, const muse::modularity::ContextPtr& iocCtx)
     382            7 :         : GuitarPro1(s, v, iocCtx) {}
     383              :     bool read(muse::io::IODevice*) override;
     384              : };
     385              : 
     386              : //---------------------------------------------------------
     387              : //   GuitarPro4
     388              : //---------------------------------------------------------
     389              : 
     390              : class GuitarPro4 : public GuitarPro
     391              : {
     392              :     std::vector<int> curDynam;
     393              :     std::vector<int> tupleKind;
     394              :     void readInfo();
     395              :     ReadNoteResult readNote(int string, int staffIdx, Note* note);
     396              :     int readBeatEffects(int track, mu::engraving::Segment* segment) override;
     397              :     bool readMixChange(mu::engraving::Measure* measure) override;
     398              :     int convertGP4SlideNum(int slide);
     399              : 
     400              : public:
     401           27 :     GuitarPro4(mu::engraving::MasterScore* s, int v, const muse::modularity::ContextPtr& iocCtx)
     402           27 :         : GuitarPro(s, v, iocCtx) {}
     403              :     bool read(muse::io::IODevice*) override;
     404              : };
     405              : 
     406              : //---------------------------------------------------------
     407              : //   GuitarPro5
     408              : //---------------------------------------------------------
     409              : 
     410              : class GuitarPro5 : public GuitarPro
     411              : {
     412              :     std::map<std::pair<int, int>, bool> dead_end;
     413              :     int _beat_counter{ 0 };
     414              :     std::unordered_map<mu::engraving::Chord*, mu::engraving::TremoloType> m_tremolosInChords; // for adding tremolo for tied notes
     415              :     std::unordered_map<Note*, Note*> m_harmonicNotes; // for adding ties for harmonic notes
     416              :     bool m_currentBeatHasRasgueado = false;
     417              :     std::unordered_set<ChordRest*> m_letRingForChords; // fixing gp5 bug with no storing let ring for tied notes
     418              :     std::vector<std::pair<Note*, Note*> > m_glissandoNotePairs;
     419              : 
     420              :     void readInfo();
     421              :     void readPageSetup();
     422              :     int readBeatEffects(int track, mu::engraving::Segment* segment) override;
     423              :     ReadNoteResult readNote(int string, Note* note);
     424              :     bool readMixChange(Measure* measure) override;
     425              :     void readMeasure(Measure * measure, int staffIdx, mu::engraving::Tuplet*[], bool mixChange);
     426              :     bool readTracks();
     427              :     void readMeasures(int startingTempo);
     428              :     Fraction readBeat(const Fraction& tick, int voice, Measure* measure, int staffIdx, mu::engraving::Tuplet** tuplets, bool mixChange);
     429              :     ReadNoteResult readNoteEffects(Note*);
     430              :     float naturalHarmonicFromFret(int fret);
     431              :     void addGlissandos();
     432              : 
     433              : public:
     434           40 :     GuitarPro5(mu::engraving::MasterScore* s, int v, const muse::modularity::ContextPtr& iocCtx)
     435           40 :         : GuitarPro(s, v, iocCtx) {}
     436              :     bool read(muse::io::IODevice*) override;
     437              : };
     438              : 
     439              : //---------------------------------------------------------
     440              : //   GuitarPro6
     441              : //---------------------------------------------------------
     442              : 
     443              : class GuitarPro6 : public GuitarPro
     444              : {
     445              :     // an integer stored in the header indicating that the file is not compressed (BCFS).
     446              :     const int GPX_HEADER_UNCOMPRESSED = 1397113666;
     447              :     // an integer stored in the header indicating that the file is not compressed (BCFZ).
     448              :     const int GPX_HEADER_COMPRESSED = 1514554178;
     449              :     int position = 0;
     450              :     // a constant storing the amount of bits per byte
     451              :     const int BITS_IN_BYTE = 8;
     452              :     // contains all the information about notes that will go in the parts
     453              :     struct GPPartInfo {
     454              :         muse::XmlDomNode masterBars;
     455              :         muse::XmlDomNode bars;
     456              :         muse::XmlDomNode voices;
     457              :         muse::XmlDomNode beats;
     458              :         muse::XmlDomNode notes;
     459              :         muse::XmlDomNode rhythms;
     460              :     };
     461              : 
     462              :     void parseFile(const char* filename, muse::ByteArray* data);
     463              : 
     464              :     int readBit(muse::ByteArray* buffer);
     465              :     muse::ByteArray getBytes(muse::ByteArray* buffer, int offset, int length);
     466              :     void readGPX(muse::ByteArray* buffer);
     467              :     int readInteger(muse::ByteArray* buffer, int offset);
     468              :     muse::ByteArray readString(muse::ByteArray* buffer, int offset, int length);
     469              :     int readBits(muse::ByteArray* buffer, int bitsToRead);
     470              :     int readBitsReversed(muse::ByteArray* buffer, int bitsToRead);
     471              :     int findNumMeasures(GPPartInfo* partInfo);
     472              :     void readMasterTracks(muse::XmlDomNode* masterTrack);
     473              :     void readDrumNote(Note* note, int element, int variation);
     474              :     muse::XmlDomNode getNode(const muse::String& id, muse::XmlDomNode currentDomNode);
     475              :     void unhandledNode(muse::String nodeName);
     476              :     void makeTie(Note* note);
     477            0 :     int readBeatEffects(int /*track*/, mu::engraving::Segment*) override { return 0; }
     478              : 
     479              :     std::map<std::pair<int, int>, Note*> slideMap;
     480              : 
     481              : protected:
     482              :     const static std::map<std::string, std::string> instrumentMapping;
     483              :     void readGpif(muse::ByteArray* data);
     484              : 
     485              :     virtual std::unique_ptr<IGPDomBuilder> createGPDomBuilder() const override;
     486              : 
     487              : public:
     488           76 :     GuitarPro6(mu::engraving::MasterScore* s, const muse::modularity::ContextPtr& iocCtx)
     489           76 :         : GuitarPro(s, 6, iocCtx) {}
     490          145 :     GuitarPro6(mu::engraving::MasterScore* s, int v, const muse::modularity::ContextPtr& iocCtx)
     491          145 :         : GuitarPro(s, v, iocCtx) {}
     492              :     bool read(muse::io::IODevice*) override;
     493              : };
     494              : 
     495              : class GuitarPro7 : public GuitarPro6
     496              : {
     497              :     virtual std::unique_ptr<IGPDomBuilder> createGPDomBuilder() const override;
     498              : 
     499              : public:
     500          145 :     GuitarPro7(mu::engraving::MasterScore* s, const muse::modularity::ContextPtr& iocCtx)
     501          145 :         : GuitarPro6(s, 7, iocCtx) {}
     502              :     bool read(muse::io::IODevice*) override;
     503              :     GPProperties readProperties(muse::ByteArray* data);
     504              : };
     505              : }
        

Generated by: LCOV version 2.0-1