//============================================================================= // MusE Score // Linux Music Score Editor // // Copyright (C) 2010 Werner Schweer and others // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //============================================================================= #ifndef __IMPORTGTP_H__ #define __IMPORTGTP_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Ms { class Score; class Chord; class Note; class Segment; class Measure; class Tuplet; class Volta; class LetRing; class PalmMute; class Vibrato; static const int GP_MAX_LYRIC_LINES = 5; static const int GP_MAX_TRACK_NUMBER = 32; static const int GP_MAX_STRING_NUMBER = 7; static const int GP_DEFAULT_PERCUSSION_CHANNEL = 9; static const int GP_INVALID_KEYSIG = 127; static const int GP_VOLTA_BINARY = 1; static const int GP_VOLTA_FLAGS = 2; Score::FileError importGTP(Score* score, const QString& filename, const char* data, unsigned int data_len); enum class Repeat : char; struct GpTrack { int patch; uchar volume, pan, chorus, reverb, phase, tremolo; }; struct GPVolta { int voltaType; QList voltaInfo; }; /* How the fermatas are represented in Guitar Pro is two integers, the * first is an index value and the second is the time division that * index value refers to, and they are givin with respect to a * measure. Time division 0 means a minim, 1 is a crotchet, 2 is a * quaver and so on, with the index (counting from 0) referring to how * many time divisions occur before the fermata. These numbers are * separated in GP6 with a '/' character. For example, a note * occurring on the third beat of a measure in a 4/4 bar would be * represented as 2/1. */ struct GPFermata { int index; int timeDivision; QString type; }; struct GPLyrics { QStringList lyrics; std::vector segments; int fromBeat; int beatCounter; int lyricTrack; }; struct GpBar { Fraction timesig; bool freeTime; int keysig; QString marker; BarLineType barLine; Repeat repeatFlags; int repeats; GPVolta volta; QString direction; QString directionStyle; QString section[2]; std::vector directions; GpBar(); }; //--------------------------------------------------------- // GuitarPro //--------------------------------------------------------- class GuitarPro { protected: std::list slideList; //list of start slide notes // note effect bit masks static const uchar EFFECT_BEND = 0x1; static const uchar EFFECT_STACATTO = 0x1; static const uchar EFFECT_HAMMER = 0x2; static const uchar EFFECT_PALM_MUTE = 0x2; static const uchar EFFECT_TREMOLO = 0x4; static const uchar EFFECT_LET_RING = 0x8; static const uchar EFFECT_SLIDE_OLD = 0x4; static const uchar EFFECT_SLIDE = 0x8; static const uchar EFFECT_GRACE = 0x10; static const uchar EFFECT_ARTIFICIAL_HARMONIC = 0x10; static const uchar EFFECT_TRILL = 0x20; static const uchar EFFECT_GHOST = 0x01; // arpeggio direction masks static const uchar ARPEGGIO_UP = 0xa; static const uchar ARPEGGIO_DOWN = 0x2; // note bit masks static const uchar NOTE_GHOST = 0x04; // 2 static const uchar NOTE_DEAD = 0x20; //5 static const uchar NOTE_DYNAMIC = 0x10; // 4 static const uchar NOTE_FRET = 0x20; //5 static const uchar NOTE_FINGERING = 0x80; //7 static const uchar NOTE_MARCATO = 0x02; //1 static const uchar NOTE_SFORZATO = 0x40; //6 static const uchar NOTE_SLUR = 0x8;//3 static const uchar NOTE_APPOGIATURA = 0x02;//1 // beat bit masks static const uchar BEAT_VIBRATO_TREMOLO = 0x02; static const uchar BEAT_FADE = 0x10; static const uchar BEAT_EFFECT = 0x20; static const uchar BEAT_TREMOLO = 0x04; static const uchar BEAT_ARPEGGIO = 0x40; static const uchar BEAT_STROKE_DIR = 0x02; static const uchar BEAT_DOTTED = 0x01; static const uchar BEAT_PAUSE = 0x40; static const uchar BEAT_TUPLET = 0x20; static const uchar BEAT_LYRICS = 0x4; static const uchar BEAT_EFFECTS = 0x8; static const uchar BEAT_MIX_CHANGE = 0x10; static const uchar BEAT_CHORD = 0x2; // score bit masks static const uchar SCORE_TIMESIG_NUMERATOR = 0x1; static const uchar SCORE_TIMESIG_DENOMINATOR = 0x2; static const uchar SCORE_REPEAT_START = 0x4; static const uchar SCORE_REPEAT_END = 0x8; static const uchar SCORE_MARKER = 0x20; static const uchar SCORE_VOLTA = 0x10; static const uchar SCORE_KEYSIG = 0x40; static const uchar SCORE_DOUBLE_BAR = 0x80; // slide kinds static const int SHIFT_SLIDE = 1; static const int LEGATO_SLIDE = 2; static const int SLIDE_OUT_DOWN = 4; static const int SLIDE_OUT_UP = 8; static const int SLIDE_IN_ABOVE = 16; static const int SLIDE_IN_BELOW = 32; static const int MAX_PITCH = 127; static const char* const errmsg[]; int version; int key { 0 }; Segment* last_segment { nullptr }; Measure* last_measure { nullptr }; int last_tempo { -1 }; QMap*> fermatas; std::vector ottava; Hairpin** hairpins; MasterScore* score; QFile* f; int curPos; int previousTempo; int previousDynamic; std::vector ottavaFound; std::vector ottavaValue; std::map> tempoMap; int tempo; QMap slides; GPLyrics gpLyrics; int slide; int voltaSequence; QTextCodec* _codec { 0 }; Slur** slurs { nullptr }; void skip(qint64 len); void read(void* p, qint64 len); int readUChar(); int readChar(); QString readPascalString(int); QString readWordPascalString(); QString readBytePascalString(); int readInt(); QString readDelphiString(); void readVolta(GPVolta*, Measure*); virtual void readBend(Note*); virtual bool readMixChange(Measure* measure); virtual int readBeatEffects(int track, Segment*) = 0; void readLyrics(); void readChannels(); void setTuplet(Tuplet* tuplet, int tuple); void setupTupletStyle(Tuplet* tuplet); Fraction len2fraction(int len); void addDynamic(Note*, int d); void createMeasures(); void applyBeatEffects(Chord*, int beatEffects); void readTremoloBar(int track, Segment*); void readChord(Segment* seg, int track, int numStrings, QString name, bool gpHeader); void restsForEmptyBeats(Segment* seg, Measure* measure, ChordRest* cr, Fraction& l, int track, const Fraction& tick); void createSlur(bool hasSlur, int staffIdx, ChordRest* cr); void createOttava(bool hasOttava, int track, ChordRest* cr, QString value); void createSlide(int slide, ChordRest* cr, int staffIdx, Note* note = nullptr); void createCrecDim(int staffIdx, int track, const Fraction& tick, bool crec); Text* addTextToNote(QString, Align, Note*); void addPalmMute(Note*); void addLetRing(Note*); void addVibrato(Note*, Vibrato::Type type = Vibrato::Type::GUITAR_VIBRATO); void addTap(Note*); void addSlap(Note*); void addPop(Note*); void createTuningString(int strings, int tuning[]); std::vector _palmMutes; std::vector _letRings; std::vector _vibratos; public: std::vector tunings; void setTempo(int n, Measure* measure); void initGuitarProDrumset(); QString title, subtitle, artist, album, composer; QString transcriber, instructions; QStringList comments; GpTrack channelDefaults[GP_MAX_TRACK_NUMBER * 2]; int staves; int measures; QList bars; enum class GuitarProError : char { GP_NO_ERROR, GP_UNKNOWN_FORMAT, GP_EOF, GP_BAD_NUMBER_OF_STRINGS }; GuitarPro(MasterScore*, int v); virtual ~GuitarPro(); virtual bool read(QFile*) = 0; QString error(GuitarProError n) const { return QString(errmsg[int(n)]); } }; //--------------------------------------------------------- // GuitarPro1 //--------------------------------------------------------- class GuitarPro1 : public GuitarPro { protected: bool readNote(int string, Note* note); virtual int readBeatEffects(int track, Segment*); public: GuitarPro1(MasterScore* s, int v) : GuitarPro(s, v) {} virtual bool read(QFile*); }; //--------------------------------------------------------- // GuitarPro2 //--------------------------------------------------------- class GuitarPro2 : public GuitarPro1 { public: GuitarPro2(MasterScore* s, int v) : GuitarPro1(s, v) {} virtual bool read(QFile*); }; //--------------------------------------------------------- // GuitarPro3 //--------------------------------------------------------- class GuitarPro3 : public GuitarPro1 { virtual int readBeatEffects(int track, Segment* segment); public: GuitarPro3(MasterScore* s, int v) : GuitarPro1(s, v) {} virtual bool read(QFile*); }; //--------------------------------------------------------- // GuitarPro4 //--------------------------------------------------------- class GuitarPro4 : public GuitarPro { std::vector curDynam; std::vector tupleKind; void readInfo(); bool readNote(int string, int staffIdx, Note* note); virtual int readBeatEffects(int track, Segment* segment); virtual bool readMixChange(Measure* measure); int convertGP4SlideNum(int slide); public: GuitarPro4(MasterScore* s, int v) : GuitarPro(s, v) {} virtual bool read(QFile*); }; //--------------------------------------------------------- // GuitarPro5 //--------------------------------------------------------- class GuitarPro5 : public GuitarPro { std::map, bool> dead_end; int _beat_counter{ 0 }; void readInfo(); void readPageSetup(); virtual int readBeatEffects(int track, Segment* segment); bool readNote(int string, Note* note); virtual bool readMixChange(Measure* measure); void readMeasure(Measure* measure, int staffIdx, Tuplet*[], bool mixChange); int readArtificialHarmonic(); bool readTracks(); void readMeasures(int startingTempo); Fraction readBeat(const Fraction& tick, int voice, Measure* measure, int staffIdx, Tuplet** tuplets, bool mixChange); bool readNoteEffects(Note*); public: GuitarPro5(MasterScore* s, int v) : GuitarPro(s, v) {} virtual bool read(QFile*); }; //--------------------------------------------------------- // GuitarPro6 //--------------------------------------------------------- class GuitarPro6 : public GuitarPro { Fraction _lastTick; Volta* _lastVolta{ nullptr }; // an integer stored in the header indicating that the file is not compressed (BCFS). const int GPX_HEADER_UNCOMPRESSED = 1397113666; // an integer stored in the header indicating that the file is not compressed (BCFZ). const int GPX_HEADER_COMPRESSED = 1514554178; int position = 0; // a constant storing the amount of bits per byte const int BITS_IN_BYTE = 8; // contains all the information about notes that will go in the parts struct GPPartInfo { QDomNode masterBars; QDomNode bars; QDomNode voices; QDomNode beats; QDomNode notes; QDomNode rhythms; }; Slur** legatos; // a mapping from identifiers to fret diagrams QMap fretDiagrams; void parseFile(const char* filename, QByteArray* data); int readBit(QByteArray* buffer); QByteArray getBytes(QByteArray* buffer, int offset, int length); void readGPX(QByteArray* buffer); int readInteger(QByteArray* buffer, int offset); QByteArray readString(QByteArray* buffer, int offset, int length); int readBits(QByteArray* buffer, int bitsToRead); int readBitsReversed(QByteArray* buffer, int bitsToRead); void readScore(QDomNode* metadata); void readChord(QDomNode* diagram, int track); int findNumMeasures(GPPartInfo* partInfo); void readMasterTracks(QDomNode* masterTrack); void readDrumNote(Note* note, int element, int variation); Fraction readBeats(QString beats, GPPartInfo* partInfo, Measure* measure, const Fraction& startTick, int staffIdx, int voiceNum, Tuplet* tuplets[], int measureCounter); void readBars(QDomNode* barList, Measure* measure, ClefType oldClefId[], GPPartInfo* partInfo, int measureCounter); virtual void readTracks(QDomNode* tracks); void readMasterBars(GPPartInfo* partInfo); Fraction rhythmToDuration(QString value); Fraction fermataToFraction(int numerator, int denominator); QDomNode getNode(const QString& id, QDomNode currentDomNode); void unhandledNode(QString nodeName); void makeTie(Note* note); void addTremoloBar(Segment* segment, int track, int whammyOrigin, int whammyMiddle, int whammyEnd); std::map, Note*> slideMap; protected: const static std::map instrumentMapping; int* previousDynamic; void readGpif(QByteArray* data); void readNote(int string, Note* note); virtual int readBeatEffects(int track, Segment*); void readTrackProperties(const QDomNode& currentNode, Part* part, int trackCounter, bool& hasTuning); public: GuitarPro6(MasterScore* s) : GuitarPro(s, 6) {} GuitarPro6(MasterScore* s, int v) : GuitarPro(s, v) {} virtual bool read(QFile*); }; class GuitarPro7 : public GuitarPro6 { virtual void readTracks(QDomNode* tracks); public: GuitarPro7(MasterScore* s) : GuitarPro6(s, 7) {} virtual bool read(QFile*); }; } // namespace Ms #endif