aboutsummaryrefslogtreecommitdiff
path: root/sc4pd/headers/plugin_interface
diff options
context:
space:
mode:
Diffstat (limited to 'sc4pd/headers/plugin_interface')
-rw-r--r--sc4pd/headers/plugin_interface/Hash.h152
-rw-r--r--sc4pd/headers/plugin_interface/SC_BoundsMacros.h29
-rw-r--r--sc4pd/headers/plugin_interface/SC_BufGen.h40
-rw-r--r--sc4pd/headers/plugin_interface/SC_Constants.h46
-rw-r--r--sc4pd/headers/plugin_interface/SC_DemandUnit.h54
-rw-r--r--sc4pd/headers/plugin_interface/SC_Dimension.h31
-rw-r--r--sc4pd/headers/plugin_interface/SC_FifoMsg.h59
-rw-r--r--sc4pd/headers/plugin_interface/SC_Graph.h53
-rw-r--r--sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h574
-rw-r--r--sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h448
-rw-r--r--sc4pd/headers/plugin_interface/SC_InterfaceTable.h175
-rw-r--r--sc4pd/headers/plugin_interface/SC_Node.h48
-rw-r--r--sc4pd/headers/plugin_interface/SC_PlugIn.h53
-rw-r--r--sc4pd/headers/plugin_interface/SC_RGen.h288
-rw-r--r--sc4pd/headers/plugin_interface/SC_Rate.h42
-rw-r--r--sc4pd/headers/plugin_interface/SC_SndBuf.h109
-rw-r--r--sc4pd/headers/plugin_interface/SC_Types.h67
-rw-r--r--sc4pd/headers/plugin_interface/SC_Unit.h101
-rw-r--r--sc4pd/headers/plugin_interface/SC_Wire.h36
-rw-r--r--sc4pd/headers/plugin_interface/SC_World.h105
-rw-r--r--sc4pd/headers/plugin_interface/SC_WorldOptions.h91
-rw-r--r--sc4pd/headers/plugin_interface/Unroll.h249
-rw-r--r--sc4pd/headers/plugin_interface/clz.h195
-rw-r--r--sc4pd/headers/plugin_interface/sc_msg_iter.h264
24 files changed, 3309 insertions, 0 deletions
diff --git a/sc4pd/headers/plugin_interface/Hash.h b/sc4pd/headers/plugin_interface/Hash.h
new file mode 100644
index 0000000..e42eaf4
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/Hash.h
@@ -0,0 +1,152 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _Hash_
+#define _Hash_
+
+#include "SC_Types.h"
+#include "SC_Endian.h"
+
+// These hash functions are among the best there are in terms of both speed and quality.
+// A good hash function makes a lot of difference.
+// I have not used Bob Jenkins own hash function because the keys I use are relatively short.
+
+
+// hash function for a string
+inline int32 Hash(const char *inKey)
+{
+ // the one-at-a-time hash.
+ // a very good hash function. ref: a web page by Bob Jenkins.
+ // http://www.burtleburtle.net/bob/hash/doobs.html
+ int32 hash = 0;
+ while (*inKey) {
+ hash += *inKey++;
+ hash += hash << 10;
+ hash ^= hash >> 6;
+ }
+ hash += hash << 3;
+ hash ^= hash >> 11;
+ hash += hash << 15;
+ return hash;
+}
+
+// hash function for a string that also returns the length
+inline int32 Hash(const char *inKey, int32 *outLength)
+{
+ // the one-at-a-time hash.
+ // a very good hash function. ref: a web page by Bob Jenkins.
+ const char *origKey = inKey;
+ int32 hash = 0;
+ while (*inKey) {
+ hash += *inKey++;
+ hash += hash << 10;
+ hash ^= hash >> 6;
+ }
+ hash += hash << 3;
+ hash ^= hash >> 11;
+ hash += hash << 15;
+ *outLength = inKey - origKey;
+ return hash;
+}
+
+// hash function for an array of char
+inline int32 Hash(const char *inKey, int32 inLength)
+{
+ // the one-at-a-time hash.
+ // a very good hash function. ref: a web page by Bob Jenkins.
+ int32 hash = 0;
+ for (int i=0; i<inLength; ++i) {
+ hash += *inKey++;
+ hash += hash << 10;
+ hash ^= hash >> 6;
+ }
+ hash += hash << 3;
+ hash ^= hash >> 11;
+ hash += hash << 15;
+ return hash;
+}
+
+// hash function for integers
+inline int32 Hash(int32 inKey)
+{
+ // Thomas Wang's integer hash.
+ // http://www.concentric.net/~Ttwang/tech/inthash.htm
+ // a faster hash for integers. also very good.
+ uint32 hash = (uint32)inKey;
+ hash += ~(hash << 15);
+ hash ^= hash >> 10;
+ hash += hash << 3;
+ hash ^= hash >> 6;
+ hash += ~(hash << 11);
+ hash ^= hash >> 16;
+ return (int32)hash;
+}
+
+inline int64 Hash64(int64 inKey)
+{
+ // Thomas Wang's 64 bit integer hash.
+ uint64 hash = (uint64)inKey;
+ hash += ~(hash << 32);
+ hash ^= (hash >> 22);
+ hash += ~(hash << 13);
+ hash ^= (hash >> 8);
+ hash += (hash << 3);
+ hash ^= (hash >> 15);
+ hash += ~(hash << 27);
+ hash ^= (hash >> 31);
+ return (int64)hash;
+}
+
+inline int32 Hash(const int32 *inKey, int32 inLength)
+{
+ // one-at-a-time hashing of a string of int32's.
+ // uses Thomas Wang's integer hash for the combining step.
+ int32 hash = 0;
+ for (int i=0; i<inLength; ++i) {
+ hash = Hash(hash + *inKey++);
+ }
+ return hash;
+}
+
+#ifndef _LASTCHAR_
+#define _LASTCHAR_
+#if BYTE_ORDER == LITTLE_ENDIAN
+const int32 kLASTCHAR = 0xFF000000;
+#else
+const int32 kLASTCHAR = 0x000000FF;
+#endif
+#endif
+
+inline int32 Hash(const int32 *inKey)
+{
+ // hashing of a string of int32's.
+ // uses Thomas Wang's integer hash for the combining step.
+ int32 hash = 0;
+ int32 c;
+ do {
+ c = *inKey++;
+ hash = Hash(hash + c);
+ } while (c & kLASTCHAR);
+ return hash;
+}
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_BoundsMacros.h b/sc4pd/headers/plugin_interface/SC_BoundsMacros.h
new file mode 100644
index 0000000..6c65795
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_BoundsMacros.h
@@ -0,0 +1,29 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_BoundsMacros_
+#define _SC_BoundsMacros_
+
+#define sc_abs(a) ((a)>=0?(a) : -(a))
+#define sc_max(a,b) (((a) > (b)) ? (a) : (b))
+#define sc_min(a,b) (((a) < (b)) ? (a) : (b))
+#define sc_clip(x, lo, hi) ((x) > (hi) ? (hi) : ((x) < (lo) ? (lo) : (x)))
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_BufGen.h b/sc4pd/headers/plugin_interface/SC_BufGen.h
new file mode 100644
index 0000000..9a275c1
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_BufGen.h
@@ -0,0 +1,40 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _BufGen_
+#define _BufGen_
+
+#include "SC_Types.h"
+
+typedef void (*BufGenFunc)(struct World *world, struct SndBuf *buf, struct sc_msg_iter *msg);
+
+struct BufGen
+{
+ int32 mBufGenName[kSCNameLen];
+ int32 mHash;
+
+ BufGenFunc mBufGenFunc;
+};
+
+extern "C" {
+bool BufGen_Create(char *inName, BufGenFunc inFunc);
+}
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_Constants.h b/sc4pd/headers/plugin_interface/SC_Constants.h
new file mode 100644
index 0000000..b9e49bf
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Constants.h
@@ -0,0 +1,46 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_Constants_
+#define _SC_Constants_
+
+#include <math.h>
+
+#ifndef __FP__
+const double pi = acos(-1.);
+#endif
+const double pi2 = pi * .5;
+const double pi32 = pi * 1.5;
+const double twopi = pi * 2.;
+const double rtwopi = 1. / twopi;
+const double log001 = log(0.001);
+const double log01 = log(0.01);
+const double log1 = log(0.1);
+const double rlog2 = 1./log(2.);
+const double sqrt2 = sqrt(2.);
+const double rsqrt2 = 1. / sqrt2;
+
+// used to truncate precision
+const float truncFloat = (float)(3. * pow(2,22));
+const double truncDouble = 3. * pow(2,51);
+
+const float kBadValue = 1e20f; // used in the secant table for values very close to 1/0
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_DemandUnit.h b/sc4pd/headers/plugin_interface/SC_DemandUnit.h
new file mode 100644
index 0000000..6f273b3
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_DemandUnit.h
@@ -0,0 +1,54 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_DemandUnit_
+#define _SC_DemandUnit_
+
+#include "SC_Unit.h"
+#include "SC_Wire.h"
+
+// demand rate unit support.
+
+inline bool IsDemandInput(Unit* unit, int index)
+{
+ Unit* fromUnit = unit->mInput[index]->mFromUnit;
+ return fromUnit && fromUnit->mCalcRate == calc_DemandRate;
+}
+
+inline float DemandInput(Unit* unit, int index)
+{
+ Unit* fromUnit = unit->mInput[index]->mFromUnit;
+ if (fromUnit && fromUnit->mCalcRate == calc_DemandRate)
+ (fromUnit->mCalcFunc)(fromUnit, 1);
+ return IN0(index);
+}
+
+inline void ResetInput(Unit* unit, int index)
+{
+ Unit* fromUnit = unit->mInput[index]->mFromUnit;
+ if (fromUnit && fromUnit->mCalcRate == calc_DemandRate)
+ (fromUnit->mCalcFunc)(fromUnit, 0);
+}
+
+#define ISDEMANDINPUT(index) IsDemandInput(unit, (index))
+#define DEMANDINPUT(index) DemandInput(unit, (index))
+#define RESETINPUT(index) ResetInput(unit, (index))
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_Dimension.h b/sc4pd/headers/plugin_interface/SC_Dimension.h
new file mode 100644
index 0000000..923b283
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Dimension.h
@@ -0,0 +1,31 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_Dimension_
+#define _SC_Dimension_
+
+struct SC_Dimension
+{
+ long mWidth, mHeight, mNumPixels;
+ float mXSlopeFactor, mYSlopeFactor;
+};
+typedef struct SC_Dimension SC_Dimension;
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_FifoMsg.h b/sc4pd/headers/plugin_interface/SC_FifoMsg.h
new file mode 100644
index 0000000..7d83e0a
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_FifoMsg.h
@@ -0,0 +1,59 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _FifoMsg_
+#define _FifoMsg_
+
+typedef void (*FifoMsgFunc)(struct FifoMsg*);
+
+struct FifoMsg
+{
+ FifoMsg() : mPerformFunc(0), mFreeFunc(0), mData(0), mWorld(0) {}
+
+ void Set(struct World *inWorld, FifoMsgFunc inPerform, FifoMsgFunc inFree, void* inData);
+ void Perform();
+ void Free();
+
+ FifoMsgFunc mPerformFunc;
+ FifoMsgFunc mFreeFunc;
+ void* mData;
+ struct World *mWorld;
+};
+
+inline void FifoMsg::Set(World *inWorld, FifoMsgFunc inPerform, FifoMsgFunc inFree, void* inData)
+{
+ mWorld = inWorld;
+ mPerformFunc = inPerform;
+ mFreeFunc = inFree;
+ mData = inData;
+}
+
+inline void FifoMsg::Perform()
+{
+ if (mPerformFunc) (mPerformFunc)(this);
+}
+
+inline void FifoMsg::Free()
+{
+ if (mFreeFunc) (mFreeFunc)(this);
+}
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_Graph.h b/sc4pd/headers/plugin_interface/SC_Graph.h
new file mode 100644
index 0000000..68d3d59
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Graph.h
@@ -0,0 +1,53 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_Graph_
+#define _SC_Graph_
+
+#include "SC_Node.h"
+#include "SC_Rate.h"
+#include "SC_Dimension.h"
+
+struct Graph
+{
+ Node mNode;
+
+ uint32 mNumWires;
+ struct Wire *mWire;
+
+ uint32 mNumControls;
+ float *mControls;
+ float **mMapControls;
+
+ uint32 mNumUnits;
+ struct Unit **mUnits;
+
+ int mNumCalcUnits;
+ struct Unit **mCalcUnits; // excludes i-rate units.
+
+ int mSampleOffset;
+ struct RGen* mRGen;
+
+ struct Unit *mLocalAudioBusUnit;
+ struct Unit *mLocalControlBusUnit;
+};
+typedef struct Graph Graph;
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h b/sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h
new file mode 100644
index 0000000..2d9668b
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h
@@ -0,0 +1,574 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _BinaryOpUGen_
+#define _BinaryOpUGen_
+
+#include "SC_BoundsMacros.h"
+#include <math.h>
+
+inline float sc_mod(float in, float hi)
+{
+ // avoid the divide if possible
+ const float lo = (float)0.;
+ if (in >= hi) {
+ in -= hi;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ in += hi;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - hi*floor(in/hi);
+}
+
+inline double sc_mod(double in, double hi)
+{
+ // avoid the divide if possible
+ const double lo = (double)0.;
+ if (in >= hi) {
+ in -= hi;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ in += hi;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - hi*floor(in/hi);
+}
+
+inline float sc_wrap(float in, float lo, float hi)
+{
+ float range;
+ // avoid the divide if possible
+ if (in >= hi) {
+ range = hi - lo;
+ in -= range;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ range = hi - lo;
+ in += range;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - range * floor((in - lo)/range);
+}
+
+inline double sc_wrap(double in, double lo, double hi)
+{
+ double range;
+ // avoid the divide if possible
+ if (in >= hi) {
+ range = hi - lo;
+ in -= range;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ range = hi - lo;
+ in += range;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - range * floor((in - lo)/range);
+}
+
+inline double sc_wrap(double in, double lo, double hi, double range)
+{
+ // avoid the divide if possible
+ if (in >= hi) {
+ in -= range;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ in += range;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - range * floor((in - lo)/range);
+}
+
+inline double sc_wrap(float in, float lo, float hi, float range)
+{
+ // avoid the divide if possible
+ if (in >= hi) {
+ in -= range;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ in += range;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ return in - range * floor((in - lo)/range);
+}
+
+inline float sc_fold(float in, float lo, float hi)
+{
+ float x, c, range, range2;
+ x = in - lo;
+
+ // avoid the divide if possible
+ if (in >= hi) {
+ in = hi + hi - in;
+ if (in >= lo) return in;
+ } else if (in < lo) {
+ in = lo + lo - in;
+ if (in < hi) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ // ok do the divide
+ range = hi - lo;
+ range2 = range + range;
+ c = x - range2 * floor(x / range2);
+ if (c>=range) c = range2 - c;
+ return c + lo;
+}
+
+inline double sc_fold(double in, double lo, double hi)
+{
+ double x, c, range, range2;
+ x = in - lo;
+
+ // avoid the divide if possible
+ if (in >= hi) {
+ in = hi + hi - in;
+ if (in >= lo) return in;
+ } else if (in < lo) {
+ in = lo + lo - in;
+ if (in < hi) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ // ok do the divide
+ range = hi - lo;
+ range2 = range + range;
+ c = x - range2 * floor(x / range2);
+ if (c>=range) c = range2 - c;
+ return c + lo;
+}
+
+inline double sc_fold(float in, float lo, float hi, float range, float range2)
+{
+ float x, c;
+ x = in - lo;
+
+ // avoid the divide if possible
+ if (in >= hi) {
+ in = hi + hi - in;
+ if (in >= lo) return in;
+ } else if (in < lo) {
+ in = lo + lo - in;
+ if (in < hi) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ // ok do the divide
+ c = x - range2 * floor(x / range2);
+ if (c>=range) c = range2 - c;
+ return c + lo;
+}
+
+inline double sc_fold(double in, double lo, double hi, double range, double range2)
+{
+ double x, c;
+ x = in - lo;
+
+ // avoid the divide if possible
+ if (in >= hi) {
+ in = hi + hi - in;
+ if (in >= lo) return in;
+ } else if (in < lo) {
+ in = lo + lo - in;
+ if (in < hi) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+ // ok do the divide
+ c = x - range2 * floor(x / range2);
+ if (c>=range) c = range2 - c;
+ return c + lo;
+}
+
+inline float sc_pow(float a, float b)
+{
+ return a >= 0.f ? pow(a, b) : -pow(-a, b);
+}
+
+inline double sc_pow(double a, double b)
+{
+ return a >= 0.f ? pow(a, b) : -pow(-a, b);
+}
+
+template <class T>
+inline float sc_thresh(T a, T b)
+{
+ return a < b ? (T)0 : a;
+}
+
+inline float sc_clip2(float a, float b)
+{
+ return sc_clip(a, -b, b);
+}
+
+inline float sc_wrap2(float a, float b)
+{
+ return sc_wrap(a, -b, b);
+}
+
+inline float sc_fold2(float a, float b)
+{
+ return sc_fold(a, -b, b);
+}
+
+inline float sc_excess(float a, float b)
+{
+ return a - sc_clip(a, -b, b);
+}
+
+inline float sc_round(float x, float quant)
+{
+ return quant==0. ? x : floor(x/quant + .5f) * quant;
+}
+
+inline double sc_round(double x, double quant)
+{
+ return quant==0. ? x : floor(x/quant + .5) * quant;
+}
+
+inline float sc_roundUp(float x, float quant)
+{
+ return quant==0. ? x : ceil(x/quant) * quant;
+}
+
+inline double sc_roundUp(double x, double quant)
+{
+ return quant==0. ? x : ceil(x/quant) * quant;
+}
+
+inline float sc_trunc(float x, float quant)
+{
+ return quant==0. ? x : floor(x/quant) * quant;
+}
+
+inline double sc_trunc(double x, double quant)
+{
+ return quant==0. ? x : floor(x/quant) * quant;
+}
+
+inline float sc_atan2(float a, float b)
+{
+ return atan2(a, b);
+}
+
+
+inline float sc_scaleneg(float a, float b)
+{
+ b = 0.5f * b + 0.5f;
+ return (fabs(a) - a) * b + a;
+}
+
+inline float sc_amclip(float a, float b)
+{
+ return a * 0.5f * (b + fabs(b));
+}
+
+inline double sc_amclip(double a, double b)
+{
+ return a * 0.5 * (b + fabs(b));
+}
+
+const float kFSQRT2M1 = sqrt(2.) - 1.;
+const double kDSQRT2M1 = sqrt(2.) - 1.;
+
+inline float sc_hypotx(float x, float y)
+{
+ float minxy;
+
+ x = fabs(x);
+ y = fabs(y);
+
+ minxy = sc_min(x,y);
+
+ return x + y - kFSQRT2M1 * minxy;
+}
+
+inline double sc_hypotx(double x, double y)
+{
+ double minxy;
+
+ x = fabs(x);
+ y = fabs(y);
+
+ minxy = sc_min(x,y);
+
+ return x + y - kDSQRT2M1 * minxy;
+}
+
+#pragma mark -
+
+
+inline int sc_div(int a, int b)
+{
+ int c;
+ if (b) {
+ if (a<0) c = (a+1)/b - 1;
+ else c = a/b;
+ } else c = a;
+ return c;
+}
+
+/*
+inline int sc_mod(int a, int b)
+{
+ long c;
+ c = a % b;
+ if (c<0) c += b;
+ return c;
+}
+*/
+
+inline int sc_mod(int in, int hi)
+{
+ // avoid the divide if possible
+ const int lo = 0;
+ if (in >= hi) {
+ in -= hi;
+ if (in < hi) return in;
+ } else if (in < lo) {
+ in += hi;
+ if (in >= lo) return in;
+ } else return in;
+
+ if (hi == lo) return lo;
+
+ int c;
+ c = in % hi;
+ if (c<0) c += hi;
+ return c;
+}
+
+inline int sc_wrap(int in, int lo, int hi)
+{
+ return sc_mod(in - lo, hi - lo + 1) + lo;
+}
+
+inline int sc_clip2(int a, int b)
+{
+ return sc_clip(a, -b, b);
+}
+
+inline int sc_wrap2(int a, int b)
+{
+ return sc_wrap(a, -b, b);
+}
+
+inline int sc_fold(int in, int lo, int hi)
+{
+ int b = hi - lo;
+ int b2 = b+b-2;
+ int c = sc_mod(in - lo, b2);
+ if (c>=b) c = b2-c;
+ return c + lo;
+}
+
+inline int sc_fold2(int a, int b)
+{
+ return sc_fold(a, -b, b);
+}
+
+inline int sc_excess(int a, int b)
+{
+ return a - sc_clip(a, -b, b);
+}
+
+inline int sc_gcd(int u, int v)
+{
+ int t;
+ u = sc_abs(u);
+ v = sc_abs(v);
+ if (u <= 1 || v <= 1) return 1;
+ while (u>0) {
+ if (u<v) { t=u; u=v; v=t; }
+ u = u % v;
+ }
+ return v;
+}
+
+inline int sc_lcm(int u, int v)
+{
+ return (u * v)/sc_gcd(u,v);
+}
+
+inline int sc_thresh(int a, int b)
+{
+ return a < b ? 0 : a;
+}
+
+inline int sc_bitAnd(int a, int b)
+{
+ return a & b;
+}
+
+inline int sc_bitOr(int a, int b)
+{
+ return a | b;
+}
+
+inline int sc_leftShift(int a, int b)
+{
+ return a << b;
+}
+
+inline int sc_rightShift(int a, int b)
+{
+ return a >> b;
+}
+
+inline int sc_unsignedRightShift(int a, int b)
+{
+ return (uint32)a >> b;
+}
+
+inline int sc_round(int x, int quant)
+{
+ return quant==0 ? x : sc_div(x + quant/2, quant) * quant;
+}
+
+
+inline int sc_roundUp(int x, int quant)
+{
+ return quant==0 ? x : sc_div(x + quant - 1, quant) * quant;
+}
+
+inline int sc_trunc(int x, int quant)
+{
+ return quant==0 ? x : sc_div(x, quant) * quant;
+}
+
+#pragma mark -
+
+#if 0
+
+inline long sc_div(long a, long b)
+{
+ int c;
+ if (b) {
+ if (a<0) c = (a+1)/b - 1;
+ else c = a/b;
+ } else c = a;
+ return c;
+}
+
+
+inline long sc_clip2(long a, long b)
+{
+ return sc_clip(a, -b, b);
+}
+
+inline long sc_wrap(long in, long lo, long hi)
+{
+ return sc_mod(in - lo, hi - lo + 1) + lo;
+}
+
+inline long sc_wrap2(long a, long b)
+{
+ return sc_wrap(a, -b, b);
+}
+
+inline long sc_fold(long in, long lo, long hi)
+{
+ long b = hi - lo;
+ long b2 = b+b-2;
+ long c = sc_mod(in - lo, b2);
+ if (c>=b) c = b2-c;
+ return c + lo;
+}
+
+inline long sc_fold2(long a, long b)
+{
+ return sc_fold(a, -b, b);
+}
+
+inline long sc_thresh(long a, long b)
+{
+ return a < b ? 0 : a;
+}
+
+inline long sc_bitAnd(long a, long b)
+{
+ return a & b;
+}
+
+inline long sc_bitOr(long a, long b)
+{
+ return a | b;
+}
+
+inline long sc_leftShift(long a, long b)
+{
+ return a << b;
+}
+
+inline long sc_rightShift(long a, long b)
+{
+ return a >> b;
+}
+
+inline long sc_unsignedRightShift(long a, long b)
+{
+ return (unsigned long)a >> b;
+}
+
+inline long sc_gcd(long u, long v)
+{
+ long t;
+ u = sc_abs(u);
+ v = sc_abs(v);
+ if (u <= 1 || v <= 1) return 1;
+ while (u>0) {
+ if (u<v) { t=u; u=v; v=t; }
+ u = u % v;
+ }
+ return v;
+}
+
+inline long sc_lcm(long u, long v)
+{
+ return (u * v)/sc_gcd(u,v);
+}
+
+inline long sc_excess(long a, long b)
+{
+ return a - sc_clip(a, -b, b);
+}
+
+inline long sc_round(long x, long quant)
+{
+ return quant==0 ? x : sc_div(x + quant/2, quant) * quant;
+}
+
+#endif
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h b/sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h
new file mode 100644
index 0000000..9ea2e0b
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h
@@ -0,0 +1,448 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _UnaryOpUGen_
+#define _UnaryOpUGen_
+
+#include "SC_Types.h"
+#include "SC_Constants.h"
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+inline bool sc_isnan(float x)
+{
+ return (!(x >= 0.f || x <= 0.f));
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+// versions provided for float32 and float64
+// did not supply template because do not want to instantiate for integers.
+// all constants explicitly cast to prevent PowerPC frsp instruction generation.
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+// this is a function for preventing pathological math operations in ugens.
+// can be used at the end of a block to fix any recirculating filter values.
+inline float32 zapgremlins(float32 x)
+{
+ float32 absx = fabs(x);
+ // very small numbers fail the first test, eliminating denormalized numbers
+ // (zero also fails the first test, but that is OK since it returns zero.)
+ // very large numbers fail the second test, eliminating infinities
+ // Not-a-Numbers fail both tests and are eliminated.
+ return (absx > (float32)1e-15 && absx < (float32)1e15) ? x : (float32)0.;
+}
+
+inline float32 sc_log2(float32 x)
+{
+ return log(fabs(x)) * rlog2;
+}
+
+inline float32 sc_log10(float32 x)
+{
+ return log10(fabs(x));
+}
+
+inline float32 sc_midicps(float32 note)
+{
+ return (float32)440. * pow((float32)2., (note - (float32)69.) * (float32)0.083333333333);
+}
+
+inline float32 sc_cpsmidi(float32 freq)
+{
+ return sc_log2(freq * (float32)0.0022727272727) * (float32)12. + (float32)69.;
+}
+
+inline float32 sc_midiratio(float32 midi)
+{
+ return pow((float32)2. , midi * (float32)0.083333333333);
+}
+
+inline float32 sc_ratiomidi(float32 ratio)
+{
+ return (float32)12. * sc_log2(ratio);
+}
+
+inline float32 sc_octcps(float32 note)
+{
+ return (float32)440. * pow((float32)2., note - (float32)4.75);
+}
+
+inline float32 sc_cpsoct(float32 freq)
+{
+ return sc_log2(freq * (float32)0.0022727272727) + (float32)4.75;
+}
+
+inline float32 sc_ampdb(float32 amp)
+{
+ return log10(amp) * (float32)20.;
+}
+
+inline float32 sc_dbamp(float32 db)
+{
+ return pow((float32)10., db * (float32).05);
+}
+
+inline float32 sc_squared(float32 x)
+{
+ return x * x;
+}
+
+inline float32 sc_cubed(float32 x)
+{
+ return x * x * x;
+}
+
+inline float32 sc_sqrt(float32 x)
+{
+ return x < (float32)0. ? -sqrt(-x) : sqrt(x);
+}
+
+
+inline float32 sc_hanwindow(float32 x)
+{
+ if (x < (float32)0. || x > (float32)1.) return (float32)0.;
+ return (float32)0.5 - (float32)0.5 * cos(x * twopi);
+}
+
+inline float32 sc_welwindow(float32 x)
+{
+ if (x < (float32)0. || x > (float32)1.) return (float32)0.;
+ return sin(x * pi);
+}
+
+inline float32 sc_triwindow(float32 x)
+{
+ if (x < (float32)0. || x > (float32)1.) return (float32)0.;
+ if (x < (float32)0.5) return (float32)2. * x;
+ else return (float32)-2. * x + (float32)2.;
+}
+
+inline float32 sc_bitriwindow(float32 x)
+{
+ float32 ax = (float32)1. - fabs(x);
+ if (ax <= (float32)0.) return (float32)0.;
+ return ax;
+}
+
+inline float32 sc_rectwindow(float32 x)
+{
+ if (x < (float32)0. || x > (float32)1.) return (float32)0.;
+ return (float32)1.;
+}
+
+inline float32 sc_scurve(float32 x)
+{
+ if (x <= (float32)0.) return (float32)0.;
+ if (x >= (float32)1.) return (float32)1.;
+ return x * x * ((float32)3. - (float32)2. * x);
+}
+
+inline float32 sc_scurve0(float32 x)
+{
+ // assumes that x is in range
+ return x * x * ((float32)3. - (float32)2. * x);
+}
+
+inline float32 sc_ramp(float32 x)
+{
+ if (x <= (float32)0.) return (float32)0.;
+ if (x >= (float32)1.) return (float32)1.;
+ return x;
+}
+
+inline float32 sc_distort(float32 x)
+{
+ return x / ((float32)1. + fabs(x));
+}
+
+inline float32 sc_softclip(float32 x)
+{
+ float32 absx = fabs(x);
+ if (absx <= (float32)0.5) return x;
+ else return (absx - (float32)0.25) / x;
+}
+
+// Taylor expansion out to x**9/9! factored into multiply-adds
+// from Phil Burk.
+inline float32 taylorsin(float32 x)
+{
+ // valid range from -pi/2 to +3pi/2
+ x = pi2 - fabs(pi2 - x);
+ float32 x2 = x * x;
+ return x*(x2*(x2*(x2*(x2*(1.0/362880.0)
+ - (1.0/5040.0))
+ + (1.0/120.0))
+ - (1.0/6.0))
+ + 1.0);
+}
+
+inline float32 sc_trunc(float32 x)
+{
+ // truncFloat is a number which causes a loss of precision of
+ // the fractional part.
+ // NOTE: this will only work if the FPU is set to round downward.
+ // That is NOT the default rounding mode. SC sets it to this mode.
+ float32 tmp1 = x + truncFloat;
+ float32 tmp2 = tmp1 - truncFloat;
+ return tmp2;
+}
+
+inline float32 sc_frac(float32 x)
+{
+ return x - sc_trunc(x);
+}
+
+inline float32 sc_lg3interp(float32 x1, float32 a, float32 b, float32 c, float32 d)
+{
+ // cubic lagrange interpolator
+ float32 x0 = x1 + 1.f;
+ float32 x2 = x1 - 1.f;
+ float32 x3 = x1 - 2.f;
+
+ float32 x03 = x0 * x3 * 0.5f;
+ float32 x12 = x1 * x2 * 0.16666666666666667f;
+
+ return x12 * (d * x0 - a * x3) + x03 * (b * x2 - c * x1);
+}
+
+inline float32 sc_CalcFeedback(float32 delaytime, float32 decaytime)
+{
+ if (delaytime == 0.f) {
+ return 0.f;
+ } else if (decaytime > 0.f) {
+ return exp(log001 * delaytime / decaytime);
+ } else if (decaytime < 0.f) {
+ return -exp(log001 * delaytime / -decaytime);
+ } else {
+ return 0.f;
+ }
+}
+
+inline float32 sc_wrap1(float32 x)
+{
+ if (x >= (float32) 1.) return x + (float32)-2.;
+ if (x < (float32)-1.) return x + (float32) 2.;
+ return x;
+}
+
+inline float32 sc_fold1(float32 x)
+{
+ if (x >= (float32) 1.) return (float32) 2. - x;
+ if (x < (float32)-1.) return (float32)-2. - x;
+ return x;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+inline float64 zapgremlins(float64 x)
+{
+ float64 absx = fabs(x);
+ // very small numbers fail the first test, eliminating denormalized numbers
+ // (zero also fails the first test, but that is OK since it returns zero.)
+ // very large numbers fail the second test, eliminating infinities
+ // Not-a-Numbers fail both tests and are eliminated.
+ return (absx > (float64)1e-15 && absx < (float64)1e15) ? x : (float64)0.;
+}
+
+inline float64 sc_log2(float64 x)
+{
+ return log(fabs(x)) * rlog2;
+}
+
+inline float64 sc_log10(float64 x)
+{
+ return log10(fabs(x));
+}
+
+inline float64 sc_midicps(float64 note)
+{
+ return (float64)440. * pow((float64)2., (note - (float64)69.) * (float64)0.083333333333);
+}
+
+inline float64 sc_cpsmidi(float64 freq)
+{
+ return sc_log2(freq * (float64)0.0022727272727) * (float64)12. + (float64)69.;
+}
+
+inline float64 sc_midiratio(float64 midi)
+{
+ return pow((float64)2. , midi * (float64)0.083333333333);
+}
+
+inline float64 sc_ratiomidi(float64 ratio)
+{
+ return (float64)12. * sc_log2(ratio);
+}
+
+inline float64 sc_octcps(float64 note)
+{
+ return (float64)440. * pow((float64)2., note - (float64)4.75);
+}
+
+inline float64 sc_cpsoct(float64 freq)
+{
+ return sc_log2(freq * (float64)0.0022727272727) + (float64)4.75;
+}
+
+inline float64 sc_ampdb(float64 amp)
+{
+ return log10(amp) * (float64)20.;
+}
+
+inline float64 sc_dbamp(float64 db)
+{
+ return pow((float64)10., db * (float64).05);
+}
+
+inline float64 sc_squared(float64 x)
+{
+ return x * x;
+}
+
+inline float64 sc_cubed(float64 x)
+{
+ return x * x * x;
+}
+
+inline float64 sc_sqrt(float64 x)
+{
+ return x < (float64)0. ? -sqrt(-x) : sqrt(x);
+}
+
+inline float64 sc_hanwindow(float64 x)
+{
+ if (x < (float64)0. || x > (float64)1.) return (float64)0.;
+ return (float64)0.5 - (float64)0.5 * cos(x * twopi);
+}
+
+inline float64 sc_welwindow(float64 x)
+{
+ if (x < (float64)0. || x > (float64)1.) return (float64)0.;
+ return sin(x * pi);
+}
+
+inline float64 sc_triwindow(float64 x)
+{
+ if (x < (float64)0. || x > (float64)1.) return (float64)0.;
+ if (x < (float64)0.5) return (float64)2. * x;
+ else return (float64)-2. * x + (float64)2.;
+}
+
+inline float64 sc_bitriwindow(float64 x)
+{
+ float64 ax = fabs(x);
+ if (ax > (float64)1.) return (float64)0.;
+ return (float64)1. - ax;
+}
+
+inline float64 sc_rectwindow(float64 x)
+{
+ if (x < (float64)0. || x > (float64)1.) return (float64)0.;
+ return (float64)1.;
+}
+
+inline float64 sc_scurve(float64 x)
+{
+ if (x <= (float64)0.) return (float64)0.;
+ if (x >= (float64)1.) return (float64)1.;
+ return x * x * ((float64)3. - (float64)2. * x);
+}
+
+inline float64 sc_scurve0(float64 x)
+{
+ // assumes that x is in range
+ return x * x * ((float64)3. - (float64)2. * x);
+}
+
+inline float64 sc_ramp(float64 x)
+{
+ if (x <= (float64)0.) return (float64)0.;
+ if (x >= (float64)1.) return (float64)1.;
+ return x;
+}
+
+inline float64 sc_distort(float64 x)
+{
+ return x / ((float64)1. + fabs(x));
+}
+
+inline float64 sc_softclip(float64 x)
+{
+ float64 absx = fabs(x);
+ if (absx <= (float64)0.5) return x;
+ else return (absx - (float64)0.25) / x;
+}
+
+// Taylor expansion out to x**9/9! factored into multiply-adds
+// from Phil Burk.
+inline float64 taylorsin(float64 x)
+{
+ x = pi2 - fabs(pi2 - x);
+ float64 x2 = x * x;
+ return x*(x2*(x2*(x2*(x2*(1.0/362880.0)
+ - (1.0/5040.0))
+ + (1.0/120.0))
+ - (1.0/6.0))
+ + 1.0);
+}
+
+inline float64 sc_trunc(float64 x)
+{
+ // truncDouble is a number which causes a loss of precision of
+ // the fractional part.
+ // NOTE: this will only work if the FPU is set to round downward.
+ // That is NOT the default rounding mode. SC sets it to this mode.
+ float64 tmp1 = x + truncDouble;
+ float64 tmp2 = tmp1 - truncDouble;
+ return tmp2;
+}
+
+inline float64 sc_frac(float64 x)
+{
+ return x - sc_trunc(x);
+}
+
+inline float64 sc_wrap1(float64 x)
+{
+ if (x >= (float64) 1.) return x + (float64)-2.;
+ if (x < (float64)-1.) return x + (float64) 2.;
+ return x;
+}
+
+inline float64 sc_fold1(float64 x)
+{
+ if (x >= (float64) 1.) return (float64) 2. - x;
+ if (x < (float64)-1.) return (float64)-2. - x;
+ return x;
+}
+
+inline int32 sc_grayCode(int32 x)
+{
+ return x ^ (x >> 1);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_InterfaceTable.h b/sc4pd/headers/plugin_interface/SC_InterfaceTable.h
new file mode 100644
index 0000000..20cb864
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_InterfaceTable.h
@@ -0,0 +1,175 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_SynthInterfaceTable_
+#define _SC_SynthInterfaceTable_
+
+#include "SC_Types.h"
+#include "SC_SndBuf.h"
+#include "SC_Unit.h"
+#include "SC_BufGen.h"
+#include "SC_FifoMsg.h"
+#include <sndfile.h>
+
+struct World;
+
+typedef bool (*AsyncStageFn)(World *inWorld, void* cmdData);
+typedef void (*AsyncFreeFn)(World *inWorld, void* cmdData);
+
+struct InterfaceTable
+{
+ unsigned int mSineSize;
+ float32 *mSineWavetable;
+ float32 *mSine;
+ float32 *mCosecant;
+
+ // call printf for debugging. should not use in finished code.
+ int (*fPrint)(const char *fmt, ...);
+
+ // get a seed for a random number generator
+ int32 (*fRanSeed)();
+
+ // define a unit def
+ bool (*fDefineUnit)(char *inUnitClassName, size_t inAllocSize,
+ UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags);
+
+ // define a command /cmd
+ bool (*fDefinePlugInCmd)(char *inCmdName, PlugInCmdFunc inFunc, void* inUserData);
+
+ // define a command for a unit generator /u_cmd
+ bool (*fDefineUnitCmd)(char *inUnitClassName, char *inCmdName, UnitCmdFunc inFunc);
+
+ // define a buf gen
+ bool (*fDefineBufGen)(char *inName, BufGenFunc inFunc);
+
+ // clear all of the unit's outputs.
+ void (*fClearUnitOutputs)(Unit *inUnit, int inNumSamples);
+
+ // non real time memory allocation
+ void* (*fNRTAlloc)(size_t inSize);
+ void* (*fNRTRealloc)(void *inPtr, size_t inSize);
+ void (*fNRTFree)(void *inPtr);
+
+ // real time memory allocation
+ void* (*fRTAlloc)(World *inWorld, size_t inSize);
+ void* (*fRTRealloc)(World *inWorld, void *inPtr, size_t inSize);
+ void (*fRTFree)(World *inWorld, void *inPtr);
+
+ // call to set a Node to run or not.
+ void (*fNodeRun)(struct Node* node, int run);
+
+ // call to stop a Graph after the next buffer.
+ void (*fNodeEnd)(struct Node* graph);
+
+ // send a trigger from a Node to clients
+ void (*fSendTrigger)(struct Node* inNode, int triggerID, float value);
+
+ // sending messages between real time and non real time levels.
+ bool (*fSendMsgFromRT)(World *inWorld, struct FifoMsg& inMsg);
+ bool (*fSendMsgToRT)(World *inWorld, struct FifoMsg& inMsg);
+
+ // libsndfile support
+ int (*fSndFileFormatInfoFromStrings)(SF_INFO *info,
+ const char *headerFormatString, const char *sampleFormatString);
+
+ // get nodes by id
+ struct Node* (*fGetNode)(World *inWorld, int inID);
+ struct Graph* (*fGetGraph)(World *inWorld, int inID);
+
+ void (*fNRTLock)(World *inWorld);
+ void (*fNRTUnlock)(World *inWorld);
+
+ bool mAltivecAvailable;
+
+ void (*fGroup_DeleteAll)(struct Group* group);
+ void (*fDoneAction)(int doneAction, struct Unit *unit);
+
+ int (*fDoAsynchronousCommand)
+ (
+ World *inWorld,
+ void* replyAddr,
+ const char* cmdName,
+ void *cmdData,
+ AsyncStageFn stage2, // stage2 is non real time
+ AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true
+ AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true
+ AsyncFreeFn cleanup,
+ int completionMsgSize,
+ void* completionMsgData
+ );
+
+
+ // fBufAlloc should only be called within a BufGenFunc
+ int (*fBufAlloc)(SndBuf *inBuf, int inChannels, int inFrames, double inSampleRate);
+};
+typedef struct InterfaceTable InterfaceTable;
+
+#define Print (*ft->fPrint)
+#define RanSeed (*ft->fRanSeed)
+#define NodeEnd (*ft->fNodeEnd)
+#define NodeRun (*ft->fNodeRun)
+#define DefineUnit (*ft->fDefineUnit)
+#define DefinePlugInCmd (*ft->fDefinePlugInCmd)
+#define DefineUnitCmd (*ft->fDefineUnitCmd)
+#define DefineBufGen (*ft->fDefineBufGen)
+#define ClearUnitOutputs (*ft->fClearUnitOutputs)
+#define SendTrigger (*ft->fSendTrigger)
+#define SendMsgFromRT (*ft->fSendMsgFromRT)
+#define SendMsgToRT (*ft->fSendMsgToRT)
+#define DoneAction (*ft->fDoneAction)
+
+#define NRTAlloc (*ft->fNRTAlloc)
+#define NRTRealloc (*ft->fNRTRealloc)
+#define NRTFree (*ft->fNRTFree)
+
+#define RTAlloc (*ft->fRTAlloc)
+#define RTRealloc (*ft->fRTRealloc)
+#define RTFree (*ft->fRTFree)
+
+#define SC_GetNode (*ft->fGetNode)
+#define SC_GetGraph (*ft->fGetGraph)
+
+#define NRTLock (*ft->fNRTLock)
+#define NRTUnlock (*ft->fNRTUnlock)
+
+#define BufAlloc (*ft->fBufAlloc)
+
+#define GroupDeleteAll (*ft->fGroup_DeleteAll)
+
+#define SndFileFormatInfoFromStrings (*ft->fSndFileFormatInfoFromStrings)
+
+#define DoAsynchronousCommand (*ft->fDoAsynchronousCommand)
+
+#define DefineSimpleUnit(name) \
+ (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, 0, 0);
+
+#define DefineDtorUnit(name) \
+ (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, \
+ (UnitDtorFunc)&name##_Dtor, 0);
+
+#define DefineSimpleCantAliasUnit(name) \
+ (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, 0, kUnitDef_CantAliasInputsToOutputs);
+
+#define DefineDtorCantAliasUnit(name) \
+ (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, \
+ (UnitDtorFunc)&name##_Dtor, kUnitDef_CantAliasInputsToOutputs);
+
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_Node.h b/sc4pd/headers/plugin_interface/SC_Node.h
new file mode 100644
index 0000000..36dd412
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Node.h
@@ -0,0 +1,48 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Node_
+#define _SC_Node_
+
+#include "SC_Types.h"
+
+typedef void (*NodeCalcFunc)(struct Node *inNode);
+
+struct Node
+{
+ int32 mID;
+ int32 mHash;
+
+ struct World *mWorld;
+ struct NodeDef *mDef;
+ NodeCalcFunc mCalcFunc;
+
+ struct Node *mPrev, *mNext;
+ struct Group *mParent;
+
+ int32 mIsGroup;
+};
+typedef struct Node Node;
+
+enum { kNode_Go, kNode_End, kNode_On, kNode_Off, kNode_Move, kNode_Info };
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_PlugIn.h b/sc4pd/headers/plugin_interface/SC_PlugIn.h
new file mode 100644
index 0000000..4f01fd3
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_PlugIn.h
@@ -0,0 +1,53 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#include "SC_World.h"
+#include "SC_Graph.h"
+#include "SC_Unit.h"
+#include "SC_Wire.h"
+#include "SC_InterfaceTable.h"
+#include "Unroll.h"
+#include "SC_InlineUnaryOp.h"
+#include "SC_InlineBinaryOp.h"
+#include "SC_BoundsMacros.h"
+#include "SC_RGen.h"
+#include "SC_DemandUnit.h"
+#include "clz.h"
+#include "sc_msg_iter.h"
+#include "SC_Altivec.h"
+#include <stdlib.h>
+
+#ifdef SC_WIN32
+
+// temporarily override __attribute__ for (unused), later we'll remove it
+#ifndef __GCC__
+#define __attribute__(x)
+#endif
+
+// workaround for IN/OUT conflict with Win32 headers. see SC_Unit.h for details
+#define IN SC_IN
+#define OUT SC_OUT
+
+#ifdef _MSC_VER
+#include <xmath.h>
+#endif //_MSC_VER
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_RGen.h b/sc4pd/headers/plugin_interface/SC_RGen.h
new file mode 100644
index 0000000..11f8c9a
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_RGen.h
@@ -0,0 +1,288 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+//----------------------------------------------------------------------------//
+// Ran088: L'Ecuyer's 1996 three-component Tausworthe generator "taus88"
+//----------------------------------------------------------------------------//
+//
+// Returns an integer random number uniformly distributed within [0,4294967295]
+//
+// The period length is approximately 2^88 (which is 3*10^26).
+// This generator is very fast and passes all standard statistical tests.
+//
+// Reference:
+// (1) P. L'Ecuyer, Maximally equidistributed combined Tausworthe generators,
+// Mathematics of Computation, 65, 203-213 (1996), see Figure 4.
+// (2) recommended in:
+// P. L'Ecuyer, Random number generation, chapter 4 of the
+// Handbook on Simulation, Ed. Jerry Banks, Wiley, 1997.
+//
+//----------------------------------------------------------------------------//
+
+//----------------------------------------------------------------------------//
+// I chose this random number generator for the following reasons:
+// fast.
+// easier and faster to seed than other high quality rng's such as Mersenne Twister.
+// the internal state is only 12 bytes.
+// the period is long enough for music/audio.
+// possible to code in altivec in future if needed.
+// - James McCartney
+//----------------------------------------------------------------------------//
+
+#ifndef _SC_RGen_
+#define _SC_RGen_
+
+#include "SC_Endian.h"
+#include "SC_Types.h"
+#include "SC_BoundsMacros.h"
+#include "Hash.h"
+#include <math.h>
+
+struct RGen
+{
+ void init(uint32 seed);
+
+ uint32 trand();
+
+ int32 irand(int32 scale);
+ int32 irand2(int32 scale);
+ int32 ilinrand(int32 scale);
+ int32 ibilinrand(int32 scale);
+
+ float fcoin();
+ float frand();
+ float frand2();
+ float frand0();
+ float frand8();
+ double drand();
+ double drand2(double scale);
+ double linrand(double scale);
+ double bilinrand(double scale);
+ double exprandrng(double lo, double hi);
+ double exprand(double scale);
+ double biexprand(double scale);
+ double sum3rand(double scale);
+
+ uint32 s1, s2, s3; // random generator state
+};
+
+inline void RGen::init(uint32 seed)
+{
+ // humans tend to use small seeds - mess up the bits
+ seed = (uint32)Hash((int)seed);
+
+ // initialize seeds using the given seed value taking care of
+ // the requirements. The constants below are arbitrary otherwise
+ s1 = 1243598713U ^ seed; if (s1 < 2) s1 = 1243598713U;
+ s2 = 3093459404U ^ seed; if (s2 < 8) s2 = 3093459404U;
+ s3 = 1821928721U ^ seed; if (s3 < 16) s3 = 1821928721U;
+}
+
+inline uint32 trand( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // This function is provided for speed in inner loops where the
+ // state variables are loaded into registers.
+ // Thus updating the instance variables can
+ // be postponed until the end of the loop.
+ s1 = ((s1 & -2) << 12) ^ (((s1 << 13) ^ s1) >> 19);
+ s2 = ((s2 & -8) << 4) ^ (((s2 << 2) ^ s2) >> 25);
+ s3 = ((s3 & -16) << 17) ^ (((s3 << 3) ^ s3) >> 11);
+ return s1 ^ s2 ^ s3;
+}
+
+inline uint32 RGen::trand()
+{
+ // generate a random 32 bit number
+ s1 = ((s1 & -2) << 12) ^ (((s1 << 13) ^ s1) >> 19);
+ s2 = ((s2 & -8) << 4) ^ (((s2 << 2) ^ s2) >> 25);
+ s3 = ((s3 & -16) << 17) ^ (((s3 << 3) ^ s3) >> 11);
+ return s1 ^ s2 ^ s3;
+}
+
+inline double RGen::drand()
+{
+ // return a double from 0.0 to 0.999...
+#if BYTE_ORDER == BIG_ENDIAN
+ union { struct { uint32 hi, lo; } i; double f; } du;
+#else
+ union { struct { uint32 lo, hi; } i; double f; } du;
+#endif
+ du.i.hi = 0x41300000;
+ du.i.lo = trand();
+ return du.f - 1048576.;
+}
+
+inline float RGen::frand()
+{
+ // return a float from 0.0 to 0.999...
+ union { uint32 i; float f; } u; // union for floating point conversion of result
+ u.i = 0x3F800000 | (trand() >> 9);
+ return u.f - 1.f;
+}
+
+inline float RGen::frand0()
+{
+ // return a float from +1.0 to +1.999...
+ union { uint32 i; float f; } u; // union for floating point conversion of result
+ u.i = 0x3F800000 | (trand() >> 9);
+ return u.f;
+}
+
+inline float RGen::frand2()
+{
+ // return a float from -1.0 to +0.999...
+ union { uint32 i; float f; } u; // union for floating point conversion of result
+ u.i = 0x40000000 | (trand() >> 9);
+ return u.f - 3.f;
+}
+
+inline float RGen::frand8()
+{
+ // return a float from -0.125 to +0.124999...
+ union { uint32 i; float f; } u; // union for floating point conversion of result
+ u.i = 0x3E800000 | (trand() >> 9);
+ return u.f - 0.375f;
+}
+
+inline float RGen::fcoin()
+{
+ // only return one of the two values -1.0 or +1.0
+ union { uint32 i; float f; } u; // union for floating point conversion of result
+ u.i = 0x3F800000 | (0x80000000 & trand());
+ return u.f;
+}
+
+inline int32 RGen::irand(int32 scale)
+{
+ // return an int from 0 to scale - 1
+ return (int32)floor(scale * drand());
+}
+
+inline int32 RGen::irand2(int32 scale)
+{
+ // return a int from -scale to +scale
+ return (int32)floor((2. * scale + 1.) * drand() - scale);
+}
+
+inline int32 RGen::ilinrand(int32 scale)
+{
+ int32 a = irand(scale);
+ int32 b = irand(scale);
+ return sc_min(a,b);
+}
+
+inline double RGen::linrand(double scale)
+{
+ double a = drand();
+ double b = drand();
+ return sc_min(a,b) * scale;
+}
+
+inline int32 RGen::ibilinrand(int32 scale)
+{
+ int32 a = irand(scale);
+ int32 b = irand(scale);
+ return a - b;
+}
+
+inline double RGen::bilinrand(double scale)
+{
+ double a = drand();
+ double b = drand();
+ return (a - b) * scale;
+}
+
+inline double RGen::exprandrng(double lo, double hi)
+{
+ return lo * exp(log(hi / lo) * drand());
+}
+
+inline double RGen::exprand(double scale)
+{
+ double z;
+ while ((z = drand()) == 0.0) {}
+ return -log(z) * scale;
+}
+
+inline double RGen::biexprand(double scale)
+{
+ double z;
+ while ((z = drand2(1.)) == 0.0 || z == -1.0) {}
+ if (z > 0.0) z = log(z);
+ else z = -log(-z);
+ return z * scale;
+}
+
+inline double RGen::sum3rand(double scale)
+{
+ // larry polansky's poor man's gaussian generator
+ return (drand() + drand() + drand() - 1.5) * 0.666666667 * scale;
+}
+
+inline double drand( uint32& s1, uint32& s2, uint32& s3 )
+{
+ union { struct { uint32 hi, lo; } i; double f; } u;
+ u.i.hi = 0x41300000;
+ u.i.lo = trand(s1,s2,s3);
+ return u.f - 1048576.;
+}
+
+inline float frand( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // return a float from 0.0 to 0.999...
+ union { uint32 i; float f; } u;
+ u.i = 0x3F800000 | (trand(s1,s2,s3) >> 9);
+ return u.f - 1.f;
+}
+
+inline float frand0( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // return a float from +1.0 to +1.999...
+ union { uint32 i; float f; } u;
+ u.i = 0x3F800000 | (trand(s1,s2,s3) >> 9);
+ return u.f;
+}
+
+inline float frand2( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // return a float from -1.0 to +0.999...
+ union { uint32 i; float f; } u;
+ u.i = 0x40000000 | (trand(s1,s2,s3) >> 9);
+ return u.f - 3.f;
+}
+
+inline float frand8( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // return a float from -0.125 to +0.124999...
+ union { uint32 i; float f; } u;
+ u.i = 0x3E800000 | (trand(s1,s2,s3) >> 9);
+ return u.f - 0.375f;
+}
+
+inline float fcoin( uint32& s1, uint32& s2, uint32& s3 )
+{
+ // only return one of the two values -1.0 or +1.0
+ union { uint32 i; float f; } u;
+ u.i = 0x3F800000 | (0x80000000 & trand(s1,s2,s3));
+ return u.f;
+}
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_Rate.h b/sc4pd/headers/plugin_interface/SC_Rate.h
new file mode 100644
index 0000000..63c160d
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Rate.h
@@ -0,0 +1,42 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _Rate_
+#define _Rate_
+
+enum { calc_ScalarRate, calc_BufRate, calc_FullRate, calc_DemandRate };
+
+struct Rate
+{
+ double mSampleRate; // samples per second
+ double mSampleDur; // seconds per sample
+ double mBufDuration; // seconds per buffer
+ double mBufRate; // buffers per second
+ double mSlopeFactor; // 1. / NumSamples
+ double mRadiansPerSample; // 2pi / SampleRate
+ int mBufLength; // length of the buffer
+ // second order filter loops are often unrolled by 3
+ int mFilterLoops, mFilterRemain;
+ double mFilterSlope;
+};
+typedef struct Rate Rate;
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_SndBuf.h b/sc4pd/headers/plugin_interface/SC_SndBuf.h
new file mode 100644
index 0000000..affd2b9
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_SndBuf.h
@@ -0,0 +1,109 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SndBuf_
+#define _SndBuf_
+
+#include <sys/types.h>
+#include <sndfile.h>
+
+struct SndBuf
+{
+ double samplerate;
+ double sampledur; // = 1/ samplerate
+ float *data;
+ int channels;
+ int samples;
+ int frames;
+ int mask; // for delay lines
+ int mask1; // for interpolating oscillators.
+ int coord; // used by fft ugens
+ SNDFILE *sndfile; // used by disk i/o
+};
+typedef struct SndBuf SndBuf;
+
+struct SndBufUpdates
+{
+ int reads;
+ int writes;
+};
+typedef struct SndBufUpdates SndBufUpdates;
+
+enum { coord_None, coord_Complex, coord_Polar };
+
+
+inline float PhaseFrac(unsigned long inPhase)
+ {
+ union { unsigned long itemp; float ftemp; } u;
+ u.itemp = 0x3F800000 | (0x007FFF80 & ((inPhase)<<7));
+ return u.ftemp - 1.f;
+ }
+
+inline float PhaseFrac1(unsigned long inPhase)
+ {
+ union { unsigned long itemp; float ftemp; } u;
+ u.itemp = 0x3F800000 | (0x007FFF80 & ((inPhase)<<7));
+ return u.ftemp;
+ }
+
+inline float lookup(float *table, int32 phase, int32 mask)
+{
+ return table[(phase >> 16) & mask];
+}
+
+
+#define xlobits 14
+#define xlobits1 13
+
+inline float lookupi(float *table, uint32 phase, uint32 mask)
+{
+ float frac = PhaseFrac(phase);
+ float *tbl = table + ((phase >> 16) & mask);
+ float a = tbl[0];
+ float b = tbl[1];
+ return a + frac * (b - a);
+}
+
+inline float lookupi2(float *table, uint32 phase, uint32 mask)
+{
+ float frac = PhaseFrac1(phase);
+ float *tbl = table + ((phase >> 16) & mask);
+ float a = tbl[0];
+ float b = tbl[1];
+ return a + frac * b;
+}
+
+inline float lookupi1(float* table0, float* table1, uint32 pphase, int32 lomask)
+{
+ float pfrac = PhaseFrac1(pphase);
+ uint32 index = ((pphase >> xlobits1) & lomask);
+ float val1 = *(float*)((char*)table0 + index);
+ float val2 = *(float*)((char*)table1 + index);
+ return val1 + val2 * pfrac;
+}
+
+
+inline float lininterp(float x, float a, float b)
+{
+ return a + x * (b - a);
+}
+
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_Types.h b/sc4pd/headers/plugin_interface/SC_Types.h
new file mode 100644
index 0000000..d635b07
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Types.h
@@ -0,0 +1,67 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_Types_
+#define _SC_Types_
+
+#include <sys/types.h>
+
+typedef int SCErr;
+
+#ifdef SC_WIN32
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+typedef long long int64;
+typedef unsigned long long uint64;
+#endif
+
+typedef int int32;
+typedef unsigned int uint32;
+#ifdef SC_DARWIN
+typedef unsigned int ulong;
+#endif
+
+typedef short int16;
+typedef unsigned short uint16;
+
+typedef signed char int8;
+typedef unsigned char uint8;
+
+typedef float float32;
+typedef double float64;
+
+typedef union {
+ uint32 u;
+ int32 i;
+ float32 f;
+} elem32;
+
+typedef union {
+ uint64 u;
+ int64 i;
+ float64 f;
+} elem64;
+
+const unsigned int kSCNameLen = 8;
+const unsigned int kSCNameByteLen = kSCNameLen * sizeof(int32);
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/SC_Unit.h b/sc4pd/headers/plugin_interface/SC_Unit.h
new file mode 100644
index 0000000..2ded017
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Unit.h
@@ -0,0 +1,101 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Unit_
+#define _SC_Unit_
+
+#include "SC_Types.h"
+
+typedef void (*UnitCtorFunc)(struct Unit* inUnit);
+typedef void (*UnitDtorFunc)(struct Unit* inUnit);
+
+typedef void (*UnitCalcFunc)(struct Unit *inThing, int inNumSamples);
+
+struct Unit
+{
+ struct World *mWorld;
+ struct UnitDef *mUnitDef;
+ struct Graph *mParent;
+ uint16 mNumInputs, mNumOutputs;
+ int16 mCalcRate;
+ int16 mSpecialIndex; // used by unary and binary ops
+ int16 mParentIndex;
+ int16 mDone;
+
+ struct Wire **mInput, **mOutput;
+ struct Rate *mRate;
+ struct SC_Dimension *mDimension;
+ float **mInBuf, **mOutBuf;
+
+ UnitCalcFunc mCalcFunc;
+ int mBufLength;
+};
+typedef struct Unit Unit;
+
+enum {
+ kUnitDef_CantAliasInputsToOutputs = 1
+};
+
+// easy macros, the unit variable must be named 'unit'.
+#ifndef SC_WIN32
+
+// These return float* pointers to input and output buffers.
+#define IN(index) (unit->mInBuf[index])
+#define OUT(index) (unit->mOutBuf[index])
+
+// These return a float value. Used for control rate inputs and outputs.
+#define IN0(index) (IN(index)[0])
+#define OUT0(index) (OUT(index)[0])
+
+#else
+
+// Win32 headers (included by C std library headers) define IN and OUT macros
+// for their own purposes. To avoid problems we don't define IN and OUT here
+// but define SC_IN and SC_OUT instead. Source files that use IN and OUT need
+// to include definitions of IN, and OUT referencing SC_IN and SC_OUT after
+// all headers have been included.
+#define SC_IN(index) (unit->mInBuf[index])
+#define SC_OUT(index) (unit->mOutBuf[index])
+#define IN0(index) (SC_IN(index)[0])
+#define OUT0(index) (SC_OUT(index)[0])
+
+#endif
+
+// get the rate of the input.
+#define INRATE(index) (unit->mInput[index]->mCalcRate)
+
+// set the calculation function
+#define SETCALC(func) (unit->mCalcFunc = (UnitCalcFunc)&func)
+
+// calculate a slope for control rate interpolation to audio rate.
+#define CALCSLOPE(next,prev) ((next - prev) * unit->mRate->mSlopeFactor)
+
+// get useful values
+#define SAMPLERATE (unit->mRate->mSampleRate)
+#define SAMPLEDUR (unit->mRate->mSampleDur)
+#define BUFLENGTH (unit->mBufLength)
+#define BUFRATE (unit->mRate->mBufRate)
+#define BUFDUR (unit->mRate->mBufDuration)
+
+typedef void (*UnitCmdFunc)(struct Unit *unit, struct sc_msg_iter *args);
+typedef void (*PlugInCmdFunc)(World *inWorld, void* inUserData, struct sc_msg_iter *args, void *replyAddr);
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_Wire.h b/sc4pd/headers/plugin_interface/SC_Wire.h
new file mode 100644
index 0000000..f2680ac
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_Wire.h
@@ -0,0 +1,36 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Wire_
+#define _SC_Wire_
+
+#include "SC_Types.h"
+
+struct Wire
+{
+ struct Unit *mFromUnit;
+ int32 mCalcRate;
+ float32 *mBuffer;
+ float32 mScalarValue;
+};
+typedef struct Wire Wire;
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_World.h b/sc4pd/headers/plugin_interface/SC_World.h
new file mode 100644
index 0000000..8586432
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_World.h
@@ -0,0 +1,105 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_World_
+#define _SC_World_
+
+#include "SC_Types.h"
+#include "SC_Rate.h"
+#include "SC_SndBuf.h"
+#include "SC_RGen.h"
+#include "SC_Lock.h"
+
+struct World
+{
+ // a pointer to private implementation, not available to plug-ins.
+ struct HiddenWorld *hw;
+
+ // a pointer to the table of function pointers that implement the plug-ins'
+ // interface to the server.
+ struct InterfaceTable *ft;
+
+ // data accessible to plug-ins :
+ double mSampleRate;
+ int mBufLength;
+ int mBufCounter;
+
+ uint32 mNumAudioBusChannels;
+ uint32 mNumControlBusChannels;
+ uint32 mNumInputs;
+ uint32 mNumOutputs;
+
+ // vector of samples for all audio busses
+ float *mAudioBus;
+
+ // vector of samples for all control busses
+ float *mControlBus;
+
+ // these tell if a buss has been written to during a control period
+ // if the value is equal to mBufCounter then the buss has been touched
+ // this control period.
+ int32 *mAudioBusTouched;
+ int32 *mControlBusTouched;
+
+ uint32 mNumSndBufs;
+ SndBuf *mSndBufs;
+ SndBuf *mSndBufsNonRealTimeMirror;
+ SndBufUpdates *mSndBufUpdates;
+
+ struct Group *mTopGroup;
+
+ Rate mFullRate, mBufRate;
+
+ uint32 mNumRGens;
+ RGen *mRGen;
+
+ uint32 mNumUnits, mNumGraphs, mNumGroups;
+ int mSampleOffset; // offset in the buffer of current event time.
+
+ SC_Lock* mNRTLock;
+
+ uint32 mNumSharedControls;
+ float *mSharedControls;
+
+ bool mRealTime;
+ bool mRunning;
+ int mDumpOSC;
+};
+
+extern "C" {
+ int scprintf(const char *fmt, ...);
+}
+
+inline SndBuf* World_GetBuf(struct World *inWorld, uint32 index)
+{
+ if (index > inWorld->mNumSndBufs) index = 0;
+ return inWorld->mSndBufs + index;
+}
+
+inline SndBuf* World_GetNRTBuf(struct World *inWorld, uint32 index)
+{
+ if (index > inWorld->mNumSndBufs) index = 0;
+ return inWorld->mSndBufsNonRealTimeMirror + index;
+}
+
+typedef void (*LoadPlugInFunc)(struct InterfaceTable *);
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/SC_WorldOptions.h b/sc4pd/headers/plugin_interface/SC_WorldOptions.h
new file mode 100644
index 0000000..b04850f
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/SC_WorldOptions.h
@@ -0,0 +1,91 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_WorldOptions_
+#define _SC_WorldOptions_
+
+#include <stdarg.h>
+#include "SC_Types.h"
+
+typedef int (*PrintFunc)(const char *format, va_list ap);
+
+struct WorldOptions
+{
+ const char* mPassword;
+ uint32 mNumBuffers;
+ uint32 mMaxLogins;
+ uint32 mMaxNodes;
+ uint32 mMaxGraphDefs;
+ uint32 mMaxWireBufs;
+ uint32 mNumAudioBusChannels;
+ uint32 mNumInputBusChannels;
+ uint32 mNumOutputBusChannels;
+ uint32 mNumControlBusChannels;
+ uint32 mBufLength;
+ uint32 mRealTimeMemorySize;
+
+ int mNumSharedControls;
+ float *mSharedControls;
+
+ bool mRealTime;
+
+ const char *mNonRealTimeCmdFilename;
+ const char *mNonRealTimeInputFilename;
+ const char *mNonRealTimeOutputFilename;
+ const char *mNonRealTimeOutputHeaderFormat;
+ const char *mNonRealTimeOutputSampleFormat;
+
+ uint32 mPreferredSampleRate;
+ uint32 mNumRGens;
+
+ uint32 mPreferredHardwareBufferFrameSize;
+
+ uint32 mLoadGraphDefs;
+
+#ifdef SC_DARWIN
+ const char *mInputStreamsEnabled;
+ const char *mOutputStreamsEnabled;
+#endif
+};
+
+const WorldOptions kDefaultWorldOptions =
+{
+ 0,1024,64,1024,1024,64,128,8,8,4096,64,8192, 0,0, 1, 0,0,0,0,0, 0, 64, 0, 1
+#ifdef SC_DARWIN
+ ,0,0
+#endif
+};
+
+#include "SC_Reply.h"
+
+extern "C" {
+ void SetPrintFunc(PrintFunc func);
+ struct World* World_New(WorldOptions *inOptions);
+ void World_OpenUDP(struct World *inWorld, int inPort);
+ void World_OpenTCP(struct World *inWorld, int inPort, int inMaxConnections, int inBacklog);
+ void World_WaitForQuit(struct World *inWorld);
+ bool World_SendPacket(struct World *inWorld, int inSize, char *inData, ReplyFunc inFunc);
+ int World_CopySndBuf(World *world, uint32 index, struct SndBuf *outBuf, bool onlyIfChanged, bool &didChange);
+ int scprintf(const char *fmt, ...);
+}
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/Unroll.h b/sc4pd/headers/plugin_interface/Unroll.h
new file mode 100644
index 0000000..12ae864
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/Unroll.h
@@ -0,0 +1,249 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+
+These macros allow one to write code which can be compiled optimally depending on
+what loop constructs the compiler can best generate code.
+
+*/
+
+#ifndef _Unroll_
+#define _Unroll_
+
+#if 1
+
+// loop type
+#define FOR_IS_FASTER 1
+#define WHILE_IS_FASTER 0
+// indexing type
+#define PREINCREMENT_IS_FASTER 1
+#define POSTINCREMENT_IS_FASTER 0
+
+#else
+
+// loop type
+#define FOR_IS_FASTER 1
+#define WHILE_IS_FASTER 0
+// indexing type
+#define PREINCREMENT_IS_FASTER 0
+#define POSTINCREMENT_IS_FASTER 1
+
+#endif
+
+
+// LOOPING MACROS :
+
+#if FOR_IS_FASTER
+
+#define LOOP(length, stmt) for (int xxi=0; xxi<(length); ++xxi) { stmt; }
+
+#elif WHILE_IS_FASTER
+
+#define LOOP(length, stmt) \
+ { int xxn = (length); \
+ while (--xxn) { \
+ stmt; \
+ } \
+ }
+
+#endif
+
+
+
+// above macros are not friendly to the debugger
+#if FOR_IS_FASTER
+
+#define LooP(length) for (int xxi=0; xxi<(length); ++xxi)
+
+#elif WHILE_IS_FASTER
+
+#define LooP(length) for (int xxi=(length); --xxi;)
+
+#endif
+
+
+// LOOP INDEXING :
+
+/*
+meanings of the indexing macros:
+ ZXP = dereference and pre or post increment
+ ZX = dereference
+ PZ = preincrement (if applicable)
+ ZP = postincrement (if applicable)
+ ZOFF = offset from the pointer of the first element of the array
+ (preincrement requires a ZOFF of 1 which is pre-subtracted from the
+ base pointer. For other indexing types ZOFF is zero)
+*/
+
+#if PREINCREMENT_IS_FASTER
+#define ZXP(z) (*++(z))
+#define ZX(z) (*(z))
+#define PZ(z) (++(z))
+#define ZP(z) (z)
+#define ZOFF (1)
+#elif POSTINCREMENT_IS_FASTER
+#define ZXP(z) (*(z)++)
+#define ZX(z) (*(z))
+#define PZ(z) (z)
+#define ZP(z) ((z)++)
+#define ZOFF (0)
+#endif
+
+// ACCESSING INLETS AND OUTLETS :
+
+// unit inputs
+#define ZIN(i) (IN(i) - ZOFF) // get buffer pointer offset for iteration
+#define ZIN0(i) (IN(i)[0]) // get first sample
+
+// unit outputs
+#define ZOUT(i) (OUT(i) - ZOFF) // get buffer pointer offset for iteration
+#define ZOUT0(i) (OUT(i)[0]) // get first sample
+
+#include "SC_BoundsMacros.h"
+
+#ifndef NDEBUG
+# define NDEBUG
+#endif
+#include <assert.h>
+
+inline void Clear(int numSamples, float *out)
+{
+ //assert((((long)(out+ZOFF) & 7) == 0)); // pointer must be 8 byte aligned
+
+ if ((numSamples & 1) == 0) {
+ // copying doubles is faster on powerpc.
+ double *outd = (double*)out - ZOFF;
+ LOOP(numSamples >> 1, ZXP(outd) = 0.; );
+ } else {
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = 0.f; );
+ }
+}
+
+inline void Copy(int numSamples, float *out, float *in)
+{
+ // pointers must be 8 byte aligned
+ //assert((((long)(out+ZOFF) & 7) == 0) && (((long)(in+ZOFF) & 7) == 0));
+ if (in == out) return;
+ if ((numSamples & 1) == 0) {
+ // copying doubles is faster on powerpc.
+ double *outd = (double*)out - ZOFF;
+ double *ind = (double*)in - ZOFF;
+ LOOP(numSamples >> 1, ZXP(outd) = ZXP(ind); );
+ } else {
+ in -= ZOFF;
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = ZXP(in); );
+ }
+}
+
+inline void Fill(int numSamples, float *out, float level)
+{
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = level; );
+}
+
+inline void Fill(int numSamples, float *out, float level, float slope)
+{
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = level; level += slope; );
+}
+
+inline void Accum(int numSamples, float *out, float *in)
+{
+ in -= ZOFF;
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) += ZXP(in); );
+}
+
+inline void Scale(int numSamples, float *out, float level)
+{
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) *= level;);
+}
+
+inline float Scale(int numSamples, float *out, float level, float slope)
+{
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) *= level; level += slope;);
+ return level;
+}
+
+inline float Scale(int numSamples, float *out, float *in, float level, float slope)
+{
+ in -= ZOFF;
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = ZXP(in) * level; level += slope;);
+ return level;
+}
+
+inline float ScaleMix(int numSamples, float *out, float *in, float level, float slope)
+{
+ in -= ZOFF;
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) += ZXP(in) * level; level += slope;);
+ return level;
+}
+
+inline void Scale(int numSamples, float *out, float *in, float level)
+{
+ in -= ZOFF;
+ out -= ZOFF;
+ LOOP(numSamples, ZXP(out) = ZXP(in) * level; );
+}
+
+// in these the pointers are assumed to already have been pre-offset.
+inline void ZCopy(int numSamples, float *out, float *in)
+{
+ // pointers must be 8 byte aligned
+ //assert((((long)(out+ZOFF) & 7) == 0) && (((long)(in+ZOFF) & 7) == 0));
+ if (in == out) return;
+ if ((numSamples & 1) == 0) {
+ // copying doubles is faster on powerpc.
+ double *outd = (double*)(out + ZOFF) - ZOFF;
+ double *ind = (double*)(in + ZOFF) - ZOFF;
+ LOOP(numSamples >> 1, ZXP(outd) = ZXP(ind); );
+ } else {
+ LOOP(numSamples, ZXP(out) = ZXP(in); );
+ }
+}
+
+inline void ZClear(int numSamples, float *out)
+{
+ // pointers must be 8 byte aligned
+ //assert((((long)(out+ZOFF) & 7) == 0) && (((long)(in+ZOFF) & 7) == 0));
+ if ((numSamples & 1) == 0) {
+ // copying doubles is faster on powerpc.
+ double *outd = (double*)(out + ZOFF) - ZOFF;
+ LOOP(numSamples >> 1, ZXP(outd) = 0.; );
+ } else {
+ LOOP(numSamples, ZXP(out) = 0.f; );
+ }
+}
+
+inline void ZAccum(int numSamples, float *out, float *in)
+{
+ LOOP(numSamples, ZXP(out) += ZXP(in); );
+}
+
+
+
+#endif
diff --git a/sc4pd/headers/plugin_interface/clz.h b/sc4pd/headers/plugin_interface/clz.h
new file mode 100644
index 0000000..f205c02
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/clz.h
@@ -0,0 +1,195 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+count leading zeroes function and those that can be derived from it
+
+*/
+
+
+#ifndef _CLZ_
+#define _CLZ_
+
+#include "SC_Types.h"
+
+#ifdef __MWERKS__
+
+#define __PPC__ 1
+#define __X86__ 0
+
+// powerpc native count leading zeroes instruction:
+#define CLZ(x) ((int)__cntlzw((unsigned int)x))
+
+#elif defined(SC_WIN32) && !defined(__GCC__)
+
+static int32 CLZ( int32 arg )
+{
+ __asm{
+ bsr eax, arg
+ jnz non_zero
+ mov arg, 32
+ jmp end
+non_zero:
+ xor eax, 31
+ mov arg, eax
+end:
+ }
+ return arg;
+}
+
+#elif defined(__ppc__) || defined(__powerpc__) || defined(__PPC__)
+
+static __inline__ int32 CLZ(int32 arg) {
+ __asm__ volatile("cntlzw %0, %1" : "=r" (arg) : "r" (arg));
+ return arg;
+}
+
+#elif defined(__i386__) || defined(__x86_64__)
+static __inline__ int32 CLZ(int32 arg) {
+ if (arg) {
+ __asm__ volatile("bsrl %0, %0\nxorl $31, %0\n"
+ : "=r" (arg) : "0" (arg));
+ } else {
+ arg = 32;
+ }
+ return arg;
+}
+
+#else
+# error "clz.h: Unsupported architecture"
+#endif
+
+// count trailing zeroes
+inline int32 CTZ(int32 x)
+{
+ return 32 - CLZ(~x & (x-1));
+}
+
+// count leading ones
+inline int32 CLO(int32 x)
+{
+ return CLZ(~x);
+}
+
+// count trailing ones
+inline int32 CTO(int32 x)
+{
+ return 32 - CLZ(x & (~x-1));
+}
+
+// number of bits required to represent x.
+inline int32 NUMBITS(int32 x)
+{
+ return 32 - CLZ(x);
+}
+
+// log2 of the next power of two greater than or equal to x.
+inline int32 LOG2CEIL(int32 x)
+{
+ return 32 - CLZ(x - 1);
+}
+
+// next power of two greater than or equal to x
+inline int32 NEXTPOWEROFTWO(int32 x)
+{
+ return 1L << LOG2CEIL(x);
+}
+
+// is x a power of two
+inline bool ISPOWEROFTWO(int32 x)
+{
+ return (x & (x-1)) == 0;
+}
+
+// input a series of counting integers, outputs a series of gray codes .
+inline int32 GRAYCODE(int32 x)
+{
+ return x & (x>>1);
+}
+
+// find least significant bit
+inline int32 LSBit(int32 x)
+{
+ return x & -x;
+}
+
+// find least significant bit position
+inline int32 LSBitPos(int32 x)
+{
+ return CTZ(x & -x);
+}
+
+// find most significant bit position
+inline int32 MSBitPos(int32 x)
+{
+ return 31 - CLZ(x);
+}
+
+// find most significant bit
+inline int32 MSBit(int32 x)
+{
+ return 1L << MSBitPos(x);
+}
+
+// count number of one bits
+inline uint32 ONES(uint32 x)
+{
+ uint32 t;
+ x = x - ((x >> 1) & 0x55555555);
+ t = ((x >> 2) & 0x33333333);
+ x = (x & 0x33333333) + t;
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ x = x + (x << 8);
+ x = x + (x << 16);
+ return x >> 24;
+}
+
+// count number of zero bits
+inline uint32 ZEROES(uint32 x)
+{
+ return ONES(~x);
+}
+
+
+// reverse bits in a word
+inline uint32 BitReverse(uint32 x)
+{
+ x = ((x & 0xAAAAAAAA) >> 1) | ((x & 0x55555555) << 1);
+ x = ((x & 0xCCCCCCCC) >> 2) | ((x & 0x33333333) << 2);
+ x = ((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4);
+ x = ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8);
+ return (x >> 16) | (x << 16);
+}
+
+// barrel shifts
+inline uint32 RotateRight (uint32 x, uint32 s)
+{
+ s = s & 31;
+ return (x << (32-s)) | (x >> s);
+}
+
+inline uint32 RotateLeft (uint32 x, uint32 s)
+{
+ s = s & 31;
+ return (x >> (32-s)) | (x << s);
+}
+
+#endif
+
diff --git a/sc4pd/headers/plugin_interface/sc_msg_iter.h b/sc4pd/headers/plugin_interface/sc_msg_iter.h
new file mode 100644
index 0000000..240a30f
--- /dev/null
+++ b/sc4pd/headers/plugin_interface/sc_msg_iter.h
@@ -0,0 +1,264 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _sc_msg_iter_
+#define _sc_msg_iter_
+
+#include "SC_Endian.h"
+#include "SC_Types.h"
+#include <string.h>
+
+// return the ptr to the byte after the OSC string.
+inline char* OSCstrskip(char *str)
+{
+// while (str[3]) { str += 4; }
+// return str + 4;
+ do { str += 4; } while (str[-1]);
+ return str;
+}
+
+// returns the number of bytes (including padding) for an OSC string.
+inline int OSCstrlen(char *strin)
+{
+ return OSCstrskip(strin) - strin;
+}
+
+// returns a float, converting an int if necessary
+inline float32 OSCfloat(char* inData)
+{
+ elem32* elem = (elem32*)inData;
+ elem->u = ntohl(elem->u);
+ return elem->f;
+}
+
+inline int32 OSCint(char* inData)
+{
+ return (int32)ntohl(*(uint32*)inData);
+}
+
+inline int64 OSCtime(char* inData)
+{
+ return ((int64)ntohl(*(uint32*)inData) << 32) + (ntohl(*(uint32*)(inData + 4)));
+}
+
+inline float64 OSCdouble(char* inData)
+{
+ elem64 slot;
+ slot.i = ((int64)ntohl(*(uint32*)inData) << 32) + (ntohl(*(uint32*)(inData + 4)));
+ return slot.f;
+}
+
+struct sc_msg_iter
+{
+ char *data, *rdpos, *endpos, *tags;
+ int size, count;
+
+ sc_msg_iter();
+ sc_msg_iter(int inSize, char* inData);
+ void init(int inSize, char* inData);
+ int32 geti(int32 defaultValue = 0);
+ float32 getf(float32 defaultValue = 0.f);
+ float64 getd(float64 defaultValue = 0.f);
+ char *gets(char* defaultValue = 0);
+ int32 *gets4(char* defaultValue = 0);
+ size_t getbsize();
+ void getb(char* outData, size_t inSize);
+ void skipb();
+ int remain() { return endpos - rdpos; }
+
+ char nextTag(char defaultTag = 'f') { return tags ? tags[count] : defaultTag; }
+};
+
+inline sc_msg_iter::sc_msg_iter()
+{
+}
+
+inline sc_msg_iter::sc_msg_iter(int inSize, char* inData)
+{
+ init(inSize, inData);
+}
+
+inline void sc_msg_iter::init(int inSize, char* inData)
+{
+ data = inData;
+ size = inSize;
+ endpos = data + size;
+ count = 0;
+ if (data[0] == ',') {
+ tags = data+1;
+ rdpos = OSCstrskip(data);
+ } else {
+ tags = 0;
+ rdpos = data;
+ }
+}
+
+inline int32 sc_msg_iter::geti(int32 defaultValue)
+{
+ int value;
+ if (remain() <= 0) return defaultValue;
+ if (tags) {
+ if (tags[count] == 'i') {
+ value = OSCint(rdpos);
+ rdpos += sizeof(int32);
+ } else if (tags[count] == 'f') {
+ value = (int32)OSCfloat(rdpos);
+ rdpos += sizeof(float32);
+/* } else if (tags[count] == 's') {
+ value = atoi(rdpos);
+ rdpos = OSCstrskip(rdpos);
+*/
+ } else {
+ value = defaultValue;
+ }
+ } else {
+ value = (int)OSCint(rdpos);
+ rdpos += sizeof(int32);
+ }
+ count ++;
+ return value;
+}
+
+inline float32 sc_msg_iter::getf(float32 defaultValue)
+{
+ float32 value;
+ if (remain() <= 0) return defaultValue;
+ if (tags) {
+ if (tags[count] == 'f') {
+ value = OSCfloat(rdpos);
+ rdpos += sizeof(float32);
+ } else if (tags[count] == 'd') {
+ value = (float64)OSCdouble(rdpos);
+ rdpos += sizeof(float64);
+ } else if (tags[count] == 'i') {
+ value = (float32)OSCint(rdpos);
+ rdpos += sizeof(int32);
+/* } else if (tags[count] == 's') {
+ value = atof(rdpos);
+ rdpos = OSCstrskip(rdpos);
+*/
+ } else {
+ value = defaultValue;
+ }
+ } else {
+ value = OSCfloat(rdpos);
+ rdpos += sizeof(float32);
+ }
+ count ++;
+ return value;
+}
+
+inline float64 sc_msg_iter::getd(float64 defaultValue)
+{
+ float64 value;
+ if (remain() <= 0) return defaultValue;
+ if (tags) {
+ if (tags[count] == 'f') {
+ value = (float64)OSCfloat(rdpos);
+ rdpos += sizeof(float32);
+ } else if (tags[count] == 'd') {
+ value = OSCdouble(rdpos);
+ rdpos += sizeof(float64);
+ } else if (tags[count] == 'i') {
+ value = (float64)OSCint(rdpos);
+ rdpos += sizeof(int32);
+/* } else if (tags[count] == 's') {
+ value = atof(rdpos);
+ rdpos = OSCstrskip(rdpos);
+*/
+ } else {
+ value = defaultValue;
+ }
+ } else {
+ value = OSCdouble(rdpos);
+ rdpos += sizeof(float64);
+ }
+ count ++;
+ return value;
+}
+
+
+inline char* sc_msg_iter::gets(char* defaultValue)
+{
+ char* value;
+ if (remain() <= 0) return 0;
+ if (tags) {
+ if (tags[count] == 's') {
+ value = rdpos;
+ rdpos = OSCstrskip(rdpos);
+ } else {
+ value = defaultValue;
+ }
+ } else {
+ value = rdpos;
+ rdpos = OSCstrskip(rdpos);
+ }
+ count ++;
+ return value;
+}
+
+inline int32* sc_msg_iter::gets4(char* defaultValue)
+{
+ int32* value;
+ if (remain() <= 0) return 0;
+ if (tags) {
+ if (tags[count] == 's') {
+ value = (int32*)rdpos;
+ rdpos = OSCstrskip(rdpos);
+ } else {
+ value = (int32*)defaultValue;
+ }
+ } else {
+ value = (int32*)rdpos;
+ rdpos = OSCstrskip(rdpos);
+ }
+ count ++;
+ return value;
+}
+
+inline size_t sc_msg_iter::getbsize()
+{
+ if (remain() <= 0) return 0;
+ if (tags && tags[count] != 'b') return 0;
+ return (size_t)OSCint(rdpos);
+}
+
+inline void sc_msg_iter::getb(char* outArray, size_t size)
+{
+ size_t len = OSCint(rdpos);
+ if (size < len) return;
+ rdpos += sizeof(int32);
+ size_t len4 = (len + 3) & -4;
+ memcpy(outArray, rdpos, size);
+ rdpos += len4;
+ count ++;
+}
+
+inline void sc_msg_iter::skipb()
+{
+ size_t len = OSCint(rdpos);
+ rdpos += sizeof(int32);
+ size_t len4 = (len + 3) & -4;
+ rdpos += len4;
+ count ++;
+}
+
+#endif