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