1 /* B.Harvestr
2  * LV2 Plugin
3  *
4  * Copyright (C) 2018, 2019 by Sven Jähnichen
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #ifndef ENVELOPE_HPP_
22 #define ENVELOPE_HPP_
23 
24 #include <cmath>
25 #include <limits>
26 #include <cstdio>
27 #define M_EXP_M3 0.049787068
28 
29 class Envelope
30 {
31 protected:
32         double attack_;
33         double decay_;
34         double sustain_;
35         double release_;
36         double releaseStartTime_;
37         double releaseStartValue_;
38 
39 public:
Envelope()40         Envelope () : Envelope (0.0, 0.0, 0.0, 0.0) {}
41 
Envelope(const double attack,const double decay,const double sustain,const double release)42         Envelope (const double attack, const double decay, const double sustain, const double release) :
43         attack_ (attack),
44         decay_ (decay),
45         sustain_ (sustain),
46         release_ (release),
47         releaseStartTime_ (std::numeric_limits<double>::max()),
48         releaseStartValue_ (0.0)
49         {}
50 
releaseAt(const double time)51         void releaseAt (const double time)
52         {
53                 releaseStartTime_ = std::numeric_limits<double>::max();
54                 releaseStartValue_ = getValue (time);
55                 releaseStartTime_ = time;
56         }
57 
getValue(const double time) const58         double getValue (const double time) const
59         {
60                 if (time < releaseStartTime_)
61                 {
62                         if (time < 0.0) return 0.0;
63 
64                         if (time < attack_)
65                         {
66                                 double t = time / attack_;
67                                 return (1.0 - exp (-3.0 * t) + t * M_EXP_M3);
68                         }
69 
70                         if (time == attack_) return 1.0;
71 
72                         if (time < attack_ + decay_)
73                         {
74                                 double t = (time - attack_) / decay_;
75                                 return 1.0 - (1.0 - sustain_) * (1.0 - exp (-3.0 * t) + t * M_EXP_M3);
76                         }
77 
78                         return sustain_;
79                 }
80                 else
81                 {
82                         if (time < releaseStartTime_ + release_)
83                         {
84                                 double t = (time - releaseStartTime_) / release_;
85                                 return releaseStartValue_ - releaseStartValue_ * (1.0 - exp (-3.0 * t) + t * M_EXP_M3);
86                         }
87 
88                         return 0.0;
89                 }
90         }
91 
getRelease() const92         double getRelease() const {return release_;}
93 
94 };
95 
96 #endif /* ENVELOPE_HPP_ */
97