/[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 3034 - (hide annotations) (download)
Mon Oct 31 00:05:00 2016 UTC (7 years, 6 months ago) by schoenebeck
File size: 12110 byte(s)
* Fixed a bunch of minor issues (mostly compiler warnings).
* Bumped version (2.0.0.svn31).

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 3034 * Copyright (C) 2005 - 2016 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 persson 2055 void EGADSR::update(event_t Event, uint SampleRate) {
31     if (atEnd(Event)) return;
32 schoenebeck 738
33 persson 783 if (Event == event_hold_end) HoldAttack = false;
34    
35 schoenebeck 738 switch (Stage) {
36     case stage_attack:
37 persson 783 switch (Event) {
38     case event_release:
39 schoenebeck 738 enterReleasePart1Stage();
40 persson 783 break;
41     case event_stage_end:
42     if (HoldAttack)
43     enterAttackHoldStage();
44     else
45     enterDecay1Part1Stage(SampleRate);
46     break;
47 schoenebeck 3034 default: ; // noop
48 schoenebeck 53 }
49 schoenebeck 738 break;
50     case stage_attack_hold:
51     switch (Event) {
52 persson 783 case event_stage_end: {// just refresh time
53     const int intMax = (unsigned int) -1 >> 1;
54     StepsLeft = intMax; // we use the highest possible value
55     break;
56     }
57     case event_hold_end:
58 schoenebeck 738 enterDecay1Part1Stage(SampleRate);
59 schoenebeck 53 break;
60 schoenebeck 738 case event_release:
61     enterReleasePart1Stage();
62     break;
63 schoenebeck 3034 default: ; // noop
64 schoenebeck 53 }
65 schoenebeck 738 break;
66     case stage_decay1_part1:
67     switch (Event) {
68 persson 768 case event_stage_end:
69     enterDecay1Part2Stage(SampleRate);
70 persson 614 break;
71 persson 1909 case event_release:
72     enterReleasePart1Stage();
73 schoenebeck 738 break;
74 schoenebeck 3034 default: ; // noop
75 persson 614 }
76 schoenebeck 738 break;
77     case stage_decay1_part2:
78     switch (Event) {
79     case event_release:
80     enterReleasePart1Stage();
81     break;
82 persson 1906 case event_stage_end:
83 persson 783 if (Level < CONFIG_EG_BOTTOM)
84     enterEndStage();
85     else if (InfiniteSustain)
86 schoenebeck 738 enterSustainStage();
87     else
88     enterDecay2Stage(SampleRate);
89     break;
90 schoenebeck 3034 default: ; // noop
91 schoenebeck 53 }
92 schoenebeck 738 break;
93     case stage_decay2:
94     switch (Event) {
95     case event_stage_end:
96     enterFadeOutStage();
97     break;
98     case event_release:
99     enterReleasePart1Stage();
100     break;
101 persson 783 case event_hold_end:
102     enterDecay1Part1Stage(SampleRate);
103     break;
104 schoenebeck 3034 default: ; // noop
105 persson 614 }
106 schoenebeck 738 break;
107     case stage_sustain:
108     switch (Event) {
109     case event_stage_end: {// just refresh time
110     const int intMax = (unsigned int) -1 >> 1;
111     StepsLeft = intMax; // we use the highest possible value
112     break;
113 schoenebeck 53 }
114 schoenebeck 738 case event_release:
115     enterReleasePart1Stage();
116     break;
117 persson 783 case event_hold_end:
118     enterDecay1Part1Stage(SampleRate);
119     break;
120 schoenebeck 3034 default: ; // noop
121 schoenebeck 53 }
122 schoenebeck 738 break;
123     case stage_release_part1:
124     switch (Event) {
125     case event_stage_end:
126     enterReleasePart2Stage();
127     break;
128     case event_cancel_release:
129     if (InfiniteSustain)
130     enterSustainStage();
131     else
132     enterDecay2Stage(SampleRate);
133     break;
134 schoenebeck 3034 default: ; // noop
135 schoenebeck 53 }
136 schoenebeck 738 break;
137     case stage_release_part2:
138     switch (Event) {
139     case event_stage_end:
140     enterFadeOutStage();
141     break;
142     case event_cancel_release:
143     if (InfiniteSustain)
144     enterSustainStage();
145     else
146     enterDecay2Stage(SampleRate);
147     break;
148 schoenebeck 3034 default: ; // noop
149 schoenebeck 53 }
150 schoenebeck 738 break;
151 schoenebeck 3034 case stage_fadeout:
152     case stage_end:
153     ; // noop
154 schoenebeck 53 }
155     }
156    
157 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) {
158     this->SustainLevel = SustainLevel / 1000.0;
159 schoenebeck 53 this->InfiniteSustain = InfiniteSustain;
160     this->HoldAttack = HoldAttack;
161    
162 schoenebeck 738 this->Decay1Time = Decay1Time;
163     this->Decay2Time = Decay2Time;
164 persson 614
165 schoenebeck 738 invVolume = 1 / Volume;
166     ExpOffset = (0.25 - 1 / 3.55) * invVolume;
167    
168     // calculate release stage parameters (lin+exp curve)
169     if (ReleaseTime < CONFIG_EG_MIN_RELEASE_TIME) ReleaseTime = CONFIG_EG_MIN_RELEASE_TIME; // to avoid click sounds at the end of the sample playback
170     const float ReleaseStepsLeft = (long) (ReleaseTime * SampleRate);
171     ReleaseSlope = 1.365 * (0 - 1) / ReleaseStepsLeft;
172     ReleaseCoeff = ReleaseSlope * invVolume;
173     ReleaseSlope *= 3.55;
174     ReleaseCoeff2 = exp(ReleaseSlope);
175     ReleaseCoeff3 = ExpOffset * (1 - ReleaseCoeff2);
176     ReleaseLevel2 = 0.25 * invVolume;
177 persson 768
178 persson 2055 enterFirstStage();
179 persson 783 enterAttackStage(PreAttack, AttackTime, SampleRate);
180 schoenebeck 738 }
181    
182 persson 783 void EGADSR::enterAttackStage(const uint PreAttack, const float AttackTime, const uint SampleRate) {
183 schoenebeck 738 Stage = stage_attack;
184     Segment = segment_lin;
185 persson 797
186 persson 2408 if (AttackTime >= 1e-8) {
187 persson 797 // Measurements of GSt output shows that the real attack time
188     // is about 65.5% of the value specified in the gig file.
189 persson 2408 // The minimum attack value used is 0.0316.
190     StepsLeft = int(0.655f * RTMath::Max(AttackTime, 0.0316f) * SampleRate);
191 schoenebeck 738 Level = (float) PreAttack / 1000.0;
192     Coeff = 0.896f * (1.0f - Level) / StepsLeft; // max level is a bit lower if attack != 0
193 persson 797 } else { // attack is zero - immediately jump to the next stage
194 persson 1046 Level = 1.029f; // a bit higher than max sustain
195 persson 783 if (HoldAttack) enterAttackHoldStage();
196 schoenebeck 738 else enterDecay1Part1Stage(SampleRate);
197 schoenebeck 53 }
198 schoenebeck 738 }
199 schoenebeck 53
200 persson 783 void EGADSR::enterAttackHoldStage() {
201 schoenebeck 738 Stage = stage_attack_hold;
202     Segment = segment_lin;
203     Coeff = 0.0f; // don't rise anymore
204 persson 783 const int intMax = (unsigned int) -1 >> 1;
205     StepsLeft = intMax; // we use the highest value possible (we refresh StepsLeft in update() in case)
206 schoenebeck 738 }
207 persson 614
208 schoenebeck 738 void EGADSR::enterDecay1Part1Stage(const uint SampleRate) {
209 persson 614 // The decay1 and release stage both consist of two parts,
210     // first a linear curve, f, followed by an exponential curve,
211     // g:
212     //
213     // f(x + d) = f(x) + Coeff
214     // g(x + d) = Coeff2 * g(x) + Coeff3
215     //
216     // (where d is 1/SampleRate). The transition from f to g is
217     // done when f(x) has reached Level2 = 25% of full volume.
218 schoenebeck 738 StepsLeft = (int) (Decay1Time * SampleRate);
219 persson 1046 if (StepsLeft && Level > SustainLevel) {
220 schoenebeck 738 Stage = stage_decay1_part1;
221     Segment = segment_lin;
222 persson 1046 Decay1Slope = (1.347f * SustainLevel - 1.361f) / StepsLeft;
223 schoenebeck 738 Coeff = Decay1Slope * invVolume;
224 persson 614 Decay1Level2 = 0.25 * invVolume;
225 persson 1147 StepsLeft = int((RTMath::Max(Decay1Level2, SustainLevel) - Level) / Coeff);
226     if (StepsLeft <= 0) enterDecay1Part2Stage(SampleRate);
227 schoenebeck 738 } else {
228     if (InfiniteSustain) enterSustainStage();
229     else enterDecay2Stage(SampleRate);
230 persson 614 }
231 schoenebeck 738 }
232 schoenebeck 53
233 persson 768 void EGADSR::enterDecay1Part2Stage(const uint SampleRate) {
234     if (SustainLevel < Decay1Level2) {
235     Stage = stage_decay1_part2;
236     Segment = segment_exp;
237     Decay1Slope *= 3.55;
238     Coeff = exp(Decay1Slope);
239     Offset = ExpOffset * (1 - Coeff);
240     StepsLeft = int(log((SustainLevel - ExpOffset) / (Level - ExpOffset)) / Decay1Slope);
241 persson 1147 if (StepsLeft > 0) return;
242 persson 768 }
243 persson 1147 if (InfiniteSustain) enterSustainStage();
244     else enterDecay2Stage(SampleRate);
245 schoenebeck 738 }
246 schoenebeck 53
247 schoenebeck 738 void EGADSR::enterDecay2Stage(const uint SampleRate) {
248     Stage = stage_decay2;
249     Segment = segment_lin;
250 persson 1046 Decay2Time = RTMath::Max(Decay2Time, 0.05f);
251 schoenebeck 738 StepsLeft = (int) (Decay2Time * SampleRate);
252     Coeff = (-1.03 / StepsLeft) * invVolume;
253     //FIXME: do we really have to calculate 'StepsLeft' two times?
254     StepsLeft = int((CONFIG_EG_BOTTOM - Level) / Coeff);
255 persson 1147 if (StepsLeft <= 0) enterEndStage();
256 schoenebeck 738 }
257 schoenebeck 53
258 schoenebeck 738 void EGADSR::enterSustainStage() {
259     Stage = stage_sustain;
260     Segment = segment_lin;
261     Coeff = 0.0f; // don't change the envelope level in this stage
262     const int intMax = (unsigned int) -1 >> 1;
263     StepsLeft = intMax; // we use the highest value possible (we refresh StepsLeft in update() in case)
264 schoenebeck 53 }
265    
266 schoenebeck 738 void EGADSR::enterReleasePart1Stage() {
267     Stage = stage_release_part1;
268     Segment = segment_lin;
269     StepsLeft = int((ReleaseLevel2 - Level) / ReleaseCoeff);
270     Coeff = ReleaseCoeff;
271 persson 1147 if (StepsLeft <= 0) enterReleasePart2Stage();
272 schoenebeck 738 }
273    
274     void EGADSR::enterReleasePart2Stage() {
275     Stage = stage_release_part2;
276     Segment = segment_exp;
277     StepsLeft = int(log((CONFIG_EG_BOTTOM - ExpOffset) / (Level - ExpOffset)) / ReleaseSlope);
278     Coeff = ReleaseCoeff2;
279     Offset = ReleaseCoeff3;
280 persson 1147 if (StepsLeft <= 0) enterFadeOutStage();
281 schoenebeck 738 }
282    
283 schoenebeck 53 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC