1 /*
2   GUIDO Library
3   Copyright (C) 2006  Grame
4 
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9 
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14 
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19   Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
20   research@grame.fr
21 
22 */
23 
24 #include <iostream>
25 #include "exceptions.h"
26 #include "guidoClosureValue.h"
27 #include "guidoScoreValue.h"
28 #include "visitor.h"
29 
30 using namespace std;
31 using namespace guido;
32 
33 namespace guidolang
34 {
35 
36 //______________________________________________________________________________
37 // guidoClosureValue
38 //______________________________________________________________________________
create(Sguidoexpression & id,Sguidoexpression & body,SguidoEnv & env,unsigned int length,const rational & dur,unsigned int voices)39 Sguidovalue	guidoClosureValue::create (Sguidoexpression& id, Sguidoexpression& body, SguidoEnv& env,
40 					unsigned int length, const rational& dur, unsigned int voices)
41 	{ valuePrint("guidoClosureValue"); guidoClosureValue * o = new guidoClosureValue(id, body, env, length, dur, voices); assert(o!=0); return o; }
42 
43 //______________________________________________________________________________
print(ostream & os)44 void guidoClosureValue::print(ostream& os)
45 {
46 	os << "guidoClosureValue";
47 }
48 
49 //______________________________________________________________________________
apply(Sguidovalue & v)50 Sguidovalue	guidoClosureValue::apply (Sguidovalue& v)
51 {
52 	if (!fIdent)	throw(newException (kNullIdent));
53 	if (!fBody)		throw(newException (kNullBody));
54 	if (!fEnv)		throw(newException (kNullEnvironment));
55 	return fBody->eval(fEnv->bind (fIdent, v));
56 }
57 
58 //______________________________________________________________________________
head(unsigned int length)59 Sguidovalue	guidoClosureValue::head	(unsigned int length)
60 {
61 	return create(fIdent, fBody, fEnv, (length < fLength) ? length : fLength, fDuration, fVoices);
62 }
63 
head(const rational & dur)64 Sguidovalue	guidoClosureValue::head	(const rational& dur)
65 {
66 	return create(fIdent, fBody, fEnv, fLength, (dur < fDuration) ? dur : fDuration, fVoices);
67 }
68 
tail(unsigned int length)69 Sguidovalue	guidoClosureValue::tail	(unsigned int length)
70 {
71 	if (length >= fLength) return guidoScoreValue::create();
72 	return create(fIdent, fBody, fEnv, fLength - length, fDuration, fVoices);
73 }
74 
tail(const rational & dur)75 Sguidovalue	guidoClosureValue::tail	(const rational& dur)
76 {
77 	if (dur >= fDuration) return guidoScoreValue::create();
78 	return create(fIdent, fBody, fEnv, fLength, fDuration - dur, fVoices);
79 }
80 
top(unsigned int vnum)81 Sguidovalue	guidoClosureValue::top (unsigned int vnum)
82 {
83 	return create(fIdent, fBody, fEnv, fLength, fDuration, (vnum < fVoices) ? vnum : fVoices);
84 }
85 
bottom(unsigned int vnum)86 Sguidovalue	guidoClosureValue::bottom (unsigned int vnum)
87 {
88 	if (vnum > fVoices) return guidoScoreValue::create();
89 	return create(fIdent, fBody, fEnv, fLength, fDuration, vnum);
90 }
91 
92 
transpose(int interval)93 Sguidovalue	guidoClosureValue::transpose(int interval)
94 {
95 
96 	return create(fIdent, fBody, fEnv, fLength, fDuration, fVoices);
97 }
98 
stretch(rational ratio)99 Sguidovalue	guidoClosureValue::stretch (rational ratio)
100 {
101 	rational dur = ratio * fDuration;
102 	return create(fIdent, fBody, fEnv, fLength, dur.rationalise(), fVoices);
103 }
104 
stretch(float ratio)105 Sguidovalue	guidoClosureValue::stretch (float ratio)
106 {
107 	rational dur = fDuration;
108 	if (ratio >= 0) dur.setNumerator(dur.getNumerator() * ratio);
109 	else dur.setDenominator(dur.getDenominator() * ratio);
110 	return create(fIdent, fBody, fEnv, fLength, dur.rationalise(), fVoices);
111 }
112 
113 
114 //______________________________________________________________________________
length()115 unsigned int guidoClosureValue::length ()		{ return fLength; }
duration()116 rational guidoClosureValue::duration()			{ return fDuration; }
voices()117 unsigned int guidoClosureValue::voices ()		{ return fVoices; }
118 
119 // todo: what's the meaning of pitch for a closure ?
pitch()120 unsigned int guidoClosureValue::pitch ()		{
121 	cerr << "warning: guidoClosureValue::pitch query !" << endl;
122 	return 60;
123 }
124 
125 //______________________________________________________________________________
acceptIn(basevisitor & v)126 void guidoClosureValue::acceptIn(basevisitor& v) {
127 	if (visitor<SguidoClosureValue>* p = dynamic_cast<visitor<SguidoClosureValue>*>(&v)) {
128 		SguidoClosureValue ge = this;
129 		p->visitStart (ge);
130 	}
131 }
132 
133 //______________________________________________________________________________
acceptOut(basevisitor & v)134 void guidoClosureValue::acceptOut(basevisitor& v) {
135 	if (visitor<SguidoClosureValue>* p = dynamic_cast<visitor<SguidoClosureValue>*>(&v)) {
136 		SguidoClosureValue ge = this;
137 		p->visitEnd (ge);
138 	}
139 }
140 
141 } // namespace
142