2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "SC_GraphDef.h"
25 #include "sc_msg_iter.h"
28 #include "SC_Prototypes.h"
31 #include "SC_Errors.h"
32 #include "scsynthsend.h"
34 NodeDef gGroupNodeDef
;
36 void Group_Dtor(Group
*inGroup
)
38 Group_DeleteAll(inGroup
);
39 inGroup
->mNode
.mWorld
->mNumGroups
--;
40 Node_Dtor(&inGroup
->mNode
);
43 void GroupNodeDef_Init()
45 str4cpy(gGroupNodeDef
.mName
, "group");
46 gGroupNodeDef
.mHash
= Hash(gGroupNodeDef
.mName
);
47 gGroupNodeDef
.mAllocSize
= sizeof(Group
);
50 int Group_New(World
*inWorld
, int32 inID
, Group
** outGroup
)
53 int err
= Node_New(inWorld
, &gGroupNodeDef
, inID
, (Node
**)&group
);
56 group
->mNode
.mCalcFunc
= (NodeCalcFunc
)&Group_Calc
;
57 group
->mNode
.mIsGroup
= true;
60 inWorld
->mNumGroups
++;
66 void Group_Calc(Group
*inGroup
)
68 Node
*child
= inGroup
->mHead
;
70 Node
*next
= child
->mNext
;
71 (*child
->mCalcFunc
)(child
);
76 void Group_CalcTrace(Group
*inGroup
)
78 scprintf("TRACE Group %d\n", inGroup
->mNode
.mID
);
79 Node
*child
= inGroup
->mHead
;
81 Node
*next
= child
->mNext
;
82 scprintf(" %d %s\n", child
->mID
, (char*)child
->mDef
->mName
);
83 (*child
->mCalcFunc
)(child
);
86 inGroup
->mNode
.mCalcFunc
= (NodeCalcFunc
)&Group_Calc
;
89 void Group_Trace(Group
*inGroup
)
91 if (inGroup
->mNode
.mCalcFunc
== (NodeCalcFunc
)&Group_Calc
) {
92 inGroup
->mNode
.mCalcFunc
= (NodeCalcFunc
)&Group_CalcTrace
;
96 void Group_DumpNodeTree(Group
*inGroup
)
98 static int tabCount
= 0;
99 if(tabCount
== 0) scprintf("NODE TREE Group %d\n", inGroup
->mNode
.mID
);
101 Node
*child
= inGroup
->mHead
;
103 Node
*next
= child
->mNext
;
104 for(int i
= 0; i
< tabCount
; i
++) scprintf(" "); // small 'tabs'
105 scprintf("%d %s\n", child
->mID
, (char*)child
->mDef
->mName
);
106 if (child
->mIsGroup
) {
107 Group_DumpTree((Group
*)child
);
109 (*child
->mCalcFunc
)(child
);
115 void Group_DumpNodeTreeAndControls(Group
*inGroup
)
117 static int tabCount
= 0;
118 if(tabCount
== 0) scprintf("NODE TREE Group %d\n", inGroup
->mNode
.mID
);
120 Node
*child
= inGroup
->mHead
;
122 Node
*next
= child
->mNext
;
124 for(i
= 0; i
< tabCount
; i
++) scprintf(" "); // small 'tabs'
125 scprintf("%d %s", child
->mID
, (char*)child
->mDef
->mName
); // def will be 'group' if it's a group
126 if (child
->mIsGroup
) {
127 Group_DumpTreeAndControls((Group
*)child
);
129 Graph
* childGraph
= (Graph
*)child
;
130 int numControls
= childGraph
->mNumControls
;
131 if(numControls
> 0) {
133 for(i
= 0; i
< tabCount
; i
++) scprintf(" ");
135 names
= new char*[numControls
];
137 for(i
= 0; i
< numControls
; i
++){
141 // check the number of named controls and stash their names at the correct index
142 GraphDef
* def
= (GraphDef
*)(child
->mDef
);
143 int numNamedControls
= def
->mNumParamSpecs
;
144 for(i
= 0; i
< numNamedControls
; i
++){
145 ParamSpec
*paramSpec
= def
->mParamSpecs
+ i
;
146 names
[paramSpec
->mIndex
] = (char*)paramSpec
->mName
;
149 // now print the names and values in index order, checking for mappings
150 for(i
=0; i
< numControls
; i
++){
151 float *ptr
= childGraph
->mControls
+ i
;
154 scprintf(" %s: ", names
[i
]);
156 scprintf(" ", names
[i
]);
158 // the ptr in nMapControls should be the same as the control itself, if not, it's mapped.
159 if((childGraph
->mMapControls
[i
]) != ptr
){
161 if(childGraph
->mControlRates
[i
] == 2){
162 bus
= (childGraph
->mMapControls
[i
]) - (child
->mWorld
->mAudioBus
);
163 bus
= (int)((float)bus
/ child
->mWorld
->mBufLength
);
164 scprintf("a%d", bus
);
166 bus
= (childGraph
->mMapControls
[i
]) - (child
->mWorld
->mControlBus
);
167 scprintf("c%d", bus
);
169 //scprintf("bus: %d\n", bus);
171 scprintf("%.14g", *ptr
);
177 (*child
->mCalcFunc
)(child
);
183 void Group_CalcDumpTree(Group
*inGroup
)
185 Group_DumpNodeTree(inGroup
);
186 inGroup
->mNode
.mCalcFunc
= (NodeCalcFunc
)&Group_Calc
;
189 void Group_DumpTree(Group
* inGroup
)
191 if (inGroup
->mNode
.mCalcFunc
== (NodeCalcFunc
)&Group_Calc
) {
192 inGroup
->mNode
.mCalcFunc
= (NodeCalcFunc
)&Group_CalcDumpTree
;
196 void Group_CalcDumpTreeAndControls(Group
*inGroup
)
198 Group_DumpNodeTreeAndControls(inGroup
);
199 inGroup
->mNode
.mCalcFunc
= (NodeCalcFunc
)&Group_Calc
;
202 void Group_DumpTreeAndControls(Group
* inGroup
)
204 if (inGroup
->mNode
.mCalcFunc
== (NodeCalcFunc
)&Group_Calc
) {
205 inGroup
->mNode
.mCalcFunc
= (NodeCalcFunc
)&Group_CalcDumpTreeAndControls
;
209 // count the children for this group (deep)
210 void Group_CountNodeTags(Group
* inGroup
, int* count
)
212 Node
*child
= inGroup
->mHead
;
214 Node
*next
= child
->mNext
;
216 if (child
->mIsGroup
) {
217 Group_CountNodeTags((Group
*)child
, count
);
218 } else { (*count
)++; } // for the defname
223 // count the children for this group (deep)
224 void Group_CountNodeAndControlTags(Group
* inGroup
, int* count
, int* controlAndDefCount
)
226 Node
*child
= inGroup
->mHead
;
228 Node
*next
= child
->mNext
;
230 if (child
->mIsGroup
) {
231 Group_CountNodeAndControlTags((Group
*)child
, count
, controlAndDefCount
);
233 //(*controlCount) += ((Graph*)child)->mNumControls + ((GraphDef*)(child->mDef))->mNumParamSpecs + 1;
234 (*controlAndDefCount
) += ((Graph
*)child
)->mNumControls
* 2 + 2; // def, numControls, name or index and value for each
240 void Group_QueryTree(Group
* inGroup
, big_scpacket
*packet
)
243 packet
->addi(inGroup
->mNode
.mID
);
245 // count the children for this group, but not their children (shallow)
247 Node
*child
= inGroup
->mHead
;
249 Node
*next
= child
->mNext
;
255 packet
->addi(count
); // numChildren; for a Group >= 0
257 // now iterate over the children
258 // id, numChildren, defname
259 child
= inGroup
->mHead
;
261 Node
*next
= child
->mNext
;
262 if (child
->mIsGroup
) {
263 Group_QueryTree((Group
*)child
, packet
);
265 packet
->addtag('i'); // nodeID
266 packet
->addtag('i'); // numChildren
267 packet
->addtag('s'); // defname
268 packet
->addi(child
->mID
);
270 packet
->adds((char*)child
->mDef
->mName
);
276 void Group_QueryTreeAndControls(Group
* inGroup
, big_scpacket
*packet
)
279 packet
->addi(inGroup
->mNode
.mID
);
281 // count the children for this group, but not their children (shallow)
283 Node
*child
= inGroup
->mHead
;
285 Node
*next
= child
->mNext
;
293 // now iterate over the children
294 // id, numChildren, defname
295 child
= inGroup
->mHead
;
297 Node
*next
= child
->mNext
;
298 if (child
->mIsGroup
) {
299 Group_QueryTreeAndControls((Group
*)child
, packet
);
304 packet
->addi(child
->mID
); // nodeID
305 packet
->addi(-1); // numChildren
306 packet
->adds((char*)child
->mDef
->mName
); // defName
308 Graph
* childGraph
= (Graph
*)child
;
309 int numControls
= childGraph
->mNumControls
;
311 packet
->addi(numControls
);
314 names
= new char*[numControls
];
316 for(i
= 0; i
< numControls
; i
++){
320 // check the number of named controls and stash their names
321 GraphDef
* def
= (GraphDef
*)(child
->mDef
);
322 int numNamedControls
= def
->mNumParamSpecs
;
323 for(i
= 0; i
< numNamedControls
; i
++){
324 ParamSpec
*paramSpec
= def
->mParamSpecs
+ i
;
325 names
[paramSpec
->mIndex
] = (char*)paramSpec
->mName
;
328 // now add the names and values in index order, checking for mappings
329 for(i
=0; i
< numControls
; i
++){
330 float *ptr
= childGraph
->mControls
+ i
;
334 packet
->adds(names
[i
]);
339 // the ptr in nMapControls should be the same as the control itself, if not, it's mapped.
340 if((childGraph
->mMapControls
[i
]) != ptr
){
342 int bus
= (childGraph
->mMapControls
[i
]) - (child
->mWorld
->mControlBus
);
343 //scprintf("bus: %d\n", bus);
344 char buf
[10]; //should be long enough
345 sprintf(buf
, "%c%d", 'c', bus
);
359 void Group_DeleteAll(Group
*inGroup
)
361 Node
*child
= inGroup
->mHead
;
363 Node
*next
= child
->mNext
;
364 child
->mPrev
= child
->mNext
= 0;
369 inGroup
->mHead
= inGroup
->mTail
= 0;
372 void Group_DeepFreeGraphs(Group
*inGroup
)
374 Node
*child
= inGroup
->mHead
;
376 Node
*next
= child
->mNext
;
377 if (child
->mIsGroup
) {
378 Group_DeepFreeGraphs((Group
*)child
);
387 void Group_AddHead (Group
*s
, Node
*child
)
389 if (child
->mID
== 0) return; // failed
391 child
->mNext
= s
->mHead
;
392 if (s
->mHead
) { s
->mHead
->mPrev
= child
; s
->mHead
= child
; }
393 else s
->mHead
= s
->mTail
= child
;
397 void Group_AddTail (Group
*s
, Node
*child
)
399 if (child
->mID
== 0) return; // failed
400 child
->mPrev
= s
->mTail
;
402 if (s
->mTail
) { s
->mTail
->mNext
= child
; s
->mTail
= child
; }
403 else s
->mHead
= s
->mTail
= child
;
407 void Group_Insert(Group
*s
, Node
*child
, int index
)
409 if (child
->mID
== 0) return; // failed
410 if (index
<= 0) Group_AddHead(s
, child
);
412 Node
*before
= s
->mHead
;
413 for (int i
=0; i
<index
; ++i
) {
414 before
= before
->mNext
;
416 Group_AddTail(s
, child
);
420 Node_AddBefore(child
, before
);
424 void Group_MapControl(Group
*inGroup
, uint32 inIndex
, uint32 inBus
)
426 Node
*child
= inGroup
->mHead
;
428 Node
*next
= child
->mNext
;
429 Node_MapControl(child
, inIndex
, inBus
);
434 void Group_MapControl(Group
*inGroup
, int32 inHash
, int32
*inName
, uint32 inIndex
, uint32 inBus
)
436 Node
*child
= inGroup
->mHead
;
438 Node
*next
= child
->mNext
;
439 Node_MapControl(child
, inHash
, inName
, inIndex
, inBus
);
444 void Group_MapAudioControl(Group
*inGroup
, uint32 inIndex
, uint32 inBus
)
446 Node
*child
= inGroup
->mHead
;
448 Node
*next
= child
->mNext
;
449 Node_MapAudioControl(child
, inIndex
, inBus
);
454 void Group_MapAudioControl(Group
*inGroup
, int32 inHash
, int32
*inName
, uint32 inIndex
, uint32 inBus
)
456 Node
*child
= inGroup
->mHead
;
458 Node
*next
= child
->mNext
;
459 Node_MapAudioControl(child
, inHash
, inName
, inIndex
, inBus
);
463 void Group_SetControl(Group
*inGroup
, uint32 inIndex
, float inValue
)
465 Node
*child
= inGroup
->mHead
;
467 Node
*next
= child
->mNext
;
468 Node_SetControl(child
, inIndex
, inValue
);
473 void Group_SetControl(Group
*inGroup
, int32 inHash
, int32
*inName
, uint32 inIndex
, float inValue
)
475 Node
*child
= inGroup
->mHead
;
477 Node
*next
= child
->mNext
;
478 Node_SetControl(child
, inHash
, inName
, inIndex
, inValue
);