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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 688 by schoenebeck, Thu Jul 14 12:25:20 2005 UTC revision 738 by schoenebeck, Tue Aug 16 17:14:25 2005 UTC
# Line 24  Line 24 
24  #ifndef __LS_GIG_EGADSR_H__  #ifndef __LS_GIG_EGADSR_H__
25  #define __LS_GIG_EGADSR_H__  #define __LS_GIG_EGADSR_H__
26    
 #include <math.h>  
   
27  #include "../../common/global.h"  #include "../../common/global.h"
28  #include "../../common/RTMath.h"  #include "../../common/RTMath.h"
 #include "../../common/Pool.h"  
 #include "../common/Event.h"  
 #include "Manipulator.h"  
 #include "Engine.h"  
29    
30  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
31    
# Line 44  namespace LinuxSampler { namespace gig { Line 38  namespace LinuxSampler { namespace gig {
38   */   */
39  class EGADSR {  class EGADSR {
40      public:      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 {          enum stage_t {
174              stage_attack,              stage_attack,
175              stage_attack_hold,              stage_attack_hold,
176              stage_decay1_init,              stage_decay1_part1,
             stage_decay1,  
             stage_decay1_part2_init,  
177              stage_decay1_part2,              stage_decay1_part2,
             stage_decay2_init,  
178              stage_decay2,              stage_decay2,
179              stage_sustain,              stage_sustain,
180              stage_release_init,              stage_release_part1,
             stage_release,  
             stage_release_part2_init,  
181              stage_release_part2,              stage_release_part2,
182              stage_fadeout,              stage_fadeout,
183              stage_end              stage_end
184          };          };
185    
186          EGADSR(gig::Engine* pEngine, Event::destination_t ModulationDestination);          float     Level;
187          void Process(uint TotalSamples, RTList<Event>* pEvents, RTList<Event>::Iterator itTriggerEvent, double SamplePos, double CurrentPitch, RTList<Event>::Iterator itKillEvent = RTList<Event>::Iterator());          float     Coeff;
188          void Trigger(uint PreAttack, double AttackTime, bool HoldAttack, long LoopStart, double Decay1Time, double Decay2Time, bool InfiniteSustain, uint SustainLevel, double ReleaseTime, uint Delay, float Volume);          float     Offset;
189          void CalculateFadeOutCoeff(float FadeOutTime, float SampleRate);          int       StepsLeft;
190          inline EGADSR::stage_t GetStage() { return Stage; }          segment_t Segment;
191      protected:          stage_t   Stage;
192          gig::Engine* pEngine;          event_t   PostponedEvent; ///< only used in Attack stage to postpone transition events until attack time is reached
193          Event::destination_t ModulationDestination;          bool      HoldAttack;
194          uint    TriggerDelay;      ///< number of sample points triggering should be delayed          bool      InfiniteSustain;
195          float   Level;          long      LoopStart;
196          stage_t Stage;          float     Decay1Time;
197          float   AttackCoeff;          float     Decay1Level2;
198          long    AttackStepsLeft;   ///< number of sample points til end of attack stage          float     Decay1Slope;
199          bool    HoldAttack;          float     Decay2Time;
200          long    LoopStart;          float     SustainLevel;
201          float   Decay1Coeff;          float     ReleaseCoeff;
202          float   Decay1Coeff2;          float     ReleaseCoeff2;
203          float   Decay1Coeff3;          float     ReleaseCoeff3;
204          float   Decay1Level2;          float     ReleaseLevel2;
205          float   Decay1Slope;          float     ReleaseSlope;
206          long    Decay1StepsLeft;   ///< number of sample points in Decay1 stage          float     invVolume;
207          float   Decay2Coeff;          float     ExpOffset;
208          long    Decay2StepsLeft;          float     FadeOutCoeff; ///< very fast ramp down for e.g. voice stealing
209          bool    InfiniteSustain;  
210          float   SustainLevel;          void enterAttackStage(const uint PreAttack, const float AttackTime, const uint SampleRate, const double SamplePos, const float CurrentPitch);
211          float   ReleaseCoeff;          void enterAttackHoldStage(const double SamplePos, const float CurrentPitch);
212          float   ReleaseCoeff2;          void enterDecay1Part1Stage(const uint SampleRate);
213          float   ReleaseCoeff3;          void enterDecay1Part2Stage();
214          float   ReleaseLevel2;          void enterDecay2Stage(const uint SampleRate);
215          float   ReleaseSlope;          void enterSustainStage();
216          long    ReleaseStepsLeft;  ///< number of sample points til end of release stage          void enterReleasePart1Stage();
217          bool    ReleasePostponed;  ///< If a "release" event occured in the previous audio fragment, but wasn't processed yet.          void enterReleasePart2Stage();
218          float   ExpOffset;          void enterFadeOutStage();
219          float   FadeOutCoeff;      ///< very fast ramp down for e.g. voice stealing          void enterEndStage();
220  };  };
221    
222  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.688  
changed lines
  Added in v.738

  ViewVC Help
Powered by ViewVC