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