b172fb2b5a29c64593cae1f37c4cfe5f27f2f346
1 /************************************************************************
2 ************************************************************************
4 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program 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
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
26 #include "property.hh"
28 int AudioType::gAllocationCount
= 0;
30 bool SimpleType::isMaximal() const ///< true when type is maximal (and therefore can't change depending of hypothesis)
32 return (fNature
==kReal
)
33 && (fVariability
==kSamp
)
34 && (fComputability
==kExec
);
39 //------------------------------------------------------------------------------------
41 // Surcharges de l'operateur d'impression <<
43 //------------------------------------------------------------------------------------
46 ostream
& operator<<(ostream
& dst
, const Type
& t
) { return t
->print(dst
);}
48 ostream
& operator<<(ostream
& dst
, const SimpleType
& t
) { return t
.print(dst
); }
50 ostream
& operator<<(ostream
& dst
, const TableType
& t
) { return t
.print(dst
); }
52 ostream
& operator<<(ostream
& dst
, const TupletType
& t
) { return t
.print(dst
); }
54 ostream
& operator<<(ostream
& dst
, const VectorType
& t
) { return t
.print(dst
); }
57 //------------------------------------------------------------------------------------
59 // Definition des methodes d'impression
61 //------------------------------------------------------------------------------------
65 * Print the content of a simple type on a stream
67 ostream
& SimpleType::print(ostream
& dst
) const
69 return dst
<< "NR"[nature()]
70 << "KB?S"[variability()]
71 << "CI?E"[computability()]
72 << "VS?TS"[vectorability()]
79 * Print the content of a table type on a stream
81 ostream
& TableType::print(ostream
& dst
) const
83 dst
<< "KB?S"[variability()]
84 << "CI?E"[computability()]
93 * true when type is maximal (and therefore can't change depending of hypothesis)
95 bool TableType::isMaximal() const
97 return (fNature
==kReal
)
98 && (fVariability
==kSamp
)
99 && (fComputability
==kExec
);
105 * Print the content of a tuplet of types on a stream
107 ostream
& TupletType::print(ostream
& dst
) const
109 dst
<< "KB?S"[variability()]
110 << "CI?E"[computability()]
114 for (unsigned int i
= 0; i
< fComponents
.size(); i
++, sep
="*") {
116 fComponents
[i
]->print(dst
);
125 * Print the content of a vector type on a stream
127 ostream
& VectorType::print(ostream
& dst
) const
129 dst
<< "vector[" << fSize
<< "," << fContent
<< "]";
135 * true when type is maximal (and therefore can't change depending of hypothesis)
137 bool TupletType::isMaximal() const
139 for (unsigned int i
= 0; i
< fComponents
.size(); i
++) {
140 if (! fComponents
[i
]->isMaximal()) return false;
146 //------------------------------------------------------------------------------------
148 // Construction des types
149 // t := p, table(t), t|t, t*t
151 //------------------------------------------------------------------------------------
153 // Essential predefined types
155 Type TINT
= makeSimpleType(kInt
, kKonst
, kComp
, kVect
, kNum
, interval());
156 Type TREAL
= makeSimpleType(kReal
, kKonst
, kComp
, kVect
, kNum
, interval());
158 Type TKONST
= makeSimpleType(kInt
, kKonst
, kComp
, kVect
, kNum
, interval());
159 Type TBLOCK
= makeSimpleType(kInt
, kBlock
, kComp
, kVect
, kNum
, interval());
160 Type TSAMP
= makeSimpleType(kInt
, kSamp
, kComp
, kVect
, kNum
, interval());
162 Type TCOMP
= makeSimpleType(kInt
, kKonst
, kComp
, kVect
, kNum
, interval());
163 Type TINIT
= makeSimpleType(kInt
, kKonst
, kInit
, kVect
, kNum
, interval());
164 Type TEXEC
= makeSimpleType(kInt
, kKonst
, kExec
, kVect
, kNum
, interval());
166 // more predefined types
168 Type TINPUT
= makeSimpleType(kReal
, kSamp
, kExec
, kVect
, kNum
, interval());
169 Type TGUI
= makeSimpleType(kReal
, kBlock
,kExec
, kVect
, kNum
, interval());
170 Type TGUI01
= makeSimpleType(kReal
, kBlock
,kExec
, kVect
, kNum
, interval(0,1));
171 Type INT_TGUI
= makeSimpleType(kInt
, kBlock
,kExec
, kVect
, kNum
, interval());
172 //Type TREC = makeSimpleType(kInt, kSamp, kInit, kVect, kNum, interval()); // kVect ou kScal ?
174 // trying to accelerate type convergence
176 Type TREC
= makeSimpleType(kInt
, kSamp
, kInit
, kScal
, kNum
, interval()); // kVect ou kScal ?
179 Type
operator| ( const Type
& t1
, const Type
& t2
)
181 SimpleType
*st1
, *st2
;
182 TableType
*tt1
, *tt2
;
183 TupletType
*nt1
, *nt2
;
185 if ( (st1
= isSimpleType(t1
)) && (st2
= isSimpleType(t2
)) ) {
187 return makeSimpleType( st1
->nature()|st2
->nature(),
188 st1
->variability()|st2
->variability(),
189 st1
->computability()|st2
->computability(),
190 st1
->vectorability()|st2
->vectorability(),
191 st1
->boolean()|st2
->boolean(),
192 reunion(st1
->getInterval(), st2
->getInterval())
195 } else if ( (tt1
= isTableType(t1
)) && (tt2
= isTableType(t2
)) ) {
197 return makeTableType( tt1
->content() | tt2
->content() );
199 } else if ( (nt1
= isTupletType(t1
)) && (nt2
= isTupletType(t2
)) ) {
202 int n
= min(nt1
->arity(), nt2
->arity());
203 for (int i
=0; i
<n
; i
++) { v
.push_back( (*nt1
)[i
] | (*nt2
)[i
]); }
204 return new TupletType( v
);
208 vector
<int> D1
, D2
, D3
;
209 Type b1
= t1
->dimensions(D1
);
210 Type b2
= t2
->dimensions(D2
);
211 if (maxdimensions(D1
, D2
, D3
)) {
213 return makeVectorType(b3
, D3
);
216 cerr
<< "Error : trying to combine incompatible types, " << t1
<< " and " << t2
<< endl
;
222 bool operator== ( const Type
& t1
, const Type
& t2
)
224 SimpleType
*st1
, *st2
;
225 TableType
*tt1
, *tt2
;
226 TupletType
*nt1
, *nt2
;
227 VectorType
*vt1
, *vt2
;
229 if (t1
->variability() != t2
->variability()) return false;
230 if (t1
->computability() != t2
->computability()) return false;
232 if ( (st1
= isSimpleType(t1
)) && (st2
= isSimpleType(t2
)) )
233 return (st1
->nature() == st2
->nature())
234 && (st1
->variability() == st2
->variability())
235 && (st1
->computability() == st2
->computability())
236 && (st1
->vectorability() == st2
->vectorability())
237 && (st1
->boolean() == st2
->boolean())
238 && (st1
->getInterval().lo
== st2
->getInterval().lo
)
239 && (st1
->getInterval().hi
== st2
->getInterval().hi
)
240 && (st1
->getInterval().valid
== st2
->getInterval().valid
);
241 if ( (tt1
= isTableType(t1
)) && (tt2
= isTableType(t2
)) )
242 return tt1
->content()== tt2
->content();
243 if ( (nt1
= isTupletType(t1
)) && (nt2
= isTupletType(t2
)) ) {
244 int a1
= nt1
->arity();
245 int a2
= nt2
->arity();
247 for (int i
=0; i
<a1
; i
++) { if ((*nt1
)[i
] != (*nt2
)[i
]) return false; }
254 // compare vector types
255 if ( (vt1
= isVectorType(t1
)) && (vt2
= isVectorType(t2
)) ) {
256 if (vt1
->size() == vt2
->size()) {
257 return vt1
->content() == vt2
->content();
263 // types are different
267 bool operator<= ( const Type
& t1
, const Type
& t2
)
269 return (t1
|t2
) == t2
;
274 Type
operator* (const Type
& t1
, const Type
& t2
)
278 TupletType
* nt1
= dynamic_cast<TupletType
*>((AudioType
*)t1
);
279 TupletType
* nt2
= dynamic_cast<TupletType
*>((AudioType
*)t2
);
282 for (int i
=0; i
<nt1
->arity(); i
++) {
283 v
.push_back((*nt1
)[i
]);
290 for (int i
=0; i
<nt2
->arity(); i
++) {
291 v
.push_back((*nt2
)[i
]);
296 return new TupletType(v
);
300 SimpleType
* isSimpleType(AudioType
* t
) { return dynamic_cast<SimpleType
*>(t
); }
301 TableType
* isTableType(AudioType
* t
) { return dynamic_cast<TableType
*>(t
); }
302 TupletType
* isTupletType(AudioType
* t
) { return dynamic_cast<TupletType
*>(t
); }
303 VectorType
* isVectorType(AudioType
* t
) { return dynamic_cast<VectorType
*>(t
); }
307 //--------------------------------------------------
308 // verification de type
310 Type
checkInt(Type t
)
312 // verifie que t est entier
313 SimpleType
* st
= isSimpleType(t
);
314 if (st
== 0 || st
->nature() > kInt
) {
315 cerr
<< "Error : checkInt failed for type " << t
<< endl
;
321 Type
checkKonst(Type t
)
323 // verifie que t est constant
324 if (t
->variability() > kKonst
) {
325 cerr
<< "Error : checkKonst failed for type " << t
<< endl
;
331 Type
checkInit(Type t
)
333 // verifie que t est connu a l'initialisation
334 if (t
->computability() > kInit
) {
335 cerr
<< "Error : checkInit failed for type " << t
<< endl
;
341 Type
checkIntParam(Type t
)
343 return checkInit(checkKonst(checkInt(t
)));
346 Type
checkWRTbl(Type tbl
, Type wr
)
348 // verifie que wr est compatible avec le contenu de tbl
349 if (wr
->nature() > tbl
->nature()) {
350 cerr
<< "Error : checkWRTbl failed, the content of " << tbl
<< " is incompatible with " << wr
<< endl
;
357 \brief Check is a type is appropriate for a delay.
358 @return -1 if not appropriate, mxd (max delay) if appropriate
361 int checkDelayInterval(Type t
)
363 interval i
= t
->getInterval();
364 if (i
.valid
&& i
.lo
>= 0) {
365 return int(i
.hi
+0.5);
367 //cerr << "checkDelayInterval failed for : " << i << endl;
373 // Donne le nom du type C correspondant �la nature d'un signal
374 string
cType (Type t
)
376 return (t
->nature() == kInt
) ? "int" : "float";
381 /*****************************************************************************
383 * codeAudioType(Type) -> Tree
384 * Code an audio type as a tree in order to benefit of memoization
386 *****************************************************************************/
388 // memoized type contruction
390 property
<AudioType
*> MemoizedTypes
;
393 Sym SIMPLETYPE
= symbol ("SimpleType");
394 Sym TABLETYPE
= symbol ("TableType");
395 Sym TUPLETTYPE
= symbol ("TupletType");
396 Sym VECTORTYPE
= symbol ("VectorType");
398 static Tree
codeSimpleType(SimpleType
* st
);
399 static Tree
codeTableType(TableType
* st
);
400 static Tree
codeTupletType(TupletType
* st
);
401 static Tree
codeVectorType(VectorType
* st
);
405 * codeAudioType(Type) -> Tree
406 * Code an audio type as a tree in order to benefit of memoization
407 * The type field (of the coded type) is used to store the audio
410 Tree
codeAudioType(AudioType
* t
)
419 if ((r
=t
->getCode())) return r
;
421 if ((st
= isSimpleType(t
))) {
422 r
= codeSimpleType(st
);
423 } else if ((tt
= isTableType(t
))) {
424 r
= codeTableType(tt
);
425 } else if ((nt
= isTupletType(t
))) {
426 r
= codeTupletType(nt
);
427 } else if ((vt
= isVectorType(t
))) {
428 r
= codeVectorType(vt
);
430 cerr
<< "ERROR in codeAudioType() : invalide pointer " << t
<< endl
;
441 * Code a simple audio type as a tree in order to benefit of memoization
443 static Tree
codeSimpleType(SimpleType
* st
)
446 elems
.push_back(tree(st
->nature()));
447 elems
.push_back(tree(st
->variability()));
448 elems
.push_back(tree(st
->computability()));
449 elems
.push_back(tree(st
->vectorability()));
450 elems
.push_back(tree(st
->boolean()));
452 elems
.push_back(tree(st
->getInterval().valid
));
453 elems
.push_back(tree(st
->getInterval().lo
));
454 elems
.push_back(tree(st
->getInterval().hi
));
456 return CTree::make(SIMPLETYPE
, elems
);
460 AudioType
* makeSimpleType(int n
, int v
, int c
, int vec
, int b
, const interval
& i
)
462 SimpleType
prototype(n
,v
,c
,vec
,b
,i
);
463 Tree code
= codeAudioType(&prototype
);
466 if (MemoizedTypes
.get(code
, t
)) {
469 AudioType::gAllocationCount
++;
470 t
= new SimpleType(n
,v
,c
,vec
,b
,i
);
471 MemoizedTypes
.set(code
, t
);
479 * Code a table type as a tree in order to benefit of memoization
482 static Tree
codeTableType(TableType
* tt
)
484 return tree(TABLETYPE
, codeAudioType(tt
->content()));
487 AudioType
* makeTableType(const Type
& ct
)
489 TableType
prototype(ct
);
490 Tree code
= codeAudioType(&prototype
);
493 if (MemoizedTypes
.get(code
, tt
)) {
496 AudioType::gAllocationCount
++;
497 tt
= new TableType(ct
);
498 MemoizedTypes
.set(code
, tt
);
504 AudioType
* makeTableType(const Type
& ct
, int n
, int v
, int c
, int vec
, int b
, const interval
& i
)
506 TableType
prototype(ct
,n
,v
,c
,vec
,b
,i
);
507 Tree code
= codeAudioType(&prototype
);
510 if (MemoizedTypes
.get(code
, tt
)) {
513 AudioType::gAllocationCount
++;
514 tt
= new TableType(ct
);
515 MemoizedTypes
.set(code
, tt
);
521 AudioType
* makeTableType(const Type
& ct
, int n
, int v
, int c
, int vec
)
523 TableType
prototype(ct
,n
,v
,c
,vec
);
524 Tree code
= codeAudioType(&prototype
);
527 if (MemoizedTypes
.get(code
, tt
)) {
530 AudioType::gAllocationCount
++;
531 tt
= new TableType(ct
);
532 MemoizedTypes
.set(code
, tt
);
540 * Code a tuplet type as a tree in order to benefit of memoization
543 static Tree
codeTupletType(TupletType
* nt
)
546 for (int i
=0; i
<nt
->arity(); i
++) {
547 elems
.push_back(codeAudioType((*nt
)[i
]));
549 return CTree::make(TUPLETTYPE
, elems
);
552 AudioType
* makeTupletType(const vector
<Type
>& vt
)
554 TupletType
prototype(vt
);
555 Tree code
= codeAudioType(&prototype
);
558 if (MemoizedTypes
.get(code
, t
)) {
561 AudioType::gAllocationCount
++;
562 t
= new TupletType(vt
);
563 MemoizedTypes
.set(code
, t
);
570 AudioType
* makeTupletType(const vector
<Type
>& vt
, int n
, int v
, int c
, int vec
, int b
, const interval
& i
)
572 TupletType
prototype(vt
,n
,v
,c
,vec
,b
,i
);
573 Tree code
= codeAudioType(&prototype
);
576 if (MemoizedTypes
.get(code
, t
)) {
579 AudioType::gAllocationCount
++;
580 t
= new TupletType(vt
,n
,v
,c
,vec
,b
,i
);
581 MemoizedTypes
.set(code
, t
);
589 * Code a vector type as a tree in order to benefit of memoization
592 static Tree
codeVectorType(VectorType
* vt
)
595 //cerr << "codeVectorType(" << *vt << ")" << endl;
597 return tree(VECTORTYPE
, tree(i
), codeAudioType(vt
->content()));
600 Type
makeVectorType(const Type
& b
, const vector
<int>& dim
)
603 for (unsigned int i
=0; i
<dim
.size(); i
++) r
= new VectorType(dim
[i
],r
);
609 * Returns true if D1 and D2 are compatible (one is the prefix of the other)).
610 * In this case D3 contains the longuest vector D1 or D2
612 bool maxdimensions(const vector
<int>& D1
, const vector
<int>& D2
, vector
<int>& D3
)
614 unsigned int n1
= D1
.size();
615 unsigned int n2
= D2
.size();
617 while ( (i
<n1
) && (i
<n2
) && (D1
[i
]==D2
[i
]) ) i
++;