/[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 80 by schoenebeck, Sun May 23 19:16:33 2004 UTC revision 239 by schoenebeck, Sun Sep 12 14:48:19 2004 UTC
# 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"  #include "../common/BiquadFilter.h"
38  #include "Engine.h"  #include "Engine.h"
# Line 82  namespace LinuxSampler { namespace gig { Line 82  namespace LinuxSampler { namespace gig {
82          public:          public:
83              // Attributes              // Attributes
84              int          MIDIKey;      ///< MIDI key number of the key that triggered the voice              int          MIDIKey;      ///< MIDI key number of the key that triggered the voice
85                uint         KeyGroup;
86              DiskThread*  pDiskThread;  ///< Pointer to the disk thread, to be able to order a disk stream and later to delete the stream again              DiskThread*  pDiskThread;  ///< Pointer to the disk thread, to be able to order a disk stream and later to delete the stream again
87    
88              // Methods              // Methods
89              Voice();              Voice();
90             ~Voice();             ~Voice();
91              void Kill();              void Kill(Event* pKillEvent);
92                void KillImmediately();
93              void Render(uint Samples);              void Render(uint Samples);
94              void Reset();              void Reset();
95              void SetOutput(AudioOutputDevice* pAudioOutputDevice);              void SetOutput(AudioOutputDevice* pAudioOutputDevice);
96              void SetEngine(Engine* pEngine);              void SetEngine(Engine* pEngine);
97              int  Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument);              int  Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer = 0);
98              inline bool IsActive() { return Active; }              inline bool IsActive() { return Active; }
99          private:          private:
100              // Types              // Types
# Line 105  namespace LinuxSampler { namespace gig { Line 107  namespace LinuxSampler { namespace gig {
107              // Attributes              // Attributes
108              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.
109              float                       Volume;             ///< Volume level of the voice              float                       Volume;             ///< Volume level of the voice
110              float*                      pOutputLeft;        ///< Audio output channel buffer (left)              float                       CrossfadeVolume;    ///< Current attenuation level caused by a crossfade (only if a crossfade is defined of course)
             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  
111              double                      Pos;                ///< Current playback position in sample              double                      Pos;                ///< Current playback position in sample
112              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
113              double                      PitchBend;          ///< Current pitch value of the pitchbend wheel              double                      PitchBend;          ///< Current pitch value of the pitchbend wheel
114              ::gig::Sample*              pSample;            ///< Pointer to the sample to be played back              ::gig::Sample*              pSample;            ///< Pointer to the sample to be played back
115              ::gig::Region*              pRegion;            ///< Pointer to the articulation information of the respective keyboard region of this voice              ::gig::Region*              pRegion;            ///< Pointer to the articulation information of the respective keyboard region of this voice
116                ::gig::DimensionRegion*     pDimRgn;            ///< Pointer to the articulation information of current dimension region of this voice
117              bool                        Active;             ///< If this voice object is currently in usage              bool                        Active;             ///< If this voice object is currently in usage
118              playback_state_t            PlaybackState;      ///< When a sample will be triggered, it will be first played from RAM cache and after a couple of sample points it will switch to disk streaming and at the end of a disk stream we have to add null samples, so the interpolator can do it's work correctly              playback_state_t            PlaybackState;      ///< When a sample will be triggered, it will be first played from RAM cache and after a couple of sample points it will switch to disk streaming and at the end of a disk stream we have to add null samples, so the interpolator can do it's work correctly
119              bool                        DiskVoice;          ///< If the sample is very short it completely fits into the RAM cache and doesn't need to be streamed from disk, in that case this flag is set to false              bool                        DiskVoice;          ///< If the sample is very short it completely fits into the RAM cache and doesn't need to be streamed from disk, in that case this flag is set to false
# Line 139  namespace LinuxSampler { namespace gig { Line 139  namespace LinuxSampler { namespace gig {
139              LFO<gig::VCFCManipulator>*  pLFO2;             ///< Low Frequency Oscillator 2 (Filter cutoff frequency)              LFO<gig::VCFCManipulator>*  pLFO2;             ///< Low Frequency Oscillator 2 (Filter cutoff frequency)
140              LFO<gig::VCOManipulator>*   pLFO3;              ///< Low Frequency Oscillator 3 (Pitch)              LFO<gig::VCOManipulator>*   pLFO3;              ///< Low Frequency Oscillator 3 (Pitch)
141              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).              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).
142                Event*                      pKillEvent;         ///< Event which caused this voice to be killed
143    
144              // Static Methods              // Static Methods
145              static float CalculateFilterCutoffCoeff();              static float CalculateFilterCutoffCoeff();
# Line 156  namespace LinuxSampler { namespace gig { Line 157  namespace LinuxSampler { namespace gig {
157                  float pos_fract = this->Pos - pos_int;             // fractional part of position                  float pos_fract = this->Pos - pos_int;             // fractional part of position
158                  pos_int <<= 1;                  pos_int <<= 1;
159    
                 #if 0 //ENABLE_FILTER  
                     UpdateFilter_Stereo(cutoff + FILTER_CUTOFF_MIN, resonance);  
                 #endif // ENABLE_FILTER  
   
