987 lines · 24.2 KB · C++
RawDownload
/*----------------------------------------------------------------------------- Entaro!  ChucK WinFuncEnv extends Envelope.  An AR Envelope that allows for envelopes in the shape of various window functions. http://en.wikipedia.org/wiki/Window_function  Copyright (c) 2015 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>#ifdef WIN32#define _USE_MATH_DEFINES#endif#include <math.h> CK_DLL_CTOR(winfuncenv_ctor);CK_DLL_DTOR(winfuncenv_dtor); // ~ envelope functionsCK_DLL_MFUN(winfuncenv_setKeyOn);CK_DLL_MFUN(winfuncenv_setKeyOff);CK_DLL_MFUN(winfuncenv_setAttack);CK_DLL_MFUN(winfuncenv_setRelease);CK_DLL_MFUN(winfuncenv_getWindowValue); // ~ window functionsCK_DLL_MFUN(winfuncenv_setBlackman);CK_DLL_MFUN(winfuncenv_setBlackmanArg);CK_DLL_MFUN(winfuncenv_setBlackmanDerivative);CK_DLL_MFUN(winfuncenv_setBlackmanHarris);CK_DLL_MFUN(winfuncenv_setBlackmanNutall);CK_DLL_MFUN(winfuncenv_setExponential);CK_DLL_MFUN(winfuncenv_setExponentialArg);CK_DLL_MFUN(winfuncenv_setHann);CK_DLL_MFUN(winfuncenv_setHannPoisson);CK_DLL_MFUN(winfuncenv_setHannPoissonArg);// TODO CK_DLL_MFUN(winfuncenv_setKaiser);CK_DLL_MFUN(winfuncenv_setNutall);CK_DLL_MFUN(winfuncenv_setParzen);CK_DLL_MFUN(winfuncenv_setPoisson);CK_DLL_MFUN(winfuncenv_setPoissonArg);CK_DLL_MFUN(winfuncenv_setTukey);CK_DLL_MFUN(winfuncenv_setTukeyArg);CK_DLL_MFUN(winfuncenv_setWelch); CK_DLL_TICK(winfuncenv_tick);t_CKINT winfuncenv_data_offset = 0; class WindowFunc{public:    virtual float attackWindow (int n, int attack) = 0;    virtual float releaseWindow (int n, int release) = 0;}; class BlackmanFunc : public WindowFunc{public:    BlackmanFunc(float a) {        // blackman coefficients        a0 = (1.0 - a)/2.0;        a1 = 1.0/2.0;        a2 = a/2.0;         // delicious pies        two_pi = 2.0 * M_PI;        four_pi = 4.0 * M_PI;         // optimization variables        N_inv = 0.0;         twoPiVal = 0.0;        fourPiVal = 0.0;    }     float attackWindow (int n, int attack) {        if( n == 0 ) {            N_inv = 1.0/(attack * 2);             twoPiVal = two_pi * N_inv;            fourPiVal = four_pi * N_inv;             return a0 - a1 + a2;        }         return a0 - a1 * cos(twoPiVal * n) + a2 * cos(fourPiVal * n);    }    float releaseWindow (int n, int release) {        if( n == 0 ) {            N_inv = 1.0/(release * 2);             twoPiVal = two_pi * N_inv;            fourPiVal = four_pi * N_inv;        }         n = n + release;         return a0 - a1 * cos(twoPiVal * n) + a2 * cos(fourPiVal * n);    }private:    // blackman coefficients    float a0, a1, a2;     // delicious pies    float two_pi,   four_pi;    float twoPiVal, fourPiVal;     // optimization variables    float N_inv;}; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~class BlackmanDerivativeFunc : public WindowFunc{public:    BlackmanDerivativeFunc(float _a0, float _a1, float _a2, float _a3) {        // blackman-derivative coefficients        a0 = _a0;        a1 = _a1;        a2 = _a2;        a3 = _a3;         two_pi = 2.0 * M_PI;        four_pi = 4.0 * M_PI;        six_pi = 6.0 * M_PI;         N_inv = 0.0;         twoPiVal = 0.0;        fourPiVal = 0.0;        sixPiVal = 0.0;    }     float attackWindow (int n, int attack) {        if( n == 0 ) {            N_inv = 1.0/(attack * 2);             twoPiVal = two_pi * N_inv;            fourPiVal = four_pi * N_inv;            sixPiVal = six_pi * N_inv;             return a0 - a1 + a2 - a3;        }         return a0 - a1 * cos(twoPiVal * n) + a2 * cos(fourPiVal * n) - a3 * cos(sixPiVal * n);    }     float releaseWindow (int n, int release) {        if( n == 0 ) {            N_inv = 1.0/(release * 2);             twoPiVal = two_pi * N_inv;            fourPiVal = four_pi * N_inv;            sixPiVal = six_pi * N_inv;        }         n = n + release;         return a0 - a1 * cos(twoPiVal * n) + a2 * cos(fourPiVal * n) - a3 * cos(sixPiVal * n);    } private:    // blackman-derivative coefficients    float a0, a1, a2, a3;     float two_pi,   four_pi,   six_pi;    float twoPiVal, fourPiVal, sixPiVal;     float N_inv; }; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~class ExponentialFunc: public WindowFunc{public:    ExponentialFunc( float _t ) {        t_inv = 0.0;        t = _t;    }     float attackWindow (int n, int attack) {        if( n == 0 ) {            t_inv = 1.0/(attack * t);        }         return exp(-abs(n - attack) * t_inv);    }    float releaseWindow (int n, int release) {        if( n == 0 ) {            t_inv = 1.0/(release * t);             return 1.0;        }         return exp(-abs(n) * t_inv);    }private:    float t_inv, t;}; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~class HannFunc : public WindowFunc{public:    HannFunc() {        two_pi = 2.0 * M_PI;        twoPiVal = 0;    }     float attackWindow (int n, int attack) {        if( n == 0 ) {            twoPiVal = two_pi * 1.0/(attack * 2);             return 0.0;        }         return 0.5 * (1.0 - cos(twoPiVal * n));    }    float releaseWindow (int n, int release) {        if( n == 0 ) {            twoPiVal = two_pi * 1.0/(release * 2);        }         n = n + release;         return 0.5 * (1.0 - cos(twoPiVal * n));    }private:    float two_pi;    float twoPiVal;}; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~class HannPoissonFunc : public WindowFunc{public:    HannPoissonFunc( float _a ) {        a = _a;        pi = M_PI;        N_inv = 0.0;    }     float attackWindow (int n, int attack) {        if( n == 0 ) {            N_inv = 1.0/attack;        }         n = attack - n;         return 0.5 * (1.0 + cos(pi * n * N_inv)) * exp(-a * n * N_inv);    }    float releaseWindow (int n, int release) {        if( n == 0 ) {            N_inv = 1.0/release;        }         return 0.5 * (1.0 + cos(pi * n * N_inv)) * exp(-a * n * N_inv);    }private:    float a;    float pi;    float N_inv;}; /* TODOclass KaiserFunc : public WindowFunc{public:    KaiserFunc( float a ) {    }     float attackWindow (int n, int attack) {        if( n == 0 )        {        }        return 0;    }    float releaseWindow (int n, int release) {        if( n == 0 )        {        }        return 0;    }private:    float a;    float pi;};*/  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~class ParzenFunc : public WindowFunc{public:    ParzenFunc() {        N_inv = 0.0;    }     float attackWindow (int n, int attack) {        if( n == 0 ) {            N_inv = 1.0/attack;        }         n = attack - n - 1;         if( n < attack * 0.5 ) {            return 1.0 - 6.0 * pow(n * N_inv, 2) * (1.0 - (n * N_inv));        }        else {            return 2.0 * pow( 1.0 - n * N_inv, 3);        }    }    float releaseWindow (int n, int release) {        if( n == 0 ) {            N_inv = 1.0/release;        }         if( n < release * 0.5 ) {            return 1.0 - 6.0 * pow(n * N_inv, 2) * (1.0 - (n * N_inv));        }        else {            return 2.0 * pow( 1.0 - n * N_inv, 3);        }    }private:    float N_inv;}; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~class PoissonFunc : public WindowFunc{public:    PoissonFunc( float _a ) {        a = _a;    }     float attackWindow (int n, int attack) {        if( n == 0 ) {            N_inv = 1.0/attack;        }         n = attack - n;         return exp(-a * n * N_inv);    }    float releaseWindow (int n, int release) {        if( n == 0 ) {            N_inv = 1.0/release;        }         return exp(-a * n * N_inv);    }private:    float a;    float N_inv;}; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~class TukeyFunc : public WindowFunc{public:    TukeyFunc( float _a ) {        a = _a;        pi = M_PI;    }     float attackWindow (int n, int attack) {        if( n == 0 )        {        }        if ( n < a * attack ) {            return 0.5 * (1.0 + cos(pi * ((2 * n)/(a * attack * 2.0) - 1.0)));        }        else {            return 1.0;        }    }    float releaseWindow (int n, int release) {        if( n == 0 )        {        }         if ( n < a * release ) {            return 1.0;        }        else {            return 0.5 * (1.0 + cos(pi * ((2 * n)/(a * release * 2.0) - 2.0/a + 1.0)));        }    }private:    float a;    float pi;}; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~class WelchFunc : public WindowFunc{public:    WelchFunc() {        N_inv = 0.0;    }     float attackWindow (int n, int attack) {        if( n == 0 ) {            N_inv = 1.0/attack;        }         return 1.0 - pow((n - attack) * N_inv, 2);    }    float releaseWindow (int n, int release) {        if( n == 0 ) {            N_inv = 1.0/release;        }         n = n + release;         return 1.0 - pow((n - release) * N_inv, 2);    }private:    float N_inv;}; // ~~~~~~~~~~~~~class WinFuncEnv{public:    // constructor    WinFuncEnv( t_CKFLOAT fs)    {        m_n = 0;         m_keyOn = 0;        m_keyOff = 0;         m_attack = 0;        m_release = 0;         m_currentLevel = 0;        m_keyOnLevel = 0;        m_keyOffLevel = 0;         m_windowValue = 0;         // default window        m_func = new HannFunc();    }     WindowFunc*  m_func;     // keyOn    int setKeyOn()    {        m_keyOnLevel = m_currentLevel;        m_n = 0;        m_keyOn = 1;        m_keyOff = 0;         return m_keyOn;    }     int setKeyOn( t_CKINT )    {        m_keyOnLevel = m_currentLevel;        m_n = 0;        m_keyOn = 1;        m_keyOff = 0;         return m_keyOn;    }     // keyOff    int setKeyOff()    {        m_keyOffLevel = m_currentLevel;        m_n = 0;

Lines 1–500 of 987.

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