/[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 738 - (show annotations) (download) (as text)
Tue Aug 16 17:14:25 2005 UTC (18 years, 8 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 8917 byte(s)
* extensive synthesis optimization: reimplementation of EGs and LFO(s),
  removed synthesis parameter prerendering and the synthesis parameter
  matrix in general, splitting each audio fragment into subfragments now
  where each subfragment uses constant synthesis parameters
  (everything's still very buggy ATM)

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

  ViewVC Help
Powered by ViewVC