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