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

Contents of /linuxsampler/trunk/src/engines/gig/EGADSR.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 783 - (show annotations) (download) (as text)
Sun Oct 2 14:40:52 2005 UTC (18 years, 5 months ago) by persson
File MIME type: text/x-c++hdr
File size: 8401 byte(s)
* EG fixes: the length of "attack hold" stage was wrong. Release stage
  can now start before attack stage ends. Cancel release didn't work
  when sustain was zero.

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 Christian Schoenebeck *
7 * *
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 #ifndef __LS_GIG_EGADSR_H__
25 #define __LS_GIG_EGADSR_H__
26
27 #include "../../common/global.h"
28 #include "../../common/RTMath.h"
29
30 namespace LinuxSampler { namespace gig {
31
32 /**
33 * ADSR Envelope Generator
34 *
35 * Envelope Generator with stage 'Attack', 'Attack_Hold', 'Decay_1',
36 * 'Decay_2', 'Sustain' and 'Release' for modulating arbitrary synthesis
37 * parameters.
38 */
39 class EGADSR {
40 public:
41
42 /**
43 * Used to define what kind of segment the envelope currently is at.
44 */
45 enum segment_t {
46 segment_end = 0, ///< final end state of envelope reached
47 segment_lin = 1, ///< envelope is currently at a linear segment
48 segment_exp = 2 ///< envelope is currently at a exponental segment
49 };
50
51 /**
52 * Used to inform the EG about an event.
53 */
54 enum event_t {
55 event_stage_end,
56 event_release,
57 event_cancel_release,
58 event_hold_end
59 };
60
61 /**
62 * Constructor
63 */
64 EGADSR();
65
66 /**
67 * Change fade out time.
68 */
69 void CalculateFadeOutCoeff(float FadeOutTime, float SampleRate);
70
71 /**
72 * Will be called by the voice when the key / voice was triggered.
73 *
74 * @param PreAttack - Preattack value for the envelope
75 * (0 - 1000 permille)
76 * @param AttackTime - Attack time for the envelope
77 * (0.000 - 60.000s)
78 * @param HoldAttack - if true, Decay1 will be postponed until the
79 * sample reached the sample loop start.
80 * @param Decay1Time - Decay1 time of the sample amplitude EG
81 * (0.000 - 60.000s)
82 * @param Decay2Time - only if !InfiniteSustain: 2nd decay stage
83 * time of the sample amplitude EG
84 * (0.000 - 60.000s)
85 * @param InfiniteSustain - if true, instead of going into Decay2
86 * stage, Decay1 level will be hold until note
87 * will be released
88 * @param SustainLevel - Sustain level of the sample amplitude EG
89 * (0 - 1000 permille)
90 * @param ReleaseTIme - Release time for the envelope
91 * (0.000 - 60.000s)
92 * @param Volume - volume the sample will be played at
93 * (0.0 - 1.0) - used when calculating the
94 * exponential curve parameters.
95 * @param SampleRate - sample rate of used audio output driver
96 */
97 void trigger(uint PreAttack, float AttackTime, bool HoldAttack, float Decay1Time, double Decay2Time, bool InfiniteSustain, uint SustainLevel, float ReleaseTime, float Volume, uint SampleRate); //FIXME: we should better use 'float' for SampleRate
98
99 /**
100 * Returns true in case envelope hasn't reached its final end state yet.
101 */
102 inline bool active() {
103 return (bool) Segment;
104 }
105
106 /**
107 * Returns what kind of segment the envelope currently is at.
108 */
109 inline segment_t getSegmentType() {
110 return Segment;
111 }
112
113 /**
114 * Advance envelope by \a SamplePoints steps.
115 */
116 inline void increment(int SamplePoints) {
117 StepsLeft = RTMath::Max(0, StepsLeft - SamplePoints);
118 }
119
120 /**
121 * Returns amount of steps until the end of current envelope stage.
122 */
123 inline int toStageEndLeft() {
124 return StepsLeft;
125 }
126
127 /**
128 * Should be called to inform the EG about an external event and
129 * also whenever an envelope stage is completed. This will handle
130 * the envelope's transition to the respective next stage.
131 *
132 * @param Event - what happened
133 */
134 void update(event_t Event, uint SampleRate);
135
136 /**
137 * Calculates exactly one, the next sample point of EG
138 * (linear segment). Call this if envelope is currently in a linear
139 * segment.
140 *
141 * @returns next envelope level
142 */
143 inline float processLin() {
144 return (Level += Coeff);
145 }
146
147 /**
148 * Calculates exactly one, the next sample point of EG
149 * (exponential segment). Call this if envelope is currently in an
150 * exponential segment.
151 *
152 * @returns next envelope level
153 */
154 inline float processExp() {
155 return (Level = Level * Coeff + Offset);
156 }
157
158 /**
159 * Returns current envelope level without modifying anything. This
160 * might be needed once the envelope reached its final end state,
161 * because calling processLin() or processExp() at this point will
162 * result in undesired behavior.
163 */
164 inline float getLevel() {
165 return Level;
166 }
167
168 private:
169
170 enum stage_t {
171 stage_attack,
172 stage_attack_hold,
173 stage_decay1_part1,
174 stage_decay1_part2,
175 stage_decay2,
176 stage_sustain,
177 stage_release_part1,
178 stage_release_part2,
179 stage_fadeout,
180 stage_end
181 };
182
183 float Level;
184 float Coeff;
185 float Offset;
186 int StepsLeft;
187 segment_t Segment;
188 stage_t Stage;
189 bool HoldAttack;
190 bool InfiniteSustain;
191 float Decay1Time;
192 float Decay1Level2;
193 float Decay1Slope;
194 float Decay2Time;
195 float SustainLevel;
196 float ReleaseCoeff;
197 float ReleaseCoeff2;
198 float ReleaseCoeff3;
199 float ReleaseLevel2;
200 float ReleaseSlope;
201 float invVolume;
202 float ExpOffset;
203 float FadeOutCoeff; ///< very fast ramp down for e.g. voice stealing
204
205 void enterAttackStage(const uint PreAttack, const float AttackTime, const uint SampleRate);
206 void enterAttackHoldStage();
207 void enterDecay1Part1Stage(const uint SampleRate);
208 void enterDecay1Part2Stage(const uint SampleRate);
209 void enterDecay2Stage(const uint SampleRate);
210 void enterSustainStage();
211 void enterReleasePart1Stage();
212 void enterReleasePart2Stage();
213 void enterFadeOutStage();
214 void enterEndStage();
215 };
216
217 }} // namespace LinuxSampler::gig
218
219 #endif // __LS_GIG_EGADSR_H__

  ViewVC Help
Powered by ViewVC