annotate projects/d-box/ADSR.h @ 0:8a575ba3ab52

Initial commit.
author andrewm
date Fri, 31 Oct 2014 19:10:17 +0100
parents
children
rev   line source
andrewm@0 1 //
andrewm@0 2 // ADRS.h
andrewm@0 3 //
andrewm@0 4 // Created by Nigel Redmon on 12/18/12.
andrewm@0 5 // EarLevel Engineering: earlevel.com
andrewm@0 6 // Copyright 2012 Nigel Redmon
andrewm@0 7 //
andrewm@0 8 // For a complete explanation of the ADSR envelope generator and code,
andrewm@0 9 // read the series of articles by the author, starting here:
andrewm@0 10 // http://www.earlevel.com/main/2013/06/01/envelope-generators/
andrewm@0 11 //
andrewm@0 12 // License:
andrewm@0 13 //
andrewm@0 14 // This source code is provided as is, without warranty.
andrewm@0 15 // You may copy and distribute verbatim copies of this document.
andrewm@0 16 // You may modify and use this source code to create binary code for your own purposes, free or commercial.
andrewm@0 17 //
andrewm@0 18
andrewm@0 19 #ifndef ADRS_h
andrewm@0 20 #define ADRS_h
andrewm@0 21
andrewm@0 22 #include <stdio.h>
andrewm@0 23 #include <string>
andrewm@0 24
andrewm@0 25 using namespace std;
andrewm@0 26
andrewm@0 27 enum envState {
andrewm@0 28 env_idle = 0,
andrewm@0 29 env_attack,
andrewm@0 30 env_decay,
andrewm@0 31 env_sustain,
andrewm@0 32 env_release
andrewm@0 33 };
andrewm@0 34
andrewm@0 35 class ADSR {
andrewm@0 36 public:
andrewm@0 37 ADSR(void);
andrewm@0 38 ~ADSR(void);
andrewm@0 39 float process(void);
andrewm@0 40 float process(int sampleCount);
andrewm@0 41 float getOutput(void);
andrewm@0 42 int getState(void);
andrewm@0 43 void gate(int on);
andrewm@0 44 void setAttackRate(float rate);
andrewm@0 45 void setDecayRate(float rate);
andrewm@0 46 void setReleaseRate(float rate);
andrewm@0 47 void setSustainLevel(float level);
andrewm@0 48 void setTargetRatioA(float targetRatio);
andrewm@0 49 void setTargetRatioDR(float targetRatio);
andrewm@0 50 void reset(void);
andrewm@0 51
andrewm@0 52 protected:
andrewm@0 53 int state;
andrewm@0 54 float output;
andrewm@0 55 float attackRate;
andrewm@0 56 float decayRate;
andrewm@0 57 float releaseRate;
andrewm@0 58 float attackCoef;
andrewm@0 59 float decayCoef;
andrewm@0 60 float releaseCoef;
andrewm@0 61 float sustainLevel;
andrewm@0 62 float targetRatioA;
andrewm@0 63 float targetRatioDR;
andrewm@0 64 float attackBase;
andrewm@0 65 float decayBase;
andrewm@0 66 float releaseBase;
andrewm@0 67 string name;
andrewm@0 68 float calcCoef(float rate, float targetRatio);
andrewm@0 69 };
andrewm@0 70
andrewm@0 71 inline float ADSR::process() {
andrewm@0 72 switch (state) {
andrewm@0 73 case env_idle:
andrewm@0 74 break;
andrewm@0 75 case env_attack:
andrewm@0 76 output = attackBase + output * attackCoef;
andrewm@0 77 if (output >= 1.0) {
andrewm@0 78 output = 1.0;
andrewm@0 79 state = env_decay;
andrewm@0 80 }
andrewm@0 81 break;
andrewm@0 82 case env_decay:
andrewm@0 83 output = decayBase + output * decayCoef;
andrewm@0 84 if (output <= sustainLevel) {
andrewm@0 85 output = sustainLevel;
andrewm@0 86 state = env_sustain;
andrewm@0 87 }
andrewm@0 88 break;
andrewm@0 89 case env_sustain:
andrewm@0 90 break;
andrewm@0 91 case env_release:
andrewm@0 92 output = releaseBase + output * releaseCoef;
andrewm@0 93 if (output <= 0.0) {
andrewm@0 94 output = 0.0;
andrewm@0 95 state = env_idle;
andrewm@0 96 }
andrewm@0 97 break;
andrewm@0 98 }
andrewm@0 99 return output;
andrewm@0 100 }
andrewm@0 101
andrewm@0 102 inline float ADSR::process(int sampleCount)
andrewm@0 103 {
andrewm@0 104 float retVal = 0;
andrewm@0 105
andrewm@0 106 if(state != env_idle)
andrewm@0 107 {
andrewm@0 108 for(int i=0; i<sampleCount; i++)
andrewm@0 109 retVal = process();
andrewm@0 110 }
andrewm@0 111
andrewm@0 112 return retVal;
andrewm@0 113 }
andrewm@0 114
andrewm@0 115 inline void ADSR::gate(int gate) {
andrewm@0 116
andrewm@0 117 if (gate)
andrewm@0 118 state = env_attack;
andrewm@0 119 else if (state != env_idle)
andrewm@0 120 state = env_release;
andrewm@0 121 }
andrewm@0 122
andrewm@0 123 inline int ADSR::getState() {
andrewm@0 124 return state;
andrewm@0 125 }
andrewm@0 126
andrewm@0 127 inline void ADSR::reset() {
andrewm@0 128 state = env_idle;
andrewm@0 129 output = 0.0;
andrewm@0 130 }
andrewm@0 131
andrewm@0 132 inline float ADSR::getOutput() {
andrewm@0 133 return output;
andrewm@0 134 }
andrewm@0 135
andrewm@0 136
andrewm@0 137 #endif