@@ -132,6 +132,170 @@ struct ADEnvelope {
132132 env = _env;
133133 }
134134};
135+
136+
137+ struct ADSREnvelope {
138+ enum Stage {
139+ IDLE ,
140+ ATTACK ,
141+ DECAY ,
142+ SUSTAIN ,
143+ RELEASE
144+ };
145+ enum Func {
146+ EASE_OUT ,
147+ LINEAR ,
148+ EASE_IN ,
149+ };
150+
151+ Stage stage = IDLE ;
152+ int current_index = 0 ;
153+ float _env = MIN_VALUE ;
154+ float env = 0 ;
155+ float attack_time = 0 .01f ;
156+ float decay_time = 0 .01f ;
157+ float release_time = 0 .01f ;
158+ float sustain_level = 0 .5f ;
159+ float attack_shape = 0 .f;
160+ float decay_shape = 0 .f;
161+ float release_shape = 0 .f;
162+ bool loop = false ;
163+ bool eoc = false ;
164+ float sampleTime = 0 ;
165+ int processCount = 0 ;
166+
167+ ADSREnvelope () {}
168+
169+ void set_attack (float attack_time) {
170+ this ->attack_time = clamp (attack_time, 0 .01f , 10 .f );
171+ }
172+ void set_decay (float decay_time) {
173+ this ->decay_time = clamp (decay_time, 0 .01f , 10 .f );
174+ }
175+ void set_release (float release_time) {
176+ this ->release_time = clamp (release_time, 0 .01f , 10 .f );
177+ }
178+ void set_sustain (float sustain_level) {
179+ this ->sustain_level = clamp (sustain_level, 0 .f , 1 .f );
180+ }
181+ void set_loop (bool loop) {
182+ this ->loop = loop;
183+ }
184+ void set_attack_shape (float shape){
185+ this ->attack_shape = shape;
186+ }
187+ void set_decay_shape (float shape){
188+ this ->decay_shape = shape;
189+ }
190+ void set_release_shape (float shape){
191+ this ->release_shape = shape;
192+ }
193+ void set_index (int index) {
194+ this ->current_index = index;
195+ }
196+ void trigger () {
197+ stage = ATTACK ;
198+ _env = MIN_VALUE ;
199+ }
200+ void retrigger () {
201+ stage = ATTACK ;
202+ }
203+ void reset () {
204+ stage = IDLE ;
205+ _env = MIN_VALUE ;
206+ }
207+ void process (float st) {
208+ processCount++;
209+ sampleTime += st;
210+ if (processCount < 64 ) {
211+ return ;
212+ }
213+ else {
214+ processCount = 0 ;
215+ st = sampleTime;
216+ sampleTime = 0 ;
217+ }
218+ switch (stage) {
219+ case IDLE :
220+ eoc = false ;
221+ break ;
222+ case ATTACK :
223+ eoc = false ;
224+ if (attack_shape < 0 .f ) {
225+ attack_shape = abs (attack_shape);
226+ float func1 = (1 .f - _env) * 6 .21461f * st / attack_time;
227+ float func2 = st / attack_time;
228+ float out = func1 * attack_shape + func2 * (1 .f - attack_shape);
229+ _env += out;
230+ }
231+ else if (attack_shape > 0 .f ) {
232+ float func1 = _env * 6 .21461f * st / attack_time;
233+ float func2 = st / attack_time;
234+ float out = func1 * attack_shape + func2 * (1 .f - attack_shape);
235+ _env += out;
236+ }
237+ else {
238+ _env += st / attack_time;
239+ }
240+ if (_env >= MAX_VALUE ) {
241+ _env = MAX_VALUE ;
242+ stage = DECAY ;
243+ }
244+ break ;
245+ case DECAY :
246+ if (decay_shape < 0 .f ) {
247+ decay_shape = abs (decay_shape);
248+ float func1 = _env * 6 .21461f * st / decay_time;
249+ float func2 = st / decay_time;
250+ float out = func1 * decay_shape + func2 * (1 .f - decay_shape);
251+ _env -= out;
252+ }
253+ else if (decay_shape > 0 .f ) {
254+ float func1 = (1 .f - _env) * 6 .21461f * st / decay_time;
255+ float func2 = st / decay_time;
256+ float out = func1 * decay_shape + func2 * (1 .f - decay_shape);
257+ _env -= out;
258+ }
259+ else {
260+ _env -= st / decay_time;
261+ }
262+ if (_env <= sustain_level) {
263+ _env = sustain_level;
264+ stage = SUSTAIN ;
265+ }
266+ break ;
267+ case SUSTAIN :
268+ eoc = false ;
269+ break ;
270+ case RELEASE :
271+ if (release_shape < 0 .f ) {
272+ release_shape = abs (release_shape);
273+ float func1 = _env * 6 .21461f * st / release_time;
274+ float func2 = st / release_time;
275+ float out = func1 * release_shape + func2 * (1 .f - release_shape);
276+ _env -= out;
277+ }
278+ else if (release_shape > 0 .f ) {
279+ float func1 = (1 .f - _env) * 6 .21461f * st / release_time;
280+ float func2 = st / release_time;
281+ float out = func1 * release_shape + func2 * (1 .f - release_shape);
282+ _env -= out;
283+ }
284+ else {
285+ _env -= st / release_time;
286+ }
287+ if (_env <= MIN_VALUE ) {
288+ _env = MIN_VALUE ;
289+ eoc = true ;
290+ if (loop) {
291+ stage = ATTACK ;
292+ } else {
293+ stage = IDLE ;
294+ }
295+ }
296+ break ;
297+ }
298+ _env = clamp (_env, MIN_VALUE , MAX_VALUE );
135299 env = _env;
136300 }
137301};
0 commit comments