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

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

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

revision 53 by schoenebeck, Mon Apr 26 17:15:51 2004 UTC revision 225 by schoenebeck, Sun Aug 22 14:46:47 2004 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck         *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *                                                                         *   *                                                                         *
7   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
8   *   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 32  Line 32 
32  #include "../../common/RTMath.h"  #include "../../common/RTMath.h"
33  #include "../../common/RingBuffer.h"  #include "../../common/RingBuffer.h"
34  #include "../../common/RTELMemoryPool.h"  #include "../../common/RTELMemoryPool.h"
35  #include "../../audiodriver/AudioOutputDevice.h"  #include "../../drivers/audio/AudioOutputDevice.h"
36  #include "../../lib/fileloader/libgig/gig.h"  #include "../../lib/fileloader/libgig/gig.h"
37    #include "../common/BiquadFilter.h"
38  #include "Engine.h"  #include "Engine.h"
39  #include "Stream.h"  #include "Stream.h"
40  #include "DiskThread.h"  #include "DiskThread.h"
# Line 42  Line 43 
43  #include "Filter.h"  #include "Filter.h"
44  #include "../common/LFO.h"  #include "../common/LFO.h"
45    
46  #define USE_LINEAR_INTERPOLATION        1  ///< set to 0 if you prefer cubic interpolation (slower, better quality)  #define USE_LINEAR_INTERPOLATION        0  ///< set to 0 if you prefer cubic interpolation (slower, better quality)
47  #define ENABLE_FILTER                   0  ///< if set to 0 then filter (VCF) code is ignored on compile time  #define ENABLE_FILTER                   1  ///< if set to 0 then filter (VCF) code is ignored on compile time
48  #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)  #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, this value will be aligned to a power of two)
49  #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  #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
50  #define FILTER_CUTOFF_MAX               10000.0f ///< maximum cutoff frequency (10kHz)  #define FILTER_CUTOFF_MAX               10000.0f ///< maximum cutoff frequency (10kHz)
51  #define FILTER_CUTOFF_MIN               100.0f   ///< minimum cutoff frequency (100Hz)  #define FILTER_CUTOFF_MIN               100.0f   ///< minimum cutoff frequency (100Hz)
# Line 104  namespace LinuxSampler { namespace gig { Line 105  namespace LinuxSampler { namespace gig {
105              // Attributes              // Attributes
106              gig::Engine*                pEngine;            ///< Pointer to the sampler engine, to be able to access the event lists.              gig::Engine*                pEngine;            ///< Pointer to the sampler engine, to be able to access the event lists.
107              float                       Volume;             ///< Volume level of the voice              float                       Volume;             ///< Volume level of the voice
             float*                      pOutputLeft;        ///< Audio output channel buffer (left)  
             float*                      pOutputRight;       ///< Audio output channel buffer (right)  
             uint                        SampleRate;         ///< Sample rate of the engines output audio signal (in Hz)  
             uint                        MaxSamplesPerCycle; ///< Size of each audio output buffer  
