337 lines · 10.5 KB · C++
RawDownload
//-----------------------------------------------------------------------------// This is a virtual analog model of the Diode Ladder filter.// The VADiodeLadderFilter and VAOnePoleFilter are taken directly from // Will Pirkle's applications notes, and can be found at//// http://www.willpirkle.com/Downloads/AN-6DiodeLadderFilter.pdf//// Ported by Owen Vallis 2015//// 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> //Pirckle files#include "VADiodeLadderFilter.h" // declaration of chugin constructorCK_DLL_CTOR(wpdiodeladder_ctor);// declaration of chugin desctructorCK_DLL_DTOR(wpdiodeladder_dtor); // Resonance goes between [0...17]CK_DLL_MFUN(wpdiodeladder_setResonance);CK_DLL_MFUN(wpdiodeladder_getResonance); // Cuttoff is in Hz [0..Nyquist)CK_DLL_MFUN(wpdiodeladder_setCutoff);CK_DLL_MFUN(wpdiodeladder_getCutoff); // Saturation is a scalar gain and // can be used to drive the signal// into the non linear saturatorCK_DLL_MFUN(wpdiodeladder_setSaturation);CK_DLL_MFUN(wpdiodeladder_getSaturation); // Enable non linear saturatorCK_DLL_MFUN(wpdiodeladder_setNonLinearProcessing);CK_DLL_MFUN(wpdiodeladder_getNonLinearProcessing); // the 1/tanh(sat) is to normalize the function // so x = [-1..+1] --> y = [-1..+1] Normalized VersionCK_DLL_MFUN(wpdiodeladder_setNonLinearType);CK_DLL_MFUN(wpdiodeladder_getNonLinearType); // for Chugins extending UGen, this is mono synthesis function for 1 sampleCK_DLL_TICK(wpdiodeladder_tick); // this is a special offset reserved for Chugin internal datat_CKINT wpdiodeladder_data_offset = 0;  // class definition for internal Chugin data// (note: this isn't strictly necessary, but serves as example// of one recommended approach)class WPDiodeLadder{public:    // constructor    WPDiodeLadder( t_CKFLOAT fs)    {        diodeFilter.prepareForPlay(fs);    }     // for Chugins extending UGen    SAMPLE tick( SAMPLE in )    {        // default: this passes whatever input is patched into Chugin        return diodeFilter.doFilter(in);    }     float setResonance( t_CKFLOAT p )    {        diodeFilter.m_dK = p;        diodeFilter.updateFilter();        return p;    }     float getResonance() { return diodeFilter.m_dK; }     float setCutoff( t_CKFLOAT p )    {        diodeFilter.m_dFc = p;        diodeFilter.updateFilter();        return p;    }     float getCutoff() { return diodeFilter.m_dFc; }     float setSaturation( t_CKFLOAT p )    {        diodeFilter.m_dSaturation = p;        return p;    }     float getSaturation() { return diodeFilter.m_dSaturation; }        bool setNonLinearProcessing( t_CKBOOL p )    {        diodeFilter.m_NonLinearProcessing = p;        return p;    }     bool getNonLinearProcessing() { return diodeFilter.m_NonLinearProcessing; }     bool setNonLinearType( t_CKBOOL p )    {        diodeFilter.m_uNLPType = p;        return p;    }     bool getNonLinearType() { return diodeFilter.m_uNLPType; }    private:    // instance data    CVADiodeLadderFilter diodeFilter;};  // 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( WPDiodeLadder ){    // hmm, don't change this...    QUERY->setname(QUERY, "WPDiodeLadder");        // begin the class definition    // can change the second argument to extend a different ChucK class    QUERY->begin_class(QUERY, "WPDiodeLadder", "UGen");    QUERY->doc_class(QUERY, "Virtual analog low pass filter based on Will Pirkle's Diode Ladder application notes");    QUERY->add_ex(QUERY, "filter/WPDiodeLadder.ck");     // register the constructor (probably no need to change)    QUERY->add_ctor(QUERY, wpdiodeladder_ctor);    // register the destructor (probably no need to change)    QUERY->add_dtor(QUERY, wpdiodeladder_dtor);        // for UGen's only: add tick function    QUERY->add_ugen_func(QUERY, wpdiodeladder_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, wpdiodeladder_setResonance, "float", "resonance");    QUERY->add_arg(QUERY, "float", "arg");    QUERY->doc_func(QUERY, "Resonance goes between [0...17]. ");     QUERY->add_mfun(QUERY, wpdiodeladder_getResonance, "float", "resonance");    QUERY->doc_func(QUERY, "Get resonance [0 - 17].");     QUERY->add_mfun(QUERY, wpdiodeladder_setCutoff, "float", "cutoff");    QUERY->add_arg(QUERY, "float", "arg");    QUERY->doc_func(QUERY, "Cuttoff is in Hz [0..Nyquist). ");     QUERY->add_mfun(QUERY, wpdiodeladder_getCutoff, "float", "cutoff");    QUERY->doc_func(QUERY, "Get cuttoff frequency in Hz [0..Nyquist).");     QUERY->add_mfun(QUERY, wpdiodeladder_setSaturation, "float", "saturation");    QUERY->add_arg(QUERY, "float", "arg");    QUERY->doc_func(QUERY, "Saturation is a scalar gain, and can be used to drive the non-linearity. ");     QUERY->add_mfun(QUERY, wpdiodeladder_getSaturation, "float", "saturation");    QUERY->doc_func(QUERY, "Get saturation. Saturation is a scalar gain, and can be used to drive the non-linearity.");        QUERY->add_mfun(QUERY, wpdiodeladder_setNonLinearProcessing, "int", "nonlinear");    QUERY->add_arg(QUERY, "int", "arg");    QUERY->doc_func(QUERY, "Enable non linear saturator. ");     QUERY->add_mfun(QUERY, wpdiodeladder_getNonLinearProcessing, "int", "nonlinear");    QUERY->doc_func(QUERY, "Get non-linear saturator setting. 1 is enabled.");        QUERY->add_mfun(QUERY, wpdiodeladder_setNonLinearType, "int", "nlp_type");    QUERY->add_arg(QUERY, "int", "arg");    QUERY->doc_func(QUERY, "Set to 1 to normalize non-linear output. ");     QUERY->add_mfun(QUERY, wpdiodeladder_getNonLinearType, "int", "nlp_type");    QUERY->doc_func(QUERY, "Get non-linear output setting. 1 is normalized.");        // this reserves a variable in the ChucK internal class to store     // referene to the c++ class we defined above    wpdiodeladder_data_offset = QUERY->add_mvar(QUERY, "int", "@wpdl_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(wpdiodeladder_ctor){    // get the offset where we'll store our internal c++ class pointer    OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset) = 0;        // instantiate our internal c++ class representation    WPDiodeLadder * bcdata = new WPDiodeLadder(API->vm->get_srate(API, SHRED));        // store the pointer in the ChucK object member    OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset) = (t_CKINT) bcdata;}  // implementation for the destructorCK_DLL_DTOR(wpdiodeladder_dtor){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // check it    if( bcdata )    {        // clean up        delete bcdata;        OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset) = 0;        bcdata = NULL;    }}  // implementation for tick functionCK_DLL_TICK(wpdiodeladder_tick){    // get our c++ class pointer    WPDiodeLadder * c = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);     // invoke our tick function; store in the magical out variable    if(c) *out = c->tick(in);     // yes    return TRUE;}  // example implementation for setterCK_DLL_MFUN(wpdiodeladder_setResonance){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // set the return value    RETURN->v_float = bcdata->setResonance(GET_NEXT_FLOAT(ARGS));}  // example implementation for getterCK_DLL_MFUN(wpdiodeladder_getResonance){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // set the return value    RETURN->v_float = bcdata->getResonance();} // example implementation for setterCK_DLL_MFUN(wpdiodeladder_setCutoff){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // set the return value    RETURN->v_float = bcdata->setCutoff(GET_NEXT_FLOAT(ARGS));}  // example implementation for getterCK_DLL_MFUN(wpdiodeladder_getCutoff){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // set the return value    RETURN->v_float = bcdata->getCutoff();} // example implementation for setterCK_DLL_MFUN(wpdiodeladder_setSaturation){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // set the return value    RETURN->v_float = bcdata->setSaturation(GET_NEXT_FLOAT(ARGS));}  // example implementation for getterCK_DLL_MFUN(wpdiodeladder_getSaturation){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // set the return value    RETURN->v_float = bcdata->getSaturation();} // example implementation for setterCK_DLL_MFUN(wpdiodeladder_setNonLinearProcessing){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // set the return value    RETURN->v_float = bcdata->setNonLinearProcessing(GET_NEXT_FLOAT(ARGS));}  // example implementation for getterCK_DLL_MFUN(wpdiodeladder_getNonLinearProcessing){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // set the return value    RETURN->v_float = bcdata->getNonLinearProcessing();} // example implementation for setterCK_DLL_MFUN(wpdiodeladder_setNonLinearType){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // set the return value    RETURN->v_float = bcdata->setNonLinearType(GET_NEXT_FLOAT(ARGS));}  // example implementation for getterCK_DLL_MFUN(wpdiodeladder_getNonLinearType){    // get our c++ class pointer    WPDiodeLadder * bcdata = (WPDiodeLadder *) OBJ_MEMBER_INT(SELF, wpdiodeladder_data_offset);    // set the return value    RETURN->v_float = bcdata->getNonLinearType();}

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