160                  #if USE_LINEAR_INTERPOLATION                  #if USE_LINEAR_INTERPOLATION
161                      #if ENABLE_FILTER                      #if ENABLE_FILTER
162                          // left channel                          // left channel
163                          pOutputLeft[i]    += this->FilterLeft.Apply(&bq_base, &bq_main, 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])));
164                          // right channel                          // right channel
165                          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])));                          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])));
166                      #else // no filter                      #else // no filter
167                          // left channel                          // left channel
168                          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]));
169                          // right channel                          // right channel
170                          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]));
171                      #endif // ENABLE_FILTER                      #endif // ENABLE_FILTER
172                  #else // polynomial interpolation                  #else // polynomial interpolation
173                      // calculate left channel                      // calculate left channel
# Line 178  namespace LinuxSampler { namespace gig { Line 175  namespace LinuxSampler { namespace gig {
175                      float x0  = pSrc[pos_int+2];                      float x0  = pSrc[pos_int+2];
176                      float x1  = pSrc[pos_int+4];                      float x1  = pSrc[pos_int+4];
177                      float x2  = pSrc[pos_int+6];                      float x2  = pSrc[pos_int+6];
178                      float a   = (3 * (x0 - x1) - xm1 + x2) / 2;                      float a   = (3.0f * (x0 - x1) - xm1 + x2) * 0.5f;
179                      float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;                      float b   = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;
180                      float c   = (x1 - xm1) / 2;                      float c   = (x1 - xm1) * 0.5f;
181                      #if ENABLE_FILTER                      #if ENABLE_FILTER
182                          pOutputLeft[i] += this->FilterLeft.Apply(&bq_base, &bq_main, 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));
183                      #else // no filter                      #else // no filter
184                          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);
185                      #endif // ENABLE_FILTER                      #endif // ENABLE_FILTER
186    
187                      //calculate right channel                      //calculate right channel
# Line 192  namespace LinuxSampler { namespace gig { Line 189  namespace LinuxSampler { namespace gig {
189                      x0  = pSrc[pos_int+3];                      x0  = pSrc[pos_int+3];
190                      x1  = pSrc[pos_int+5];                      x1  = pSrc[pos_int+5];
191                      x2  = pSrc[pos_int+7];                      x2  = pSrc[pos_int+7];
192                      a   = (3 * (x0 - x1) - xm1 + x2) / 2;                      a   = (3.0f * (x0 - x1) - xm1 + x2) * 0.5f;
193                      b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;                      b   = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;
194                      c   = (x1 - xm1) / 2;                      c   = (x1 - xm1) * 0.5f;
195                      #if ENABLE_FILTER                      #if ENABLE_FILTER
196                          pOutputLeft[i++] += this->FilterRight.Apply(&bq_base, &bq_main, 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));
197                      #else // no filter                      #else // no filter
198                          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);
199                      #endif // ENABLE_FILTER                      #endif // ENABLE_FILTER
200                  #endif // USE_LINEAR_INTERPOLATION                  #endif // USE_LINEAR_INTERPOLATION
201    
202                  this->Pos += pitch;                  this->Pos += pitch;
203              }              }
204    
205              inline void InterpolateOneStep_Mono(sample_t* pSrc, int& i, float& effective_volume, float& pitch,  biquad_param_t& bq_base, biquad_param_t& bq_main) {              inline void InterpolateOneStep_Mono(sample_t* pSrc, int& i, float& effective_volume, float& pitch,  biquad_param_t& bq_base, biquad_param_t& bq_main) {
206                  int   pos_int   = RTMath::DoubleToInt(this->Pos);  // integer position                  int   pos_int   = RTMath::DoubleToInt(this->Pos);  // integer position
207                  float pos_fract = this->Pos - pos_int;             // fractional part of position                  float pos_fract = this->Pos - pos_int;             // fractional part of position
208    
                 #if 0 //ENABLE_FILTER  
                     UpdateFilter_Mono(cutoff + FILTER_CUTOFF_MIN, resonance);  
                 #endif // ENABLE_FILTER  
   
209                  #if USE_LINEAR_INTERPOLATION                  #if USE_LINEAR_INTERPOLATION
210                      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]));
211                  #else // polynomial interpolation                  #else // polynomial interpolation
# Line 219  namespace LinuxSampler { namespace gig { Line 213  namespace LinuxSampler { namespace gig {
213                      float x0  = pSrc[pos_int+1];                      float x0  = pSrc[pos_int+1];
214                      float x1  = pSrc[pos_int+2];                      float x1  = pSrc[pos_int+2];
215                      float x2  = pSrc[pos_int+3];                      float x2  = pSrc[pos_int+3];
216                      float a   = (3 * (x0 - x1) - xm1 + x2) / 2;                      float a   = (3.0f * (x0 - x1) - xm1 + x2) * 0.5f;
217                      float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;                      float b   = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;
218                      float c   = (x1 - xm1) / 2;                      float c   = (x1 - xm1) * 0.5f;
219                      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);
220                  #endif // USE_LINEAR_INTERPOLATION                  #endif // USE_LINEAR_INTERPOLATION
221    
# Line 229  namespace LinuxSampler { namespace gig { Line 223  namespace LinuxSampler { namespace gig {
223                      sample_point = this->FilterLeft.Apply(&bq_base, &bq_main, sample_point);                      sample_point = this->FilterLeft.Apply(&bq_base, &bq_main, sample_point);
224                  #endif // ENABLE_FILTER                  #endif // ENABLE_FILTER
225    
226                  pOutputLeft[i]    += sample_point;                  pEngine->pOutputLeft[i]    += sample_point;
227                  pOutputRight[i++] += sample_point;                  pEngine->pOutputRight[i++] += sample_point;
228    
229                  this->Pos += pitch;                  this->Pos += pitch;
230              }              }
231  #if 0  
232              inline void UpdateFilter_Stereo(float cutoff, float& resonance) {              inline float CrossfadeAttenuation(uint8_t& CrossfadeControllerValue) {
233                  if (!(++FilterUpdateCounter % FILTER_UPDATE_PERIOD) && (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance())) {                  return (CrossfadeControllerValue <= pDimRgn->Crossfade.in_start)  ? 0.0f
234                      FilterLeft.SetParameters(cutoff, resonance, SampleRate);                       : (CrossfadeControllerValue < pDimRgn->Crossfade.in_end)     ? float(CrossfadeControllerValue - pDimRgn->Crossfade.in_start) / float(pDimRgn->Crossfade.in_end - pDimRgn->Crossfade.in_start)
235                      FilterRight.SetParameters(cutoff, resonance, SampleRate);                       : (CrossfadeControllerValue <= pDimRgn->Crossfade.out_start) ? 1.0f
236                  }                       : (CrossfadeControllerValue < pDimRgn->Crossfade.out_end)    ? float(CrossfadeControllerValue - pDimRgn->Crossfade.out_start) / float(pDimRgn->Crossfade.out_end - pDimRgn->Crossfade.out_start)
237              }                       : 0.0f;
             inline void UpdateFilter_Mono(float cutoff, float& resonance) {  
                 if (!(++FilterUpdateCounter % FILTER_UPDATE_PERIOD) && (cutoff != FilterLeft.Cutoff() || resonance != FilterLeft.Resonance())) {  
                     FilterLeft.SetParameters(cutoff, resonance, SampleRate);  
                 }  
238              }              }
239  #endif  
240              inline float Constrain(float ValueToCheck, float Min, float Max) {              inline float Constrain(float ValueToCheck, float Min, float Max) {
241                  if      (ValueToCheck > Max) ValueToCheck = Max;                  if      (ValueToCheck > Max) ValueToCheck = Max;
242                  else if (ValueToCheck < Min) ValueToCheck = Min;                  else if (ValueToCheck < Min) ValueToCheck = Min;

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

  ViewVC Help
Powered by ViewVC