1 /* 2 Copyright © Grame 2008 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with this library; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 18 Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France 19 research@grame.fr 20 21 */ 22 23 #ifndef __pitchApplyOperation__ 24 #define __pitchApplyOperation__ 25 26 #include <vector> 27 #include <iostream> 28 29 #include "ARChord.h" 30 #include "ARNote.h" 31 #include "AROthers.h" 32 #include "arexport.h" 33 #include "clonevisitor.h" 34 #include "operation.h" 35 #include "guidorational.h" 36 #include "pitchvisitor.h" 37 #include "transposeOperation.h" 38 #include "tree_browser.h" 39 40 namespace guido 41 { 42 43 /*! 44 \addtogroup operations 45 @{ 46 */ 47 48 /*! 49 \brief the base visitor of pitch application. 50 51 Intended to minimize code size. 52 Can only be instantiated by derived class. 53 */ 54 class gar_export pitchApplyBaseOperation : 55 public operation, 56 public clonevisitor 57 { 58 protected: pitchApplyBaseOperation(chordPitchMode m)59 pitchApplyBaseOperation(chordPitchMode m) : fMode(m) { fBrowser.set(this); } ~pitchApplyBaseOperation()60 virtual ~pitchApplyBaseOperation() {} 61 62 63 bool fInChord; 64 chordPitchMode fMode; // the chord pitch extraction and application mode; 65 tree_browser<guidoelement> fBrowser; 66 int fCurrentScoreOctave; // the original score current octave 67 int fCurrentOctave; // used to code implicit octave 68 int fLastOctave; // used to restore correct octave at iterator end pos and at chords beginning 69 int fChordBase; // used to transpose chords 70 71 Sguidoelement browse ( const Sguidoelement& score ); 72 virtual void visitStart ( SARVoice& elt ); 73 virtual void setPitch ( SARNote& note, const pitchvisitor::TPitch& pitch, int& currentOctave ) const; 74 virtual void startChord ( SARChord& elt, bool clone ); 75 virtual void endChord ( SARChord& elt, int targetpitch, bool clone ); 76 virtual void setChordBase ( SARNote& elt ); 77 virtual void octaveCheck ( SARNote& elt ); 78 virtual SARNote startNote ( SARNote& elt ); 79 }; 80 81 /*! 82 \brief A visitor that applies a list of pitches to a score. 83 */ 84 template <typename T> class gar_export pitchApplyOperation : public pitchApplyBaseOperation 85 { 86 public: 87 typedef typename T::iterator pitchIterator; pitchApplyOperation(chordPitchMode m)88 pitchApplyOperation(chordPitchMode m) : pitchApplyBaseOperation(m) {} ~pitchApplyOperation()89 virtual ~pitchApplyOperation() {} 90 91 /*! applies a list of pitches to a score 92 \param score the taret score 93 \param start an iterator on pitch values 94 \param end an iterator on the end of pitch values 95 \return a new score 96 */ operator()97 Sguidoelement operator() ( const Sguidoelement& score, pitchIterator start, pitchIterator end ) { 98 fPos = start; 99 fEndPos = end; 100 return browse(score); 101 } 102 103 /*! applies a list of durations to a score 104 \param score1 the taret score 105 \param score2 a score which pitch is applied to the target score 106 \return a new score 107 \note pitch is extracted from the first voice only. 108 */ operator()109 SARMusic operator() ( const SARMusic& score1, const SARMusic& score2 ) 110 { 111 pitchvisitor pv(fMode); 112 T list; 113 pv.pitch(score2, 0, &list); 114 Sguidoelement elt = (*this)(score1, list.begin(), list.end()); 115 return dynamic_cast<ARMusic*>((guidoelement*)elt); 116 } 117 118 protected: 119 typename T::iterator fPos, fEndPos; 120 visitStart(SARNote & elt)121 virtual void visitStart( SARNote& elt ) { 122 SARNote note = startNote(elt); 123 if (note) { 124 if (fPos != fEndPos) { 125 pitchvisitor::TPitch pitch = *fPos; 126 if (!fInChord) { 127 setPitch( note, pitch, fCurrentOctave); 128 push( note ); 129 fPos++; 130 } 131 else setChordBase (elt); 132 } 133 else { 134 octaveCheck (note); 135 push( note ); 136 } 137 } 138 } 139 visitStart(SARChord & elt)140 virtual void visitStart( SARChord& elt ) { startChord (elt, fPos == fEndPos); } visitEnd(SARChord & elt)141 virtual void visitEnd ( SARChord& elt ) { 142 if (fPos == fEndPos) endChord (elt, 0, true); 143 else { 144 endChord (elt, pitchvisitor::midiPitch (*fPos), false); 145 fPos++; 146 } 147 } 148 }; 149 150 /// \brief a specialized class on low chords pitches 151 template <typename T> class gar_export pitchLowApplyOperation : public pitchApplyOperation<T> 152 { pitchLowApplyOperation()153 public: pitchLowApplyOperation() : pitchApplyOperation<T>(kUseLowest) {} 154 }; 155 156 /// \brief a specialized class on high chords pitches 157 template <typename T> class gar_export pitchHighApplyOperation : public pitchApplyOperation<T> 158 { pitchHighApplyOperation()159 public: pitchHighApplyOperation() : pitchApplyOperation<T>(kUseHighest) {} 160 }; 161 162 /*! @} */ 163 164 } // namespace MusicXML 165 166 167 #endif 168