108              double                      Pos;                ///< Current playback position in sample              double                      Pos;                ///< Current playback position in sample
109              double                      PitchBase;          ///< Basic pitch depth, stays the same for the whole life time of the voice              double                      PitchBase;          ///< Basic pitch depth, stays the same for the whole life time of the voice
110              double                      PitchBend;          ///< Current pitch value of the pitchbend wheel              double                      PitchBend;          ///< Current pitch value of the pitchbend wheel
# Line 130  namespace LinuxSampler { namespace gig { Line 127  namespace LinuxSampler { namespace gig {
127              midi_ctrl                   VCFResonanceCtrl;              midi_ctrl                   VCFResonanceCtrl;
128              int                         FilterUpdateCounter; ///< Used to update filter parameters all FILTER_UPDATE_PERIOD samples              int                         FilterUpdateCounter; ///< Used to update filter parameters all FILTER_UPDATE_PERIOD samples
129              static const float          FILTER_CUTOFF_COEFF;              static const float          FILTER_CUTOFF_COEFF;
130                static const int            FILTER_UPDATE_MASK;
131              VCAManipulator*             pVCAManipulator;              VCAManipulator*             pVCAManipulator;
132              VCFCManipulator*            pVCFCManipulator;              VCFCManipulator*            pVCFCManipulator;
133              VCOManipulator*             pVCOManipulator;              VCOManipulator*             pVCOManipulator;
# Line 140  namespace LinuxSampler { namespace gig { Line 138  namespace LinuxSampler { namespace gig {
138    
139              // Static Methods              // Static Methods
140              static float CalculateFilterCutoffCoeff();              static float CalculateFilterCutoffCoeff();
141                static int   CalculateFilterUpdateMask();
142    
143              // Methods              // Methods
144              void        ProcessEvents(uint Samples);              void        ProcessEvents(uint Samples);
145                #if ENABLE_FILTER
146                void        CalculateBiquadParameters(uint Samples);
147                #endif // ENABLE_FILTER
148              void        Interpolate(uint Samples, sample_t* pSrc, uint Skip);              void        Interpolate(uint Samples, sample_t* pSrc, uint Skip);
149              void        InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip);              void        InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip);
150              inline void InterpolateOneStep_Stereo(sample_t* pSrc, int& i, float& effective_volume, float& pitch, float& cutoff, float& resonance) {              inline void InterpolateOneStep_Stereo(sample_t* pSrc, int& i, float& effective_volume, float& pitch, biquad_param_t& bq_base, biquad_param_t& bq_main) {
151                  int   pos_int   = RTMath::DoubleToInt(this->Pos);  // integer position                  int   pos_int   = RTMath::DoubleToInt(this->Pos);  // integer position
152                  float pos_fract = this->Pos - pos_int;             // fractional part of position                  float pos_fract = this->Pos - pos_int;             // fractional part of position
153                  pos_int <<= 1;                  pos_int <<= 1;
154    
                 #if ENABLE_FILTER  
                     UpdateFilter_Stereo(cutoff + FILTER_CUTOFF_MIN, resonance);  
                 #endif // ENABLE_FILTER  
   
155                  #if USE_LINEAR_INTERPOLATION                  #if USE_LINEAR_INTERPOLATION
156                      #if ENABLE_FILTER                      #if ENABLE_FILTER
157                          // left channel                          // left channel
158                          pOutputLeft[i]    += this->FilterLeft.Apply(effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int])));                          pEngine->pOutputLeft[i]    += this->FilterLeft.Apply(&bq_base, &bq_main, effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int])));
159                          // right channel                          // right channel
160                          pOutputRight[i++] += this->FilterRight.Apply(effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1])));                          pEngine->pOutputRight[i++] += this->FilterRight.Apply(&bq_base, &bq_main, effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1])));
161                      #else // no filter                      #else // no filter
162                          // left channel                          // left channel
163                          pOutputLeft[i]    += effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int]));                          pEngine->pOutputLeft[i]    += effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int]));
164                          // right channel                          // right channel
165                          pOutputRight[i++] += effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1]));                          pEngine->pOutputRight[i++] += effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1]));
166                      #endif // ENABLE_FILTER                      #endif // ENABLE_FILTER
167                  #else // polynomial interpolation                  #else // polynomial interpolation
168                      // calculate left channel                      // calculate left channel
# Line 172  namespace LinuxSampler { namespace gig { Line 170  namespace LinuxSampler { namespace gig {
170                      float x0  = pSrc[pos_int+2];                      float x0  = pSrc[pos_int+2];
171                      float x1  = pSrc[pos_int+4];                      float x1  = pSrc[pos_int+4];
172                      float x2  = pSrc[pos_int+6];                      float x2  = pSrc[pos_int+6];
173                      float a   = (3 * (x0 - x1) - xm1 + x2) / 2;                      float a   = (3.0f * (x0 - x1) - xm1 + x2) * 0.5f;
174                      float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;                      float b   = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;
175                      float c   = (x1 - xm1) / 2;                      float c   = (x1 - xm1) * 0.5f;
176                      #if ENABLE_FILTER                      #if ENABLE_FILTER
177                          pOutputLeft[i] += this->FilterLeft.Apply(effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0));                          pEngine->pOutputLeft[i] += this->FilterLeft.Apply(&bq_base, &bq_main, effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0));
178                      #else // no filter                      #else // no filter
179                          pOutputRight[i] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);                          pEngine->pOutputLeft[i] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);
180                      #endif // ENABLE_FILTER                      #endif // ENABLE_FILTER
181    
182                      //calculate right channel                      //calculate right channel
# Line 186  namespace LinuxSampler { namespace gig { Line 184  namespace LinuxSampler { namespace gig {
184                      x0  = pSrc[pos_int+3];                      x0  = pSrc[pos_int+3];
185                      x1  = pSrc[pos_int+5];                      x1  = pSrc[pos_int+5];
186                      x2  = pSrc[pos_int+7];                      x2  = pSrc[pos_int+7];
187                      a   = (3 * (x0 - x1) - xm1 + x2) / 2;                      a   = (3.0f * (x0 - x1) - xm1 + x2) * 0.5f;
188                      b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;                      b   = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;
189                      c   = (x1 - xm1) / 2;                      c   = (x1 - xm1) * 0.5f;
190                      #if ENABLE_FILTER                      #if ENABLE_FILTER
191                          pOutputLeft[i++] += this->FilterRight.Apply(effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0));                          pEngine->pOutputRight[i++] += this->FilterRight.Apply(&bq_base, &bq_main, effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0));
192                      #else // no filter                      #else // no filter
193                          pOutputRight[i++] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);                          pEngine->pOutputRight[i++] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);
194                      #endif // ENABLE_FILTER                      #endif // ENABLE_FILTER
195                  #endif // USE_LINEAR_INTERPOLATION                  #endif // USE_LINEAR_INTERPOLATION
196    
197                  this->Pos += pitch;                  this->Pos += pitch;
198              }              }
199              inline void InterpolateOneStep_Mono(sample_t* pSrc, int& i, float& effective_volume, float& pitch, float& cutoff, float& resonance) {  
200                inline void InterpolateOneStep_Mono(sample_t* pSrc, int& i, float& effective_volume, float& pitch,  biquad_param_t& bq_base, biquad_param_t& bq_main) {
201                  int   pos_int   = RTMath::DoubleToInt(this->Pos);  // integer position                  int   pos_int   = RTMath::DoubleToInt(this->Pos);  // integer position
202                  float pos_fract = this->Pos - pos_int;             // fractional part of position                  float pos_fract = this->Pos - pos_int;             // fractional part of position
203    
                 #if ENABLE_FILTER  
                     UpdateFilter_Mono(cutoff + FILTER_CUTOFF_MIN, resonance);  
                 #endif // ENABLE_FILTER  
   
204                  #if USE_LINEAR_INTERPOLATION                  #if USE_LINEAR_INTERPOLATION
205                      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]));
206                  #else // polynomial interpolation                  #else // polynomial interpolation
# Line 213  namespace LinuxSampler { namespace gig { Line 208  namespace LinuxSampler { namespace gig {
208                      float x0  = pSrc[pos_int+1];                      float x0  = pSrc[pos_int+1];
209                      float x1  = pSrc[pos_int+2];                      float x1  = pSrc[pos_int+2];
210                      float x2  = pSrc[pos_int+3];                      float x2  = pSrc[pos_int+3];
211                      float a   = (3 * (x0 - x1) - xm1 + x2) / 2;                      float a   = (3.0f * (x0 - x1) - xm1 + x2) * 0.5f;
212                      float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;                      float b   = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;
213                      float c   = (x1 - xm1) / 2;                      float c   = (x1 - xm1) * 0.5f;
214                      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);
215                  #endif // USE_LINEAR_INTERPOLATION                  #endif // USE_LINEAR_INTERPOLATION
216    
217                  #if ENABLE_FILTER                  #if ENABLE_FILTER
218                      sample_point = this->FilterLeft.Apply(sample_point);                      sample_point = this->FilterLeft.Apply(&bq_base, &bq_main, sample_point);
219                  #endif // ENABLE_FILTER                  #endif // ENABLE_FILTER
220    
221                  pOutputLeft[i]    += sample_point;                  pEngine->pOutputLeft[i]    += sample_point;
222                  pOutputRight[i++] += sample_point;                  pEngine->pOutputRight[i++] += sample_point;
223    
224                  this->Pos += pitch;                  this->Pos += pitch;
225              }              }
226              inline void UpdateFilter_Stereo(float cutoff, float& resonance) {  
                 if (!(++FilterUpdateCounter % FILTER_UPDATE_PERIOD) && (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance())) {  
                     FilterLeft.SetParameters(cutoff, resonance, SampleRate);  
                     FilterRight.SetParameters(cutoff, resonance, SampleRate);  
                 }  
             }  
             inline void UpdateFilter_Mono(float cutoff, float& resonance) {  
                 if (!(++FilterUpdateCounter % FILTER_UPDATE_PERIOD) && (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance())) {  
                     FilterLeft.SetParameters(cutoff, resonance, SampleRate);  
                 }  
             }  
227              inline float Constrain(float ValueToCheck, float Min, float Max) {              inline float Constrain(float ValueToCheck, float Min, float Max) {
228                  if      (ValueToCheck > Max) ValueToCheck = Max;                  if      (ValueToCheck > Max) ValueToCheck = Max;
229                  else if (ValueToCheck < Min) ValueToCheck = Min;                  else if (ValueToCheck < Min) ValueToCheck = Min;

Legend:
Removed from v.53  
changed lines
  Added in v.225

  ViewVC Help
Powered by ViewVC