234 lines
9.4 KiB
C++
234 lines
9.4 KiB
C++
//=============================================================================
|
|
// MuseScore
|
|
// Linux Music Score Editor
|
|
//
|
|
// Copyright (C) 2015 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 __IMPORTMXMLPASS2_H__
|
|
#define __IMPORTMXMLPASS2_H__
|
|
|
|
#include "libmscore/score.h"
|
|
#include "libmscore/tuplet.h"
|
|
#include "importxmlfirstpass.h"
|
|
#include "importmxmlpass1.h"
|
|
#include "musicxml.h" // a.o. for Slur
|
|
#include "musicxmlsupport.h"
|
|
|
|
namespace Ms {
|
|
|
|
//---------------------------------------------------------
|
|
// support enums / structs / classes
|
|
//---------------------------------------------------------
|
|
|
|
typedef QList<Chord*> GraceChordList;
|
|
typedef QVector<FiguredBass*> FiguredBassList;
|
|
|
|
//---------------------------------------------------------
|
|
// MxmlStartStop
|
|
//---------------------------------------------------------
|
|
|
|
enum class MxmlStartStop : char {
|
|
START, STOP, NONE
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// MusicXmlTupletDesc
|
|
//---------------------------------------------------------
|
|
|
|
/**
|
|
Describe the information extracted from
|
|
a single note/notations/tuplet element.
|
|
*/
|
|
|
|
struct MusicXmlTupletDesc {
|
|
MusicXmlTupletDesc();
|
|
MxmlStartStop type;
|
|
Element::Placement placement;
|
|
Tuplet::BracketType bracket;
|
|
Tuplet::NumberType shownumber;
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// MusicXmlSpannerDesc
|
|
//---------------------------------------------------------
|
|
|
|
struct MusicXmlSpannerDesc {
|
|
SLine* sp;
|
|
Element::Type tp;
|
|
int nr;
|
|
MusicXmlSpannerDesc(SLine* _sp, Element::Type _tp, int _nr) : sp(_sp), tp(_tp), nr(_nr) {}
|
|
MusicXmlSpannerDesc(Element::Type _tp, int _nr) : sp(0), tp(_tp), nr(_nr) {}
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// MusicXMLParserPass2
|
|
//---------------------------------------------------------
|
|
|
|
class FretDiagram;
|
|
class FiguredBassItem;
|
|
|
|
class MusicXMLParserPass2 {
|
|
public:
|
|
MusicXMLParserPass2(Score* score, MusicXMLParserPass1& pass1);
|
|
void initPartState(const QString& partId);
|
|
Score::FileError parse(QIODevice* device);
|
|
Score::FileError parse();
|
|
void scorePartwise();
|
|
void partList();
|
|
void scorePart();
|
|
void part();
|
|
void measChordNote( /*, const MxmlPhase2Note note, ChordRest& currChord */);
|
|
void measChordFlush( /*, ChordRest& currChord */);
|
|
void measure(const QString& partId, const Fraction time);
|
|
void attributes(const QString& partId, Measure* measure, const int tick);
|
|
void measureStyle(Measure* measure);
|
|
void print(Measure* measure);
|
|
void barline(const QString& partId, Measure* measure);
|
|
void key(const QString& partId, Measure* measure, const int tick);
|
|
void clef(const QString& partId, Measure* measure, const int tick);
|
|
void time(const QString& partId, Measure* measure, const int tick);
|
|
void divisions();
|
|
void transpose(const QString& partId);
|
|
void note(const QString& partId, Measure* measure, const Fraction sTime, const Fraction prevTime,
|
|
Fraction& dura, QString& currentVoice, GraceChordList& gcl, Beam*& beam, FiguredBassList& fbl);
|
|
FiguredBassItem* figure(const int idx, const bool paren);
|
|
FiguredBass* figuredBass();
|
|
FretDiagram* frame();
|
|
void harmony(const QString& partId, Measure* measure, const Fraction sTime);
|
|
Accidental* accidental();
|
|
void beam(Beam::Mode& beamMode);
|
|
void duration(Fraction& dura);
|
|
void forward(Fraction& dura);
|
|
void backup(Fraction& dura);
|
|
void timeModification(Fraction& timeMod, TDuration& normalType);
|
|
void pitch(int& step, int& alter, int& oct, Accidental::Type& accid);
|
|
void rest(int& step, int& octave);
|
|
void lyric(QMap<int, Lyrics*>& numbrdLyrics, QMap<int, Lyrics*>& defyLyrics,
|
|
QList<Lyrics*>& unNumbrdLyrics);
|
|
void notations(Note* note, ChordRest* cr, const int tick, MusicXmlTupletDesc& tupletDesc);
|
|
void stem(MScore::Direction& sd, bool& nost);
|
|
void fermata(ChordRest* cr);
|
|
void tuplet(MusicXmlTupletDesc& tupletDesc);
|
|
void doEnding(const QString& partId, Measure* measure, const QString& number, const QString& type, const QString& text);
|
|
QString getParseStatus() const { return _parseStatus; }
|
|
//QString getParseResult() const { return parseResult; }
|
|
void logDebugTrace(const QString& info);
|
|
void logDebugInfo(const QString& info);
|
|
void logError(const QString& error);
|
|
void skipLogCurrElem();
|
|
|
|
// part specific data interface functions
|
|
void addSpanner(const MusicXmlSpannerDesc& desc);
|
|
SLine* getSpanner(const MusicXmlSpannerDesc& desc);
|
|
void clearSpanner(const MusicXmlSpannerDesc& desc);
|
|
|
|
// multi-measure rest state handling
|
|
void setMultiMeasureRestCount(int count);
|
|
int getAndDecMultiMeasureRestCount();
|
|
|
|
private:
|
|
// generic pass 2 data
|
|
|
|
QXmlStreamReader _e;
|
|
int _divs; // the current divisions value
|
|
QString _parseStatus; // the parse status (typicallay a short error message)
|
|
Score* const _score; // the score
|
|
MusicXMLParserPass1& _pass1; // the pass1 results
|
|
|
|
// part specific data (TODO: move to part-specific class)
|
|
|
|
// Measure duration according to last timesig read
|
|
// TODO: store timesigs read in pass 1, use those instead
|
|
// or use score->sigmap() ?
|
|
Fraction _timeSigDura;
|
|
|
|
QVector<Tuplet*> _tuplets; ///< Current tuplet for each track in the current part
|
|
SlurDesc _slur[MAX_NUMBER_LEVEL];
|
|
Trill* _trills[MAX_NUMBER_LEVEL]; ///< Current trills
|
|
SLine* _brackets[MAX_BRACKETS];
|
|
SLine* _dashes[MAX_DASHES];
|
|
SLine* _ottavas[MAX_NUMBER_LEVEL]; ///< Current ottavas
|
|
SLine* _hairpins[MAX_NUMBER_LEVEL]; ///< Current hairpins
|
|
// TODO SLine* trills[MAX_NUMBER_LEVEL]; ///< Current trills
|
|
|
|
Glissando* _glissandi[MAX_NUMBER_LEVEL][2]; ///< Current slides ([0]) / glissandi ([1])
|
|
|
|
Tie* _tie;
|
|
Volta* _lastVolta;
|
|
|
|
MusicXmlSpannerMap _spanners;
|
|
|
|
SLine* _pedal; ///< Current pedal
|
|
Pedal* _pedalContinue; ///< Current pedal type="change" requiring fixup
|
|
Harmony* _harmony; ///< Current harmony
|
|
Chord* _tremStart; ///< Starting chord for current tremolo
|
|
FiguredBass* _figBass; ///< Current figured bass element (to attach to next note)
|
|
int _multiMeasureRestCount;
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// MusicXMLParserDirection
|
|
//---------------------------------------------------------
|
|
|
|
class MusicXMLParserDirection {
|
|
public:
|
|
MusicXMLParserDirection(QXmlStreamReader& e, Score* score, const MusicXMLParserPass1& pass1, MusicXMLParserPass2& pass2);
|
|
void direction(const QString& partId, Measure* measure, const int tick, MusicXmlSpannerMap& spanners);
|
|
void logError(const QString& error);
|
|
void logDebugInfo(const QString& info);
|
|
void skipLogCurrElem();
|
|
|
|
private:
|
|
QXmlStreamReader& _e;
|
|
Score* const _score; // the score
|
|
const MusicXMLParserPass1& _pass1; // the pass1 results
|
|
MusicXMLParserPass2& _pass2; // the pass2 results
|
|
|
|
QStringList _dynamicsList;
|
|
QString _enclosure;
|
|
QString _wordsText;
|
|
QString _metroText;
|
|
QString _rehearsalText;
|
|
QString _dynaVelocity;
|
|
QString _tempo;
|
|
QString _sndCapo;
|
|
QString _sndCoda;
|
|
QString _sndDacapo;
|
|
QString _sndDalsegno;
|
|
QString _sndSegno;
|
|
QString _sndFine;
|
|
bool _hasDefaultY;
|
|
qreal _defaultY;
|
|
bool _coda;
|
|
bool _segno;
|
|
double _tpoMetro; // tempo according to metronome
|
|
double _tpoSound; // tempo according to sound
|
|
QList<Element*> _elems;
|
|
|
|
void directionType(QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops);
|
|
void bracket(const QString& type, const int number, QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops);
|
|
void octaveShift(const QString& type, const int number, QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops);
|
|
void pedal(const QString& type, const int number, QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops);
|
|
void dashes(const QString& type, const int number, QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops);
|
|
void wedge(const QString& type, const int number, QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops);
|
|
QString metronome(double& r);
|
|
void sound();
|
|
void dynamics();
|
|
void handleRepeats(Measure* measure, const int track);
|
|
};
|
|
|
|
} // namespace Ms
|
|
#endif
|