X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/c7f552fd8888da2f0d8cfb228fe0f28d3df3a12c..b4b6f2ea75b9f0f3ca918f5b84016610bf7a4d4f:/interpretor/preprocessor/faust-0.9.47mr3/architecture/puredata.cpp diff --git a/interpretor/preprocessor/faust-0.9.47mr3/architecture/puredata.cpp b/interpretor/preprocessor/faust-0.9.47mr3/architecture/puredata.cpp new file mode 100644 index 0000000..a41324a --- /dev/null +++ b/interpretor/preprocessor/faust-0.9.47mr3/architecture/puredata.cpp @@ -0,0 +1,760 @@ +/************************************************************************ + ************************************************************************ + FAUST Architecture File + Copyright (C) 2006-2011 Albert Graef + --------------------------------------------------------------------- + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + ************************************************************************ + ************************************************************************/ + +/* Pd architecture file, written by Albert Graef . + This was derived from minimal.cpp included in the Faust distribution. + Please note that this is to be compiled as a shared library, which is + then loaded dynamically by Pd as an external. */ + +#include +#include +#include +#include + +using namespace std; + +// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero) +// flags to avoid costly denormals +#ifdef __SSE__ + #include + #ifdef __SSE2__ + #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040) + #else + #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000) + #endif +#else + #warning *** puredata.cpp: NO SSE FLAG (denormals may slow things down) *** + #define AVOIDDENORMALS +#endif + +struct Meta +{ + void declare (const char* key, const char* value) {} +}; + +//------------------------------------------------------------------- +// 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 T abs (T a) { return (a> n); } + +/****************************************************************************** +******************************************************************************* + + VECTOR INTRINSICS + +******************************************************************************* +*******************************************************************************/ + +//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); } +//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); } + +<> + +/****************************************************************************** +******************************************************************************* + + ABSTRACT USER INTERFACE + +******************************************************************************* +*******************************************************************************/ + +class UI +{ + bool fStopped; +public: + + UI() : fStopped(false) {} + virtual ~UI() {} + + 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; + + virtual void addNumDisplay(const char* label, float* zone, int precision) = 0; + virtual void addTextDisplay(const char* label, float* zone, const 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; + + 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 run() = 0; + + void stop() { fStopped = true; } + bool stopped() { return fStopped; } + + virtual void declare(float* zone, const char* key, const char* value) {} +}; + +/*************************************************************************** + Pd UI interface + ***************************************************************************/ + +enum ui_elem_type_t { + UI_BUTTON, UI_TOGGLE_BUTTON, UI_CHECK_BUTTON, + UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY, + UI_V_BARGRAPH, UI_H_BARGRAPH, + UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP +}; + +struct ui_elem_t { + ui_elem_type_t type; + char *label; + float *zone; + float init, min, max, step; +}; + +class PdUI : public UI +{ +public: + int nelems; + ui_elem_t *elems; + + PdUI(); + PdUI(const char *s); + virtual ~PdUI(); + +protected: + string path; + void add_elem(ui_elem_type_t type, const char *label = NULL); + void add_elem(ui_elem_type_t type, const char *label, float *zone); + void add_elem(ui_elem_type_t type, const char *label, float *zone, + float init, float min, float max, float step); + void add_elem(ui_elem_type_t type, const char *label, float *zone, + float min, float max); + +public: + virtual void addButton(const char* label, float* zone); + virtual void addToggleButton(const char* label, float* zone); + virtual void addCheckButton(const char* label, float* zone); + virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step); + virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step); + virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step); + + virtual void addNumDisplay(const char* label, float* zone, int precision); + virtual void addTextDisplay(const char* label, float* zone, const 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); + + 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(); + + virtual void run(); +}; + +static string mangle(const char *s) +{ + const char *s0 = s; + string t = ""; + if (!s) return t; + while (*s) + if (isalnum(*s)) + t += *(s++); + else { + const char *s1 = s; + while (*s && !isalnum(*s)) ++s; + if (s1 != s0 && *s) t += "-"; + } + return t; +} + +static string normpath(string path) +{ + path = string("/")+path; + int pos = path.find("//"); + while (pos >= 0) { + path.erase(pos, 1); + pos = path.find("//"); + } + return path; +} + +static string pathcat(string path, string label) +{ + if (path.empty()) + return normpath(label); + else if (label.empty()) + return normpath(path); + else + return normpath(path+"/"+label); +} + +PdUI::PdUI() +{ + nelems = 0; + elems = NULL; + path = ""; +} + +PdUI::PdUI(const char *s) +{ + nelems = 0; + elems = NULL; + path = s?s:""; +} + +PdUI::~PdUI() +{ + if (elems) { + for (int i = 0; i < nelems; i++) + if (elems[i].label) + free(elems[i].label); + free(elems); + } +} + +inline void PdUI::add_elem(ui_elem_type_t type, const char *label) +{ + ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t)); + if (elems1) + elems = elems1; + else + return; + string s = pathcat(path, mangle(label)); + elems[nelems].type = type; + elems[nelems].label = strdup(s.c_str()); + elems[nelems].zone = NULL; + elems[nelems].init = 0.0; + elems[nelems].min = 0.0; + elems[nelems].max = 0.0; + elems[nelems].step = 0.0; + nelems++; +} + +inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone) +{ + ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t)); + if (elems1) + elems = elems1; + else + return; + string s = pathcat(path, mangle(label)); + elems[nelems].type = type; + elems[nelems].label = strdup(s.c_str()); + elems[nelems].zone = zone; + elems[nelems].init = 0.0; + elems[nelems].min = 0.0; + elems[nelems].max = 1.0; + elems[nelems].step = 1.0; + nelems++; +} + +inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone, + float init, float min, float max, float step) +{ + ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t)); + if (elems1) + elems = elems1; + else + return; + string s = pathcat(path, mangle(label)); + elems[nelems].type = type; + elems[nelems].label = strdup(s.c_str()); + elems[nelems].zone = zone; + elems[nelems].init = init; + elems[nelems].min = min; + elems[nelems].max = max; + elems[nelems].step = step; + nelems++; +} + +inline void PdUI::add_elem(ui_elem_type_t type, const char *label, float *zone, + float min, float max) +{ + ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t)); + if (elems1) + elems = elems1; + else + return; + string s = pathcat(path, mangle(label)); + elems[nelems].type = type; + elems[nelems].label = strdup(s.c_str()); + elems[nelems].zone = zone; + elems[nelems].init = 0.0; + elems[nelems].min = min; + elems[nelems].max = max; + elems[nelems].step = 0.0; + nelems++; +} + +void PdUI::addButton(const char* label, float* zone) +{ add_elem(UI_BUTTON, label, zone); } +void PdUI::addToggleButton(const char* label, float* zone) +{ add_elem(UI_TOGGLE_BUTTON, label, zone); } +void PdUI::addCheckButton(const char* label, float* zone) +{ add_elem(UI_CHECK_BUTTON, label, zone); } +void PdUI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) +{ add_elem(UI_V_SLIDER, label, zone, init, min, max, step); } +void PdUI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) +{ add_elem(UI_H_SLIDER, label, zone, init, min, max, step); } +void PdUI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step) +{ add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); } + +// FIXME: addNumDisplay and addTextDisplay not implemented in Faust yet? +void PdUI::addNumDisplay(const char* label, float* zone, int precision) {} +void PdUI::addTextDisplay(const char* label, float* zone, const char* names[], float min, float max) {} +void PdUI::addHorizontalBargraph(const char* label, float* zone, float min, float max) +{ add_elem(UI_H_BARGRAPH, label, zone, min, max); } +void PdUI::addVerticalBargraph(const char* label, float* zone, float min, float max) +{ add_elem(UI_V_BARGRAPH, label, zone, min, max); } + +void PdUI::openFrameBox(const char* label) +{ + if (!path.empty()) path += "/"; + path += mangle(label); +} +void PdUI::openTabBox(const char* label) +{ + if (!path.empty()) path += "/"; + path += mangle(label); +} +void PdUI::openHorizontalBox(const char* label) +{ + if (!path.empty()) path += "/"; + path += mangle(label); +} +void PdUI::openVerticalBox(const char* label) +{ + if (!path.empty()) path += "/"; + path += mangle(label); +} +void PdUI::closeBox() +{ + int pos = path.rfind("/"); + if (pos < 0) pos = 0; + path.erase(pos); +} + +void PdUI::run() {} + +/****************************************************************************** +******************************************************************************* + + FAUST DSP + +******************************************************************************* +*******************************************************************************/ + + + +//---------------------------------------------------------------- +// abstract definition of a signal processor +//---------------------------------------------------------------- + +class dsp { + protected: + int fSamplingFreq; + public: + dsp() {} + 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; +}; + +//---------------------------------------------------------------------------- +// FAUST generated signal processor +//---------------------------------------------------------------------------- + + +<> + +#include +#include +#include "m_pd.h" + +#define faust_setup(name) xfaust_setup(name) +#define xfaust_setup(name) name ## _tilde_setup(void) +#define sym(name) xsym(name) +#define xsym(name) #name + +// time for "active" toggle xfades in secs +#define XFADE_TIME 0.1f + +static t_class *faust_class; + +struct t_faust { + t_object x_obj; +#ifdef __MINGW32__ + /* This seems to be necessary as some as yet undetermined Pd routine seems + to write past the end of x_obj on Windows. */ + int fence; /* dummy field (not used) */ +#endif + mydsp *dsp; + PdUI *ui; + string *label; + int active, xfade, n_xfade, rate, n_in, n_out; + t_sample **inputs, **outputs, **buf; + t_outlet *out; + t_sample f; +}; + +static t_symbol *s_button, *s_checkbox, *s_vslider, *s_hslider, *s_nentry, + *s_vbargraph, *s_hbargraph; + +static inline void zero_samples(int k, int n, t_sample **out) +{ + for (int i = 0; i < k; i++) +#ifdef __STDC_IEC_559__ + /* IEC 559 a.k.a. IEEE 754 floats can be initialized faster like this */ + memset(out[i], 0, n*sizeof(t_sample)); +#else + for (int j = 0; j < n; j++) + out[i][j] = 0.0f; +#endif +} + +static inline void copy_samples(int k, int n, t_sample **out, t_sample **in) +{ + for (int i = 0; i < k; i++) + memcpy(out[i], in[i], n*sizeof(t_sample)); +} + +static t_int *faust_perform(t_int *w) +{ + t_faust *x = (t_faust *)(w[1]); + int n = (int)(w[2]); + if (!x->dsp || !x->buf) return (w+3); + AVOIDDENORMALS; + if (x->xfade > 0) { + float d = 1.0f/x->n_xfade, f = (x->xfade--)*d; + d = d/n; + x->dsp->compute(n, x->inputs, x->buf); + if (x->active) + if (x->n_in == x->n_out) + /* xfade inputs -> buf */ + for (int j = 0; j < n; j++, f -= d) + for (int i = 0; i < x->n_out; i++) + x->outputs[i][j] = f*x->inputs[i][j]+(1.0f-f)*x->buf[i][j]; + else + /* xfade 0 -> buf */ + for (int j = 0; j < n; j++, f -= d) + for (int i = 0; i < x->n_out; i++) + x->outputs[i][j] = (1.0f-f)*x->buf[i][j]; + else + if (x->n_in == x->n_out) + /* xfade buf -> inputs */ + for (int j = 0; j < n; j++, f -= d) + for (int i = 0; i < x->n_out; i++) + x->outputs[i][j] = f*x->buf[i][j]+(1.0f-f)*x->inputs[i][j]; + else + /* xfade buf -> 0 */ + for (int j = 0; j < n; j++, f -= d) + for (int i = 0; i < x->n_out; i++) + x->outputs[i][j] = f*x->buf[i][j]; + } else if (x->active) { + x->dsp->compute(n, x->inputs, x->buf); + copy_samples(x->n_out, n, x->outputs, x->buf); + } else if (x->n_in == x->n_out) { + copy_samples(x->n_out, n, x->buf, x->inputs); + copy_samples(x->n_out, n, x->outputs, x->buf); + } else + zero_samples(x->n_out, n, x->outputs); + return (w+3); +} + +static void faust_dsp(t_faust *x, t_signal **sp) +{ + int n = sp[0]->s_n, sr = (int)sp[0]->s_sr; + if (x->rate <= 0) { + /* default sample rate is whatever Pd tells us */ + PdUI *ui = x->ui; + float *z = NULL; + if (ui->nelems > 0 && + (z = (float*)malloc(ui->nelems*sizeof(float)))) { + /* save the current control values */ + for (int i = 0; i < ui->nelems; i++) + if (ui->elems[i].zone) + z[i] = *ui->elems[i].zone; + } + /* set the proper sample rate; this requires reinitializing the dsp */ + x->rate = sr; + x->dsp->init(sr); + if (z) { + /* restore previous control values */ + for (int i = 0; i < ui->nelems; i++) + if (ui->elems[i].zone) + *ui->elems[i].zone = z[i]; + free(z); + } + } + if (n > 0) + x->n_xfade = (int)(x->rate*XFADE_TIME/n); + dsp_add(faust_perform, 2, x, n); + for (int i = 0; i < x->n_in; i++) + x->inputs[i] = sp[i+1]->s_vec; + for (int i = 0; i < x->n_out; i++) + x->outputs[i] = sp[x->n_in+i+1]->s_vec; + if (x->buf != NULL) + for (int i = 0; i < x->n_out; i++) { + x->buf[i] = (t_sample*)malloc(n*sizeof(t_sample)); + if (x->buf[i] == NULL) { + for (int j = 0; j < i; j++) + free(x->buf[j]); + free(x->buf); + x->buf = NULL; + break; + } + } +} + +static int pathcmp(const char *s, const char *t) +{ + int n = strlen(s), m = strlen(t); + if (n == 0 || m == 0) + return 0; + else if (t[0] == '/') + return strcmp(s, t); + else if (n <= m || s[n-m-1] != '/') + return strcmp(s+1, t); + else + return strcmp(s+n-m, t); +} + +static void faust_any(t_faust *x, t_symbol *s, int argc, t_atom *argv) +{ + if (!x->dsp) return; + PdUI *ui = x->ui; + if (s == &s_bang) { + for (int i = 0; i < ui->nelems; i++) + if (ui->elems[i].label && ui->elems[i].zone) { + t_atom args[6]; + t_symbol *_s; + switch (ui->elems[i].type) { + case UI_BUTTON: + _s = s_button; + break; + case UI_TOGGLE_BUTTON: + case UI_CHECK_BUTTON: + _s = s_checkbox; + break; + case UI_V_SLIDER: + _s = s_vslider; + break; + case UI_H_SLIDER: + _s = s_hslider; + break; + case UI_NUM_ENTRY: + _s = s_nentry; + break; + case UI_V_BARGRAPH: + _s = s_vbargraph; + break; + case UI_H_BARGRAPH: + _s = s_hbargraph; + break; + default: + continue; + } + SETSYMBOL(&args[0], gensym(ui->elems[i].label)); + SETFLOAT(&args[1], *ui->elems[i].zone); + SETFLOAT(&args[2], ui->elems[i].init); + SETFLOAT(&args[3], ui->elems[i].min); + SETFLOAT(&args[4], ui->elems[i].max); + SETFLOAT(&args[5], ui->elems[i].step); + outlet_anything(x->out, _s, 6, args); + } + } else { + const char *label = s->s_name; + int count = 0; + for (int i = 0; i < ui->nelems; i++) + if (ui->elems[i].label && + pathcmp(ui->elems[i].label, label) == 0) { + if (argc == 0) { + if (ui->elems[i].zone) { + t_atom arg; + SETFLOAT(&arg, *ui->elems[i].zone); + outlet_anything(x->out, gensym(ui->elems[i].label), 1, &arg); + } + ++count; + } else if (argc == 1 && + (argv[0].a_type == A_FLOAT || + argv[0].a_type == A_DEFFLOAT) && + ui->elems[i].zone) { + float f = atom_getfloat(argv); + *ui->elems[i].zone = f; + ++count; + } else + pd_error(x, "[faust] %s: bad control argument: %s", + x->label->c_str(), label); + } + if (count == 0 && strcmp(label, "active") == 0) { + if (argc == 0) { + t_atom arg; + SETFLOAT(&arg, (float)x->active); + outlet_anything(x->out, gensym((char*)"active"), 1, &arg); + } else if (argc == 1 && + (argv[0].a_type == A_FLOAT || + argv[0].a_type == A_DEFFLOAT)) { + float f = atom_getfloat(argv); + x->active = (int)f; + x->xfade = x->n_xfade; + } + } + } +} + +static void faust_free(t_faust *x) +{ + if (x->label) delete x->label; + if (x->dsp) delete x->dsp; + if (x->ui) delete x->ui; + if (x->inputs) free(x->inputs); + if (x->outputs) free(x->outputs); + if (x->buf) { + for (int i = 0; i < x->n_out; i++) + if (x->buf[i]) free(x->buf[i]); + free(x->buf); + } +} + +static void *faust_new(t_symbol *s, int argc, t_atom *argv) +{ + t_faust *x = (t_faust*)pd_new(faust_class); + int sr = -1; + t_symbol *id = NULL; + x->active = 1; + for (int i = 0; i < argc; i++) + if (argv[i].a_type == A_FLOAT || argv[i].a_type == A_DEFFLOAT) + sr = (int)argv[i].a_w.w_float; + else if (argv[i].a_type == A_SYMBOL || argv[i].a_type == A_DEFSYMBOL) + id = argv[i].a_w.w_symbol; + x->rate = sr; + if (sr <= 0) sr = 44100; + x->xfade = 0; x->n_xfade = (int)(sr*XFADE_TIME/64); + x->inputs = x->outputs = x->buf = NULL; + x->label = new string(sym(mydsp) "~"); + x->dsp = new mydsp(); + x->ui = new PdUI(id?id->s_name:NULL); + if (!x->dsp || !x->ui || !x->label) goto error; + if (id) { + *x->label += " "; + *x->label += id->s_name; + } + x->n_in = x->dsp->getNumInputs(); + x->n_out = x->dsp->getNumOutputs(); + if (x->n_in > 0) + x->inputs = (t_sample**)malloc(x->n_in*sizeof(t_sample*)); + if (x->n_out > 0) { + x->outputs = (t_sample**)malloc(x->n_out*sizeof(t_sample*)); + x->buf = (t_sample**)malloc(x->n_out*sizeof(t_sample*)); + } + if ((x->n_in > 0 && x->inputs == NULL) || + (x->n_out > 0 && (x->outputs == NULL || x->buf == NULL))) + goto error; + for (int i = 0; i < x->n_out; i++) + x->buf[i] = NULL; + x->dsp->init(sr); + x->dsp->buildUserInterface(x->ui); + for (int i = 0; i < x->n_in; i++) + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + x->out = outlet_new(&x->x_obj, 0); + for (int i = 0; i < x->n_out; i++) + outlet_new(&x->x_obj, &s_signal); + return (void *)x; + error: + faust_free(x); + x->dsp = NULL; x->ui = NULL; + x->inputs = x->outputs = x->buf = NULL; + return (void *)x; +} + +extern "C" void faust_setup(mydsp) +{ + t_symbol *s = gensym(sym(mydsp) "~"); + faust_class = + class_new(s, (t_newmethod)faust_new, (t_method)faust_free, + sizeof(t_faust), CLASS_DEFAULT, + A_GIMME, A_NULL); + class_addmethod(faust_class, (t_method)faust_dsp, gensym((char*)"dsp"), A_NULL); + class_addanything(faust_class, faust_any); + class_addmethod(faust_class, nullfn, &s_signal, A_NULL); + s_button = gensym((char*)"button"); + s_checkbox = gensym((char*)"checkbox"); + s_vslider = gensym((char*)"vslider"); + s_hslider = gensym((char*)"hslider"); + s_nentry = gensym((char*)"nentry"); + s_vbargraph = gensym((char*)"vbargraph"); + s_hbargraph = gensym((char*)"hbargrap"); + /* give some indication that we're loaded and ready to go */ + mydsp dsp = mydsp(); + post("[faust] %s: %d inputs, %d outputs", sym(mydsp) "~", + dsp.getNumInputs(), dsp.getNumOutputs()); +}