687 lines · 18.8 KB · C++
RawDownload
/*----------------------------------------------------------------------------- Entaro!  An ADSR Envelope that allows for power-shaped stages.  Copyright (c) 2017 Eric Heep. All rights reserved.  This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details.  You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U.S.A.-----------------------------------------------------------------------------*/ #include "chuck_dl.h"#include "chuck_def.h" #include <stdio.h>#include <limits.h>#include <math.h> CK_DLL_CTOR(poweradsr_ctor);CK_DLL_DTOR(poweradsr_dtor); // settersCK_DLL_MFUN(poweradsr_setKeyOn);CK_DLL_MFUN(poweradsr_setKeyOff); CK_DLL_MFUN(poweradsr_setAllTimes);CK_DLL_MFUN(poweradsr_setAttackTime);CK_DLL_MFUN(poweradsr_setDecayTime);CK_DLL_MFUN(poweradsr_setReleaseTime); CK_DLL_MFUN(poweradsr_setAllCurves);CK_DLL_MFUN(poweradsr_setAttackCurve);CK_DLL_MFUN(poweradsr_setDecayCurve);CK_DLL_MFUN(poweradsr_setReleaseCurve); CK_DLL_MFUN(poweradsr_setSustainLevel); // gettersCK_DLL_MFUN(poweradsr_getSustainLevel); CK_DLL_MFUN(poweradsr_getAttackTime);CK_DLL_MFUN(poweradsr_getDecayTime);CK_DLL_MFUN(poweradsr_getReleaseTime); CK_DLL_MFUN(poweradsr_getAttackCurve);CK_DLL_MFUN(poweradsr_getDecayCurve);CK_DLL_MFUN(poweradsr_getReleaseCurve); CK_DLL_MFUN(poweradsr_getValue);CK_DLL_MFUN(poweradsr_getState); // tickCK_DLL_TICK(poweradsr_tick); t_CKINT poweradsr_data_offset = 0;  class PowerADSR{public:    // constructor    PowerADSR( t_CKFLOAT fs)    {        // stage durations, set to 1::second        m_attackDuration = fs;        m_decayDuration = fs;        m_releaseDuration = fs;         m_sustainLevel = 0.5;         // for one less calculation per tick        m_inverseAttackDuration = 1.0/fs;        m_inverseDecayDuration = 1.0/fs;        m_inverseReleaseDuration = 1.0/fs;         // values        m_linearValue = 0.0;        m_powerValue = 0.0;        m_offsetValue = 0.0;        m_scalarValue = 1.0;         // sample multipler        m_value = 0.0;        m_target = 1.0;         // time tracking        m_sampleCount = 0.0;         // initializes to linear envelopes        m_attackCurve = 1.0;        m_decayCurve = 1.0;        m_releaseCurve = 1.0;         m_curve = 1.0;        m_inverseDuration = 0.0;         m_state = DONE;    }     // for Chugins extending UGen    SAMPLE tick( SAMPLE in )    {        switch(m_state)        {         case ATTACK:            m_sampleCount++;            if (m_sampleCount >= m_attackDuration) {                m_sampleCount = m_decayDuration;                m_inverseDuration = m_inverseDecayDuration;                m_curve = m_decayCurve;                m_offsetValue = m_sustainLevel;                m_scalarValue = m_target - m_sustainLevel;                 m_state = DECAY;            }            break;         case DECAY:            m_sampleCount--;            if (m_sampleCount <= 0.0) {                m_sampleCount = m_releaseDuration;                m_inverseDuration = m_inverseReleaseDuration;                m_curve = m_releaseCurve;                m_offsetValue = 0.0;                m_scalarValue = m_sustainLevel;                 m_state = SUSTAIN;            }            break;         case SUSTAIN:            break;         case RELEASE:            m_sampleCount--;            if (m_sampleCount <= 0.0) {                m_linearValue = 0.0;                m_scalarValue = 1.0;                m_state = DONE;            }            break;         case DONE:            break;        }         // linear scaling derived from duration        m_linearValue = m_sampleCount * m_inverseDuration;         // power curve        m_powerValue = pow(m_linearValue, m_curve);         // added calculations for stage changes        m_value = m_powerValue * m_scalarValue + m_offsetValue;         return in * m_value;    }     // keyOn stuff    int setKeyOn()    {        m_sampleCount = 0.0;        m_inverseDuration = m_inverseAttackDuration;        m_curve = m_attackCurve;        m_offsetValue = m_value;        m_scalarValue = m_target - m_value;         m_state = ATTACK;        return 1;    }     int setKeyOn( t_CKINT )    {        m_sampleCount = 0.0;        m_inverseDuration = m_inverseAttackDuration;        m_curve = m_attackCurve;        m_offsetValue = m_value;        m_scalarValue = m_target - m_value;         m_state = ATTACK;        return 1;    }     // keyOff stuff    int setKeyOff()    {        m_sampleCount = m_releaseDuration;        m_inverseDuration = m_inverseReleaseDuration;        m_curve = m_releaseCurve;        m_offsetValue = 0.0;        m_scalarValue = m_value;         m_state = RELEASE;        return 0;    }     int setKeyOff( t_CKINT )    {        m_sampleCount = m_releaseDuration;        m_inverseDuration = m_inverseReleaseDuration;        m_curve = m_releaseCurve;        m_offsetValue = 0.0;        m_scalarValue = m_value;         m_state = RELEASE;        return 0;    }     // set all durations and sustain level    void setAll( t_CKDUR a, t_CKDUR d, t_CKFLOAT s, t_CKDUR r )    {        setAttackTime(a);        setDecayTime(d);        setSustainLevel(s);        setReleaseTime(r);    }     float setAttackTime( t_CKDUR a )    {        m_attackDuration = (float)a;         if (m_attackDuration < 0.0) {            m_attackDuration = -m_attackDuration;        }         m_inverseAttackDuration = 1.0 / m_attackDuration;        return a;    }     float setDecayTime( t_CKDUR d )    {        m_decayDuration = (float)d;         if (m_decayDuration < 0.0) {            m_decayDuration = -m_decayDuration;        }         m_inverseDecayDuration = 1.0 / m_decayDuration;        return d;    }     float setSustainLevel( t_CKFLOAT s )    {        m_sustainLevel = s;         if (m_sustainLevel < 0.0) {            m_sustainLevel = -m_sustainLevel;        }         return s;    }     float setReleaseTime( t_CKDUR r )    {        m_releaseDuration = (float)r;         if (m_releaseDuration < 0.0) {            m_releaseDuration = -m_releaseDuration;        }         m_inverseReleaseDuration = 1.0 / m_releaseDuration;        return m_releaseDuration;    }     // set all power curves    void setAllCurves( t_CKFLOAT a, t_CKFLOAT d, t_CKFLOAT r )    {        setAttackCurve(a);        setDecayCurve(d);        setReleaseCurve(r);    }     float setAttackCurve( t_CKFLOAT a)    {        m_attackCurve = a;        return a;    }     float setDecayCurve( t_CKFLOAT d)    {        m_decayCurve = d;        return d;    }     float setReleaseCurve( t_CKFLOAT r)    {        m_releaseCurve = r;        return r;    }     float getAttackTime()    {        return m_attackDuration;    }     float getDecayTime()    {        return m_decayDuration;    }     float getSustainLevel()    {        return m_sustainLevel;    }     float getReleaseTime()    {        return m_releaseDuration;    }     float getAttackCurve()    {        return m_attackCurve;    }     float getDecayCurve()    {        return m_decayCurve;    }     float getReleaseCurve()    {        return m_releaseCurve;    }     float getValue()    {        return m_value;    }     int getState()    {        return m_state;    }  private:    // stage durations    float m_attackDuration;    float m_decayDuration;    float m_releaseDuration;     float m_sustainLevel;     // for one less calculation per tick    float m_inverseAttackDuration;    float m_inverseDecayDuration;    float m_inverseReleaseDuration;     // values    float m_linearValue;    float m_powerValue;    float m_offsetValue;    float m_scalarValue;     // sample multiplier    float m_value;    float m_target;     // time tracking    float m_sampleCount;     // curves    float m_attackCurve;    float m_decayCurve;    float m_releaseCurve;     float m_curve;    float m_inverseDuration;     enum States {        DONE = 0,        ATTACK,        DECAY,        SUSTAIN,        RELEASE,    };     States m_state;};  CK_DLL_QUERY( PowerADSR){    QUERY->setname(QUERY, "PowerADSR");     QUERY->begin_class(QUERY, "PowerADSR", "Envelope");    QUERY->doc_class(QUERY, "ADSR envelope that uses a power function to create curved envelope phases. In general, curves under 1.0 are sharp, while curves over 1.0 are soft.");    QUERY->add_ex(QUERY, "effects/PowerADSR-feedback-beatings.ck");    QUERY->add_ex(QUERY, "effects/PowerADSR.ck");     QUERY->add_ctor(QUERY, poweradsr_ctor);    QUERY->add_dtor(QUERY, poweradsr_dtor);     QUERY->add_ugen_func(QUERY, poweradsr_tick, NULL, 1, 1);     QUERY->add_mfun(QUERY, poweradsr_setKeyOn, "int", "keyOn");    QUERY->doc_func(QUERY, "Begins the attack phase of the envelope.");     QUERY->add_mfun(QUERY, poweradsr_setKeyOn, "int", "keyOn");    QUERY->add_arg(QUERY, "int", "keyOn");    QUERY->doc_func(QUERY, "Begins the attack phase of the envelope.");     QUERY->add_mfun(QUERY, poweradsr_setKeyOff, "int", "keyOff");    QUERY->doc_func(QUERY, "Begins the release phase of the envelope.");     QUERY->add_mfun(QUERY, poweradsr_setKeyOff, "int", "keyOff");    QUERY->add_arg(QUERY, "int", "keyOff");    QUERY->doc_func(QUERY, "Begins the release phase of the envelope.");     QUERY->add_mfun(QUERY, poweradsr_setAllTimes, "void", "set");    QUERY->add_arg(QUERY, "dur", "attackDuration");    QUERY->add_arg(QUERY, "dur", "decayDuration");    QUERY->add_arg(QUERY, "float", "sustainLevel");    QUERY->add_arg(QUERY, "dur", "releaseDuration");    QUERY->doc_func(QUERY, "Sets duration of the attack, decay, and release phases; as well as the sustain level (ADSR order).");     QUERY->add_mfun(QUERY, poweradsr_setAttackTime, "dur", "attack");    QUERY->add_arg(QUERY, "dur", "attackDuration");    QUERY->doc_func(QUERY, "Sets duration of the attack phase.");     QUERY->add_mfun(QUERY, poweradsr_setAttackTime, "dur", "attackTime");    QUERY->add_arg(QUERY, "dur", "attackDuration");    QUERY->doc_func(QUERY, "Sets duration of the attack phase.");     QUERY->add_mfun(QUERY, poweradsr_setDecayTime, "dur", "decay");    QUERY->add_arg(QUERY, "dur", "decayDuration");    QUERY->doc_func(QUERY, "Sets duration of the decay phase.");     QUERY->add_mfun(QUERY, poweradsr_setDecayTime, "dur", "decayTime");    QUERY->add_arg(QUERY, "dur", "decayDuration");    QUERY->doc_func(QUERY, "Sets duration of the decay phase.");     QUERY->add_mfun(QUERY, poweradsr_setSustainLevel, "float", "sustainLevel");    QUERY->add_arg(QUERY, "float", "sustainLevel");    QUERY->doc_func(QUERY, "Sets sustain level.");     QUERY->add_mfun(QUERY, poweradsr_setReleaseTime, "dur", "release");    QUERY->add_arg(QUERY, "dur", "releaseDuration");    QUERY->doc_func(QUERY, "Sets duration of the release phase.");     QUERY->add_mfun(QUERY, poweradsr_setReleaseTime, "dur", "releaseTime");    QUERY->add_arg(QUERY, "dur", "releaseDuration");    QUERY->doc_func(QUERY, "Sets duration of the release phase.");     QUERY->add_mfun(QUERY, poweradsr_setAllCurves, "void", "setCurves");    QUERY->add_arg(QUERY, "float", "attackCurve");    QUERY->add_arg(QUERY, "float", "decayCurve");    QUERY->add_arg(QUERY, "float", "releaseCurve");    QUERY->doc_func(QUERY, "Sets envelope curves of the attack, decay, and release phases.");     QUERY->add_mfun(QUERY, poweradsr_setAttackCurve, "float", "attackCurve");    QUERY->add_arg(QUERY, "float", "attackCurve");    QUERY->doc_func(QUERY, "Sets envelope curve of the attack phase.");     QUERY->add_mfun(QUERY, poweradsr_setDecayCurve, "float", "decayCurve");    QUERY->add_arg(QUERY, "float", "decayCurve");    QUERY->doc_func(QUERY, "Sets envelope curve of the decay phase.");     QUERY->add_mfun(QUERY, poweradsr_setReleaseCurve, "float", "releaseCurve");    QUERY->add_arg(QUERY, "float", "releaseCurve");    QUERY->doc_func(QUERY, "Sets envelope curve of the release phase.");     QUERY->add_mfun(QUERY, poweradsr_getSustainLevel, "float", "sustainLevel");    QUERY->doc_func(QUERY, "Gets sustain level.");     QUERY->add_mfun(QUERY, poweradsr_getAttackTime, "dur", "attackTime");    QUERY->doc_func(QUERY, "Gets the attack duration.");     QUERY->add_mfun(QUERY, poweradsr_getDecayTime, "dur", "decayTime");    QUERY->doc_func(QUERY, "Gets the decay duration.");     QUERY->add_mfun(QUERY, poweradsr_getReleaseTime, "dur", "releaseTime");    QUERY->doc_func(QUERY, "Gets the release duration.");     QUERY->add_mfun(QUERY, poweradsr_getAttackCurve, "float", "attackCurve");    QUERY->doc_func(QUERY, "Gets the attack curve.");     QUERY->add_mfun(QUERY, poweradsr_getDecayCurve, "float", "decayCurve");    QUERY->doc_func(QUERY, "Gets the decay curve.");     QUERY->add_mfun(QUERY, poweradsr_getReleaseCurve, "float", "releaseCurve");    QUERY->doc_func(QUERY, "Gets the release curve.");     QUERY->add_mfun(QUERY, poweradsr_getValue, "float", "value");    QUERY->doc_func(QUERY, "Gets current envelope value."); 

Lines 1–500 of 687.

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