1 /* 2 MusicXML Library 3 Copyright (C) Grame 2006-2013 4 5 This Source Code Form is subject to the terms of the Mozilla Public 6 License, v. 2.0. If a copy of the MPL was not distributed with this 7 file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 9 Grame Research Laboratory, 11, cours de Verdun Gensoul 69002 Lyon - France 10 research@grame.fr 11 */ 12 13 #ifndef __xmlpart2guido__ 14 #define __xmlpart2guido__ 15 16 #include <ostream> 17 #include <stack> 18 #include <queue> 19 #include <map> 20 #include <string> 21 22 #include "clefvisitor.h" 23 #include "exports.h" 24 #include "guido.h" 25 #include "keysignvisitor.h" 26 #include "metronomevisitor.h" 27 #include "notevisitor.h" 28 #include "rational.h" 29 #include "timesignvisitor.h" 30 #include "typedefs.h" 31 #include "visitor.h" 32 #include "xml.h" 33 34 namespace MusicXML2 35 { 36 37 /*! 38 \ingroup visitors guido 39 @{ 40 */ 41 42 /*! 43 \brief A score visitor to produce a Guido representation. 44 */ 45 //______________________________________________________________________________ 46 class EXP xmlpart2guido : 47 public clefvisitor, 48 public timesignvisitor, 49 public notevisitor, 50 public keysignvisitor, 51 public visitor<S_backup>, 52 public visitor<S_barline>, 53 public visitor<S_coda>, 54 public visitor<S_direction>, 55 public visitor<S_divisions>, 56 public visitor<S_ending>, 57 public visitor<S_forward>, 58 public visitor<S_measure>, 59 public visitor<S_octave_shift>, 60 public visitor<S_part>, 61 public visitor<S_repeat>, 62 public visitor<S_segno>, 63 public visitor<S_sound>, 64 public visitor<S_wedge>, 65 public visitor<S_rehearsal>, // for rehearsal Markup 66 public visitor<S_attributes> // to get clef, division, staves, time and key in order! 67 { 68 // the guido elements stack 69 std::stack<Sguidoelement> fStack; 70 // structure to store delayed elements ie elements enclosed in direction with offset 71 typedef struct { 72 long delay; 73 Sguidoelement element; 74 } delayedElement; 75 vector<delayedElement> fDelayed; 76 // fields to controls the guido output generation 77 bool fGenerateComments, fGenerateBars, fGeneratePositions, fGenerateAutoMeasureNum, fLyricsManualSpacing; 78 // bool fGenerateStem; 79 80 // internal parsing state 81 bool fInCue, fInGrace, fInhibitNextBar, fPendingBar, fBeamOpened, fMeasureEmpty, fCrescPending,fWavyTrillOpened, fSingleScopeTrill, fNonStandardNoteHead, fDoubleBar, fTremoloInProgress; 82 83 int fTextTagOpen; 84 int fTupletOpen; // Number of opened Tuplets 85 86 std::queue<int> fDirectionEraserStack; // To skip already visited Directions when looking ahead because of grace notes 87 std::stack< std::pair<int, int> > fBeamStack; // first int: Internal num, 2nd int: XML num 88 std::vector< std::pair<int, int> > fSlurStack; // first int: Internal num, 2nd int: XML num 89 90 Sguidoelement fLyricOpened; 91 92 bool isProcessingChord; 93 94 S_measure fCurrentMeasure; 95 S_part fCurrentPart; 96 97 bool fNotesOnly; // a flag to generate notes only (used for several voices on the same staff) 98 bool fSkipDirection; // a flag to skip direction elements (for notes only mode or due to different staff) 99 int fCurrentStaffIndex; // the index of the current guido staff 100 int fCurrentStaff; // the staff we're currently generating events for (0 by default) 101 int fTargetStaff; // the musicxml target staff (0 by default) 102 int fTargetVoice; // the musicxml target voice (0 by default) 103 104 long fCurrentDivision; // the current measure division, expresses the time unit in division of the quarter note 105 long fCurrentOffset; // the current direction offset: represents an element relative displacement in current division unit 106 rational fCurrentMeasureLength; // the current measure length (max of the current measure positions) 107 rational fCurrentMeasurePosition;// the current position in the measure 108 rational fCurrentVoicePosition; // the current position within a voice 109 rational fCurrentTimeSign; // the current time signature 110 int fMeasNum; 111 112 int fCurrentBeamNumber; // number attribute of the current beam 113 int fCurrentStemDirection; // the current stems direction, used for stem direction changes 114 int fPendingPops; // elements to be popped at chord exit (like fermata, articulations...) 115 start(Sguidoelement & elt)116 void start (Sguidoelement& elt) { fStack.push(elt); } add(Sguidoelement & elt)117 void add (Sguidoelement& elt) { if (fStack.size()) fStack.top()->add(elt); } 118 void addDelayed (Sguidoelement elt, long offset); // adding elements to the delayed elements 119 void checkDelayed (long time); // checks the delayed elements for ready elements push(Sguidoelement & elt)120 void push (Sguidoelement& elt) { add(elt); fStack.push(elt); } pop()121 void pop () { fStack.pop(); } 122 123 void moveMeasureTime (int duration, bool moveVoiceToo=false, int x_default = 0); 124 void reset (); 125 void stackClean (); 126 127 int checkArticulation ( const notevisitor& note ); // returns the count of articulations pushed on the stack 128 void checkPostArticulation ( const notevisitor& note ); /// Articulations that should be generated in ADD mode after note creation 129 130 int checkChordOrnaments ( const notevisitor& note ); // returns the count of articulations pushed on the stack 131 132 std::vector<Sxmlelement> getChord ( const S_note& note ); // build a chord vector 133 std::vector<Sxmlelement> getChord ( const Sxmlelement& note ); // build a chord vector 134 void checkStaff (int staff ); // check for staff change 135 void checkStem ( const S_stem& stem ); 136 void checkBeamBegin ( const std::vector<S_beam>& beams ); 137 void checkBeamEnd ( const std::vector<S_beam>& beams ); 138 void checkTupletBegin( const std::vector<S_tuplet>& tuplets, 139 const notevisitor& nv, 140 const S_note& elt); 141 void checkTupletEnd ( const std::vector<S_tuplet>& tuplets ); 142 void checkCue ( const notevisitor& nv ); 143 void checkGrace ( const notevisitor& nv ); 144 void checkGraceEnd(const notevisitor& nv); 145 int checkFermata ( const notevisitor& stem ); 146 void checkSlur ( const std::vector<S_slur>& slurs ); 147 void checkSlurBegin ( const std::vector<S_slur>& slurs ); 148 void checkSlurEnd ( const std::vector<S_slur>& slurs ); 149 bool isSlurClosing(S_slur elt); 150 void checkTiedBegin ( const std::vector<S_tied>& tied ); 151 void checkTiedEnd ( const std::vector<S_tied>& tied ); 152 void checkVoiceTime ( const rational& currTime, const rational& voiceTime); 153 int checkRestFormat ( const notevisitor& nv ); 154 int checkNoteFormatDx ( const notevisitor& nv , rational posInMeasure); 155 void checkWavyTrillBegin ( const notevisitor& nv ); 156 void checkWavyTrillEnd ( const notevisitor& nv ); 157 void checkTextEnd(); 158 void newNote ( const notevisitor& nv, rational posInMeasure, const S_note& elt); 159 160 int checkTremolo(const notevisitor& note, const S_note& elt); 161 162 std::string noteName ( const notevisitor& nv ); 163 guidonoteduration noteDuration ( const notevisitor& nv); 164 165 std::vector<S_beam>::const_iterator findValue ( const std::vector<S_beam>& beams, const std::string& val ) const; 166 std::vector<S_slur>::const_iterator findTypeValue ( const std::vector<S_slur>& slurs, const std::string& val ) const; 167 std::vector<S_tied>::const_iterator findTypeValue ( const std::vector<S_tied>& tied, const std::string& val ) const; 168 std::vector< std::pair<int, int> >::const_iterator findSlur ( const int xmlnum ) const; 169 170 /// Lyrics handling by AC 171 void checkLyricBegin ( const std::vector<S_lyric>& lyrics ); 172 void checkLyricEnd ( const std::vector<S_lyric>& lyrics ); 173 std::vector<S_lyric>::const_iterator findValue ( const std::vector<S_lyric>& lyrics, 174 const std::string& val ) const; 175 std::string lyricParams; 176 177 178 static std::string alter2accident ( float alter ); 179 180 protected: 181 enum { kStemUndefined, kStemUp, kStemDown, kStemNone }; 182 enum { kLeaveChord=-1, kNoChord, kEnterChord } chordState; 183 184 virtual void visitStart( S_backup& elt); 185 virtual void visitStart( S_barline& elt); 186 virtual void visitStart( S_coda& elt); 187 virtual void visitStart( S_direction& elt); 188 virtual void visitStart( S_divisions& elt); 189 virtual void visitStart( S_forward& elt); 190 virtual void visitStart( S_measure& elt); 191 virtual void visitStart( S_note& elt); 192 virtual void visitStart( S_octave_shift& elt); 193 virtual void visitStart( S_part& elt); 194 virtual void visitStart( S_segno& elt); 195 virtual void visitStart( S_wedge& elt); 196 virtual void visitStart( S_rehearsal& elt); 197 virtual void visitStart( S_attributes& elt); 198 199 virtual void visitEnd ( S_direction& elt); 200 virtual void visitEnd ( S_ending& elt); 201 virtual void visitEnd ( S_key& elt); 202 virtual void visitEnd ( S_measure& elt); 203 virtual void visitEnd ( S_note& elt); 204 virtual void visitEnd ( S_repeat& elt); 205 virtual void visitEnd ( S_sound& elt); 206 virtual void visitEnd ( S_time& elt); 207 208 std::string parseMetronome ( metronomevisitor &mv ); 209 210 bool findNextNote(const S_note& elt, ctree<xmlelement>::iterator &nextnote); 211 float getNoteDistanceFromStaffTop(const notevisitor& nv); 212 213 rational durationInCue; 214 215 std::map<int, float> fStaffDistance; 216 217 bool fIgnoreWedgeWithOffset; 218 219 // Internal Parsing facilities 220 float xPosFromTimePos(float default_x, float relative_x); /// Infer X-Position from TimePosition 221 222 public: 223 xmlpart2guido(bool generateComments, bool generateStem, bool generateBar=true); ~xmlpart2guido()224 virtual ~xmlpart2guido() {} 225 current()226 Sguidoelement& current () { return fStack.top(); } 227 void initialize (Sguidoelement seq, int staff, int guidostaff, int voice, bool notesonly, rational defaultTimeSign); generatePositions(bool state)228 void generatePositions (bool state) { fGeneratePositions = state; } getTimeSign()229 const rational& getTimeSign () const { return fCurrentTimeSign; } 230 bool fHasLyrics; hasLyrics()231 bool hasLyrics() const {return fHasLyrics;} 232 std::multimap<int, std::pair< int, std::pair< rational, string > > > staffClefMap; 233 234 std::string getClef(int staffIndex, rational pos, int measureNum); 235 236 /// Containing default-x positions on a fCurrentVoicePosition (rational) of measure(int) 237 std::map< int, std::map< rational, std::vector<int> > > timePositions; 238 239 void addPosYforNoteHead(const notevisitor& nv, Sxmlelement elt, Sguidoelement& tag, float offset); 240 241 }; 242 243 244 } // namespace MusicXML2 245 246 247 #endif 248