462 lines · 13.3 KB · C++
RawDownload
//-----------------------------------------------------------------------------// name: Range.cpp// desc: Scale an input signal from one number range to another. //       This is useful for things such as making LFOs that drive//       parameters that are do not fall under the output range of //       most oscillators, like vibrato. // // example:// // Use range to make an easy vibrato// SinOsc lfo = > Range r = > blackhole;// SinOsc tone = > dac;//// // Help reveals all secrets// Range.help();//// 3 = > lfo.freq;// (0, 1, 440, 10) = > r.radius;// // while (10::ms = > now) {//    r.last() = > tone.freq;// }//// authors: Nick Shaheed (nshaheed@ccrma.stanford.edu)// date: Winter 2022////----------------------------------------------------------------------------- // 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> // declaration of chugin constructorCK_DLL_CTOR(range_ctor);// declaration of chugin desctructorCK_DLL_DTOR(range_dtor); // getters and settersCK_DLL_MFUN(range_setInRange);CK_DLL_MFUN(range_setInRadius);CK_DLL_MFUN(range_setOutRange);CK_DLL_MFUN(range_setOutRadius);CK_DLL_MFUN(range_setRange);CK_DLL_MFUN(range_setRadius); CK_DLL_MFUN(range_getInMin);CK_DLL_MFUN(range_getInMax);CK_DLL_MFUN(range_getOutMin);CK_DLL_MFUN(range_getOutMax);CK_DLL_MFUN(range_getInCenter);CK_DLL_MFUN(range_getInRadius);CK_DLL_MFUN(range_getOutCenter);CK_DLL_MFUN(range_getOutRadius); CK_DLL_MFUN(range_setClip);CK_DLL_MFUN(range_getClip); // for Chugins extending UGen, this is mono synthesis function for 1 sampleCK_DLL_TICK(range_tick); // this is a special offset reserved for Chugin internal datat_CKINT range_data_offset = 0; class Range{public:    // constructor    Range( t_CKFLOAT fs)    {        m_param = 0;        m_in_min = -1;        m_in_max = 1;        m_out_min = 0;        m_out_max = 1;        m_clip = 0;    }     // for Chugins extending UGen    SAMPLE tick( SAMPLE in )    {        SAMPLE out = (in - m_in_min) / (m_in_max - m_in_min);        out = out * (m_out_max - m_out_min) + m_out_min;         if (!m_clip) return out;         // hard clipping - nothing past the limits allowed.        if (out < m_out_min) out = m_out_min;        if (out > m_out_max) out = m_out_max;         // default: this passes whatever input is patched into Chugin        return out;    }     t_CKVOID setInRange( t_CKFLOAT in_min, t_CKFLOAT in_max ) {        m_in_min = in_min;        m_in_max = in_max;    }     t_CKVOID setInRadius( t_CKFLOAT in_center, t_CKFLOAT in_radius ) {        m_in_min = in_center - in_radius;        m_in_max = in_center + in_radius;    }     t_CKVOID setOutRange( t_CKFLOAT out_min, t_CKFLOAT out_max ) {        m_out_min = out_min;        m_out_max = out_max;    }     t_CKVOID setOutRadius( t_CKFLOAT out_center, t_CKFLOAT out_radius ) {        m_out_min = out_center - out_radius;        m_out_max = out_center + out_radius;    }     t_CKVOID setRange( t_CKFLOAT in_min, t_CKFLOAT in_max, t_CKFLOAT out_min, t_CKFLOAT out_max ) {        m_in_min = in_min;        m_in_max = in_max;        m_out_min = out_min;        m_out_max = out_max;    }     t_CKVOID setRadius(t_CKFLOAT in_center, t_CKFLOAT in_radius, t_CKFLOAT out_center, t_CKFLOAT out_radius) {        m_in_min = in_center - in_radius;        m_in_max = in_center + in_radius;        m_out_min = out_center - out_radius;        m_out_max = out_center + out_radius;    }     t_CKINT setClip(t_CKINT val)     {        m_clip = val;        return val;    }     t_CKINT getClip()    {        return m_clip;    }     // get parameter example    t_CKFLOAT getInMin() { return m_in_min; }    t_CKFLOAT getInMax() { return m_in_max; }    t_CKFLOAT getOutMin() { return m_out_min; }    t_CKFLOAT getOutMax() { return m_out_max; }     t_CKFLOAT getInCenter() { return (m_in_min + m_in_max) / 2; }    t_CKFLOAT getInRadius() { return (m_in_max - m_in_min) / 2; }    t_CKFLOAT getOutCenter() { return (m_out_min + m_out_max) / 2; }    t_CKFLOAT getOutRadius() { return (m_out_max - m_out_min) / 2; }  private:    // instance data    t_CKFLOAT m_param;    t_CKFLOAT m_in_min, m_in_max, m_out_min, m_out_max;    t_CKINT m_clip;};  // 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( Range ){    // hmm, don't change this...    QUERY->setname(QUERY, "Range");        // begin the class definition    // can change the second argument to extend a different ChucK class    QUERY->begin_class(QUERY, "Range", "UGen");     // register the constructor (probably no need to change)    QUERY->add_ctor(QUERY, range_ctor);    // register the destructor (probably no need to change)    QUERY->add_dtor(QUERY, range_dtor);        // for UGen's only: add tick function    QUERY->add_ugen_func(QUERY, range_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, range_setInRange, "void", "inRange");    QUERY->add_arg(QUERY, "float", "min");    QUERY->add_arg(QUERY, "float", "max");    QUERY->doc_func(QUERY, "Set the expected input range.");     QUERY->add_mfun(QUERY, range_setInRadius, "void", "inRadius");    QUERY->add_arg(QUERY, "float", "center");    QUERY->add_arg(QUERY, "float", "radius");    QUERY->doc_func(QUERY, "Set the expected input radius.");     QUERY->add_mfun(QUERY, range_setOutRange, "void", "outRange");    QUERY->add_arg(QUERY, "float", "min");    QUERY->add_arg(QUERY, "float", "max");    QUERY->doc_func(QUERY, "Set the output range.");     QUERY->add_mfun(QUERY, range_setOutRadius, "void", "outRadius");    QUERY->add_arg(QUERY, "float", "center");    QUERY->add_arg(QUERY, "float", "radius");    QUERY->doc_func(QUERY, "Set the output radius.");     QUERY->add_mfun(QUERY, range_setRange, "void", "range");    QUERY->add_arg(QUERY, "float", "inMin");    QUERY->add_arg(QUERY, "float", "inMax");    QUERY->add_arg(QUERY, "float", "outMin");    QUERY->add_arg(QUERY, "float", "outMax");    QUERY->doc_func(QUERY, "Set the expected input range and desired output range.");     QUERY->add_mfun(QUERY, range_setRadius, "void", "radius");    QUERY->add_arg(QUERY, "float", "inCenter");    QUERY->add_arg(QUERY, "float", "inRadius");    QUERY->add_arg(QUERY, "float", "outCenter");    QUERY->add_arg(QUERY, "float", "outRadius");    QUERY->doc_func(QUERY, "Set the expected input range and desired output range in terms of a center with a radius.");     QUERY->add_mfun(QUERY, range_getInMin, "float", "inMin");    QUERY->doc_func(QUERY, "Get input min.");     QUERY->add_mfun(QUERY, range_getInMax, "float", "inMax");    QUERY->doc_func(QUERY, "Get input max.");     QUERY->add_mfun(QUERY, range_getOutMin, "float", "outMin");    QUERY->doc_func(QUERY, "Get output min.");     QUERY->add_mfun(QUERY, range_getOutMax, "float", "outMax");    QUERY->doc_func(QUERY, "Get output max.");     QUERY->add_mfun(QUERY, range_getInCenter, "float", "inCenter");    QUERY->doc_func(QUERY, "Get input center.");     QUERY->add_mfun(QUERY, range_getInRadius, "float", "inRad");    QUERY->doc_func(QUERY, "Get input radius.");     QUERY->add_mfun(QUERY, range_getOutCenter, "float", "outCenter");    QUERY->doc_func(QUERY, "Get output center.");     QUERY->add_mfun(QUERY, range_getOutRadius, "float", "outRad");    QUERY->doc_func(QUERY, "Get output radius.");     QUERY->add_mfun(QUERY, range_setClip, "int", "clip");    QUERY->add_arg(QUERY, "int", "val");    QUERY->doc_func(QUERY, "Set Range's clipping mode. Accepted values are: 0 (no clipping), 1 (hard clipping). Defaults to 0");     QUERY->add_mfun(QUERY, range_getClip, "int", "clip");    QUERY->doc_func(QUERY, "Get clip state.");         // this reserves a variable in the ChucK internal class to store     // referene to the c++ class we defined above    range_data_offset = QUERY->add_mvar(QUERY, "int", "@s_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(range_ctor){    // get the offset where we'll store our internal c++ class pointer    OBJ_MEMBER_INT(SELF, range_data_offset) = 0;        // instantiate our internal c++ class representation    Range * s_obj = new Range(API->vm->get_srate(API, SHRED));        // store the pointer in the ChucK object member    OBJ_MEMBER_INT(SELF, range_data_offset) = (t_CKINT) s_obj;}  // implementation for the destructorCK_DLL_DTOR(range_dtor){    // get our c++ class pointer    Range * s_obj = (Range *) OBJ_MEMBER_INT(SELF, range_data_offset);    // check it    if( s_obj )    {        // clean up        delete s_obj;        OBJ_MEMBER_INT(SELF, range_data_offset) = 0;        s_obj = NULL;    }}  // implementation for tick functionCK_DLL_TICK(range_tick){    // get our c++ class pointer    Range * s_obj = (Range *) OBJ_MEMBER_INT(SELF, range_data_offset);     // invoke our tick function; store in the magical out variable    if(s_obj) *out = s_obj->tick(in);     // yes    return TRUE;} CK_DLL_MFUN(range_setInRange){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);     t_CKFLOAT inMin = GET_NEXT_FLOAT(ARGS);    t_CKFLOAT inMax = GET_NEXT_FLOAT(ARGS);     // set the return value    s_obj->setInRange(inMin, inMax);} CK_DLL_MFUN(range_setInRadius){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);     t_CKFLOAT inCenter = GET_NEXT_FLOAT(ARGS);    t_CKFLOAT inRadius = GET_NEXT_FLOAT(ARGS);     // set the return value    s_obj->setInRadius(inCenter, inRadius);} CK_DLL_MFUN(range_setOutRange){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);     t_CKFLOAT outMin = GET_NEXT_FLOAT(ARGS);    t_CKFLOAT outMax = GET_NEXT_FLOAT(ARGS);     // set the return value    s_obj->setOutRange(outMin, outMax);} CK_DLL_MFUN(range_setOutRadius){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);     t_CKFLOAT outCenter = GET_NEXT_FLOAT(ARGS);    t_CKFLOAT outRadius = GET_NEXT_FLOAT(ARGS);     // set the return value    s_obj->setOutRadius(outCenter, outRadius);} CK_DLL_MFUN(range_setRange){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);     t_CKFLOAT inMin = GET_NEXT_FLOAT(ARGS);    t_CKFLOAT inMax = GET_NEXT_FLOAT(ARGS);    t_CKFLOAT outMin = GET_NEXT_FLOAT(ARGS);    t_CKFLOAT outMax = GET_NEXT_FLOAT(ARGS);     // set the return value    s_obj->setRange(inMin, inMax, outMin, outMax);} CK_DLL_MFUN(range_setRadius){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);     t_CKFLOAT inCenter = GET_NEXT_FLOAT(ARGS);    t_CKFLOAT inRadius = GET_NEXT_FLOAT(ARGS);    t_CKFLOAT outCenter = GET_NEXT_FLOAT(ARGS);    t_CKFLOAT outRadius = GET_NEXT_FLOAT(ARGS);     // set the return value    s_obj->setRadius(inCenter, inRadius, outCenter, outRadius);} CK_DLL_MFUN(range_getInMin){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);    // set the return value    RETURN->v_float = s_obj->getInMin();} CK_DLL_MFUN(range_getInMax){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);    // set the return value    RETURN->v_float = s_obj->getInMax();} CK_DLL_MFUN(range_getOutMin){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);    // set the return value    RETURN->v_float = s_obj->getOutMin();} CK_DLL_MFUN(range_getOutMax){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);    // set the return value    RETURN->v_float = s_obj->getOutMax();} CK_DLL_MFUN(range_getInCenter){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);    // set the return value    RETURN->v_float = s_obj->getInCenter();} CK_DLL_MFUN(range_getInRadius){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);    // set the return value    RETURN->v_float = s_obj->getInRadius();} CK_DLL_MFUN(range_getOutCenter){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);    // set the return value    RETURN->v_float = s_obj->getOutCenter();} CK_DLL_MFUN(range_getOutRadius){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);    // set the return value    RETURN->v_float = s_obj->getOutRadius();} CK_DLL_MFUN(range_setClip){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);    // set the return value    RETURN->v_int = s_obj->setClip(GET_NEXT_INT(ARGS));} CK_DLL_MFUN(range_getClip){    // get our c++ class pointer    Range* s_obj = (Range*)OBJ_MEMBER_INT(SELF, range_data_offset);    // set the return value    RETURN->v_int = s_obj->getClip();}

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