1 //============================================================================= 2 // MuseScore 3 // Linux Music Score Editor 4 // 5 // Copyright (C) 2015 Werner Schweer and others 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 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 //============================================================================= 19 20 #ifndef __IMPORTMXMLPASS2_H__ 21 #define __IMPORTMXMLPASS2_H__ 22 23 #include <array> 24 25 #include "libmscore/score.h" 26 #include "libmscore/tuplet.h" 27 #include "importxmlfirstpass.h" 28 #include "importmxmlpass1.h" 29 #include "musicxml.h" // a.o. for Slur 30 #include "musicxmlsupport.h" 31 32 namespace Ms { 33 34 //--------------------------------------------------------- 35 // support enums / structs / classes 36 //--------------------------------------------------------- 37 38 using GraceChordList = QList<Chord*>; 39 using FiguredBassList = QVector<FiguredBass*>; 40 // typedef QList<Chord*> GraceChordList; 41 // typedef QVector<FiguredBass*> FiguredBassList; 42 using Tuplets = std::map<QString, Tuplet*>; 43 44 //--------------------------------------------------------- 45 // MxmlStartStop 46 //--------------------------------------------------------- 47 /* 48 enum class MxmlStartStop : char { 49 START, STOP, NONE 50 }; 51 */ 52 53 //--------------------------------------------------------- 54 // MusicXmlSlash 55 //--------------------------------------------------------- 56 57 enum class MusicXmlSlash : char { 58 NONE, RHYTHM, SLASH 59 }; 60 61 //--------------------------------------------------------- 62 // MusicXmlTupletDesc 63 //--------------------------------------------------------- 64 65 /** 66 Describe the information extracted from 67 a single note/notations/tuplet element. 68 */ 69 70 struct MusicXmlTupletDesc { 71 MusicXmlTupletDesc(); 72 MxmlStartStop type; 73 Placement placement; 74 TupletBracketType bracket; 75 TupletNumberType shownumber; 76 }; 77 78 //--------------------------------------------------------- 79 // MusicXmlSpannerDesc 80 //--------------------------------------------------------- 81 82 struct MusicXmlSpannerDesc { 83 SLine* _sp; 84 ElementType _tp; 85 int _nr; MusicXmlSpannerDescMusicXmlSpannerDesc86 MusicXmlSpannerDesc(SLine* sp, ElementType tp, int nr) : _sp(sp), _tp(tp), _nr(nr) {} MusicXmlSpannerDescMusicXmlSpannerDesc87 MusicXmlSpannerDesc(ElementType tp, int nr) : _sp(0), _tp(tp), _nr(nr) {} 88 }; 89 90 //--------------------------------------------------------- 91 // NewMusicXmlSpannerDesc 92 //--------------------------------------------------------- 93 94 struct MusicXmlExtendedSpannerDesc { 95 SLine* _sp { nullptr }; 96 Fraction _tick2 { 0, 0 }; 97 int _track2 {}; 98 bool _isStarted { false }; 99 bool _isStopped { false }; MusicXmlExtendedSpannerDescMusicXmlExtendedSpannerDesc100 MusicXmlExtendedSpannerDesc() {} 101 QString toString() const; 102 }; 103 104 //--------------------------------------------------------- 105 // MusicXmlLyricsExtend 106 //--------------------------------------------------------- 107 108 class MusicXmlLyricsExtend { 109 public: MusicXmlLyricsExtend()110 MusicXmlLyricsExtend() {} 111 void init(); 112 void addLyric(Lyrics* const lyric); 113 void setExtend(const int no, const int track, const Fraction& tick); 114 115 private: 116 QSet<Lyrics*> _lyrics; 117 }; 118 119 //--------------------------------------------------------- 120 // MusicXMLParserLyric 121 //--------------------------------------------------------- 122 123 class MusicXMLParserLyric { 124 public: 125 MusicXMLParserLyric(const LyricNumberHandler lyricNumberHandler, 126 QXmlStreamReader& e, Score* score, MxmlLogger* logger); extendedLyrics()127 QSet<Lyrics*> extendedLyrics() const { return _extendedLyrics; } numberedLyrics()128 QMap<int, Lyrics*> numberedLyrics() const { return _numberedLyrics; } 129 void parse(); 130 private: 131 void skipLogCurrElem(); 132 const LyricNumberHandler _lyricNumberHandler; 133 QXmlStreamReader& _e; 134 Score* const _score; // the score 135 MxmlLogger* _logger; ///< Error logger 136 QMap<int, Lyrics*> _numberedLyrics; // lyrics with valid number 137 QSet<Lyrics*> _extendedLyrics; // lyrics with the extend flag set 138 }; 139 140 //--------------------------------------------------------- 141 // Notation 142 // Most with text base attributes (font-*, placement) 143 //--------------------------------------------------------- 144 145 class Notation { 146 public: 147 Notation(const QString& name, const QString& parent = "", 148 const SymId& symId = SymId::noSym) { _name = name; _parent = parent; _symId = symId; } 149 void addAttribute(const QStringRef name, const QStringRef value); 150 QString attribute(const QString& name) const; name()151 QString name() const { return _name; } parent()152 QString parent() const { return _parent; } setSymId(const SymId & symId)153 void setSymId(const SymId& symId) { _symId = symId; } symId()154 SymId symId() const { return _symId; } setSubType(const QString & subType)155 void setSubType(const QString& subType) { _subType = subType; } subType()156 QString subType() const { return _subType; } 157 QString print() const; setText(const QString & text)158 void setText(const QString& text) { _text = text; } text()159 QString text() const { return _text; } 160 static Notation notationWithAttributes(const QString& name, const QXmlStreamAttributes attributes, 161 const QString& parent = "", const SymId& symId = SymId::noSym); 162 private: 163 QString _name; 164 QString _parent; 165 SymId _symId { SymId::noSym }; 166 QString _subType; 167 QString _text; 168 std::map<QString, QString> _attributes; 169 }; 170 171 //--------------------------------------------------------- 172 // forward references and defines 173 //--------------------------------------------------------- 174 175 class FretDiagram; 176 class FiguredBassItem; 177 class Glissando; 178 class Pedal; 179 class Trill; 180 class MxmlLogger; 181 182 using SlurStack = std::array<SlurDesc, MAX_NUMBER_LEVEL>; 183 using TrillStack = std::array<Trill*, MAX_NUMBER_LEVEL>; 184 using BracketsStack = std::array<MusicXmlExtendedSpannerDesc, MAX_NUMBER_LEVEL>; 185 using OttavasStack = std::array<MusicXmlExtendedSpannerDesc, MAX_NUMBER_LEVEL>; 186 using HairpinsStack = std::array<MusicXmlExtendedSpannerDesc, MAX_NUMBER_LEVEL>; 187 using SpannerStack = std::array<MusicXmlExtendedSpannerDesc, MAX_NUMBER_LEVEL>; 188 using SpannerSet = std::set<Spanner*>; 189 190 //--------------------------------------------------------- 191 // MusicXMLParserNotations 192 //--------------------------------------------------------- 193 194 class MusicXMLParserNotations { 195 public: 196 MusicXMLParserNotations(QXmlStreamReader& e, Score* score, MxmlLogger* logger); 197 void parse(); 198 void addToScore(ChordRest* const cr, Note* const note, const int tick, SlurStack& slurs, 199 Glissando* glissandi[MAX_NUMBER_LEVEL][2], MusicXmlSpannerMap& spanners, TrillStack& trills, 200 Tie*& tie); tupletDesc()201 MusicXmlTupletDesc tupletDesc() const { return _tupletDesc; } tremoloType()202 QString tremoloType() const { return _tremoloType; } tremoloNr()203 int tremoloNr() const { return _tremoloNr; } mustStopGraceAFter()204 bool mustStopGraceAFter() const { return _slurStop || _wavyLineStop; } 205 private: 206 void addNotation(const Notation& notation, ChordRest* const cr, Note* const note); 207 void addTechnical(const Notation& notation, Note* note); 208 void harmonic(); 209 void articulations(); 210 void dynamics(); 211 void fermata(); 212 void glissandoSlide(); 213 void mordentNormalOrInverted(); 214 void ornaments(); 215 void slur(); 216 void skipLogCurrElem(); 217 void technical(); 218 void tied(); 219 void tuplet(); 220 QXmlStreamReader& _e; 221 Score* const _score; // the score 222 MxmlLogger* _logger; // the error logger 223 MusicXmlTupletDesc _tupletDesc; 224 QString _dynamicsPlacement; 225 QStringList _dynamicsList; 226 std::vector<Notation> _notations; 227 SymId _breath { SymId::noSym }; 228 QString _tremoloType; 229 int _tremoloNr { 0 }; 230 QString _wavyLineType; 231 int _wavyLineNo { 0 }; 232 QString _arpeggioType; 233 bool _slurStop { false }; 234 bool _wavyLineStop { false }; 235 }; 236 237 //--------------------------------------------------------- 238 // MusicXMLParserPass2 239 //--------------------------------------------------------- 240 241 class MusicXMLParserPass2 { 242 public: 243 MusicXMLParserPass2(Score* score, MusicXMLParserPass1& pass1, MxmlLogger* logger); 244 Score::FileError parse(QIODevice* device); 245 246 // part specific data interface functions 247 void addSpanner(const MusicXmlSpannerDesc& desc); 248 MusicXmlExtendedSpannerDesc& getSpanner(const MusicXmlSpannerDesc& desc); 249 void clearSpanner(const MusicXmlSpannerDesc& desc); 250 251 private: 252 void initPartState(const QString& partId); 253 SpannerSet findIncompleteSpannersAtPartEnd(); 254 Score::FileError parse(); 255 void scorePartwise(); 256 void partList(); 257 void scorePart(); 258 void part(); 259 void measChordNote( /*, const MxmlPhase2Note note, ChordRest& currChord */); 260 void measChordFlush( /*, ChordRest& currChord */); 261 void measure(const QString& partId, const Fraction time); 262 void attributes(const QString& partId, Measure* measure, const Fraction& tick); 263 void measureStyle(Measure* measure); 264 void barline(const QString& partId, Measure* measure, const Fraction& tick); 265 void key(const QString& partId, Measure* measure, const Fraction& tick); 266 void clef(const QString& partId, Measure* measure, const Fraction& tick); 267 void time(const QString& partId, Measure* measure, const Fraction& tick); 268 void divisions(); 269 void transpose(const QString& partId, const Fraction& tick); 270 Note* note(const QString& partId, Measure* measure, const Fraction sTime, const Fraction prevTime, 271 Fraction& missingPrev, Fraction& dura, Fraction& missingCurr, QString& currentVoice, GraceChordList& gcl, int& gac, 272 Beam*& beam, FiguredBassList& fbl, int& alt, MxmlTupletStates& tupletStates, Tuplets& tuplets); 273 void notePrintSpacingNo(Fraction& dura); 274 FiguredBassItem* figure(const int idx, const bool paren); 275 FiguredBass* figuredBass(); 276 FretDiagram* frame(); 277 void harmony(const QString& partId, Measure* measure, const Fraction sTime); 278 Accidental* accidental(); 279 void beam(Beam::Mode& beamMode); 280 void duration(Fraction& dura); 281 void forward(Fraction& dura); 282 void backup(Fraction& dura); 283 void timeModification(Fraction& timeMod, TDuration& normalType); 284 void stem(Direction& sd, bool& nost); 285 void doEnding(const QString& partId, Measure* measure, const QString& number, const QString& type, const QString& text); 286 void staffDetails(const QString& partId); 287 void staffTuning(StringData* t); 288 void skipLogCurrElem(); 289 290 // multi-measure rest state handling 291 void setMultiMeasureRestCount(int count); 292 int getAndDecMultiMeasureRestCount(); 293 294 // generic pass 2 data 295 296 QXmlStreamReader _e; 297 int _divs; // the current divisions value 298 Score* const _score; // the score 299 MusicXMLParserPass1& _pass1; // the pass1 results 300 MxmlLogger* _logger; ///< Error logger 301 302 // part specific data (TODO: move to part-specific class) 303 304 // Measure duration according to last timesig read 305 // TODO: store timesigs read in pass 1, use those instead 306 // or use score->sigmap() ? 307 Fraction _timeSigDura; 308 309 SlurStack _slurs { {} }; 310 TrillStack _trills { {} }; ///< Current trills 311 BracketsStack _brackets; 312 OttavasStack _ottavas; ///< Current ottavas 313 HairpinsStack _hairpins; ///< Current hairpins 314 MusicXmlExtendedSpannerDesc _dummyNewMusicXmlSpannerDesc; 315 316 Glissando* _glissandi[MAX_NUMBER_LEVEL][2]; ///< Current slides ([0]) / glissandi ([1]) 317 318 Tie* _tie; 319 Volta* _lastVolta; 320 bool _hasDrumset; ///< drumset defined TODO: move to pass 1 321 322 MusicXmlSpannerMap _spanners; 323 324 MusicXmlExtendedSpannerDesc _pedal; ///< Current pedal 325 Pedal* _pedalContinue; ///< Current pedal type="change" requiring fixup 326 Harmony* _harmony; ///< Current harmony 327 Chord* _tremStart; ///< Starting chord for current tremolo 328 FiguredBass* _figBass; ///< Current figured bass element (to attach to next note) 329 int _multiMeasureRestCount; 330 MusicXmlLyricsExtend _extendedLyrics; ///< Lyrics with "extend" requiring fixup 331 332 MusicXmlSlash _measureStyleSlash; ///< Are we inside a measure to be displayed as slashes? 333 }; 334 335 //--------------------------------------------------------- 336 // MusicXMLParserDirection 337 //--------------------------------------------------------- 338 339 class MusicXMLParserDirection { 340 public: 341 MusicXMLParserDirection(QXmlStreamReader& e, Score* score, const MusicXMLParserPass1& pass1, MusicXMLParserPass2& pass2, MxmlLogger* logger); 342 void direction(const QString& partId, Measure* measure, const Fraction& tick, const int divisions, MusicXmlSpannerMap& spanners); 343 344 private: 345 QXmlStreamReader& _e; 346 Score* const _score; // the score 347 const MusicXMLParserPass1& _pass1; // the pass1 results 348 MusicXMLParserPass2& _pass2; // the pass2 results 349 MxmlLogger* _logger; ///< Error logger 350 351 QStringList _dynamicsList; 352 QString _enclosure; 353 QString _wordsText; 354 QString _metroText; 355 QString _rehearsalText; 356 QString _dynaVelocity; 357 QString _tempo; 358 QString _sndCapo; 359 QString _sndCoda; 360 QString _sndDacapo; 361 QString _sndDalsegno; 362 QString _sndSegno; 363 QString _sndFine; 364 bool _hasDefaultY; 365 qreal _defaultY; 366 bool _coda; 367 bool _segno; 368 double _tpoMetro; // tempo according to metronome 369 double _tpoSound; // tempo according to sound 370 QList<Element*> _elems; 371 Fraction _offset; 372 373 void directionType(QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops); 374 void bracket(const QString& type, const int number, QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops); 375 void octaveShift(const QString& type, const int number, QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops); 376 void pedal(const QString& type, const int number, QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops); 377 void dashes(const QString& type, const int number, QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops); 378 void wedge(const QString& type, const int number, QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops); 379 QString metronome(double& r); 380 void sound(); 381 void dynamics(); 382 void handleRepeats(Measure* measure, const int track); 383 void skipLogCurrElem(); 384 }; 385 386 } // namespace Ms 387 #endif 388