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 __guido__
14 #define __guido__
15 
16 #include <vector>
17 #include <string>
18 #include <iostream>
19 
20 #include "exports.h"
21 #include "smartpointer.h"
22 
23 namespace MusicXML2
24 {
25 
26 class guidovisitor;
27 class guidoelement;
28 class guidoparam;
29 typedef SMARTP<guidoelement> 	Sguidoelement;
30 typedef SMARTP<guidoparam> 		Sguidoparam;
31 
32 
33 EXP std::ostream& operator<< (std::ostream& os, const Sguidoelement& elt);
34 
35 /*!
36 \addtogroup guido
37 @{
38 */
39 
40 /*!
41 \brief A guidotag parameter representation.
42 
43 	A parameter is represented by its value.
44 */
45 class EXP guidoparam : public smartable {
46 	public:
47         static SMARTP<guidoparam> create(std::string value, bool quote=true);
48         static SMARTP<guidoparam> create(long value, bool quote=true);
49 
50 		//! the parameter value
51 		void set (std::string value, bool quote=true);
52 		void set (long value, bool quote=true);
get()53 		std::string get () const 						{ return fValue; }
quote()54 		bool   quote () const 						{ return fQuote; }
55 
56     protected:
57 		guidoparam(std::string value, bool quote);
58 		guidoparam(long value, bool quote);
59 		virtual ~guidoparam ();
60 
61     private:
62 		std::string 	fValue;
63 		bool	fQuote;
64 };
65 
66 /*!
67 \brief A generic guido element representation.
68 
69 	An element is represented by its name and the
70 	list of its enclosed elements plus optional parameters.
71 */
72 class EXP guidoelement : public smartable {
73 	public:
74         static SMARTP<guidoelement> create(std::string name, std::string sep=" ");
75 
76 		long add (Sguidoelement& elt);
77 		long add (Sguidoparam& param);
78 		long add (Sguidoparam param);
79 		virtual void print (std::ostream& os) const;
80 
81 		//! the element name
setName(std::string name)82 		void 	setName (std::string name)			{ fName = name; }
getName()83 		std::string 	getName () const				{ return fName; }
getStart()84 		std::string 	getStart () const				{ return fStartList; }
getEnd()85 		std::string 	getEnd () const					{ return fEndList; }
getSep()86 		std::string 	getSep () const					{ return fSep; }
setEnd(std::string end)87         void            setEnd (std::string end) 		{ fEndList=end; }
elements()88         std::vector<Sguidoelement>& elements()			{ return fElements; }
elements()89 		const std::vector<Sguidoelement>& elements() const 	{ return fElements; }
parameters()90         const std::vector<Sguidoparam>& parameters() const 	{ return fParams; }
91 
empty()92 		bool empty () const 				{ return fElements.empty(); }
isSeq()93 		virtual bool isSeq () const 		{ return false; }
isChord()94 		virtual bool isChord () const 		{ return false; }
isTag()95 		virtual bool isTag () const 		{ return false; }
isNote()96 		virtual bool isNote () const 		{ return false; }
97 
98 		int countNotes () const;
99 
100     protected:
101 				 guidoelement(std::string name, std::string sep=" ");
102 		virtual ~guidoelement();
103 
104 		void printparams (std::ostream& os) const;
105 
106 		std::string	fName;
107 		//! the contained element start marker (default to empty)
108 		std::string	fStartList;
109 		//! the contained element end marker (default to empty)
110 		std::string	fEndList;
111 		//! the element separator (default to space)
112 		std::string	fSep;
113 		//! list of the enclosed elements
114 		std::vector<Sguidoelement>	fElements;
115 		//! list of optional parameters
116 		std::vector<Sguidoparam>	fParams;
117 };
118 
119 /*!
120 \brief A guido note duration representation.
121 
122 	A note duration is represented by a numerator
123     (denotes the number of beats), a denominator (denotes the beat value)
124      and optional dots.
125      Triplets are repesented as 1/3, 1/6, ... quintuplets, septuplets and so on
126      are handled analogously.
127 */
128 class EXP guidonoteduration {
129 	public:
130 		guidonoteduration(long num, long denom, long dots=0)
131             { set (num, denom, dots); }
~guidonoteduration()132 		virtual ~guidonoteduration() {}
133 
134         void set (long num, long denom, long dots=0)
135             { fNum=num; fDenom=denom; fDots=dots; }
136         guidonoteduration& operator= (const guidonoteduration& dur)
137             { fNum=dur.fNum; fDenom=dur.fDenom; fDots=dur.fDots; return *this; }
138         bool operator!= (const guidonoteduration& dur) const
139             { return (fNum!=dur.fNum) || (fDenom!=dur.fDenom) || (fDots!=dur.fDots); }
140 
141         long	fNum;
142 		long	fDenom;
143 		long	fDots;
144 };
145 
146 /*!
147 \brief A guido note representation.
148 
149 	A note is represented by its name, optional accidentals,
150     duration (in the form of numerator/denominator) and optional dots.
151 */
152 class EXP guidonote : public guidoelement {
153 	public:
154         static SMARTP<guidonote> create(unsigned short voice);
155         static SMARTP<guidonote> create(unsigned short voice, std::string name, char octave,
156                                                 guidonoteduration& dur, std::string acc="");
157 
158 		void set (unsigned short voice, std::string name, char octave, guidonoteduration& dur, std::string acc);
setName(const std::string name)159 		void setName (const std::string name)			{ fNote = name; }
setOctave(char octave)160 		void setOctave (char octave)					{ fOctave = octave; }
setDuration(const guidonoteduration & dur)161 		void setDuration (const guidonoteduration& dur)	{ fDuration = dur; }
setAccidental(const std::string acc)162 		void setAccidental (const std::string acc)		{ fAccidental = acc; }
163 
name()164 		const char * 	name() const		{ return fNote.c_str(); }
accidental()165 		const char * 	accidental() const	{ return fAccidental.c_str(); }
octave()166 		char 			octave() const		{ return fOctave; }
duration()167 		const guidonoteduration& duration() const { return fDuration; }
168 
isNote()169 		virtual bool isNote () const { return true; }
170 
171 	protected:
172 		guidonote(unsigned short voice);
173 		guidonote(unsigned short voice, std::string name, char octave,
174                     guidonoteduration& dur, std::string acc="");
175 		virtual ~guidonote();
176 
177 	std::string 	fNote;
178 	std::string 	fAccidental;
179 	char 	fOctave;
180 	guidonoteduration fDuration;
181 
182 };
183 typedef SMARTP<guidonote> Sguidonote;
184 
185 /*!
186 \brief Represents the current status of notes duration and octave.
187 
188     Octave and duration may be ommitted for guido notes. If so,
189     they are infered from preceeding notes (or rest), within the same
190     sequence or chord, or assumed to have standard values.
191 \n
192 	The object is defined as a multi-voices singleton: a single
193     object is allocated for a specific voice and thus it will
194 	not operate correctly on a same voice parrallel formatting
195     operations.
196 
197 \todo handling the current beat value for \e *num duration form.
198 */
199 class EXP guidonotestatus {
200 	public:
201         enum { kMaxInstances=128 };
202 
203 		static guidonotestatus* get(unsigned short voice);
204 		static void resetall();
205 		static void freeall();
206 
207         enum { defoctave=1, defnum=1, defdenom=4 };
208 
reset()209         void reset()	{ fOctave=defoctave; fDur.set(defnum, defdenom, 0); }
210         guidonotestatus& operator= (const guidonoteduration& dur)	{ fDur = dur; return *this; }
211         bool operator!= (const guidonoteduration& dur) const		{ return fDur!= dur; }
212 
213 		char				fOctave;
214 		guidonoteduration 	fDur;
215 //		char				fBeat;
216 
217 	protected:
guidonotestatus()218 		guidonotestatus() :	fOctave(defoctave), fDur(defnum, defdenom, 0) {}
219 	private:
220 		static guidonotestatus * fInstances[kMaxInstances];
221 };
222 
223 /*!
224 \brief The guido sequence element
225 */
226 class EXP guidoseq : public guidoelement {
227 	public:
228         static SMARTP<guidoseq> create();
isSeq()229 		virtual bool isSeq () const 		{ return true; }
230 
231 	protected:
232 				 guidoseq();
233 		virtual ~guidoseq();
234 };
235 typedef SMARTP<guidoseq> Sguidoseq;
236 
237 /*!
238 \brief The guido chord element
239 */
240 class EXP guidochord : public guidoelement {
241 	public:
242         static SMARTP<guidochord> create();
isChord()243 		virtual bool isChord () const 	{ return true; }
244 
245 	protected:
246 				 guidochord ();
247 		virtual ~guidochord();
248 
249 		virtual void print (std::ostream& os) const;
250 };
251 typedef SMARTP<guidochord> Sguidochord;
252 
253 /*!
254 \brief A guido tag representation.
255 
256 	A tag is represented by its name and optional parameters.
257 	A range tag contains enclosed elements.
258 */
259 class EXP guidotag : public guidoelement {
260 	public:
261 		static SMARTP<guidotag> create(std::string name);
262     	static SMARTP<guidotag> create(std::string name, std::string sep);
isTag()263 		virtual bool isTag () const 		{ return true; }
264 
265 	protected:
266         		 guidotag(std::string name);
267         		 guidotag(std::string name, std::string sep);
268 		virtual ~guidotag();
269 };
270 typedef SMARTP<guidotag> Sguidotag;
271 /*! @} */
272 
273 }
274 
275 #endif
276