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
24 #include "SC_GraphDef.h"
26 #include "SC_WireSpec.h"
27 #include "SC_UnitSpec.h"
28 #include "SC_UnitDef.h"
29 #include "SC_HiddenWorld.h"
33 #include "ReadWriteMacros.h"
34 #include "SC_Prototypes.h"
35 #include "SC_CoreAudio.h"
36 #include "SC_DirUtils.h"
39 #include "SC_Win32Utils.h"
48 extern Malloc gMalloc
;
50 int32
GetHash(ParamSpec
* inParamSpec
)
52 return inParamSpec
->mHash
;
55 int32
* GetKey(ParamSpec
* inParamSpec
)
57 return inParamSpec
->mName
;
61 void ReadName(char*& buffer
, int32
* name
);
62 void ReadName(char*& buffer
, int32
* name
)
64 uint32 namelen
= readUInt8(buffer
);
65 if (namelen
>= kSCNameByteLen
) {
66 std::ostringstream os
;
67 os
<< "name too long (> " << kSCNameByteLen
- 1 << " chars): "
68 << std::string(buffer
, namelen
);
69 throw std::runtime_error(os
.str());
71 memset(name
, 0, kSCNameByteLen
);
72 readData(buffer
, (char*)name
, namelen
);
75 void ReadNodeDefName(char*& buffer
, int32
* name
);
76 void ReadNodeDefName(char*& buffer
, int32
* name
)
78 uint32 namelen
= readUInt8(buffer
);
79 if (namelen
>= kSCNodeDefNameByteLen
) {
80 std::ostringstream os
;
81 os
<< "node definition name too long (> " << kSCNodeDefNameByteLen
- 1 << " chars): "
82 << std::string(buffer
, namelen
);
83 throw std::runtime_error(os
.str());
85 memset(name
, 0, kSCNodeDefNameByteLen
);
86 readData(buffer
, (char*)name
, namelen
);
89 void ParamSpec_Read(ParamSpec
* inParamSpec
, char*& buffer
);
90 void ParamSpec_Read(ParamSpec
* inParamSpec
, char*& buffer
)
92 ReadName(buffer
, inParamSpec
->mName
);
93 inParamSpec
->mIndex
= readInt16_be(buffer
);
94 inParamSpec
->mHash
= Hash(inParamSpec
->mName
);
97 void InputSpec_Read(InputSpec
* inInputSpec
, char*& buffer
);
98 void InputSpec_Read(InputSpec
* inInputSpec
, char*& buffer
)
100 inInputSpec
->mFromUnitIndex
= (int16
)readInt16_be(buffer
);
101 inInputSpec
->mFromOutputIndex
= (int16
)readInt16_be(buffer
);
103 inInputSpec
->mWireIndex
= -1;
106 void OutputSpec_Read(OutputSpec
* inOutputSpec
, char*& buffer
);
107 void OutputSpec_Read(OutputSpec
* inOutputSpec
, char*& buffer
)
109 inOutputSpec
->mCalcRate
= readInt8(buffer
);
111 inOutputSpec
->mWireIndex
= -1;
112 inOutputSpec
->mBufferIndex
= -1;
113 inOutputSpec
->mNumConsumers
= 0;
116 void UnitSpec_Read(UnitSpec
* inUnitSpec
, char*& buffer
);
117 void UnitSpec_Read(UnitSpec
* inUnitSpec
, char*& buffer
)
119 int32 name
[kSCNameLen
];
120 ReadName(buffer
, name
);
122 inUnitSpec
->mUnitDef
= GetUnitDef(name
);
123 if (!inUnitSpec
->mUnitDef
) {
125 sprintf(str
, "UGen '%s' not installed.", (char*)name
);
126 throw std::runtime_error(str
);
129 inUnitSpec
->mCalcRate
= readInt8(buffer
);
131 inUnitSpec
->mNumInputs
= readInt16_be(buffer
);
132 inUnitSpec
->mNumOutputs
= readInt16_be(buffer
);
133 inUnitSpec
->mSpecialIndex
= readInt16_be(buffer
);
134 inUnitSpec
->mInputSpec
= (InputSpec
*)malloc(sizeof(InputSpec
) * inUnitSpec
->mNumInputs
);
135 inUnitSpec
->mOutputSpec
= (OutputSpec
*)malloc(sizeof(OutputSpec
) * inUnitSpec
->mNumOutputs
);
136 for (uint32 i
=0; i
<inUnitSpec
->mNumInputs
; ++i
) {
137 InputSpec_Read(inUnitSpec
->mInputSpec
+ i
, buffer
);
139 for (uint32 i
=0; i
<inUnitSpec
->mNumOutputs
; ++i
) {
140 OutputSpec_Read(inUnitSpec
->mOutputSpec
+ i
, buffer
);
142 int numPorts
= inUnitSpec
->mNumInputs
+ inUnitSpec
->mNumOutputs
;
143 inUnitSpec
->mAllocSize
= inUnitSpec
->mUnitDef
->mAllocSize
+ numPorts
* (sizeof(Wire
*) + sizeof(float*));
146 GraphDef
* GraphDef_Read(World
*inWorld
, char*& buffer
, GraphDef
* inList
, int32 inVersion
);
148 GraphDef
* GraphDefLib_Read(World
*inWorld
, char* buffer
, GraphDef
* inList
);
149 GraphDef
* GraphDefLib_Read(World
*inWorld
, char* buffer
, GraphDef
* inList
)
151 int32 magic
= readInt32_be(buffer
);
152 if (magic
!= (('S'<<24)|('C'<<16)|('g'<<8)|'f') /*'SCgf'*/) return inList
;
154 int32 version
= readInt32_be(buffer
);
155 if (version
> 1) return inList
;
157 uint32 numDefs
= readInt16_be(buffer
);
159 for (uint32 i
=0; i
<numDefs
; ++i
) {
160 inList
= GraphDef_Read(inWorld
, buffer
, inList
, version
);
166 void ChooseMulAddFunc(GraphDef
*graphDef
, UnitSpec
* unitSpec
);
167 void DoBufferColoring(World
*inWorld
, GraphDef
*inGraphDef
);
169 void GraphDef_ReadVariant(World
*inWorld
, char*& buffer
, GraphDef
* inGraphDef
, GraphDef
* inVariant
)
171 memcpy(inVariant
, inGraphDef
, sizeof(GraphDef
));
173 inVariant
->mNumVariants
= 0;
174 inVariant
->mVariants
= 0;
176 ReadName(buffer
, inVariant
->mNodeDef
.mName
);
177 inVariant
->mNodeDef
.mHash
= Hash(inVariant
->mNodeDef
.mName
);
179 inVariant
->mInitialControlValues
= (float32
*)malloc(sizeof(float32
) * inGraphDef
->mNumControls
);
180 for (uint32 i
=0; i
<inGraphDef
->mNumControls
; ++i
) {
181 inVariant
->mInitialControlValues
[i
] = readFloat_be(buffer
);
185 GraphDef
* GraphDef_Read(World
*inWorld
, char*& buffer
, GraphDef
* inList
, int32 inVersion
)
187 int32 name
[kSCNodeDefNameLen
];
188 ReadNodeDefName(buffer
, name
);
190 GraphDef
* graphDef
= (GraphDef
*)calloc(1, sizeof(GraphDef
));
192 graphDef
->mOriginal
= graphDef
;
194 graphDef
->mNodeDef
.mAllocSize
= sizeof(Graph
);
196 memcpy((char*)graphDef
->mNodeDef
.mName
, (char*)name
, kSCNodeDefNameByteLen
);
198 graphDef
->mNodeDef
.mHash
= Hash(graphDef
->mNodeDef
.mName
);
200 graphDef
->mNumConstants
= readInt16_be(buffer
);
201 graphDef
->mConstants
= (float*)malloc(graphDef
->mNumConstants
* sizeof(float));
202 for (uint32 i
=0; i
<graphDef
->mNumConstants
; ++i
) {
203 graphDef
->mConstants
[i
] = readFloat_be(buffer
);
206 graphDef
->mNumControls
= readInt16_be(buffer
);
207 graphDef
->mInitialControlValues
= (float32
*)malloc(sizeof(float32
) * graphDef
->mNumControls
);
208 for (uint32 i
=0; i
<graphDef
->mNumControls
; ++i
) {
209 graphDef
->mInitialControlValues
[i
] = readFloat_be(buffer
);
212 graphDef
->mNumParamSpecs
= readInt16_be(buffer
);
213 if (graphDef
->mNumParamSpecs
) {
214 int hashTableSize
= NEXTPOWEROFTWO(graphDef
->mNumParamSpecs
);
215 graphDef
->mParamSpecTable
= new ParamSpecTable(&gMalloc
, hashTableSize
, false);
216 graphDef
->mParamSpecs
= (ParamSpec
*)malloc(graphDef
->mNumParamSpecs
* sizeof(ParamSpec
));
217 for (uint32 i
=0; i
<graphDef
->mNumParamSpecs
; ++i
) {
218 ParamSpec
*paramSpec
= graphDef
->mParamSpecs
+ i
;
219 ParamSpec_Read(paramSpec
, buffer
);
220 graphDef
->mParamSpecTable
->Add(paramSpec
);
223 // empty table to eliminate test in Graph_SetControl
224 graphDef
->mParamSpecTable
= new ParamSpecTable(&gMalloc
, 4, false);
225 graphDef
->mParamSpecs
= 0;
228 graphDef
->mNumWires
= graphDef
->mNumConstants
;
229 graphDef
->mNumUnitSpecs
= readInt16_be(buffer
);
230 graphDef
->mUnitSpecs
= (UnitSpec
*)malloc(sizeof(UnitSpec
) * graphDef
->mNumUnitSpecs
);
231 graphDef
->mNumCalcUnits
= 0;
232 for (uint32 i
=0; i
<graphDef
->mNumUnitSpecs
; ++i
) {
233 UnitSpec
*unitSpec
= graphDef
->mUnitSpecs
+ i
;
234 UnitSpec_Read(unitSpec
, buffer
);
236 switch (unitSpec
->mCalcRate
)
238 case calc_ScalarRate
:
239 unitSpec
->mRateInfo
= &inWorld
->mBufRate
;
242 graphDef
->mNumCalcUnits
++;
243 unitSpec
->mRateInfo
= &inWorld
->mBufRate
;
246 graphDef
->mNumCalcUnits
++;
247 unitSpec
->mRateInfo
= &inWorld
->mFullRate
;
249 case calc_DemandRate
:
250 unitSpec
->mRateInfo
= &inWorld
->mBufRate
;
254 graphDef
->mNodeDef
.mAllocSize
+= unitSpec
->mAllocSize
;
255 graphDef
->mNumWires
+= unitSpec
->mNumOutputs
;
258 DoBufferColoring(inWorld
, graphDef
);
260 graphDef
->mWiresAllocSize
= graphDef
->mNumWires
* sizeof(Wire
);
261 graphDef
->mUnitsAllocSize
= graphDef
->mNumUnitSpecs
* sizeof(Unit
*);
262 graphDef
->mCalcUnitsAllocSize
= graphDef
->mNumCalcUnits
* sizeof(Unit
*);
264 graphDef
->mNodeDef
.mAllocSize
+= graphDef
->mWiresAllocSize
;
265 graphDef
->mNodeDef
.mAllocSize
+= graphDef
->mUnitsAllocSize
;
266 graphDef
->mNodeDef
.mAllocSize
+= graphDef
->mCalcUnitsAllocSize
;
268 graphDef
->mControlAllocSize
= graphDef
->mNumControls
* sizeof(float);
269 graphDef
->mNodeDef
.mAllocSize
+= graphDef
->mControlAllocSize
;
271 graphDef
->mMapControlsAllocSize
= graphDef
->mNumControls
* sizeof(float*);
272 graphDef
->mNodeDef
.mAllocSize
+= graphDef
->mMapControlsAllocSize
;
274 graphDef
->mMapControlRatesAllocSize
= graphDef
->mNumControls
* sizeof(int*);
275 graphDef
->mNodeDef
.mAllocSize
+= graphDef
->mMapControlRatesAllocSize
;
278 graphDef
->mNext
= inList
;
279 graphDef
->mRefCount
= 1;
281 if (inVersion
>= 1) {
282 graphDef
->mNumVariants
= readInt16_be(buffer
);
283 if (graphDef
->mNumVariants
) {
284 graphDef
->mVariants
= (GraphDef
*)calloc(graphDef
->mNumVariants
, sizeof(GraphDef
));
285 for (uint32 i
=0; i
<graphDef
->mNumVariants
; ++i
) {
286 GraphDef_ReadVariant(inWorld
, buffer
, graphDef
, graphDef
->mVariants
+ i
);
295 void GraphDef_Define(World
*inWorld
, GraphDef
*inList
)
297 GraphDef
*graphDef
= inList
;
299 GraphDef
*next
= graphDef
->mNext
;
301 GraphDef
* previousDef
= World_GetGraphDef(inWorld
, graphDef
->mNodeDef
.mName
);
303 World_RemoveGraphDef(inWorld
, previousDef
);
304 if (--previousDef
->mRefCount
== 0) {
305 GraphDef_DeleteMsg(inWorld
, previousDef
);
308 World_AddGraphDef(inWorld
, graphDef
);
314 void GraphDef_Remove(World
*inWorld
, int32
*inName
)
316 GraphDef
* graphDef
= World_GetGraphDef(inWorld
, inName
);
318 World_RemoveGraphDef(inWorld
, graphDef
);
319 if (--graphDef
->mRefCount
== 0) {
320 GraphDef_DeleteMsg(inWorld
, graphDef
);
325 void GraphDef_DeleteMsg(World
*inWorld
, GraphDef
*inDef
)
327 DeleteGraphDefMsg msg
;
329 inWorld
->hw
->mDeleteGraphDefs
.Write(msg
);
332 GraphDef
* GraphDef_Recv(World
*inWorld
, char *buffer
, GraphDef
*inList
)
336 inList
= GraphDefLib_Read(inWorld
, buffer
, inList
);
337 } catch (std::exception
& exc
) {
338 scprintf("exception in GraphDef_Recv: %s\n", exc
.what());
340 scprintf("unknown exception in GraphDef_Recv\n");
346 GraphDef
* GraphDef_LoadGlob(World
*inWorld
, const char *pattern
, GraphDef
*inList
)
348 SC_GlobHandle
* glob
= sc_Glob(pattern
);
349 if (!glob
) return inList
;
351 const char* filename
;
352 while ((filename
= sc_GlobNext(glob
)) != 0) {
353 int len
= strlen(filename
);
354 if (strncmp(filename
+len
-9, ".scsyndef", 9)==0) {
355 inList
= GraphDef_Load(inWorld
, filename
, inList
);
358 GraphDef_Load(inWorld
, filename
, inList
);
365 GraphDef
* GraphDef_Load(World
*inWorld
, const char *filename
, GraphDef
*inList
)
367 FILE *file
= fopen(filename
, "rb");
370 scprintf("*** ERROR: can't fopen '%s'\n", filename
);
374 fseek(file
, 0, SEEK_END
);
375 int size
= ftell(file
);
376 char *buffer
= (char*)malloc(size
);
378 scprintf("*** ERROR: can't malloc buffer size %d\n", size
);
382 fseek(file
, 0, SEEK_SET
);
384 size_t readSize
= fread(buffer
, 1, size
, file
);
387 if (readSize
!= size
) {
388 scprintf("*** ERROR: invalid fread\n", size
);
394 inList
= GraphDefLib_Read(inWorld
, buffer
, inList
);
395 } catch (std::exception
& exc
) {
396 scprintf("exception in GrafDef_Load: %s\n", exc
.what());
397 scprintf("while reading file '%s'\n", filename
);
399 scprintf("unknown exception in GrafDef_Load\n");
400 scprintf("while reading file '%s'\n", filename
);
408 GraphDef
* GraphDef_LoadDir(World
*inWorld
, char *dirname
, GraphDef
*inList
)
410 SC_DirHandle
*dir
= sc_OpenDir(dirname
);
412 scprintf("*** ERROR: open directory failed '%s'\n", dirname
);
417 char diritem
[MAXPATHLEN
];
418 bool skipItem
= false;
419 bool validItem
= sc_ReadDir(dir
, dirname
, diritem
, skipItem
);
420 if (!validItem
) break;
421 if (skipItem
) continue;
423 if (sc_DirectoryExists(diritem
)) {
424 inList
= GraphDef_LoadDir(inWorld
, diritem
, inList
);
426 int dnamelen
= strlen(diritem
);
427 if (strncmp(diritem
+dnamelen
-9, ".scsyndef", 9) == 0) {
428 inList
= GraphDef_Load(inWorld
, diritem
, inList
);
437 void UnitSpec_Free(UnitSpec
*inUnitSpec
);
438 void UnitSpec_Free(UnitSpec
*inUnitSpec
)
440 free(inUnitSpec
->mInputSpec
);
441 free(inUnitSpec
->mOutputSpec
);
444 void GraphDef_Free(GraphDef
*inGraphDef
)
446 if (inGraphDef
!= inGraphDef
->mOriginal
) return;
448 for (uint32 i
=0; i
<inGraphDef
->mNumUnitSpecs
; ++i
) {
449 UnitSpec_Free(inGraphDef
->mUnitSpecs
+ i
);
451 for (uint32 i
=0; i
<inGraphDef
->mNumVariants
; ++i
) {
452 free(inGraphDef
->mVariants
[i
].mInitialControlValues
);
454 delete inGraphDef
->mParamSpecTable
;
455 free(inGraphDef
->mParamSpecs
);
456 free(inGraphDef
->mInitialControlValues
);
457 free(inGraphDef
->mConstants
);
458 free(inGraphDef
->mUnitSpecs
);
459 free(inGraphDef
->mVariants
);
463 void NodeDef_Dump(NodeDef
*inNodeDef
)
465 scprintf("mName '%s'\n", (char*)inNodeDef
->mName
);
466 scprintf("mHash %d\n", inNodeDef
->mHash
);
467 scprintf("mAllocSize %lu\n", inNodeDef
->mAllocSize
);
470 void GraphDef_Dump(GraphDef
*inGraphDef
)
472 NodeDef_Dump(&inGraphDef
->mNodeDef
);
474 scprintf("mNumControls %d\n", inGraphDef
->mNumControls
);
475 scprintf("mNumWires %d\n", inGraphDef
->mNumWires
);
476 scprintf("mNumUnitSpecs %d\n", inGraphDef
->mNumUnitSpecs
);
477 scprintf("mNumWireBufs %d\n", inGraphDef
->mNumWireBufs
);
479 for (uint32 i
=0; i
<inGraphDef
->mNumControls
; ++i
) {
480 scprintf(" %d mInitialControlValues %g\n", i
, inGraphDef
->mInitialControlValues
[i
]);
483 for (uint32 i
=0; i
<inGraphDef
->mNumWires
; ++i
) {
484 //WireSpec_Dump(inGraphDef->mWireSpec + i);
486 for (uint32 i
=0; i
<inGraphDef
->mNumUnitSpecs
; ++i
) {
487 //UnitSpec_Dump(inGraphDef->mUnitSpecs + i);
494 var nextBufIndex = 0;
506 if (stack.size > 0, {
507 bufNumber = stack.pop
509 bufNumber = nextBufIndex;
510 nextBufIndex = nextBufIndex + 1;
512 refs.add(bufNumber, count);
515 release { arg bufNumber;
516 refs.remove(bufNumber);
517 if (refs.includes(bufNumber).not, { stack = stack.add(bufNumber) });
519 numBufs { ^nextBufIndex }
523 struct BufColorAllocator
533 ~BufColorAllocator();
535 int alloc(int count
);
536 bool release(int inIndex
);
537 int NumBufs() { return nextIndex
; }
540 inline BufColorAllocator::BufColorAllocator()
544 refs
= (int16
*)calloc(refsMaxSize
, sizeof(int16
));
545 stack
= (int16
*)calloc(stackMaxSize
, sizeof(int16
));
550 inline BufColorAllocator::~BufColorAllocator()
556 inline int BufColorAllocator::alloc(int count
)
560 outIndex
= stack
[--stackPtr
];
562 outIndex
= nextIndex
++;
564 if (outIndex
>= refsMaxSize
) {
565 refs
= (int16
*)realloc(refs
, refsMaxSize
*2*sizeof(int16
));
566 memset(refs
+ refsMaxSize
, 0, refsMaxSize
*sizeof(int16
));
569 refs
[outIndex
] = count
;
573 inline bool BufColorAllocator::release(int inIndex
)
575 if (refs
[inIndex
] == 0) return false;
576 if (--refs
[inIndex
] == 0) {
577 if (stackPtr
>= stackMaxSize
) {
578 stack
= (int16
*)realloc(stack
, stackMaxSize
*2*sizeof(int16
));
579 memset(stack
+ stackMaxSize
, 0, stackMaxSize
*sizeof(int16
));
582 stack
[stackPtr
++] = inIndex
;
587 void ReleaseInputBuffers(GraphDef
*inGraphDef
, UnitSpec
*unitSpec
, BufColorAllocator
& bufColor
)
589 //scprintf("ReleaseInputBuffers %s numinputs %d\n", unitSpec->mUnitDef->mUnitDefName, unitSpec->mNumInputs);
590 for (int i
=unitSpec
->mNumInputs
-1; i
>=0; --i
) {
591 InputSpec
*inputSpec
= unitSpec
->mInputSpec
+ i
;
592 if (inputSpec
->mFromUnitIndex
>= 0) {
593 UnitSpec
*outUnit
= inGraphDef
->mUnitSpecs
+ inputSpec
->mFromUnitIndex
;
594 OutputSpec
*outputSpec
= outUnit
->mOutputSpec
+ inputSpec
->mFromOutputIndex
;
595 inputSpec
->mWireIndex
= outputSpec
->mWireIndex
;
596 if (outputSpec
->mCalcRate
== calc_FullRate
) {
597 if (!bufColor
.release(outputSpec
->mBufferIndex
)) {
598 scprintf("buffer coloring error: tried to release output with zero count\n");
599 scprintf("output: %d %s %d\n", inputSpec
->mFromUnitIndex
,
600 outUnit
->mUnitDef
->mUnitDefName
, inputSpec
->mFromOutputIndex
);
601 scprintf("input: %s %d\n", unitSpec
->mUnitDef
->mUnitDefName
, i
);
602 throw std::runtime_error("buffer coloring error.");
606 inputSpec
->mWireIndex
= inputSpec
->mFromOutputIndex
;
611 void AllocOutputBuffers(UnitSpec
*unitSpec
, BufColorAllocator
& bufColor
, int& wireIndexCtr
)
613 //scprintf("AllocOutputBuffers %s numoutputs %d\n", unitSpec->mUnitDef->mUnitDefName, unitSpec->mNumOutputs);
614 for (uint32 i
=0; i
<unitSpec
->mNumOutputs
; ++i
) {
615 OutputSpec
*outputSpec
= unitSpec
->mOutputSpec
+ i
;
616 outputSpec
->mWireIndex
= wireIndexCtr
++;
617 if (outputSpec
->mCalcRate
== calc_FullRate
) {
618 int bufIndex
= bufColor
.alloc(outputSpec
->mNumConsumers
);
619 outputSpec
->mBufferIndex
= bufIndex
;
624 void DoBufferColoring(World
*inWorld
, GraphDef
*inGraphDef
)
626 // count consumers of outputs
627 for (uint32 j
=0; j
<inGraphDef
->mNumUnitSpecs
; ++j
) {
628 UnitSpec
*unitSpec
= inGraphDef
->mUnitSpecs
+ j
;
629 for (uint32 i
=0; i
<unitSpec
->mNumInputs
; ++i
) {
630 InputSpec
*inputSpec
= unitSpec
->mInputSpec
+ i
;
631 if (inputSpec
->mFromUnitIndex
>= 0) {
632 UnitSpec
*outUnit
= inGraphDef
->mUnitSpecs
+ inputSpec
->mFromUnitIndex
;
633 OutputSpec
*outputSpec
= outUnit
->mOutputSpec
+ inputSpec
->mFromOutputIndex
;
634 outputSpec
->mNumConsumers
++;
641 BufColorAllocator bufColor
;
642 int wireIndexCtr
= inGraphDef
->mNumConstants
;
643 for (uint32 j
=0; j
<inGraphDef
->mNumUnitSpecs
; ++j
) {
644 UnitSpec
*unitSpec
= inGraphDef
->mUnitSpecs
+ j
;
645 if (unitSpec
->mUnitDef
->mFlags
& kUnitDef_CantAliasInputsToOutputs
) {
646 // set wire index, alloc outputs
647 AllocOutputBuffers(unitSpec
, bufColor
, wireIndexCtr
);
648 // set wire index, release inputs
649 ReleaseInputBuffers(inGraphDef
, unitSpec
, bufColor
);
651 // set wire index, release inputs
652 ReleaseInputBuffers(inGraphDef
, unitSpec
, bufColor
);
653 // set wire index, alloc outputs
654 AllocOutputBuffers(unitSpec
, bufColor
, wireIndexCtr
);
658 inGraphDef
->mNumWireBufs
= bufColor
.NumBufs();
659 if (inWorld
->mRunning
)
661 // cannot reallocate interconnect buffers while running audio.
662 if (inGraphDef
->mNumWireBufs
> inWorld
->hw
->mMaxWireBufs
) {
663 throw std::runtime_error("exceeded number of interconnect buffers.");
666 inWorld
->hw
->mMaxWireBufs
= sc_max(inWorld
->hw
->mMaxWireBufs
, inGraphDef
->mNumWireBufs
);
670 // multiply buf indices by buf length for proper offset
671 int bufLength
= inWorld
->mBufLength
;
672 for (uint32 j
=0; j
<inGraphDef
->mNumUnitSpecs
; ++j
) {
673 UnitSpec
*unitSpec
= inGraphDef
->mUnitSpecs
+ j
;
674 for (uint32 i
=0; i
<unitSpec
->mNumOutputs
; ++i
) {
675 OutputSpec
*outputSpec
= unitSpec
->mOutputSpec
+ i
;
676 if (outputSpec
->mCalcRate
== calc_FullRate
) {
677 outputSpec
->mBufferIndex
*= bufLength
;