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