/[svn]/linuxsampler/trunk/src/engines/common/EG.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/common/EG.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2055 - (show annotations) (download) (as text)
Sat Jan 30 10:30:02 2010 UTC (14 years, 2 months ago) by persson
File MIME type: text/x-c++hdr
File size: 5908 byte(s)
* sfz engine: added support for v2 multiple stage envelope generators
* sfz engine: added a fine-tuned v1 envelope generator instead of
  using the one from the gig engine

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 - 2010 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., 51 Franklin St, Fifth Floor, Boston, *
21 * MA 02110-1301 USA *
22 ***************************************************************************/
23
24 #ifndef LS_EG_H
25 #define LS_EG_H
26
27 #include <cmath>
28 #include "../../common/RTMath.h"
29
30 namespace LinuxSampler {
31 class EG {
32 public:
33
34 /**
35 * Used to define what kind of segment the envelope currently is at.
36 */
37 enum segment_t {
38 segment_end = 0, ///< final end state of envelope reached
39 segment_lin = 1, ///< envelope is currently at a linear segment
40 segment_exp = 2, ///< envelope is currently at a exponential segment
41 segment_pow = 3 ///< envelope is currently at a power segment
42 };
43
44 /**
45 * Used to inform the EG about an event.
46 */
47 enum event_t {
48 event_stage_end,
49 event_release,
50 event_cancel_release,
51 event_hold_end
52 };
53
54 /**
55 * Change fade out time.
56 */
57 void CalculateFadeOutCoeff(float FadeOutTime, float SampleRate);
58
59 /**
60 * Returns true in case envelope hasn't reached its final end state yet.
61 */
62 bool active() {
63 return Segment;
64 }
65
66 /**
67 * Returns what kind of segment the envelope currently is at.
68 */
69 segment_t getSegmentType() {
70 return Segment;
71 }
72
73 /**
74 * Advance envelope by \a SamplePoints steps.
75 */
76 void increment(int SamplePoints) {
77 StepsLeft = RTMath::Max(0, StepsLeft - SamplePoints);
78 }
79
80 /**
81 * Returns amount of steps until the end of current envelope stage.
82 */
83 int toStageEndLeft() {
84 return StepsLeft;
85 }
86
87 /**
88 * Should be called to inform the EG about an external event and
89 * also whenever an envelope stage is completed. This will handle
90 * the envelope's transition to the respective next stage.
91 *
92 * @param Event - what happened
93 */
94 virtual void update(event_t Event, uint SampleRate) = 0;
95
96 /**
97 * Calculates exactly one, the next sample point of EG
98 * (linear segment). Call this if envelope is currently in a linear
99 * segment.
100 *
101 * @returns next envelope level
102 */
103 float processLin() {
104 return (Level += Coeff);
105 }
106
107 /**
108 * Calculates exactly one, the next sample point of EG
109 * (exponential segment). Call this if envelope is currently in an
110 * exponential segment.
111 *
112 * @returns next envelope level
113 */
114 float processExp() {
115 return (Level = Level * Coeff + Offset);
116 }
117
118 /**
119 * Calculates exactly one, the next sample point of EG (power
120 * segment). Call this if envelope is currently in an power
121 * segment.
122 *
123 * @returns next envelope level
124 */
125 float processPow() {
126 // TODO: this could be optimised by a pow approximation
127 Level = Offset + Coeff * powf(X, Exp);
128 X += XDelta;
129 return Level;
130 }
131
132 /**
133 * Returns current envelope level without modifying anything. This
134 * might be needed once the envelope reached its final end state,
135 * because calling processLin() or processExp() at this point will
136 * result in undesired behavior.
137 */
138 float getLevel() {
139 return Level;
140 }
141
142 void enterFadeOutStage();
143 void enterFadeOutStage(int maxFadeOutSteps);
144
145 protected:
146 float Level;
147 float Coeff;
148 float Offset;
149 float Exp;
150 float X;
151 float XDelta;
152 int StepsLeft;
153 segment_t Segment;
154
155 EG();
156 void enterFirstStage() { // must be called in trigger
157 Stage = stage_main;
158 }
159 bool atEnd(event_t Event); // must be called first in update
160 void enterEndStage();
161
162 private:
163 enum stage_t {
164 stage_main,
165 stage_fadeout,
166 stage_end
167 };
168
169 stage_t Stage;
170 float FadeOutCoeff; ///< very fast ramp down for e.g. voice stealing
171 };
172 }
173
174 #endif

  ViewVC Help
Powered by ViewVC