From d0ae3caca5828675335d3b19ab5dd987e7369b23 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Wed, 14 Jul 2004 16:21:44 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r1857, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/tb/; revision=1858 --- sc4pd/headers/plugin_interface/Unroll.h | 249 ++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 sc4pd/headers/plugin_interface/Unroll.h (limited to 'sc4pd/headers/plugin_interface/Unroll.h') 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 + +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 -- cgit v1.2.1