/[svn]/linuxsampler/trunk/src/engines/gig/EGADSR.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/engines/gig/EGADSR.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3328 - (hide annotations) (download)
Sun Jul 23 18:27:29 2017 UTC (6 years, 9 months ago) by schoenebeck
File size: 15814 byte(s)
* gig Engine: Added support for controlling whether the individual
  EGADSR stages may be aborted (as LinuxSampler extension to the
  original GigaStudio 4 format).
* Bumped version (2.0.0.svn73).

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 56 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 3328 * Copyright (C) 2005 - 2017 Christian Schoenebeck *
7 schoenebeck 53 * *
8     * This program is free software; you can redistribute it and/or modify *
9     * it under the terms of the GNU General Public License as published by *
10     * the Free Software Foundation; either version 2 of the License, or *
11     * (at your option) any later version. *
12     * *
13     * This program is distributed in the hope that it will be useful, *
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16     * GNU General Public License for more details. *
17     * *
18     * You should have received a copy of the GNU General Public License *
19     * along with this program; if not, write to the Free Software *
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21     * MA 02111-1307 USA *
22     ***************************************************************************/
23    
24     #include "EGADSR.h"
25    
26 schoenebeck 1424 #include "../../common/global_private.h"
27    
28 schoenebeck 53 namespace LinuxSampler { namespace gig {
29    
30 schoenebeck 3328 EGADSR::EGADSR() : EG() {
31     AttackCancel = true;
32     AttackHoldCancel = true;
33     Decay1Cancel = true;
34     Decay2Cancel = true;
35     ReleaseCancel = true;
36     }
37    
38     #define isTransitionEvent(type) \
39     ( type == event_release || type == event_cancel_release )
40    
41 persson 2055 void EGADSR::update(event_t Event, uint SampleRate) {
42     if (atEnd(Event)) return;
43 schoenebeck 738
44 persson 783 if (Event == event_hold_end) HoldAttack = false;
45    
46 schoenebeck 738 switch (Stage) {
47     case stage_attack:
48 persson 783 switch (Event) {
49     case event_release:
50 schoenebeck 3328 if (AttackCancel)
51     enterNextStageForReleaseEvent(SampleRate);
52     else
53     PostponedEvent = Event;
54 persson 783 break;
55     case event_stage_end:
56 schoenebeck 3328 if (PostponedEvent == event_release)
57     enterNextStageForReleaseEvent(SampleRate);
58     else if (HoldAttack)
59 persson 783 enterAttackHoldStage();
60     else
61     enterDecay1Part1Stage(SampleRate);
62     break;
63 schoenebeck 3034 default: ; // noop
64 schoenebeck 53 }
65 schoenebeck 738 break;
66     case stage_attack_hold:
67     switch (Event) {
68 persson 783 case event_stage_end: {// just refresh time
69     const int intMax = (unsigned int) -1 >> 1;
70     StepsLeft = intMax; // we use the highest possible value
71     break;
72     }
73     case event_hold_end:
74 schoenebeck 3328 if (PostponedEvent == event_release)
75     enterNextStageForReleaseEvent(SampleRate);
76     else
77     enterDecay1Part1Stage(SampleRate);
78 schoenebeck 53 break;
79 schoenebeck 738 case event_release:
80 schoenebeck 3328 if (AttackHoldCancel)
81     enterNextStageForReleaseEvent(SampleRate);
82     else
83     PostponedEvent = Event;
84 schoenebeck 738 break;
85 schoenebeck 3034 default: ; // noop
86 schoenebeck 53 }
87 schoenebeck 738 break;
88     case stage_decay1_part1:
89     switch (Event) {
90 persson 768 case event_stage_end:
91     enterDecay1Part2Stage(SampleRate);
92 persson 614 break;
93 persson 1909 case event_release:
94 schoenebeck 3328 if (Decay1Cancel)
95     enterNextStageForReleaseEvent(SampleRate);
96     else
97     PostponedEvent = Event;
98 schoenebeck 738 break;
99 schoenebeck 3034 default: ; // noop
100 persson 614 }
101 schoenebeck 738 break;
102     case stage_decay1_part2:
103     switch (Event) {
104     case event_release:
105 schoenebeck 3328 if (Decay1Cancel)
106     enterNextStageForReleaseEvent(SampleRate);
107     else
108     PostponedEvent = Event;
109 schoenebeck 738 break;
110 persson 1906 case event_stage_end:
111 persson 783 if (Level < CONFIG_EG_BOTTOM)
112     enterEndStage();
113 schoenebeck 3328 else if (PostponedEvent == event_release)
114     enterNextStageForReleaseEvent(SampleRate);
115 persson 783 else if (InfiniteSustain)
116 schoenebeck 738 enterSustainStage();
117     else
118     enterDecay2Stage(SampleRate);
119     break;
120 schoenebeck 3034 default: ; // noop
121 schoenebeck 53 }
122 schoenebeck 738 break;
123     case stage_decay2:
124     switch (Event) {
125     case event_stage_end:
126     enterFadeOutStage();
127     break;
128     case event_release:
129 schoenebeck 3328 if (Decay2Cancel)
130     enterReleasePart1Stage();
131     else
132     PostponedEvent = Event;
133 schoenebeck 738 break;
134 persson 783 case event_hold_end:
135 schoenebeck 3328 if (PostponedEvent == event_release && Decay1Cancel)
136     enterReleasePart1Stage();
137     else
138     enterDecay1Part1Stage(SampleRate);
139 persson 783 break;
140 schoenebeck 3034 default: ; // noop
141 persson 614 }
142 schoenebeck 738 break;
143     case stage_sustain:
144     switch (Event) {
145     case event_stage_end: {// just refresh time
146     const int intMax = (unsigned int) -1 >> 1;
147     StepsLeft = intMax; // we use the highest possible value
148     break;
149 schoenebeck 53 }
150 schoenebeck 738 case event_release:
151     enterReleasePart1Stage();
152     break;
153 persson 783 case event_hold_end:
154     enterDecay1Part1Stage(SampleRate);
155     break;
156 schoenebeck 3034 default: ; // noop
157 schoenebeck 53 }
158 schoenebeck 738 break;
159     case stage_release_part1:
160     switch (Event) {
161     case event_stage_end:
162     enterReleasePart2Stage();
163     break;
164     case event_cancel_release:
165 schoenebeck 3328 if (!ReleaseCancel)
166     break;
167 schoenebeck 738 if (InfiniteSustain)
168     enterSustainStage();
169     else
170     enterDecay2Stage(SampleRate);
171     break;
172 schoenebeck 3034 default: ; // noop
173 schoenebeck 53 }
174 schoenebeck 738 break;
175     case stage_release_part2:
176     switch (Event) {
177     case event_stage_end:
178     enterFadeOutStage();
179     break;
180     case event_cancel_release:
181 schoenebeck 3328 if (!ReleaseCancel)
182     break;
183 schoenebeck 738 if (InfiniteSustain)
184     enterSustainStage();
185     else
186     enterDecay2Stage(SampleRate);
187     break;
188 schoenebeck 3034 default: ; // noop
189 schoenebeck 53 }
190 schoenebeck 738 break;
191 schoenebeck 3034 case stage_fadeout:
192     case stage_end:
193     ; // noop
194 schoenebeck 53 }
195     }
196    
197 persson 783 void EGADSR::trigger(uint PreAttack, float AttackTime, bool HoldAttack, float Decay1Time, double Decay2Time, bool InfiniteSustain, uint SustainLevel, float ReleaseTime, float Volume, uint SampleRate) {
198     this->SustainLevel = SustainLevel / 1000.0;
199 schoenebeck 53 this->InfiniteSustain = InfiniteSustain;
200     this->HoldAttack = HoldAttack;
201    
202 schoenebeck 738 this->Decay1Time = Decay1Time;
203     this->Decay2Time = Decay2Time;
204 persson 614
205 schoenebeck 738 invVolume = 1 / Volume;
206     ExpOffset = (0.25 - 1 / 3.55) * invVolume;
207    
208     // calculate release stage parameters (lin+exp curve)
209     if (ReleaseTime < CONFIG_EG_MIN_RELEASE_TIME) ReleaseTime = CONFIG_EG_MIN_RELEASE_TIME; // to avoid click sounds at the end of the sample playback
210     const float ReleaseStepsLeft = (long) (ReleaseTime * SampleRate);
211     ReleaseSlope = 1.365 * (0 - 1) / ReleaseStepsLeft;
212     ReleaseCoeff = ReleaseSlope * invVolume;
213     ReleaseSlope *= 3.55;
214     ReleaseCoeff2 = exp(ReleaseSlope);
215     ReleaseCoeff3 = ExpOffset * (1 - ReleaseCoeff2);
216     ReleaseLevel2 = 0.25 * invVolume;
217 persson 768
218 schoenebeck 3328 PostponedEvent = (event_t) -1; // init with anything except release or cancel_release
219    
220 persson 2055 enterFirstStage();
221 persson 783 enterAttackStage(PreAttack, AttackTime, SampleRate);
222 schoenebeck 738 }
223    
224 schoenebeck 3328 void EGADSR::setStateOptions(bool AttackCancel, bool AttackHoldCancel, bool Decay1Cancel, bool Decay2Cancel, bool ReleaseCancel) {
225     this->AttackCancel = AttackCancel;
226     this->AttackHoldCancel = AttackHoldCancel;
227     this->Decay1Cancel = Decay1Cancel;
228     this->Decay2Cancel = Decay2Cancel;
229     this->ReleaseCancel = ReleaseCancel;
230     }
231    
232     void EGADSR::enterNextStageForReleaseEvent(uint SampleRate) {
233     switch (Stage) {
234     case stage_attack:
235     if (HoldAttack && !AttackHoldCancel) {
236     enterAttackHoldStage();
237     return;
238     }
239     case stage_attack_hold:
240     if (!Decay1Cancel) {
241     enterDecay1Part1Stage(SampleRate);
242     return;
243     }
244     case stage_decay1_part1:
245     case stage_decay1_part2:
246     if (InfiniteSustain) {
247     enterReleasePart1Stage();
248     return;
249     } else if (!Decay2Cancel) {
250     enterDecay2Stage(SampleRate);
251     return;
252     }
253     default:
254     enterReleasePart1Stage();
255     }
256     }
257    
258 persson 783 void EGADSR::enterAttackStage(const uint PreAttack, const float AttackTime, const uint SampleRate) {
259 schoenebeck 738 Stage = stage_attack;
260     Segment = segment_lin;
261 persson 797
262 persson 2408 if (AttackTime >= 1e-8) {
263 persson 797 // Measurements of GSt output shows that the real attack time
264     // is about 65.5% of the value specified in the gig file.
265 persson 2408 // The minimum attack value used is 0.0316.
266     StepsLeft = int(0.655f * RTMath::Max(AttackTime, 0.0316f) * SampleRate);
267 schoenebeck 738 Level = (float) PreAttack / 1000.0;
268     Coeff = 0.896f * (1.0f - Level) / StepsLeft; // max level is a bit lower if attack != 0
269 persson 797 } else { // attack is zero - immediately jump to the next stage
270 persson 1046 Level = 1.029f; // a bit higher than max sustain
271 persson 783 if (HoldAttack) enterAttackHoldStage();
272 schoenebeck 738 else enterDecay1Part1Stage(SampleRate);
273 schoenebeck 53 }
274 schoenebeck 738 }
275 schoenebeck 53
276 persson 783 void EGADSR::enterAttackHoldStage() {
277 schoenebeck 738 Stage = stage_attack_hold;
278     Segment = segment_lin;
279     Coeff = 0.0f; // don't rise anymore
280 persson 783 const int intMax = (unsigned int) -1 >> 1;
281     StepsLeft = intMax; // we use the highest value possible (we refresh StepsLeft in update() in case)
282 schoenebeck 738 }
283 persson 614
284 schoenebeck 738 void EGADSR::enterDecay1Part1Stage(const uint SampleRate) {
285 persson 614 // The decay1 and release stage both consist of two parts,
286     // first a linear curve, f, followed by an exponential curve,
287     // g:
288     //
289     // f(x + d) = f(x) + Coeff
290     // g(x + d) = Coeff2 * g(x) + Coeff3
291     //
292     // (where d is 1/SampleRate). The transition from f to g is
293     // done when f(x) has reached Level2 = 25% of full volume.
294 schoenebeck 738 StepsLeft = (int) (Decay1Time * SampleRate);
295 persson 1046 if (StepsLeft && Level > SustainLevel) {
296 schoenebeck 738 Stage = stage_decay1_part1;
297     Segment = segment_lin;
298 persson 1046 Decay1Slope = (1.347f * SustainLevel - 1.361f) / StepsLeft;
299 schoenebeck 738 Coeff = Decay1Slope * invVolume;
300 persson 614 Decay1Level2 = 0.25 * invVolume;
301 persson 1147 StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);
302     if (StepsLeft <= 0) enterDecay1Part2Stage(SampleRate);
303 schoenebeck 738 } else {
304 schoenebeck 3328 if (PostponedEvent == event_release) {
305     Stage = stage_decay1_part2; // pretend decay 1 part 2 was completed
306     enterNextStageForReleaseEvent(SampleRate);
307     }��else if (InfiniteSustain) {
308     enterSustainStage();
309     }��else {
310     enterDecay2Stage(SampleRate);
311     }
312 persson 614 }
313 schoenebeck 738 }
314 schoenebeck 53
315 persson 768 void EGADSR::enterDecay1Part2Stage(const uint SampleRate) {
316     if (SustainLevel < Decay1Level2) {
317     Stage = stage_decay1_part2;
318     Segment = segment_exp;
319     Decay1Slope *= 3.55;
320     Coeff = exp(Decay1Slope);
321     Offset = ExpOffset * (1 - Coeff);
322     StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);
323 persson 1147 if (StepsLeft > 0) return;
324 persson 768 }
325 schoenebeck 3328 if (PostponedEvent == event_release) {
326     Stage = stage_decay1_part2;
327     enterNextStageForReleaseEvent(SampleRate);
328     }��else if (InfiniteSustain) {
329     enterSustainStage();
330     }��else {
331     enterDecay2Stage(SampleRate);
332     }
333 schoenebeck 738 }
334 schoenebeck 53
335 schoenebeck 738 void EGADSR::enterDecay2Stage(const uint SampleRate) {
336     Stage = stage_decay2;
337     Segment = segment_lin;
338 persson 1046 Decay2Time = RTMath::Max(Decay2Time, 0.05f);
339 schoenebeck 738 StepsLeft = (int) (Decay2Time * SampleRate);
340     Coeff = (-1.03 / StepsLeft) * invVolume;
341     //FIXME: do we really have to calculate 'StepsLeft' two times?
342     StepsLeft = int((CONFIG_EG_BOTTOM - Level) / Coeff);
343 persson 1147 if (StepsLeft <= 0) enterEndStage();
344 schoenebeck 738 }
345 schoenebeck 53
346 schoenebeck 738 void EGADSR::enterSustainStage() {
347     Stage = stage_sustain;
348     Segment = segment_lin;
349     Coeff = 0.0f; // don't change the envelope level in this stage
350     const int intMax = (unsigned int) -1 >> 1;
351     StepsLeft = intMax; // we use the highest value possible (we refresh StepsLeft in update() in case)
352 schoenebeck 3328 PostponedEvent = (event_t) -1; // reset with anything except release or cancel_release
353 schoenebeck 53 }
354    
355 schoenebeck 738 void EGADSR::enterReleasePart1Stage() {
356     Stage = stage_release_part1;
357     Segment = segment_lin;
358     StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);
359     Coeff = ReleaseCoeff;
360 schoenebeck 3328 PostponedEvent = (event_t) -1; // reset with anything except release or cancel_release
361 persson 1147 if (StepsLeft <= 0) enterReleasePart2Stage();
362 schoenebeck 738 }
363    
364     void EGADSR::enterReleasePart2Stage() {
365     Stage = stage_release_part2;
366     Segment = segment_exp;
367     StepsLeft = int(log((CONFIG_EG_BOTTOM - ExpOffset) / (Level - ExpOffset)) / ReleaseSlope);
368     Coeff = ReleaseCoeff2;
369     Offset = ReleaseCoeff3;
370 persson 1147 if (StepsLeft <= 0) enterFadeOutStage();
371 schoenebeck 738 }
372    
373 schoenebeck 53 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC