+++ /dev/null
-/************************************************************************
- ************************************************************************
- FAUST Architecture File
- Copyright (C) 2006-2011 Albert Graef <Dr.Graef@t-online.de>
- ---------------------------------------------------------------------
- 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 <Dr.Graef@t-online.de>.
- 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 <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <string>
-
-using namespace std;
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
- #include <xmmintrin.h>
- #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<b) ? a : b; }
-
-inline long min (long a, long b) { return (a<b) ? a : b; }
-inline long min (int a, long b) { return (a<b) ? a : b; }
-inline long min (long a, int b) { return (a<b) ? a : b; }
-
-inline float min (float a, float b) { return (a<b) ? a : b; }
-inline float min (int a, float b) { return (a<b) ? a : b; }
-inline float min (float a, int b) { return (a<b) ? a : b; }
-inline float min (long a, float b) { return (a<b) ? a : b; }
-inline float min (float a, long b) { return (a<b) ? a : b; }
-
-inline double min (double a, double b) { return (a<b) ? a : b; }
-inline double min (int a, double b) { return (a<b) ? a : b; }
-inline double min (double a, int b) { return (a<b) ? a : b; }
-inline double min (long a, double b) { return (a<b) ? a : b; }
-inline double min (double a, long b) { return (a<b) ? a : b; }
-inline double min (float a, double b) { return (a<b) ? a : b; }
-inline double min (double a, float b) { return (a<b) ? a : b; }
-
-// abs is now predefined
-//template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
-
-
-inline int lsr (int x, int n) { return int(((unsigned int)x) >> 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); }
-
-<<includeIntrinsic>>
-
-/******************************************************************************
-*******************************************************************************
-
- 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
-//----------------------------------------------------------------------------
-
-
-<<includeclass>>
-
-#include <stdio.h>
-#include <string.h>
-#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());
-}