1 /** 2 * Copyright 2017 Cut Through Recordings 3 * License: MIT License 4 * Author(s): Ethan Reker 5 */ 6 module ddsp.util.envelope; 7 8 import std.math; 9 import std.algorithm; 10 11 /// Envelop Detector with adjustable attack and release times. Great for compressors 12 /// and meters. 13 /+ 14 http://www.musicdsp.org/showArchiveComment.php?ArchiveID=97 15 +/ 16 class EnvelopeDetector 17 { 18 public: 19 nothrow: 20 @nogc: 21 22 this() 23 { 24 _envelope = 0f; 25 } 26 27 void setSampleRate(const float sampleRate) 28 { 29 _sampleRate = sampleRate; 30 } 31 32 void setEnvelope(const float attackTime, const float releaseTime) 33 { 34 _ga = exp(-1/(_sampleRate * attackTime / 1000)); 35 _gr = exp(-1 / (_sampleRate * releaseTime / 1000)); 36 } 37 38 void detect(float input) 39 { 40 float envIn = abs(input); 41 42 if(_envelope < envIn) 43 _envelope = _envelope * _ga + (1 - _ga) * envIn; 44 else 45 _envelope = _envelope * _gr + (1 - _gr) * envIn; 46 47 } 48 49 float getEnvelope() 50 { 51 return _envelope; 52 } 53 54 private: 55 /// Attack coefficient 56 float _ga; 57 58 /// Release coefficient 59 float _gr; 60 61 /// stores the current value of the envelope; 62 float _envelope; 63 64 /// Sample Rate 65 float _sampleRate; 66 } 67 68 /// Simple Peak envelope follower, useful for meters. 69 /+ 70 http://www.musicdsp.org/archive.php?classid=2#19 71 +/ 72 class PeakFollower 73 { 74 public: 75 nothrow: 76 @nogc: 77 78 this() 79 { 80 _envelope = 0f; 81 } 82 83 void setSampleRate(const float sampleRate) 84 { 85 _sampleRate = sampleRate; 86 } 87 88 void initialize(const float decayTime) 89 { 90 _decay = pow(0.5, 1.0 / (decayTime * _sampleRate)); 91 } 92 93 void detect(const float input) 94 { 95 float absInput = abs(input); 96 97 if(absInput >= _envelope) 98 _envelope = absInput; 99 else 100 { 101 _envelope = clamp(_envelope * _decay, 0.0f, 1.0f); 102 } 103 } 104 105 float getEnvelope() 106 { 107 return _envelope; 108 } 109 110 private: 111 float _envelope; 112 113 float _decay; 114 115 float _sampleRate; 116 } 117 118 /+class SimpleRMS 119 { 120 public: 121 nothrow: 122 @nogc: 123 124 this() 125 { 126 _envelope = 0.0f; 127 } 128 129 void setSampleRate(float sampleRate) 130 { 131 _sampleRate = sampleRate; 132 } 133 134 void initialize(uint windowSize) 135 { 136 _windowSize = windowSize; 137 buffer = cast(T*) malloc(windowSize * T.sizeof); 138 } 139 140 void detect(float input) 141 { 142 143 } 144 145 float getEnvelope() 146 { 147 return _envelope; 148 } 149 150 private: 151 float[] buffer; 152 }+/