Merging various recent changes from trunk into 34 - inc sc.app menu tweak, synthdef...
[supercollider.git] / common / Headers / plugin_interface / SC_Unit.h
blob7c2fdd17b2929df26731b19f1dfba3c320a77919
1 /*
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
22 #ifndef _SC_Unit_
23 #define _SC_Unit_
25 #include "SC_Types.h"
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 {
33 float * todo;
36 struct Unit
38 struct World *mWorld;
39 struct UnitDef *mUnitDef;
40 struct Graph *mParent;
41 uint16 mNumInputs, mNumOutputs;
42 int16 mCalcRate;
43 int16 mSpecialIndex; // used by unary and binary ops
44 int16 mParentIndex;
45 int16 mDone;
46 struct Wire **mInput, **mOutput;
47 struct Rate *mRate;
48 SC_Unit_Extensions* mExtensions; //future proofing and backwards compatibility; used to be SC_Dimension struct pointer
49 float **mInBuf, **mOutBuf;
51 UnitCalcFunc mCalcFunc;
52 int mBufLength;
55 typedef struct Unit Unit;
57 enum {
58 kUnitDef_CantAliasInputsToOutputs = 1
61 // easy macros, the unit variable must be named 'unit'.
62 #ifndef SC_WIN32
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])
72 #else
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])
84 #endif
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)
98 // get useful values
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
108 #define GET_BUF \
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; \
119 } else { \
120 bufnum = 0; \
121 unit->m_buf = world->mSndBufs + bufnum; \
123 } else { \
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; \
148 } else { \
149 bufnum = 0; \
150 unit->m_buf = world->mSndBufs + bufnum; \
152 } else { \
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
160 #define RGET \
161 RGen& rgen = *unit->mParent->mRGen; \
162 uint32 s1 = rgen.s1; \
163 uint32 s2 = rgen.s2; \
164 uint32 s3 = rgen.s3;
165 #define RPUT \
166 rgen.s1 = s1; \
167 rgen.s2 = s2; \
168 rgen.s3 = s3;
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);
173 #endif