/[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 239 by schoenebeck, Sun Sep 12 14:48:19 2004 UTC revision 783 by persson, Sun Oct 2 14:40:52 2005 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   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  *   *   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  *   *   it under the terms of the GNU General Public License as published by  *
# Line 23  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/RTELMemoryPool.h"  
 #include "../common/Event.h"  
 #include "Manipulator.h"  
 #include "Engine.h"  
   
 #define EG_ENVELOPE_LIMIT       0.001  
 #define EG_MIN_RELEASE_TIME     0.005  
29    
30  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
31    
# Line 46  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                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 {          enum stage_t {
171              stage_attack,              stage_attack,
172              stage_attack_hold,              stage_attack_hold,
173              stage_decay1,              stage_decay1_part1,
174                stage_decay1_part2,
175              stage_decay2,              stage_decay2,
176              stage_sustain,              stage_sustain,
177              stage_release,              stage_release_part1,
178                stage_release_part2,
179                stage_fadeout,
180              stage_end              stage_end
181          };          };
182    
183          EGADSR(gig::Engine* pEngine, Event::destination_t ModulationDestination);          float     Level;
184          void Process(uint TotalSamples, RTEList<Event>* pEvents, Event* pTriggerEvent, double SamplePos, double CurrentPitch, Event* pKillEvent = NULL);          float     Coeff;
185          void Trigger(uint PreAttack, double AttackTime, bool HoldAttack, long LoopStart, double Decay1Time, double Decay2Time, bool InfiniteSustain, uint SustainLevel, double ReleaseTime, uint Delay);          float     Offset;
186          inline EGADSR::stage_t GetStage() { return Stage; }          int       StepsLeft;
187      protected:          segment_t Segment;
188          gig::Engine* pEngine;          stage_t   Stage;
189          Event::destination_t ModulationDestination;          bool      HoldAttack;
190          uint    TriggerDelay;      ///< number of sample points triggering should be delayed          bool      InfiniteSustain;
191          float   Level;          float     Decay1Time;
192          stage_t Stage;          float     Decay1Level2;
193          float   AttackCoeff;          float     Decay1Slope;
194          long    AttackStepsLeft;   ///< number of sample points til end of attack stage          float     Decay2Time;
195          bool    HoldAttack;          float     SustainLevel;
196          long    LoopStart;          float     ReleaseCoeff;
197          float   Decay1Coeff;          float     ReleaseCoeff2;
198          long    Decay1StepsLeft;   ///< number of sample points in Decay1 stage          float     ReleaseCoeff3;
199          float   Decay2Coeff;          float     ReleaseLevel2;
200          bool    InfiniteSustain;          float     ReleaseSlope;
201          float   SustainLevel;          float     invVolume;
202          float   ReleaseCoeff;          float     ExpOffset;
203          long    ReleaseStepsLeft;  ///< number of sample points til end of release stage          float     FadeOutCoeff; ///< very fast ramp down for e.g. voice stealing
204          bool    ReleasePostponed;  ///< If a "release" event occured in the previous audio fragment, but wasn't processed yet.  
205          const static float EndCoeff;          void enterAttackStage(const uint PreAttack, const float AttackTime, const uint SampleRate);
206      private:          void enterAttackHoldStage();
207          static float CalculateEndCoeff();          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  }} // namespace LinuxSampler::gig

Legend:
Removed from v.239  
changed lines
  Added in v.783

  ViewVC Help
Powered by ViewVC