/[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 1748 - (hide annotations) (download)
Sun Jun 22 14:46:46 2008 UTC (15 years, 9 months ago) by persson
File size: 13791 byte(s)
* bugfix: notes triggered at position 0 in the audio buffer were
  sometimes wrongly killed in the same buffer, causing no sound to be
  played
* fixes for audio drivers with varying buffer sizes
* Makefile fix: JACK_CFLAGS wasn't used
* JACK driver: use jack_client_open instead of the deprecated
  jack_client_new

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

  ViewVC Help
Powered by ViewVC