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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2055 - (hide annotations) (download) (as text)
Sat Jan 30 10:30:02 2010 UTC (14 years, 3 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 persson 2055 /***************************************************************************
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