/[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 38 by schoenebeck, Tue Mar 16 13:25:39 2004 UTC revision 39 by schoenebeck, Sun Mar 21 16:09:43 2004 UTC
# Line 32  Line 32 
32  #include "rtelmemorypool.h"  #include "rtelmemorypool.h"
33  #include "audiothread.h"  #include "audiothread.h"
34  #include "filter.h"  #include "filter.h"
35    #include "lfo.h"
36    
37  #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
38  #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)
# Line 52  Line 53 
53  /// Reflects a MIDI controller  /// Reflects a MIDI controller
54  struct midi_ctrl {  struct midi_ctrl {
55      uint8_t controller; ///< MIDI control change controller number      uint8_t controller; ///< MIDI control change controller number
56      uint8_t value;      ///< Current controller value      uint8_t value;      ///< Current MIDI controller value
57        float   fvalue;     ///< Transformed / effective value (e.g. volume level or filter cutoff frequency)
58  };  };
59    
60  class Voice {  class Voice {
# Line 105  class Voice { Line 107  class Voice {
107          GigFilter            FilterRight;          GigFilter            FilterRight;
108          midi_ctrl            VCFCutoffCtrl;          midi_ctrl            VCFCutoffCtrl;
109          midi_ctrl            VCFResonanceCtrl;          midi_ctrl            VCFResonanceCtrl;
110          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).                  LFO*                 pLFO1;
111            LFO*                 pLFO2;
112            LFO*                 pLFO3;
113            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).
114    
115          // Methods          // Methods
116          void        ProcessEvents(uint Samples);          void        ProcessEvents(uint Samples);
# Line 115  class Voice { Line 120  class Voice {
120              int   pos_int   = double_to_int(this->Pos);  // integer position              int   pos_int   = double_to_int(this->Pos);  // integer position
121              float pos_fract = this->Pos - pos_int;       // fractional part of position              float pos_fract = this->Pos - pos_int;       // fractional part of position
122              pos_int <<= 1;              pos_int <<= 1;
123                
124              #if ENABLE_FILTER              #if ENABLE_FILTER
125                  UpdateFilter_Stereo(cutoff, resonance);                  UpdateFilter_Stereo(cutoff + 20.0f, resonance); // 20Hz min.
126              #endif // ENABLE_FILTER              #endif // ENABLE_FILTER
127    
128              #if USE_LINEAR_INTERPOLATION              #if USE_LINEAR_INTERPOLATION
# Line 126  class Voice { Line 131  class Voice {
131                      this->pOutputLeft[i]    += this->FilterLeft.Apply(effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int])));                      this->pOutputLeft[i]    += this->FilterLeft.Apply(effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int])));
132                      // right channel                      // right channel
133                      this->pOutputRight[i++] += this->FilterRight.Apply(effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1])));                      this->pOutputRight[i++] += this->FilterRight.Apply(effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1])));
134                  #else // no filter                                  #else // no filter
135                      // left channel                      // left channel
136                      this->pOutputLeft[i]    += effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int]));                      this->pOutputLeft[i]    += effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int]));
137                      // right channel                      // right channel
# Line 145  class Voice { Line 150  class Voice {
150                      this->pOutputLeft[i] += this->FilterLeft.Apply(effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0));                      this->pOutputLeft[i] += this->FilterLeft.Apply(effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0));
151                  #else // no filter                  #else // no filter
152                      this->pOutputLeft[i] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);                      this->pOutputLeft[i] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);
153                  #endif // ENABLE_FILTER                                  #endif // ENABLE_FILTER
154    
155                  //calculate right channel                  //calculate right channel
156                  xm1 = pSrc[pos_int+1];                  xm1 = pSrc[pos_int+1];
# Line 167  class Voice { Line 172  class Voice {
172          inline void InterpolateOneStep_Mono(sample_t* pSrc, int& i, float& effective_volume, float& pitch, float& cutoff, float& resonance) {          inline void InterpolateOneStep_Mono(sample_t* pSrc, int& i, float& effective_volume, float& pitch, float& cutoff, float& resonance) {
173              int   pos_int   = double_to_int(this->Pos);  // integer position              int   pos_int   = double_to_int(this->Pos);  // integer position
174              float pos_fract = this->Pos - pos_int;       // fractional part of position              float pos_fract = this->Pos - pos_int;       // fractional part of position
175                
176              #if ENABLE_FILTER              #if ENABLE_FILTER
177                  UpdateFilter_Mono(cutoff, resonance);                  UpdateFilter_Mono(cutoff + 20.0f, resonance); // 20Hz min.
178              #endif // ENABLE_FILTER              #endif // ENABLE_FILTER
179    
180              #if USE_LINEAR_INTERPOLATION              #if USE_LINEAR_INTERPOLATION
# Line 183  class Voice { Line 188  class Voice {
188                  float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;                  float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;
189                  float c   = (x1 - xm1) / 2;                  float c   = (x1 - xm1) / 2;
190                  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);
191              #endif // USE_LINEAR_INTERPOLATION                          #endif // USE_LINEAR_INTERPOLATION
192    
193              #if ENABLE_FILTER                                                              #if ENABLE_FILTER
194                  sample_point = this->FilterLeft.Apply(sample_point);                  sample_point = this->FilterLeft.Apply(sample_point);
195              #endif // ENABLE_FILTER              #endif // ENABLE_FILTER
196    
# Line 194  class Voice { Line 199  class Voice {
199    
200              this->Pos += pitch;              this->Pos += pitch;
201          }          }
202          inline void UpdateFilter_Stereo(float& cutoff, float& resonance) {          inline void UpdateFilter_Stereo(float cutoff, float& resonance) {
203              static int updatecounter = 0; // we update the filter all FILTER_UPDATE_PERIOD samples              static int updatecounter = 0; // we update the filter all FILTER_UPDATE_PERIOD samples
204              if (!(++updatecounter % FILTER_UPDATE_PERIOD) && cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance()) {              if (!(++updatecounter % FILTER_UPDATE_PERIOD) && (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance())) {
205                  FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());                  FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
206                  FilterRight.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());                  FilterRight.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
207              }              }
208          }          }
209          inline void UpdateFilter_Mono(float& cutoff, float& resonance) {          inline void UpdateFilter_Mono(float cutoff, float& resonance) {
210              static int updatecounter = 0; // we update the filter all FILTER_UPDATE_PERIOD samples              static int updatecounter = 0; // we update the filter all FILTER_UPDATE_PERIOD samples
211              if (!(++updatecounter % FILTER_UPDATE_PERIOD) && cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance()) {              if (!(++updatecounter % FILTER_UPDATE_PERIOD) && (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance())) {
212                  FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());                  FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
213              }              }
214          }          }
215          inline void ForceUpdateFilter_Stereo(float& cutoff, float& resonance) {          inline void ForceUpdateFilter_Stereo(float cutoff, float& resonance) {
216              if (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance()) {              if (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance()) {
217                  FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());                  FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
218                  FilterRight.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());                              FilterRight.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
219              }                      }
220          }          }
221          inline void ForceUpdateFilter_Mono(float& cutoff, float& resonance) {          inline void ForceUpdateFilter_Mono(float cutoff, float& resonance) {
222              if (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance()) {              if (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance()) {
223                  FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());                  FilterLeft.SetParameters(cutoff, resonance, ModulationSystem::SampleRate());
224              }              }
# Line 221  class Voice { Line 226  class Voice {
226          inline float Constrain(float ValueToCheck, float Min, float Max) {          inline float Constrain(float ValueToCheck, float Min, float Max) {
227              if      (ValueToCheck > Max) ValueToCheck = Max;              if      (ValueToCheck > Max) ValueToCheck = Max;
228              else if (ValueToCheck < Min) ValueToCheck = Min;              else if (ValueToCheck < Min) ValueToCheck = Min;
229              return ValueToCheck;                                    return ValueToCheck;
230          }          }
231          inline int double_to_int(double f) {          inline int double_to_int(double f) {
232              #if ARCH_X86              #if ARCH_X86

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

  ViewVC Help
Powered by ViewVC