388 lines · 11.0 KB · C++
RawDownload
//-----------------------------------------------------------------------------// Entaro ChucK Developer!// This is a Chugin boilerplate, generated by chuginate!//----------------------------------------------------------------------------- // this should align with the correct versions of these ChucK files#include "chuck_dl.h"#include "chuck_def.h" // general includes#include <stdio.h>#include <limits.h>#include <math.h> // for pow() #define DEF_CURVE      1#define DEF_NUMPTS    20#define DEF_BUFLEN 88200#define MIN_BUFLEN   100#define CLIP(a, lo, hi) ( (a)>(lo)?( (a)<(hi)?(a):(hi) ):(lo) ) // declaration of chugin constructorCK_DLL_CTOR(expdelay_ctor);// declaration of chugin desctructorCK_DLL_DTOR(expdelay_dtor); CK_DLL_MFUN(expdelay_setMix);CK_DLL_MFUN(expdelay_setDurCurve);CK_DLL_MFUN(expdelay_setAmpCurve);CK_DLL_MFUN(expdelay_setDelay);CK_DLL_MFUN(expdelay_setMaxDelay);CK_DLL_MFUN(expdelay_setReps); CK_DLL_MFUN(expdelay_getMix);CK_DLL_MFUN(expdelay_getDurCurve);CK_DLL_MFUN(expdelay_getAmpCurve);CK_DLL_MFUN(expdelay_getDelay);CK_DLL_MFUN(expdelay_getMaxDelay);CK_DLL_MFUN(expdelay_getReps); // for Chugins extending UGen, this is mono synthesis function for 1 sampleCK_DLL_TICK(expdelay_tick); // this is a special offset reserved for Chugin internal datat_CKINT expdelay_data_offset = 0;  // class definition for internal Chugin data// (note: this isn't strictly necessary, but serves as example// of one recommended approach)class ExpDelay{public:  // constructor  ExpDelay( t_CKFLOAT fs)  {    _durcurve = DEF_CURVE;    _ampcurve = DEF_CURVE;    _maxbuflen = DEF_BUFLEN;    _buflen = _maxbuflen;    _bufIndex = 0;    _numpts = DEF_NUMPTS;    _delbuf = new SAMPLE[_maxbuflen];    for (int i=0; i<_maxbuflen; i++)      _delbuf[i] = 0.0f;    double amptotal = 0;    for (int i=0; i<_numpts; i++)      {	amptotal += experp (i, 0, _numpts, _ampcurve, 1, 0);      }    _gainscale = (float) (1.0/amptotal);    _mix = 1.0f;  }   ~ExpDelay()  {    delete [] _delbuf;  }    // for Chugins extending UGen  SAMPLE tick( SAMPLE in )  {    // default: this passes whatever input is patched into Chugin    for (int i=0; i<_numpts; i++)      {	float amp = experp (i, 0, _numpts, _ampcurve, 1, 0);	unsigned int bufpt = (unsigned int)experp (i, 0, _numpts, _durcurve, 0, _buflen);	unsigned int adjustedBufpt = (bufpt + _bufIndex) % _buflen;	_delbuf[adjustedBufpt] += in * amp * _gainscale;      }    SAMPLE out = _delbuf[_bufIndex];    _delbuf[_bufIndex] = 0.0f;    _bufIndex++;    if (_bufIndex >= _buflen) _bufIndex = 0;    return (out*_mix) + (in*(1-_mix));  }    float setMix ( t_CKFLOAT p )  {    _mix = CLIP(p,0.0f,1.0f);    return _mix;  }   int setReps( t_CKINT p )  {    if (p < 1) p = 1;    _numpts = p;    double amptotal = 0;    for (int i=0; i<_numpts; i++)      {	amptotal += experp (i, 0, _numpts, _ampcurve, 1, 0);      }    _gainscale = (float) (1.0/amptotal);    return _numpts;  }   float setDurCurve( t_CKFLOAT p )  {    if (p <= 0) p=0.0001;    _durcurve = p;    return _durcurve;  }   float setAmpCurve( t_CKFLOAT p )  {    if (p <= 0) p=0.0001;    _ampcurve = p;    double amptotal = 0;    for (int i=0; i<_numpts; i++)      {	amptotal += experp (i, 0, _numpts, _ampcurve, 1, 0);      }    _gainscale = (float) (1.0/amptotal);    return _ampcurve;  }   t_CKDUR setDelay ( t_CKDUR p )  {    unsigned int temp = (unsigned int)p;    if (temp < MIN_BUFLEN)      {	printf("ExpDelay error: delay must be greater than %d samples.\n",MIN_BUFLEN);	return p;      }    if (temp > _maxbuflen)      {	printf("ExpDelay error: cannot set delay greater than max delay.\n");	return p;      }    _buflen = temp;    for (int i=_buflen; i<_maxbuflen; i++)      _delbuf[i] = 0.0f;    return _buflen;  }   t_CKDUR setMaxDelay ( t_CKDUR p )  {    _maxbuflen = (unsigned int)p;    if (_maxbuflen < MIN_BUFLEN) _maxbuflen = MIN_BUFLEN;    delete [] _delbuf;    _delbuf = new SAMPLE[_maxbuflen];    for (int i=0; i<_maxbuflen; i++)      _delbuf[i] = 0.0f;    return p;  }    float getMix() { return _mix; }  float getReps() { return _numpts; }  float getDurCurve() { return _durcurve; }  float getAmpCurve() { return _ampcurve; }  t_CKDUR getDelay() { return (t_CKDUR)_buflen; }  t_CKDUR getMaxDelay() { return (t_CKDUR)_maxbuflen; }  private:  // exponential interpolation  double experp (double inval, double inlo, double inhi, double curve, double outlo, double outhi)  {    double lerp = (inval - inlo) / (inhi - inlo);    double expval = pow (lerp, curve);    return expval * (outhi - outlo) + outlo;  }  // instance data  SAMPLE * _delbuf;  unsigned int _buflen, _maxbuflen;  unsigned int _bufIndex;  float _durcurve, _ampcurve;  unsigned int _numpts;  float _gainscale;  float _mix;};  // query function: chuck calls this when loading the Chugin// NOTE: developer will need to modify this function to// add additional functions to this ChuginCK_DLL_QUERY( ExpDelay ){  // hmm, don't change this...  QUERY->setname(QUERY, "ExpDelay");    // begin the class definition  // can change the second argument to extend a different ChucK class  QUERY->begin_class(QUERY, "ExpDelay", "UGen");    // register the constructor (probably no need to change)  QUERY->add_ctor(QUERY, expdelay_ctor);  // register the destructor (probably no need to change)  QUERY->add_dtor(QUERY, expdelay_dtor);   QUERY->doc_class(QUERY, "Feedback delay at exponentially changing delay times.");  QUERY->add_ex(QUERY, "effects/ExpDelay.ck");    // for UGen's only: add tick function  QUERY->add_ugen_func(QUERY, expdelay_tick, NULL, 1, 1);    // NOTE: if this is to be a UGen with more than 1 channel,   // e.g., a multichannel UGen -- will need to use add_ugen_funcf()  // and declare a tickf function using CK_DLL_TICKF   QUERY->add_mfun(QUERY, expdelay_setMix, "float", "mix");  QUERY->add_arg(QUERY, "float", "mix");  QUERY->doc_func(QUERY, "Set dry/wet mix [0-1].");   QUERY->add_mfun(QUERY, expdelay_setReps, "int", "reps");  QUERY->add_arg(QUERY, "int", "reps");  QUERY->doc_func(QUERY, "Set number of repetitions.");    QUERY->add_mfun(QUERY, expdelay_setDurCurve, "float", "durcurve");  QUERY->add_arg(QUERY, "float", "durcurve");  QUERY->doc_func(QUERY, "Set steepness of delay curve [0.0001-inf]:\n"                  "       1 = steady\n"                  "      <1 = starts fast and slows down\n"                  "      >1 = starts slow and speeds up"                  );   QUERY->add_mfun(QUERY, expdelay_setAmpCurve, "float", "ampcurve");  QUERY->add_arg(QUERY, "float", "ampcurve");  QUERY->doc_func(QUERY, "Set steepness of amplitude decay [0.0001-inf].");    QUERY->add_mfun(QUERY, expdelay_setDelay, "dur", "delay");  QUERY->add_arg(QUERY, "dur", "delay");  QUERY->doc_func(QUERY, "Set duration of delay.");   QUERY->add_mfun(QUERY, expdelay_setMaxDelay, "dur", "max");  QUERY->add_arg(QUERY, "dur", "max");  QUERY->doc_func(QUERY, "Set maximum possible delay duration.");   QUERY->add_mfun(QUERY, expdelay_getMix, "float", "mix");  QUERY->doc_func(QUERY, "Get dry/wet mix [0-1].");  QUERY->add_mfun(QUERY, expdelay_getReps, "int", "reps");  QUERY->doc_func(QUERY, "Get number of repetitions.");  QUERY->add_mfun(QUERY, expdelay_getDurCurve, "float", "durcurve");  QUERY->doc_func(QUERY, "Get steepness of delay curve [0.0001-inf].");  QUERY->add_mfun(QUERY, expdelay_getAmpCurve, "float", "ampcurve");  QUERY->doc_func(QUERY, "Get steepness of amplitude decay [0.0001-inf].");  QUERY->add_mfun(QUERY, expdelay_getDelay, "dur", "delay");  QUERY->doc_func(QUERY, "Get duration of delay.");  QUERY->add_mfun(QUERY, expdelay_getMaxDelay, "dur", "max");  QUERY->doc_func(QUERY, "Get maximum possible delay duration.");   // this reserves a variable in the ChucK internal class to store   // referene to the c++ class we defined above  expdelay_data_offset = QUERY->add_mvar(QUERY, "int", "@ed_data", false);    // end the class definition  // IMPORTANT: this MUST be called!  QUERY->end_class(QUERY);    // wasn't that a breeze?  return TRUE;}  // implementation for the constructorCK_DLL_CTOR(expdelay_ctor){  // get the offset where we'll store our internal c++ class pointer  OBJ_MEMBER_INT(SELF, expdelay_data_offset) = 0;    // instantiate our internal c++ class representation  ExpDelay * bcdata = new ExpDelay(API->vm->get_srate(API, SHRED));    // store the pointer in the ChucK object member  OBJ_MEMBER_INT(SELF, expdelay_data_offset) = (t_CKINT) bcdata;}  // implementation for the destructorCK_DLL_DTOR(expdelay_dtor){  // get our c++ class pointer  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  // check it  if( bcdata )    {      // clean up      delete bcdata;      OBJ_MEMBER_INT(SELF, expdelay_data_offset) = 0;      bcdata = NULL;    }}  // implementation for tick functionCK_DLL_TICK(expdelay_tick){  // get our c++ class pointer  ExpDelay * c = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);    // invoke our tick function; store in the magical out variable  if(c) *out = c->tick(in);    // yes  return TRUE;} // set methodsCK_DLL_MFUN(expdelay_setMix){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_float = bcdata->setMix(GET_NEXT_FLOAT(ARGS));} CK_DLL_MFUN(expdelay_setReps){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_int = bcdata->setReps(GET_NEXT_INT(ARGS));} CK_DLL_MFUN(expdelay_setDurCurve){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_float = bcdata->setDurCurve(GET_NEXT_FLOAT(ARGS));} CK_DLL_MFUN(expdelay_setAmpCurve){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_float = bcdata->setAmpCurve(GET_NEXT_FLOAT(ARGS));} CK_DLL_MFUN(expdelay_setDelay){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_dur = bcdata->setDelay(GET_NEXT_DUR(ARGS));} CK_DLL_MFUN(expdelay_setMaxDelay){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_dur = bcdata->setMaxDelay(GET_NEXT_DUR(ARGS));} // get methodsCK_DLL_MFUN(expdelay_getMix){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_float = bcdata->getMix();} CK_DLL_MFUN(expdelay_getReps){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_int = bcdata->getReps();} CK_DLL_MFUN(expdelay_getDurCurve){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_float = bcdata->getDurCurve();} CK_DLL_MFUN(expdelay_getAmpCurve){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_float = bcdata->getAmpCurve();} CK_DLL_MFUN(expdelay_getDelay){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_dur = bcdata->getDelay();} CK_DLL_MFUN(expdelay_getMaxDelay){  ExpDelay * bcdata = (ExpDelay *) OBJ_MEMBER_INT(SELF, expdelay_data_offset);  RETURN->v_dur = bcdata->getMaxDelay();}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t