1 /*
2 
3   guidoar Library
4   Copyright (C) 2008-2012  Grame
5 
6   This library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Lesser General Public
8   License as published by the Free Software Foundation; either
9   version 2.1 of the License, or (at your option) any later version.
10 
11   This library is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   Lesser General Public License for more details.
15 
16   You should have received a copy of the GNU Lesser General Public
17   License along with this library; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20   Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
21   research@grame.fr
22 
23 */
24 
25 #include <fstream>
26 #include <string.h>
27 
28 #include "libguidoar.h"
29 
30 #include "AROthers.h"
31 #include "bottomOperation.h"
32 #include "clonevisitor.h"
33 #include "durationOperation.h"
34 #include "eheadOperation.h"
35 #include "etailOperation.h"
36 #include "event2timevisitor.h"
37 #include "guidoelement.h"
38 #include "guidoparser.h"
39 #include "headOperation.h"
40 #ifdef MIDIEXPORT
41 #include "midiconverter.h"
42 #endif
43 #include "mirrorOperation.h"
44 #include "parOperation.h"
45 #include "seqOperation.h"
46 #include "tailOperation.h"
47 #include "topOperation.h"
48 #include "transposeOperation.h"
49 #include "ringvector.h"
50 #include "rythmApplyOperation.h"
51 #include "pitchApplyOperation.h"
52 #include "unrolled_guido_browser.h"
53 
54 using namespace std;
55 namespace guido
56 {
57 
58 //----------------------------------------------------------------------------
guidoarVersion()59 gar_export float			guidoarVersion()	{ return 1.00; }
guidoarVersionStr()60 gar_export const char*		guidoarVersionStr()	{ return "1.00"; }
61 
62 //----------------------------------------------------------------------------
read(const char * buff)63 static SARMusic read (const char* buff)
64 {
65 	if (!buff) return 0;
66 	guidoparser r;
67 	return r.parseString(buff);
68 }
69 
70 //----------------------------------------------------------------------------
guido2unrolled(const char * gmn,std::ostream & out)71 gar_export garErr guido2unrolled(const char* gmn, std::ostream& out)
72 {
73 	garErr err = kNoErr;
74 	Sguidoelement score =  read(gmn);
75 	if (!score) return kInvalidArgument;
76 
77 	clonevisitor cv;
78 	unrolled_guido_browser ugb(&cv);
79 	ugb.browse (score);
80 	score = cv.result();
81 	if (score) out << score << endl;
82 	else err = kOperationFailed;
83 	return err;
84 }
85 
86 //----------------------------------------------------------------------------
guidoEv2Time(const char * gmn,unsigned int index,unsigned int voice)87 gar_export rational	guidoEv2Time(const char* gmn, unsigned int index, unsigned int voice)
88 {
89 	Sguidoelement score =  read(gmn);
90 	if (!score) return kInvalidArgument;
91 	event2timevisitor convert;
92 	return convert.event2time (score, index, voice);
93 }
94 
95 //----------------------------------------------------------------------------
guidoTime2Ev(const char * gmn,const rational & date,unsigned int voice)96 gar_export int guidoTime2Ev(const char* gmn, const rational& date, unsigned int voice)
97 {
98 	Sguidoelement score =  read(gmn);
99 	if (!score) return kInvalidArgument;
100 	event2timevisitor convert;
101 	return convert.time2event (score, date, voice);
102 }
103 
104 
105 //----------------------------------------------------------------------------
106 // wrappers for score operations
107 //----------------------------------------------------------------------------
opWrapper(const char * gmn,ARG param,std::ostream & out)108 template<typename OP, typename ARG> garErr opWrapper(const char* gmn, ARG param, std::ostream& out)
109 {
110 	Sguidoelement score =  read(gmn);
111 	if (!score) return kInvalidArgument;
112 
113 	OP op;
114 	score = op(score, param);
115 	if (score) out << score << endl;
116 	else return kOperationFailed;
117 	return kNoErr;
118 }
119 
120 //----------------------------------------------------------------------------
opgmnWrapper(const char * gmn,const char * gmnSpec,std::ostream & out)121 template<typename OP> garErr opgmnWrapper(const char* gmn, const char* gmnSpec,  std::ostream& out)
122 {
123 	SARMusic score =  read(gmn);
124 	SARMusic dscore = read(gmnSpec);
125 	if (!score || !dscore) return kInvalidArgument;
126 
127 	OP op;
128 	score = op(score, dscore);
129 	if (score) out << Sguidoelement(score) << endl;
130 	else return kOperationFailed;
131 	return kNoErr;
132 }
133 
134 //----------------------------------------------------------------------------
135 // score operations
136 //----------------------------------------------------------------------------
guidoGBottom(const char * gmn,const char * gmnSpec,std::ostream & out)137 gar_export garErr guidoGBottom(const char* gmn, const char* gmnSpec, std::ostream& out)
138 							{ return opgmnWrapper<bottomOperation>(gmn, gmnSpec, out); }
guidoVBottom(const char * gmn,int nvoices,std::ostream & out)139 gar_export garErr guidoVBottom(const char* gmn, int nvoices, std::ostream& out)
140 							{ return opWrapper<bottomOperation, int>(gmn, nvoices, out); }
141 
142 //----------------------------------------------------------------------------
guidoGTop(const char * gmn,const char * gmnSpec,std::ostream & out)143 gar_export garErr guidoGTop(const char* gmn, const char* gmnSpec, std::ostream& out)
144 							{ return opgmnWrapper<topOperation>(gmn, gmnSpec, out); }
guidoVTop(const char * gmn,int nvoices,std::ostream & out)145 gar_export garErr guidoVTop(const char* gmn, int nvoices, std::ostream& out)
146 							{ return opWrapper<topOperation, int>(gmn, nvoices, out); }
147 
148 //----------------------------------------------------------------------------
guidoGSetDuration(const char * gmn,const char * gmnSpec,std::ostream & out)149 gar_export garErr guidoGSetDuration(const char* gmn, const char* gmnSpec, std::ostream& out)
150 							{ return opgmnWrapper<durationOperation>(gmn, gmnSpec, out); }
guidoVSetDuration(const char * gmn,rational duration,std::ostream & out)151 gar_export garErr guidoVSetDuration(const char* gmn, rational duration, std::ostream& out)
152 							{ return opWrapper<durationOperation, rational>(gmn, duration, out); }
guidoVMultDuration(const char * gmn,float duration,std::ostream & out)153 gar_export garErr guidoVMultDuration(const char* gmn, float duration, std::ostream& out)
154 							{ return opWrapper<durationOperation, float>(gmn, duration, out); }
155 
156 //----------------------------------------------------------------------------
guidoApplyRythm(const char * gmn,const char * gmnSpec,TApplyMode mode,std::ostream & out)157 gar_export garErr guidoApplyRythm(const char* gmn, const char* gmnSpec, TApplyMode mode, std::ostream& out)
158 {
159 	switch (mode) {
160 		case kApplyOnce:
161 			return opgmnWrapper<rythmApplyOperation<vector<rational> > >(gmn, gmnSpec, out);
162 		case kApplyForwardLoop:
163 			return opgmnWrapper<rythmApplyOperation<ringvector<rational> > >(gmn, gmnSpec, out);
164 		case kApplyForwardBackwardLoop: ;
165 			return opgmnWrapper<rythmApplyOperation<fwbwvector<rational> > >(gmn, gmnSpec, out);
166 	}
167 	return kInvalidArgument;
168 }
169 
170 //----------------------------------------------------------------------------
guidoApplyPitch(const char * gmn,const char * gmnSpec,TApplyMode mode,chordPitchMode pmode,std::ostream & out)171 gar_export garErr guidoApplyPitch(const char* gmn, const char* gmnSpec, TApplyMode mode, chordPitchMode pmode, std::ostream& out)
172 {
173 	switch (pmode) {
174 		 case kUseLowest:
175 			switch (mode) {
176 				case kApplyOnce:
177 					return opgmnWrapper<pitchLowApplyOperation<vector<pitchvisitor::TPitch> > >(gmn, gmnSpec, out);
178 				case kApplyForwardLoop:
179 					return opgmnWrapper<pitchLowApplyOperation<ringvector<pitchvisitor::TPitch> > >(gmn, gmnSpec, out);
180 				case kApplyForwardBackwardLoop: ;
181 					return opgmnWrapper<pitchLowApplyOperation<fwbwvector<pitchvisitor::TPitch> > >(gmn, gmnSpec, out);
182 			}
183 			break;
184 		 case kUseHighest:
185 			switch (mode) {
186 				case kApplyOnce:
187 					return opgmnWrapper<pitchHighApplyOperation<vector<pitchvisitor::TPitch> > >(gmn, gmnSpec, out);
188 				case kApplyForwardLoop:
189 					return opgmnWrapper<pitchHighApplyOperation<ringvector<pitchvisitor::TPitch> > >(gmn, gmnSpec, out);
190 				case kApplyForwardBackwardLoop: ;
191 					return opgmnWrapper<pitchHighApplyOperation<fwbwvector<pitchvisitor::TPitch> > >(gmn, gmnSpec, out);
192 			}
193 			break;
194 	}
195 	return kInvalidArgument;
196 }
197 
198 //----------------------------------------------------------------------------
guidoVTranpose(const char * gmn,int interval,std::ostream & out)199 gar_export garErr guidoVTranpose(const char* gmn, int interval, std::ostream& out)
200 							{ return opWrapper<transposeOperation, int>(gmn, interval, out); }
guidoGTranpose(const char * gmn,const char * gmnSpec,std::ostream & out)201 gar_export garErr guidoGTranpose(const char* gmn, const char* gmnSpec, std::ostream& out)
202 							{ return opgmnWrapper<transposeOperation>(gmn, gmnSpec, out); }
203 
204 //----------------------------------------------------------------------------
guidoVHead(const char * gmn,rational duration,std::ostream & out)205 gar_export garErr guidoVHead(const char* gmn, rational duration, std::ostream& out)
206 							{ return opWrapper<headOperation, rational>(gmn, duration, out); }
guidoGHead(const char * gmn,const char * gmnSpec,std::ostream & out)207 gar_export garErr guidoGHead(const char* gmn, const char* gmnSpec, std::ostream& out)
208 							{ return opgmnWrapper<headOperation>(gmn, gmnSpec, out); }
209 
210 //----------------------------------------------------------------------------
guidoVEHead(const char * gmn,int duration,std::ostream & out)211 gar_export garErr guidoVEHead(const char* gmn, int duration, std::ostream& out)
212 							{ return opWrapper<eheadOperation, int>(gmn, duration, out); }
guidoGEHead(const char * gmn,const char * gmnSpec,std::ostream & out)213 gar_export garErr guidoGEHead(const char* gmn, const char* gmnSpec, std::ostream& out)
214 							{ return opgmnWrapper<eheadOperation>(gmn, gmnSpec, out); }
215 
216 //----------------------------------------------------------------------------
guidoVTail(const char * gmn,rational duration,std::ostream & out)217 gar_export garErr guidoVTail(const char* gmn, rational duration, std::ostream& out)
218 							{ return opWrapper<tailOperation, rational>(gmn, duration, out); }
guidoGTail(const char * gmn,const char * gmnSpec,std::ostream & out)219 gar_export garErr guidoGTail(const char* gmn, const char* gmnSpec, std::ostream& out)
220 							{ return opgmnWrapper<tailOperation>(gmn, gmnSpec, out); }
221 
222 //----------------------------------------------------------------------------
guidoVETail(const char * gmn,int duration,std::ostream & out)223 gar_export garErr guidoVETail(const char* gmn, int duration, std::ostream& out)
224 							{ return opWrapper<etailOperation, int>(gmn, duration, out); }
guidoGETail(const char * gmn,const char * gmnSpec,std::ostream & out)225 gar_export garErr guidoGETail(const char* gmn, const char* gmnSpec, std::ostream& out)
226 							{ return opgmnWrapper<etailOperation>(gmn, gmnSpec, out); }
227 
228 //----------------------------------------------------------------------------
guidoGSeq(const char * gmn1,const char * gmn2,std::ostream & out)229 gar_export garErr guidoGSeq(const char* gmn1, const char* gmn2, std::ostream& out)
230 							{ return opgmnWrapper<seqOperation>(gmn1, gmn2, out); }
guidoGPar(const char * gmn1,const char * gmn2,std::ostream & out)231 gar_export garErr guidoGPar(const char* gmn1, const char* gmn2, std::ostream& out)
232 							{ return opgmnWrapper<parOperation>(gmn1, gmn2, out); }
guidoGRPar(const char * gmn1,const char * gmn2,std::ostream & out)233 gar_export garErr guidoGRPar(const char* gmn1, const char* gmn2, std::ostream& out)
234 							{ return opgmnWrapper<rparOperation>(gmn1, gmn2, out); }
235 
236 //----------------------------------------------------------------------------
guidoGMirror(const char * gmn1,const char * gmn2,std::ostream & out)237 gar_export garErr guidoGMirror(const char* gmn1, const char* gmn2, std::ostream& out)
238 							{ return opgmnWrapper<mirrorOperation>(gmn1, gmn2, out); }
239 
240 //----------------------------------------------------------------------------
guidoDuration(const char * gmn)241 gar_export rational guidoDuration(const char* gmn)
242 {
243 	rational duration (-1,1);
244 	Sguidoelement score =  read(gmn);
245 	if (score) {
246 		durationvisitor dv;
247 		duration = dv.duration (score);
248 	}
249 	return duration;
250 }
251 
252 //----------------------------------------------------------------------------
guido2midifile(const char * gmn,const char * file)253 gar_export garErr guido2midifile(const char* gmn, const char* file)
254 {
255 #ifdef MIDIEXPORT
256 	Sguidoelement score =  read(gmn);
257 	if (!score) return kInvalidArgument;
258 
259 	midiconverter mc;
260 	return mc.score2midifile(score, file) ? kNoErr : kOperationFailed;
261 #else
262 	cerr << "guido2midifile: no support for midifile conversion embedded in the guidoar library" << endl;
263 	return kOperationFailed;
264 #endif
265 }
266 
267 //----------------------------------------------------------------------------
guidocheck(const char * gmn)268 gar_export bool guidocheck(const char* gmn)
269 {
270 	Sguidoelement score =  read(gmn);
271 	return score ? true : false;
272 }
273 
274 }
275