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 __IMPORTMXMLPASS1_H__
21 #define __IMPORTMXMLPASS1_H__
22 
23 #include "libmscore/score.h"
24 #include "importxmlfirstpass.h"
25 #include "musicxml.h" // for the creditwords and MusicXmlPartGroupList definitions
26 #include "musicxmlsupport.h"
27 
28 namespace Ms {
29 
30 //---------------------------------------------------------
31 //   PageFormat
32 //---------------------------------------------------------
33 
34 struct PageFormat {
35       QSizeF size;
36       qreal printableWidth;        // _width - left margin - right margin
37       qreal evenLeftMargin;        // values in inch
38       qreal oddLeftMargin;
39       qreal evenTopMargin;
40       qreal evenBottomMargin;
41       qreal oddTopMargin;
42       qreal oddBottomMargin;
43       bool twosided;
44       };
45 
46 typedef QMap<QString, Part*> PartMap;
47 typedef std::map<int,MusicXmlPartGroup*> MusicXmlPartGroupMap;
48 
49 //---------------------------------------------------------
50 //   MxmlOctaveShiftDesc
51 //---------------------------------------------------------
52 
53 struct MxmlOctaveShiftDesc {
54       enum class Type : char { UP, DOWN, STOP, NONE };
55       Type tp;
56       short size;
57       Fraction time;
58       short num;
MxmlOctaveShiftDescMxmlOctaveShiftDesc59       MxmlOctaveShiftDesc() : tp(Type::NONE), size(0), num(-1) {}
MxmlOctaveShiftDescMxmlOctaveShiftDesc60       MxmlOctaveShiftDesc(Type _tp, short _size, Fraction _tm) : tp(_tp), size(_size), time(_tm), num(-1) {}
61       };
62 
63 //---------------------------------------------------------
64 //   MxmlStartStop (also used in pass 2)
65 //---------------------------------------------------------
66 
67 enum class MxmlStartStop : char {
68       NONE, START, STOP
69       };
70 
71 enum class MxmlTupletFlag : char {
72       NONE = 0,
73       STOP_PREVIOUS = 1,
74       START_NEW = 2,
75       ADD_CHORD = 4,
76       STOP_CURRENT = 8
77       };
78 
79 typedef QFlags<MxmlTupletFlag> MxmlTupletFlags;
80 
81 struct MxmlTupletState {
82       void addDurationToTuplet(const Fraction duration, const Fraction timeMod);
83       MxmlTupletFlags determineTupletAction(const Fraction noteDuration,
84                                             const Fraction timeMod,
85                                             const MxmlStartStop tupletStartStop,
86                                             const TDuration normalType,
87                                             Fraction& missingPreviousDuration,
88                                             Fraction& missingCurrentDuration
89                                             );
90       bool m_inTuplet { false };
91       bool m_implicit { false };
92       int m_actualNotes { 1 };
93       int m_normalNotes { 1 };
94       Fraction m_duration { 0, 1 };
95       int m_tupletType { 0 }; // smallest note type in the tuplet // TODO_NOW rename ?
96       int m_tupletCount { 0 }; // number of smallest notes in the tuplet // TODO_NOW rename ?
97       };
98 
99 using MxmlTupletStates = std::map<QString, MxmlTupletState>;
100 
101 //---------------------------------------------------------
102 //   declarations
103 //---------------------------------------------------------
104 
105 void determineTupletFractionAndFullDuration(const Fraction duration, Fraction& fraction, Fraction& fullDuration);
106 Fraction missingTupletDuration(const Fraction duration);
107 
108 
109 //---------------------------------------------------------
110 //   MusicXMLParserPass1
111 //---------------------------------------------------------
112 
113 class MxmlLogger;
114 
115 class MusicXMLParserPass1 {
116 public:
117       MusicXMLParserPass1(Score* score, MxmlLogger* logger);
118       void initPartState(const QString& partId);
119       Score::FileError parse(QIODevice* device);
120       Score::FileError parse();
121       void scorePartwise();
122       void identification();
123       void credit(CreditWordsList& credits);
124       void defaults();
125       void pageLayout(PageFormat& pf, const qreal conversion);
126       void partList(MusicXmlPartGroupList& partGroupList);
127       void partGroup(const int scoreParts, MusicXmlPartGroupList& partGroupList, MusicXmlPartGroupMap& partGroups);
128       void scorePart();
129       void scoreInstrument(const QString& partId);
130       void midiInstrument(const QString& partId);
131       void part();
132       void measure(const QString& partId, const Fraction cTime, Fraction& mdur, VoiceOverlapDetector& vod, const int measureNr);
133       void print(const int measureNr);
134       void attributes(const QString& partId, const Fraction cTime);
135       void clef(const QString& partId);
136       void time(const Fraction cTime);
137       void transpose(const QString& partId, const Fraction& tick);
138       void divisions();
139       void staves(const QString& partId);
140       void direction(const QString& partId, const Fraction cTime);
141       void directionType(const Fraction cTime, QList<MxmlOctaveShiftDesc>& starts, QList<MxmlOctaveShiftDesc>& stops);
142       void handleOctaveShift(const Fraction cTime, const QString& type, short size, MxmlOctaveShiftDesc& desc);
143       void notations(MxmlStartStop& tupletStartStop);
144       void note(const QString& partId, const Fraction cTime, Fraction& missingPrev, Fraction& dura, Fraction& missingCurr, VoiceOverlapDetector& vod, MxmlTupletStates& tupletStates);
145       void notePrintSpacingNo(Fraction& dura);
146       void duration(Fraction& dura);
147       void forward(Fraction& dura);
148       void backup(Fraction& dura);
149       void timeModification(Fraction& timeMod);
150       void pitch(int& step, float& alter, int& oct);
151       void rest();
152       void skipLogCurrElem();
153       bool determineMeasureLength(QVector<Fraction>& ml) const;
154       VoiceList getVoiceList(const QString id) const;
155       bool determineStaffMoveVoice(const QString& id, const int mxStaff, const QString& mxVoice,
156                                    int& msMove, int& msTrack, int& msVoice) const;
157       int trackForPart(const QString& id) const;
158       bool hasPart(const QString& id) const;
getPart(const QString & id)159       Part* getPart(const QString& id) const { return _partMap.value(id); }
getMusicXmlPart(const QString & id)160       MusicXmlPart getMusicXmlPart(const QString& id) const { return _parts.value(id); }
getInstruments(const QString & id)161       MusicXMLInstruments getInstruments(const QString& id) const { return _instruments.value(id); }
162       void setDrumsetDefault(const QString& id, const QString& instrId, const NoteHead::Group hg, const int line, const Direction sd);
163       MusicXmlInstrList getInstrList(const QString id) const;
164       MusicXmlIntervalList getIntervals(const QString id) const;
165       Fraction getMeasureStart(const int i) const;
166       int octaveShift(const QString& id, const int staff, const Fraction f) const;
credits()167       const CreditWordsList& credits() const { return _credits; }
hasBeamingInfo()168       bool hasBeamingInfo() const { return _hasBeamingInfo; }
169 
170 private:
171       // functions
172       // none
173 
174       // generic pass 1 data
175       QXmlStreamReader _e;
176       int _divs;                                ///< Current MusicXML divisions value
177       QMap<QString, MusicXmlPart> _parts;       ///< Parts data, mapped on part id
178       std::set<int> _systemStartMeasureNrs;     ///< Measure numbers of measures starting a page
179       std::set<int> _pageStartMeasureNrs;       ///< Measure numbers of measures starting a page
180       QVector<Fraction> _measureLength;         ///< Length of each measure
181       QVector<Fraction> _measureStart;          ///< Start time of each measure
182       CreditWordsList _credits;                 ///< All credits collected
183       PartMap _partMap;                         ///< TODO merge into MusicXmlPart ??
184       QMap<QString, MusicXMLInstruments> _instruments; ///< instruments for each part, mapped on part id
185       Score* _score;                            ///< MuseScore score
186       MxmlLogger* _logger;                      ///< Error logger
187       bool _hasBeamingInfo;                     ///< Whether the score supports or contains beaming info
188 
189       // part specific data (TODO: move to part-specific class)
190       Fraction _timeSigDura;                    ///< Measure duration according to last timesig read
191       QMap<int, MxmlOctaveShiftDesc> _octaveShifts; ///< Pending octave-shifts
192       QSize _pageSize;                          ///< Page width read from defaults
193       };
194 
195 } // namespace Ms
196 #endif
197