X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/c7f552fd8888da2f0d8cfb228fe0f28d3df3a12c..b4b6f2ea75b9f0f3ca918f5b84016610bf7a4d4f:/interpretor/faust-0.9.47mr3/architecture/supercollider.cpp diff --git a/interpretor/faust-0.9.47mr3/architecture/supercollider.cpp b/interpretor/faust-0.9.47mr3/architecture/supercollider.cpp deleted file mode 100644 index 2f1f0a0..0000000 --- a/interpretor/faust-0.9.47mr3/architecture/supercollider.cpp +++ /dev/null @@ -1,640 +0,0 @@ -// If other than 'faust2sc --prefix Faust' is used, sed this as well: -#define SC_FAUST_PREFIX "Faust" - -//------------------------------------------------------------------- -// FAUST architecture file for SuperCollider. -// Copyright (C) 2005-2008 Stefan Kersten. -// -// 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 -#include -#include -#include -#include -#include - -#if defined(__GNUC__) && __GNUC__ >= 4 -# define FAUST_EXPORT __attribute__((visibility("default"))) -#else -# define FAUST_EXPORT /* NOP */ -#endif - -//------------------------------------------------------------------- -// Generic min and max using C++ inline -//------------------------------------------------------------------- - -inline int max (unsigned int a, unsigned int b) { return (a>b) ? a : b; } -inline int max (int a, int b) { return (a>b) ? a : b; } - -inline long max (long a, long b) { return (a>b) ? a : b; } -inline long max (int a, long b) { return (a>b) ? a : b; } -inline long max (long a, int b) { return (a>b) ? a : b; } - -inline float max (float a, float b) { return (a>b) ? a : b; } -inline float max (int a, float b) { return (a>b) ? a : b; } -inline float max (float a, int b) { return (a>b) ? a : b; } -inline float max (long a, float b) { return (a>b) ? a : b; } -inline float max (float a, long b) { return (a>b) ? a : b; } - -inline double max (double a, double b) { return (a>b) ? a : b; } -inline double max (int a, double b) { return (a>b) ? a : b; } -inline double max (double a, int b) { return (a>b) ? a : b; } -inline double max (long a, double b) { return (a>b) ? a : b; } -inline double max (double a, long b) { return (a>b) ? a : b; } -inline double max (float a, double b) { return (a>b) ? a : b; } -inline double max (double a, float b) { return (a>b) ? a : b; } - - -inline int min (int a, int b) { return (a> n); } -inline int int2pow2 (int x) { int r=0; while ((1<> - -/****************************************************************************** -******************************************************************************* - - META DATA - -******************************************************************************* -*******************************************************************************/ - -struct Meta : std::map -{ - void declare(const char* key, const char* value) - { - (*this)[key] = value; - } -}; - -/****************************************************************************** -******************************************************************************* - - GRAPHIC USER INTERFACE - -******************************************************************************* -*******************************************************************************/ - -//---------------------------------------------------------------------------- -// Abstract user interface -//---------------------------------------------------------------------------- - -class UI -{ -public: - virtual ~UI() { } - - // active widgets - virtual void addButton(const char* label, float* zone) = 0; - virtual void addToggleButton(const char* label, float* zone) = 0; - virtual void addCheckButton(const char* label, float* zone) = 0; - virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0; - virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0; - virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0; - - // passive widgets - virtual void addNumDisplay(const char* label, float* zone, int precision) = 0; - virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0; - virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0; - virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0; - - // layout widgets - virtual void openFrameBox(const char* label) = 0; - virtual void openTabBox(const char* label) = 0; - virtual void openHorizontalBox(const char* label) = 0; - virtual void openVerticalBox(const char* label) = 0; - virtual void closeBox() = 0; - - virtual void declare(float* zone, const char* key, const char* value) {} -}; - -//---------------------------------------------------------------------------- -// Control counter -//---------------------------------------------------------------------------- - -class ControlCounter : public UI -{ -public: - ControlCounter() - : mNumControlInputs(0), - mNumControlOutputs(0) - { } - - size_t getNumControls() const { return getNumControlInputs(); } - size_t getNumControlInputs() const { return mNumControlInputs; } - size_t getNumControlOutputs() const { return mNumControlOutputs; } - - // active widgets - virtual void addButton(const char* label, float* zone) - { addControlInput(); } - virtual void addToggleButton(const char* label, float* zone) - { addControlInput(); } - virtual void addCheckButton(const char* label, float* zone) - { addControlInput(); } - virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) - { addControlInput(); } - virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) - { addControlInput(); } - virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) - { addControlInput(); } - - // passive widgets - virtual void addNumDisplay(const char* label, float* zone, int precision) { addControlOutput(); } - virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) { addControlOutput(); } - virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) { addControlOutput(); } - virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) { addControlOutput(); } - - // layout widgets - virtual void openFrameBox(const char* label) { } - virtual void openTabBox(const char* label) { } - virtual void openHorizontalBox(const char* label) { } - virtual void openVerticalBox(const char* label) { } - virtual void closeBox() { } - -protected: - void addControlInput() { mNumControlInputs++; } - void addControlOutput() { mNumControlOutputs++; } - -private: - size_t mNumControlInputs; - size_t mNumControlOutputs; -}; - -//---------------------------------------------------------------------------- -// UI control -//---------------------------------------------------------------------------- - -struct Control -{ - typedef void (*UpdateFunction)(Control* self, float value); - - UpdateFunction updateFunction; - float min, max, step; - float* zone; - - inline void update(float value) - { - (*updateFunction)(this, value); - } - - static void simpleUpdate(Control* self, float value) - { - *self->zone = value; - } - static void boundedUpdate(Control* self, float value) - { - *self->zone = sc_clip(value, self->min, self->max); - } -}; - -//---------------------------------------------------------------------------- -// Control allocator -//---------------------------------------------------------------------------- - -class ControlAllocator : public UI -{ -public: - ControlAllocator(Control* controls) - : mControls(controls) - { } - - // active widgets - virtual void addButton(const char* label, float* zone) - { addSimpleControl(zone); } - virtual void addToggleButton(const char* label, float* zone) - { addSimpleControl(zone); } - virtual void addCheckButton(const char* label, float* zone) - { addSimpleControl(zone); } - virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) - { addBoundedControl(zone, min, max, step); } - virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) - { addBoundedControl(zone, min, max, step); } - virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) - { addBoundedControl(zone, min, max, step); } - - // passive widgets - virtual void addNumDisplay(const char* label, float* zone, int precision) { } - virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) { } - virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) { } - virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) { } - - // layout widgets - virtual void openFrameBox(const char* label) { } - virtual void openTabBox(const char* label) { } - virtual void openHorizontalBox(const char* label) { } - virtual void openVerticalBox(const char* label) { } - virtual void closeBox() { } - -private: - void addControl(Control::UpdateFunction updateFunction, float* zone, float min, float max, float step) - { - Control* ctrl = mControls++; - ctrl->updateFunction = updateFunction; - ctrl->min = min; - ctrl->max = max; - ctrl->step = step; - ctrl->zone = zone; - } - void addSimpleControl(float* zone) - { - addControl(Control::simpleUpdate, zone, 0.f, 0.f, 0.f); - } - void addBoundedControl(float* zone, float min, float max, float step) - { - addControl(Control::boundedUpdate, zone, min, max, step); - } - -private: - Control* mControls; -}; - - -/****************************************************************************** -******************************************************************************* - - FAUST DSP - -******************************************************************************* -*******************************************************************************/ - -//---------------------------------------------------------------------------- -// Abstract DSP interface -//---------------------------------------------------------------------------- - -class dsp -{ -public: - virtual ~dsp(); - virtual int getNumInputs() = 0; - virtual int getNumOutputs() = 0; - virtual void buildUserInterface(UI* interface) = 0; - virtual void init(int samplingRate) = 0; - virtual void compute(int len, float** inputs, float** outputs) = 0; - -protected: - int fSamplingFreq; -}; - -dsp::~dsp() { } - -//---------------------------------------------------------------------------- -// FAUST generated code -//---------------------------------------------------------------------------- - -<> - - -/****************************************************************************** -******************************************************************************* - - SUPERCOLLIDER DSP INTERFACE - -******************************************************************************* -*******************************************************************************/ - -struct Faust : public Unit -{ - // Faust dsp instance - mydsp mDSP; - // Buffers for control to audio rate conversion - float** mInBufCopy; - float* mInBufValue; - // Controls - size_t mNumControls; - // NOTE: This needs to be the last field! - // - // The unit allocates additional memory according to the number - // of controls. - Control mControls[0]; - - int getNumAudioInputs() { return mDSP.getNumInputs(); } -}; - -// Global state - -static size_t g_numControls; // Number of controls -static const char* g_unitName; // Unit name - -// Initialize the global state with unit name and sample rate. -void initState(const std::string& name, int sampleRate); - -// Return the unit size in bytes, including static fields and controls. -static size_t unitSize(); - -// Convert a file name to a valid unit name. -static std::string fileNameToUnitName(const std::string& fileName); - -// Convert the XML unit name to a valid class name. -static std::string normalizeClassName(const std::string& name); - -void initState(const std::string& name, int sampleRate) -{ - g_unitName = strdup(name.c_str()); - - mydsp* dsp = new mydsp; - ControlCounter* cc = new ControlCounter; - - dsp->classInit(sampleRate); - dsp->buildUserInterface(cc); - g_numControls = cc->getNumControls(); - - delete dsp; - delete cc; -} - -size_t unitSize() -{ - return sizeof(Faust) + g_numControls * sizeof(Control); -} - -std::string fileNameToUnitName(const std::string& fileName) -{ - // Extract basename - size_t lpos = fileName.rfind('/', fileName.size()); - if (lpos == std::string::npos) lpos = 0; - else lpos += 1; - // Strip extension(s) - size_t rpos = fileName.find('.', lpos); - // Return substring - return fileName.substr(lpos, rpos > lpos ? rpos - lpos : 0); -} - -// Globals - -static InterfaceTable *ft; - -// The SuperCollider UGen class name generated here must match -// that generated by faust2sc: -static std::string normalizeClassName(const std::string& name) -{ - std::string s; - char c; - - unsigned int i=0; - bool upnext=true; - while (c=name[i++]) { - if (upnext) { c = toupper(c); upnext=false; } - if ( (c == '_') || (c == '-') || isspace(c)) { upnext=true; continue; } - s += c; - if (i > 31) { break; } - } - return s; -} - -extern "C" -{ -#ifdef SC_API_EXPORT - int api_version(void); -#endif - void load(InterfaceTable*); - void Faust_next(Faust*, int); - void Faust_next_copy(Faust*, int); - void Faust_next_clear(Faust*, int); - void Faust_Ctor(Faust*); - void Faust_Dtor(Faust*); -}; - -inline static void fillBuffer(float* dst, int n, float v) -{ - Fill(n, dst, v); -} - -inline static void fillBuffer(float* dst, int n, float v0, float v1) -{ - Fill(n, dst, v0, (v1 - v0) / n); -} - -inline static void copyBuffer(float* dst, int n, float* src) -{ - Copy(n, dst, src); -} - -inline static void Faust_updateControls(Faust* unit) -{ - Control* controls = unit->mControls; - int numControls = unit->mNumControls; - int curControl = unit->mDSP.getNumInputs(); - for (int i=0; i < numControls; ++i) { - float value = IN0(curControl); - (controls++)->update(value); - curControl++; - } -} - -void Faust_next(Faust* unit, int inNumSamples) -{ - // update controls - Faust_updateControls(unit); - // dsp computation - unit->mDSP.compute(inNumSamples, unit->mInBuf, unit->mOutBuf); -} - -void Faust_next_copy(Faust* unit, int inNumSamples) -{ - // update controls - Faust_updateControls(unit); - // Copy buffers - for (int i = 0; i < unit->getNumAudioInputs(); ++i) { - float* b = unit->mInBufCopy[i]; - if (INRATE(i) == calc_FullRate) { - // Audio rate: copy buffer - copyBuffer(b, inNumSamples, unit->mInBuf[i]); - } else { - // Control rate: linearly interpolate input - float v1 = IN0(i); - fillBuffer(b, inNumSamples, unit->mInBufValue[i], v1); - unit->mInBufValue[i] = v1; - } - } - // dsp computation - unit->mDSP.compute(inNumSamples, unit->mInBufCopy, unit->mOutBuf); -} - -void Faust_next_clear(Faust* unit, int inNumSamples) -{ - ClearUnitOutputs(unit, inNumSamples); -} - -void Faust_Ctor(Faust* unit) // module constructor -{ - // init dsp - unit->mDSP.instanceInit((int)SAMPLERATE); - - // allocate controls - unit->mNumControls = g_numControls; - ControlAllocator ca(unit->mControls); - unit->mDSP.buildUserInterface(&ca); - unit->mInBufCopy = 0; - unit->mInBufValue = 0; - - // check input/output channel configuration - const size_t numInputs = unit->mDSP.getNumInputs() + unit->mNumControls; - const size_t numOutputs = unit->mDSP.getNumOutputs(); - - bool channelsValid = (numInputs == unit->mNumInputs) - && (numOutputs == unit->mNumOutputs); - - if (channelsValid) { - bool rateValid = true; - for (int i = 0; i < unit->getNumAudioInputs(); ++i) { - if (INRATE(i) != calc_FullRate) { - rateValid = false; - break; - } - } - if (rateValid) { - SETCALC(Faust_next); - } else { - unit->mInBufCopy = (float**)RTAlloc(unit->mWorld, unit->getNumAudioInputs()*sizeof(float*)); - // Allocate memory for input buffer copies (numInputs * bufLength) - // and linear interpolation state (numInputs) - // = numInputs * (bufLength + 1) - unit->mInBufValue = (float*)RTAlloc(unit->mWorld, unit->getNumAudioInputs()*sizeof(float)); - float* mem = (float*)RTAlloc(unit->mWorld, unit->getNumAudioInputs()*BUFLENGTH*sizeof(float)); - // Aquire memory for interpolator state. - for (int i=0; i < unit->getNumAudioInputs(); ++i) { - // Initialize interpolator. - unit->mInBufValue[i] = IN0(i); - // Aquire buffer memory. - unit->mInBufCopy[i] = mem; - mem += BUFLENGTH; - } - SETCALC(Faust_next_copy); - } -#if !defined(NDEBUG) - Print("Faust[%s]:\n", g_unitName); - Print(" Inputs: %d\n" - " Outputs: %d\n" - " Callback: %s\n", - numInputs, numOutputs, - unit->mCalcFunc == (UnitCalcFunc)Faust_next ? "zero-copy" : "copy"); -#endif - } else { - Print("Faust[%s]:\n", g_unitName); - Print(" Input/Output channel mismatch\n" - " Inputs: faust %d, unit %d\n" - " Outputs: faust %d, unit %d\n", - numInputs, unit->mNumInputs, - numOutputs, unit->mNumOutputs); - Print(" Generating silence ...\n"); - SETCALC(Faust_next_clear); - } -} - -void Faust_Dtor(Faust* unit) // module destructor -{ - if (unit->mInBufValue) { - RTFree(unit->mWorld, unit->mInBufValue); - } - if (unit->mInBufCopy) { - if (unit->mInBufCopy[0]) { - RTFree(unit->mWorld, unit->mInBufCopy[0]); - } - RTFree(unit->mWorld, unit->mInBufCopy); - } -} - -#ifdef SC_API_EXPORT -FAUST_EXPORT int api_version(void) { return sc_api_version; } -#endif - -FAUST_EXPORT void load(InterfaceTable* inTable) -{ - - ft = inTable; - - Meta meta; - mydsp::metadata(&meta); - - std::string name = meta["name"]; - - if (name.empty()) { - name = fileNameToUnitName(__FILE__); - } - - name = normalizeClassName(name); - -#if !defined(NDEBUG) & defined(SC_API_EXPORT) - Print("*** Faust: supercollider.cpp: sc_api_version = %d\n",sc_api_version); -#endif - - if (name.empty()) { - // Catch empty name - Print("*** Faust: supercollider.cpp: " - "Could not create unit-generator module name from filename\n" - " bailing out ...\n"); - return; - } - - if (strncmp(name.c_str(),SC_FAUST_PREFIX,strlen(SC_FAUST_PREFIX))!=0){ - name = SC_FAUST_PREFIX + name; - } - - // Initialize global data - // TODO: Use correct sample rate - initState(name, 48000); - - // Register ugen - (*ft->fDefineUnit)( - (char*)name.c_str(), - unitSize(), - (UnitCtorFunc)&Faust_Ctor, - (UnitDtorFunc)&Faust_Dtor, - kUnitDef_CantAliasInputsToOutputs - ); - -#if !defined(NDEBUG) - Print("Faust: %s numControls=%d\n", name.c_str(), g_numControls); -#endif // NDEBUG -} - -// EOF