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
27 typedef void (*UnitCtorFunc
)(struct Unit
* inUnit
);
28 typedef void (*UnitDtorFunc
)(struct Unit
* inUnit
);
30 typedef void (*UnitCalcFunc
)(struct Unit
*inThing
, int inNumSamples
);
32 struct SC_Unit_Extensions
{
39 struct UnitDef
*mUnitDef
;
40 struct Graph
*mParent
;
41 uint16 mNumInputs
, mNumOutputs
;
43 int16 mSpecialIndex
; // used by unary and binary ops
46 struct Wire
**mInput
, **mOutput
;
48 SC_Unit_Extensions
* mExtensions
; //future proofing and backwards compatibility; used to be SC_Dimension struct pointer
49 float **mInBuf
, **mOutBuf
;
51 UnitCalcFunc mCalcFunc
;
55 typedef struct Unit Unit
;
58 kUnitDef_CantAliasInputsToOutputs
= 1
61 // easy macros, the unit variable must be named 'unit'.
64 // These return float* pointers to input and output buffers.
65 #define IN(index) (unit->mInBuf[index])
66 #define OUT(index) (unit->mOutBuf[index])
68 // These return a float value. Used for control rate inputs and outputs.
69 #define IN0(index) (IN(index)[0])
70 #define OUT0(index) (OUT(index)[0])
74 // Win32 headers (included by C std library headers) define IN and OUT macros
75 // for their own purposes. To avoid problems we don't define IN and OUT here
76 // but define SC_IN and SC_OUT instead. Source files that use IN and OUT need
77 // to include definitions of IN, and OUT referencing SC_IN and SC_OUT after
78 // all headers have been included.
79 #define SC_IN(index) (unit->mInBuf[index])
80 #define SC_OUT(index) (unit->mOutBuf[index])
81 #define IN0(index) (SC_IN(index)[0])
82 #define OUT0(index) (SC_OUT(index)[0])
86 // get the rate of the input.
87 #define INRATE(index) (unit->mInput[index]->mCalcRate)
89 // get the blocksize of the input
90 #define INBUFLENGTH(index) (unit->mInput[index]->mFromUnit->mBufLength)
92 // set the calculation function
93 #define SETCALC(func) (unit->mCalcFunc = (UnitCalcFunc)&func)
95 // calculate a slope for control rate interpolation to audio rate.
96 #define CALCSLOPE(next,prev) ((next - prev) * sc_typeof_cast(next)unit->mRate->mSlopeFactor)
99 #define SAMPLERATE (unit->mRate->mSampleRate)
100 #define SAMPLEDUR (unit->mRate->mSampleDur)
101 #define BUFLENGTH (unit->mBufLength)
102 #define BUFRATE (unit->mRate->mBufRate)
103 #define BUFDUR (unit->mRate->mBufDuration)
104 #define FULLRATE (unit->mWorld->mFullRate.mSampleRate)
105 #define FULLBUFLENGTH (unit->mWorld->mFullRate.mBufLength)
107 // macros to grab a Buffer reference from the buffer indicated by the UGen's FIRST input
109 float fbufnum = ZIN0(0); \
110 if (fbufnum < 0.f) { fbufnum = 0.f; } \
111 if (fbufnum != unit->m_fbufnum) { \
112 uint32 bufnum = (int)fbufnum; \
113 World *world = unit->mWorld; \
114 if (bufnum >= world->mNumSndBufs) { \
115 int localBufNum = bufnum - world->mNumSndBufs; \
116 Graph *parent = unit->mParent; \
117 if(localBufNum <= parent->localBufNum) { \
118 unit->m_buf = parent->mLocalSndBufs + localBufNum; \
121 unit->m_buf = world->mSndBufs + bufnum; \
124 unit->m_buf = world->mSndBufs + bufnum; \
126 unit->m_fbufnum = fbufnum; \
128 SndBuf *buf = unit->m_buf; \
129 float *bufData __attribute__((__unused__)) = buf->data; \
130 uint32 bufChannels __attribute__((__unused__)) = buf->channels; \
131 uint32 bufSamples __attribute__((__unused__)) = buf->samples; \
132 uint32 bufFrames = buf->frames; \
133 int mask __attribute__((__unused__)) = buf->mask; \
134 int guardFrame __attribute__((__unused__)) = bufFrames - 2;
137 #define SIMPLE_GET_BUF \
138 float fbufnum = ZIN0(0); \
139 fbufnum = sc_max(0.f, fbufnum); \
140 if (fbufnum != unit->m_fbufnum) { \
141 uint32 bufnum = (int)fbufnum; \
142 World *world = unit->mWorld; \
143 if (bufnum >= world->mNumSndBufs) { \
144 int localBufNum = bufnum - world->mNumSndBufs; \
145 Graph *parent = unit->mParent; \
146 if(localBufNum <= parent->localBufNum) { \
147 unit->m_buf = parent->mLocalSndBufs + localBufNum; \
150 unit->m_buf = world->mSndBufs + bufnum; \
153 unit->m_buf = world->mSndBufs + bufnum; \
155 unit->m_fbufnum = fbufnum; \
157 SndBuf *buf = unit->m_buf; \
159 // macros to get pseudo-random number generator, and put its state in registers
161 RGen& rgen = *unit->mParent->mRGen; \
162 uint32 s1 = rgen.s1; \
163 uint32 s2 = rgen.s2; \
170 typedef void (*UnitCmdFunc
)(struct Unit
*unit
, struct sc_msg_iter
*args
);
171 typedef void (*PlugInCmdFunc
)(World
*inWorld
, void* inUserData
, struct sc_msg_iter
*args
, void *replyAddr
);