/[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 203 by schoenebeck, Tue Jul 13 22:44:13 2004 UTC revision 242 by schoenebeck, Wed Sep 15 13:59:08 2004 UTC
# Line 80  namespace LinuxSampler { namespace gig { Line 80  namespace LinuxSampler { namespace gig {
80       */       */
81      class Voice {      class Voice {
82          public:          public:
83                // Types
84                enum type_t {
85                    type_normal,
86                    type_release_trigger_required,  ///< If the key of this voice will be released, it causes a release triggered voice to be spawned
87                    type_release_trigger            ///< Release triggered voice which cannot be killed by releasing its key
88                };
89    
90              // Attributes              // Attributes
91                type_t       Type;         ///< Voice Type
92              int          MIDIKey;      ///< MIDI key number of the key that triggered the voice              int          MIDIKey;      ///< MIDI key number of the key that triggered the voice
93                uint         KeyGroup;
94              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
95    
96              // Methods              // Methods
97              Voice();              Voice();
98             ~Voice();             ~Voice();
99              void Kill();              void Kill(Event* pKillEvent);
100                void KillImmediately();
101              void Render(uint Samples);              void Render(uint Samples);
102              void Reset();              void Reset();
103              void SetOutput(AudioOutputDevice* pAudioOutputDevice);              void SetOutput(AudioOutputDevice* pAudioOutputDevice);
104              void SetEngine(Engine* pEngine);              void SetEngine(Engine* pEngine);
105              int  Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument);              int  Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer = 0, bool ReleaseTriggerVoice = false);
106              inline bool IsActive() { return Active; }              inline bool IsActive() { return Active; }
107          private:          private:
108              // Types              // Types
# Line 105  namespace LinuxSampler { namespace gig { Line 115  namespace LinuxSampler { namespace gig {
115              // Attributes              // Attributes
116              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.
117              float                       Volume;             ///< Volume level of the voice              float                       Volume;             ///< Volume level of the voice
118              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  
119              double                      Pos;                ///< Current playback position in sample              double                      Pos;                ///< Current playback position in sample
120              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
121              double                      PitchBend;          ///< Current pitch value of the pitchbend wheel              double                      PitchBend;          ///< Current pitch value of the pitchbend wheel
122              ::gig::Sample*              pSample;            ///< Pointer to the sample to be played back              ::gig::Sample*              pSample;            ///< Pointer to the sample to be played back
123              ::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
124                ::gig::DimensionRegion*     pDimRgn;            ///< Pointer to the articulation information of current dimension region of this voice
125              bool                        Active;             ///< If this voice object is currently in usage              bool                        Active;             ///< If this voice object is currently in usage
126              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
127              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 147  namespace LinuxSampler { namespace gig {
147              LFO<gig::VCFCManipulator>*  pLFO2;             ///< Low Frequency Oscillator 2 (Filter cutoff frequency)              LFO<gig::VCFCManipulator>*  pLFO2;             ///< Low Frequency Oscillator 2 (Filter cutoff frequency)
148              LFO<gig::VCOManipulator>*   pLFO3;              ///< Low Frequency Oscillator 3 (Pitch)              LFO<gig::VCOManipulator>*   pLFO3;              ///< Low Frequency Oscillator 3 (Pitch)
149              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).
150                Event*                      pKillEvent;         ///< Event which caused this voice to be killed
151    
152              // Static Methods              // Static Methods
153              static float CalculateFilterCutoffCoeff();              static float CalculateFilterCutoffCoeff();
# Line 159  namespace LinuxSampler { namespace gig { Line 168  namespace LinuxSampler { namespace gig {
168                  #if USE_LINEAR_INTERPOLATION                  #if USE_LINEAR_INTERPOLATION
169                      #if ENABLE_FILTER                      #if ENABLE_FILTER
170                          // left channel                          // left channel
171                          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])));
172                          // right channel                          // right channel
173                          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])));
174                      #else // no filter                      #else // no filter
175                          // left channel                          // left channel
176                          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]));
177                          // right channel                          // right channel
178                          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]));
179                      #endif // ENABLE_FILTER                      #endif // ENABLE_FILTER
180                  #else // polynomial interpolation                  #else // polynomial interpolation
181                      // calculate left channel                      // calculate left channel
# Line 178  namespace LinuxSampler { namespace gig { Line 187  namespace LinuxSampler { namespace gig {
187                      float b   = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;                      float b   = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;
188                      float c   = (x1 - xm1) * 0.5f;                      float c   = (x1 - xm1) * 0.5f;
189                      #if ENABLE_FILTER                      #if ENABLE_FILTER
190                          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));
191                      #else // no filter                      #else // no filter
192                          pOutputLeft[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);
193                      #endif // ENABLE_FILTER                      #endif // ENABLE_FILTER
194    
195                      //calculate right channel                      //calculate right channel
# Line 192  namespace LinuxSampler { namespace gig { Line 201  namespace LinuxSampler { namespace gig {
201                      b   = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;                      b   = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;
202                      c   = (x1 - xm1) * 0.5f;                      c   = (x1 - xm1) * 0.5f;
203                      #if ENABLE_FILTER                      #if ENABLE_FILTER
204                          pOutputRight[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));
205                      #else // no filter                      #else // no filter
206                          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);
207                      #endif // ENABLE_FILTER                      #endif // ENABLE_FILTER
208                  #endif // USE_LINEAR_INTERPOLATION                  #endif // USE_LINEAR_INTERPOLATION
209    
# Line 222  namespace LinuxSampler { namespace gig { Line 231  namespace LinuxSampler { namespace gig {
231                      sample_point = this->FilterLeft.Apply(&bq_base, &bq_main, sample_point);                      sample_point = this->FilterLeft.Apply(&bq_base, &bq_main, sample_point);
232                  #endif // ENABLE_FILTER                  #endif // ENABLE_FILTER
233    
234                  pOutputLeft[i]    += sample_point;                  pEngine->pOutputLeft[i]    += sample_point;
235                  pOutputRight[i++] += sample_point;                  pEngine->pOutputRight[i++] += sample_point;
236    
237                  this->Pos += pitch;                  this->Pos += pitch;
238              }              }
239    
240                inline float CrossfadeAttenuation(uint8_t& CrossfadeControllerValue) {
241                    return (CrossfadeControllerValue <= pDimRgn->Crossfade.in_start)  ? 0.0f
242                         : (CrossfadeControllerValue < pDimRgn->Crossfade.in_end)     ? float(CrossfadeControllerValue - pDimRgn->Crossfade.in_start) / float(pDimRgn->Crossfade.in_end - pDimRgn->Crossfade.in_start)
243                         : (CrossfadeControllerValue <= pDimRgn->Crossfade.out_start) ? 1.0f
244                         : (CrossfadeControllerValue < pDimRgn->Crossfade.out_end)    ? float(CrossfadeControllerValue - pDimRgn->Crossfade.out_start) / float(pDimRgn->Crossfade.out_end - pDimRgn->Crossfade.out_start)
245                         : 0.0f;
246                }
247    
248              inline float Constrain(float ValueToCheck, float Min, float Max) {              inline float Constrain(float ValueToCheck, float Min, float Max) {
249                  if      (ValueToCheck > Max) ValueToCheck = Max;                  if      (ValueToCheck > Max) ValueToCheck = Max;
250                  else if (ValueToCheck < Min) ValueToCheck = Min;                  else if (ValueToCheck < Min) ValueToCheck = Min;

Legend:
Removed from v.203  
changed lines
  Added in v.242

  ViewVC Help
Powered by ViewVC