/[svn]/linuxsampler/trunk/src/voice.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/voice.h

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

revision 37 by schoenebeck, Fri Mar 5 13:46:15 2004 UTC revision 38 by schoenebeck, Tue Mar 16 13:25:39 2004 UTC
# Line 31  Line 31 
31  #include "eg_vca.h"  #include "eg_vca.h"
32  #include "rtelmemorypool.h"  #include "rtelmemorypool.h"
33  #include "audiothread.h"  #include "audiothread.h"
34    #include "filter.h"
35    
36  #define MAX_PITCH                       4  //FIXME: at the moment in octaves, should be changed into semitones  #define MAX_PITCH                       4  //FIXME: at the moment in octaves, should be changed into semitones
37  #define USE_LINEAR_INTERPOLATION        1  ///< set to 0 if you prefer cubic interpolation (slower, better quality)  #define USE_LINEAR_INTERPOLATION        1  ///< set to 0 if you prefer cubic interpolation (slower, better quality)
38    #define ENABLE_FILTER                   0  ///< if set to 0 then filter (VCF) code is ignored on compile time
39    #define FILTER_UPDATE_PERIOD            64 ///< amount of sample points after which filter parameters (cutoff, resonance) are going to be updated (higher value means less CPU load, but also worse parameter resolution)
40    #define FORCE_FILTER_USAGE              0  ///< if set to 1 then filter is always used, if set to 0 filter is used only in case the instrument file defined one
41    
42    // Uncomment following line to override external cutoff controller
43    //#define OVERRIDE_FILTER_CUTOFF_CTRL   1  ///< set to an arbitrary MIDI control change controller (e.g. 1 for 'modulation wheel')
44    
45    // Uncomment following line to override external resonance controller
46    //#define OVERRIDE_FILTER_RES_CTRL      91  ///< set to an arbitrary MIDI control change controller (e.g. 91 for 'effect 1 depth')
47    
48    // Uncomment following line to override filter type
49    //#define OVERRIDE_FILTER_TYPE          gig::vcf_type_lowpass  ///< either gig::vcf_type_lowpass, gig::vcf_type_bandpass or gig::vcf_type_highpass
50    
51    
52    /// Reflects a MIDI controller
53    struct midi_ctrl {
54        uint8_t controller; ///< MIDI control change controller number
55        uint8_t value;      ///< Current controller value
56    };
57    
58  class Voice {  class Voice {
59      public:      public:
# Line 81  class Voice { Line 101  class Voice {
101          int                  LoopCyclesLeft;     ///< In case there is a RAMLoop and it's not an endless loop; reflects number of loop cycles left to be passed          int                  LoopCyclesLeft;     ///< In case there is a RAMLoop and it's not an endless loop; reflects number of loop cycles left to be passed
102          uint                 Delay;              ///< Number of sample points the rendering process of this voice should be delayed (jitter correction), will be set to 0 after the first audio fragment cycle          uint                 Delay;              ///< Number of sample points the rendering process of this voice should be delayed (jitter correction), will be set to 0 after the first audio fragment cycle
103          EG_VCA               EG1;          EG_VCA               EG1;
104          ModulationSystem::Event* pTriggerEvent;    ///< First event on the key's list the voice should process (only needed for the first audio fragment in which voice was triggered, after that it will be set to NULL).          GigFilter            FilterLeft;
105            GigFilter            FilterRight;
106            midi_ctrl            VCFCutoffCtrl;
107            midi_ctrl            VCFResonanceCtrl;
108            ModulationSystem::Event* pTriggerEvent;    ///< First event on the key's list the voice should process (only needed for the first audio fragment in which voice was triggered, after that it will be set to NULL).        
109    
110          // Methods          // Methods
111          void        ProcessEvents(uint Samples);          void        ProcessEvents(uint Samples);
112          void        Interpolate(uint Samples, sample_t* pSrc, uint Skip);          void        Interpolate(uint Samples, sample_t* pSrc, uint Skip);
113          void        InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip);          void        InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip);
114          inline void InterpolateOneStep_Stereo(sample_t* pSrc, int& i, float& effective_volume, float& pitch) {          inline void InterpolateOneStep_Stereo(sample_t* pSrc, int& i, float& effective_volume, float& pitch, float& cutoff, float& resonance) {
115              int   pos_int   = double_to_int(this->Pos);  // integer position              int   pos_int   = double_to_int(this->Pos);  // integer position
116              float pos_fract = this->Pos - pos_int;       // fractional part of position              float pos_fract = this->Pos - pos_int;       // fractional part of position
117              pos_int <<= 1;              pos_int <<= 1;
118                
119                #if ENABLE_FILTER
120                    UpdateFilter_Stereo(cutoff, resonance);
121                #endif // ENABLE_FILTER
122    
123              #if USE_LINEAR_INTERPOLATION              #if USE_LINEAR_INTERPOLATION
124                  // left channel                  #if ENABLE_FILTER
125                  this->pOutputLeft[i]    += effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int]));                      // left channel
126                  // right channel                      this->pOutputLeft[i]    += this->FilterLeft.Apply(effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int])));
127                  this->pOutputRight[i++] += effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1]));                      // right channel
128                        this->pOutputRight[i++] += this->FilterRight.Apply(effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1])));
129                    #else // no filter                
130                        // left channel
131                        this->pOutputLeft[i]    += effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int]));
132                        // right channel
133                        this->pOutputRight[i++] += effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1]));
134                    #endif // ENABLE_FILTER
135              #else // polynomial interpolation              #else // polynomial interpolation
136                  // calculate left channel                  // calculate left channel
137                  float xm1 = pSrc[pos_int];                  float xm1 = pSrc[pos_int];
# Line 106  class Voice { Line 141  class Voice {
141                  float a   = (3 * (x0 - x1) - xm1 + x2) / 2;                  float a   = (3 * (x0 - x1) - xm1 + x2) / 2;
142                  float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;                  float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;
143                  float c   = (x1 - xm1) / 2;                  float c   = (x1 - xm1) / 2;
144                  this->pOutputLeft[i] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);                  #if ENABLE_FILTER
145                        this->pOutputLeft[i] += this->FilterLeft.Apply(effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0));
146                    #else // no filter
147                        this->pOutputLeft[i] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);
148                    #endif // ENABLE_FILTER                
149    
150                  //calculate right channel                  //calculate right channel
151                  xm1 = pSrc[pos_int+1];                  xm1 = pSrc[pos_int+1];
# Line 116  class Voice { Line 155  class Voice {
155                  a   = (3 * (x0 - x1) - xm1 + x2) / 2;                  a   = (3 * (x0 - x1) - xm1 + x2) / 2;
156                  b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;                  b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;
157                  c   = (x1 - xm1) / 2;                  c   = (x1 - xm1) / 2;
158                  this->pOutputRight[i++] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);                  #if ENABLE_FILTER
159                        this->pOutputRight[i++] += this->FilterRight.Apply(effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0));
160                    #else // no filter
161                        this->pOutputRight[i++] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);
162                    #endif // ENABLE_FILTER
163              #endif // USE_LINEAR_INTERPOLATION              #endif // USE_LINEAR_INTERPOLATION
164    
165              this->Pos += pitch;              this->Pos += pitch;
166          }          }
167          inline void InterpolateOneStep_Mono(sample_t* pSrc, int& i, float& effective_volume, float& pitch) {          inline void InterpolateOneStep_Mono(sample_t* pSrc, int& i, float& effective_volume, float& pitch, float& cutoff, float& resonance) {
168              int   pos_int   = double_to_int(this->Pos);  // integer position              int   pos_int   = double_to_int(this->Pos);  // integer position
169              float pos_fract = this->Pos - pos_int;       // fractional part of position              float pos_fract = this->Pos - pos_int;       // fractional part of position
170                
171                #if ENABLE_FILTER
172                    UpdateFilter_Mono(cutoff, resonance);
173                #endif // ENABLE_FILTER
174    
175              #if USE_LINEAR_INTERPOLATION              #if USE_LINEAR_INTERPOLATION
176                  float sample_point  = effective_volume * (pSrc[pos_int] + pos_fract * (pSrc[pos_int+1] - pSrc[pos_int]));                  float sample_point  = effective_volume * (pSrc[pos_int] + pos_fract * (pSrc[pos_int+1] - pSrc[pos_int]));
# Line 136  class Voice { Line 183  class Voice {
183                  float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;                  float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;
184                  float c   = (x1 - xm1) / 2;                  float c   = (x1 - xm1) / 2;
185                  float sample_point = effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);                  float sample_point = effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);
186              #endif // USE_LINEAR_INTERPOLATION              #endif // USE_LINEAR_INTERPOLATION            
187    
188                #if ENABLE_FILTER                                                
189                    sample_point = this->FilterLeft.Apply(sample_point);
190                #endif // ENABLE_FILTER
191    
192              this->pOutputLeft[i]    += sample_point;              this->pOutputLeft[i]    += sample_point;
193              this->pOutputRight[i++] += sample_point;              this->pOutputRight[i++] += sample_point;
194    
195              this->Pos += pitch;              this->Pos += pitch;
196          }          }
197            inline void UpdateFilter_Stereo(float& cutoff, float& resonance) {
198                static int updatecounter = 0; // we update the filter all FILTER_UPDATE_PERIOD samples
199                if (!(++updatecounter % FILTER_UPDATE_PERIOD) && cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance()) {
200                    FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
201                    FilterRight.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
202                }
203            }
204            inline void UpdateFilter_Mono(float& cutoff, float& resonance) {
205                static int updatecounter = 0; // we update the filter all FILTER_UPDATE_PERIOD samples
206                if (!(++updatecounter % FILTER_UPDATE_PERIOD) && cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance()) {
207                    FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
208                }
209            }
210            inline void ForceUpdateFilter_Stereo(float& cutoff, float& resonance) {
211                if (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance()) {
212                    FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
213                    FilterRight.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());            
214                }        
215            }
216            inline void ForceUpdateFilter_Mono(float& cutoff, float& resonance) {
217                if (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance()) {
218                    FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
219                }
220            }
221            inline float Constrain(float ValueToCheck, float Min, float Max) {
222                if      (ValueToCheck > Max) ValueToCheck = Max;
223                else if (ValueToCheck < Min) ValueToCheck = Min;
224                return ValueToCheck;                      
225            }
226          inline int double_to_int(double f) {          inline int double_to_int(double f) {
227              #if ARCH_X86              #if ARCH_X86
228              int i;              int i;

Legend:
Removed from v.37  
changed lines
  Added in v.38

  ViewVC Help
Powered by ViewVC