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

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

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

revision 239 by schoenebeck, Sun Sep 12 14:48:19 2004 UTC revision 438 by persson, Wed Mar 9 22:12:15 2005 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6     *   Copyright (C) 2005 Christian Schoenebeck                              *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   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 22  Line 23 
23    
24  #include "EGADSR.h"  #include "EGADSR.h"
25  #include "Manipulator.h"  #include "Manipulator.h"
26    #include "../../common/Features.h"
27    #include "Synthesizer.h"
28    
29  #include "Voice.h"  #include "Voice.h"
30    
31  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
32    
     // TODO: no support for crossfades yet  
   
33      const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());      const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());
34    
35      const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());      const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());
# Line 47  namespace LinuxSampler { namespace gig { Line 48  namespace LinuxSampler { namespace gig {
48      Voice::Voice() {      Voice::Voice() {
49          pEngine     = NULL;          pEngine     = NULL;
50          pDiskThread = NULL;          pDiskThread = NULL;
51          Active = false;          PlaybackState = playback_state_end;
52          pEG1   = NULL;          pEG1   = NULL;
53          pEG2   = NULL;          pEG2   = NULL;
54          pEG3   = NULL;          pEG3   = NULL;
# Line 58  namespace LinuxSampler { namespace gig { Line 59  namespace LinuxSampler { namespace gig {
59          pLFO2  = NULL;          pLFO2  = NULL;
60          pLFO3  = NULL;          pLFO3  = NULL;
61          KeyGroup = 0;          KeyGroup = 0;
62            SynthesisMode = 0; // set all mode bits to 0 first
63            // select synthesis implementation (currently either pure C++ or MMX+SSE(1))
64            #if ARCH_X86
65            SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
66            #else
67            SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
68            #endif
69            SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true);
70    
71            FilterLeft.Reset();
72            FilterRight.Reset();
73      }      }
74    
75      Voice::~Voice() {      Voice::~Voice() {
# Line 105  namespace LinuxSampler { namespace gig { Line 117  namespace LinuxSampler { namespace gig {
117       *  Initializes and triggers the voice, a disk stream will be launched if       *  Initializes and triggers the voice, a disk stream will be launched if
118       *  needed.       *  needed.
119       *       *
120       *  @param pNoteOnEvent - event that caused triggering of this voice       *  @param pEngineChannel      - engine channel on which this voice was ordered
121       *  @param PitchBend    - MIDI detune factor (-8192 ... +8191)       *  @param itNoteOnEvent       - event that caused triggering of this voice
122       *  @param pInstrument  - points to the loaded instrument which provides sample wave(s) and articulation data       *  @param PitchBend           - MIDI detune factor (-8192 ... +8191)
123       *  @param iLayer       - layer number this voice refers to (only if this is a layered sound of course)       *  @param pInstrument         - points to the loaded instrument which provides sample wave(s) and articulation data
124       *  @returns            0 on success, a value < 0 if something failed       *  @param iLayer              - layer number this voice refers to (only if this is a layered sound of course)
125         *  @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)
126         *  @param VoiceStealing       - wether the voice is allowed to steal voices for further subvoices
127         *  @returns 0 on success, a value < 0 if the voice wasn't triggered
128         *           (either due to an error or e.g. because no region is
129         *           defined for the given key)
130       */       */
131      int Voice::Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer) {      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) {
132            this->pEngineChannel = pEngineChannel;
133          if (!pInstrument) {          if (!pInstrument) {
134             dmsg(1,("voice::trigger: !pInstrument\n"));             dmsg(1,("voice::trigger: !pInstrument\n"));
135             exit(EXIT_FAILURE);             exit(EXIT_FAILURE);
136          }          }
137            if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // FIXME: should be removed before the final release (purpose: just a sanity check for debugging)
138                dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
139            }
140    
141          Active          = true;          Type            = type_normal;
142          MIDIKey         = pNoteOnEvent->Key;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
143          pRegion         = pInstrument->GetRegion(MIDIKey);          pRegion         = pInstrument->GetRegion(MIDIKey);
144          PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed          PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
145          Delay           = pNoteOnEvent->FragmentPos();          Delay           = itNoteOnEvent->FragmentPos();
146          pTriggerEvent   = pNoteOnEvent;          itTriggerEvent  = itNoteOnEvent;
147          pKillEvent      = NULL;          itKillEvent     = Pool<Event>::Iterator();
148            itChildVoice    = Pool<Voice>::Iterator();
149    
150          if (!pRegion) {          if (!pRegion) {
151              std::cerr << "gig::Voice: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;              dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey));
             KillImmediately();  
152              return -1;              return -1;
153          }          }
154    
# Line 135  namespace LinuxSampler { namespace gig { Line 156  namespace LinuxSampler { namespace gig {
156    
157          // get current dimension values to select the right dimension region          // get current dimension values to select the right dimension region
158          //FIXME: controller values for selecting the dimension region here are currently not sample accurate          //FIXME: controller values for selecting the dimension region here are currently not sample accurate
159          uint DimValues[5] = {0,0,0,0,0};          uint DimValues[8] = { 0 };
160          for (int i = pRegion->Dimensions - 1; i >= 0; i--) {          for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
161              switch (pRegion->pDimensionDefinitions[i].dimension) {              switch (pRegion->pDimensionDefinitions[i].dimension) {
162                  case ::gig::dimension_samplechannel:                  case ::gig::dimension_samplechannel:
# Line 146  namespace LinuxSampler { namespace gig { Line 167  namespace LinuxSampler { namespace gig {
167                      // if this is the 1st layer then spawn further voices for all the other layers                      // if this is the 1st layer then spawn further voices for all the other layers
168                      if (iLayer == 0)                      if (iLayer == 0)
169                          for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++)                          for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++)
170                              pEngine->LaunchVoice(pNoteOnEvent, iNewLayer);                              itChildVoice = pEngine->LaunchVoice(pEngineChannel, itNoteOnEvent, iNewLayer, ReleaseTriggerVoice, VoiceStealing);
171                      break;                      break;
172                  case ::gig::dimension_velocity:                  case ::gig::dimension_velocity:
173                      DimValues[i] = pNoteOnEvent->Velocity;                      DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
174                      break;                      break;
175                  case ::gig::dimension_channelaftertouch:                  case ::gig::dimension_channelaftertouch:
176                      DimValues[i] = 0; //TODO: we currently ignore this dimension                      DimValues[i] = 0; //TODO: we currently ignore this dimension
177                      break;                      break;
178                  case ::gig::dimension_releasetrigger:                  case ::gig::dimension_releasetrigger:
179                      DimValues[i] = 0; //TODO: we currently ignore this dimension                      Type = (ReleaseTriggerVoice) ? type_release_trigger : (!iLayer) ? type_release_trigger_required : type_normal;
180                        DimValues[i] = (uint) ReleaseTriggerVoice;
181                      break;                      break;
182                  case ::gig::dimension_keyboard:                  case ::gig::dimension_keyboard:
183                      DimValues[i] = (uint) pNoteOnEvent->Key;                      DimValues[i] = (uint) pEngineChannel->CurrentKeyDimension;
184                        break;
185                    case ::gig::dimension_roundrobin:
186                        DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on
187                        break;
188                    case ::gig::dimension_random:
189                        pEngine->RandomSeed = pEngine->RandomSeed * 1103515245 + 12345; // classic pseudo random number generator
190                        DimValues[i] = (uint) pEngine->RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random
191                      break;                      break;
192                  case ::gig::dimension_modwheel:                  case ::gig::dimension_modwheel:
193                      DimValues[i] = pEngine->ControllerTable[1];                      DimValues[i] = pEngineChannel->ControllerTable[1];
194                      break;                      break;
195                  case ::gig::dimension_breath:                  case ::gig::dimension_breath:
196                      DimValues[i] = pEngine->ControllerTable[2];                      DimValues[i] = pEngineChannel->ControllerTable[2];
197                      break;                      break;
198                  case ::gig::dimension_foot:                  case ::gig::dimension_foot:
199                      DimValues[i] = pEngine->ControllerTable[4];                      DimValues[i] = pEngineChannel->ControllerTable[4];
200                      break;                      break;
201                  case ::gig::dimension_portamentotime:                  case ::gig::dimension_portamentotime:
202                      DimValues[i] = pEngine->ControllerTable[5];                      DimValues[i] = pEngineChannel->ControllerTable[5];
203                      break;                      break;
204                  case ::gig::dimension_effect1:                  case ::gig::dimension_effect1:
205                      DimValues[i] = pEngine->ControllerTable[12];                      DimValues[i] = pEngineChannel->ControllerTable[12];
206                      break;                      break;
207                  case ::gig::dimension_effect2:                  case ::gig::dimension_effect2:
208                      DimValues[i] = pEngine->ControllerTable[13];                      DimValues[i] = pEngineChannel->ControllerTable[13];
209                      break;                      break;
210                  case ::gig::dimension_genpurpose1:                  case ::gig::dimension_genpurpose1:
211                      DimValues[i] = pEngine->ControllerTable[16];                      DimValues[i] = pEngineChannel->ControllerTable[16];
212                      break;                      break;
213                  case ::gig::dimension_genpurpose2:                  case ::gig::dimension_genpurpose2:
214                      DimValues[i] = pEngine->ControllerTable[17];                      DimValues[i] = pEngineChannel->ControllerTable[17];
215                      break;                      break;
216                  case ::gig::dimension_genpurpose3:                  case ::gig::dimension_genpurpose3:
217                      DimValues[i] = pEngine->ControllerTable[18];                      DimValues[i] = pEngineChannel->ControllerTable[18];
218                      break;                      break;
219                  case ::gig::dimension_genpurpose4:                  case ::gig::dimension_genpurpose4:
220                      DimValues[i] = pEngine->ControllerTable[19];                      DimValues[i] = pEngineChannel->ControllerTable[19];
221                      break;                      break;
222                  case ::gig::dimension_sustainpedal:                  case ::gig::dimension_sustainpedal:
223                      DimValues[i] = pEngine->ControllerTable[64];                      DimValues[i] = pEngineChannel->ControllerTable[64];
224                      break;                      break;
225                  case ::gig::dimension_portamento:                  case ::gig::dimension_portamento:
226                      DimValues[i] = pEngine->ControllerTable[65];                      DimValues[i] = pEngineChannel->ControllerTable[65];
227                      break;                      break;
228                  case ::gig::dimension_sostenutopedal:                  case ::gig::dimension_sostenutopedal:
229                      DimValues[i] = pEngine->ControllerTable[66];                      DimValues[i] = pEngineChannel->ControllerTable[66];
230                      break;                      break;
231                  case ::gig::dimension_softpedal:                  case ::gig::dimension_softpedal:
232                      DimValues[i] = pEngine->ControllerTable[67];                      DimValues[i] = pEngineChannel->ControllerTable[67];
233                      break;                      break;
234                  case ::gig::dimension_genpurpose5:                  case ::gig::dimension_genpurpose5:
235                      DimValues[i] = pEngine->ControllerTable[80];                      DimValues[i] = pEngineChannel->ControllerTable[80];
236                      break;                      break;
237                  case ::gig::dimension_genpurpose6:                  case ::gig::dimension_genpurpose6:
238                      DimValues[i] = pEngine->ControllerTable[81];                      DimValues[i] = pEngineChannel->ControllerTable[81];
239                      break;                      break;
240                  case ::gig::dimension_genpurpose7:                  case ::gig::dimension_genpurpose7:
241                      DimValues[i] = pEngine->ControllerTable[82];                      DimValues[i] = pEngineChannel->ControllerTable[82];
242                      break;                      break;
243                  case ::gig::dimension_genpurpose8:                  case ::gig::dimension_genpurpose8:
244                      DimValues[i] = pEngine->ControllerTable[83];                      DimValues[i] = pEngineChannel->ControllerTable[83];
245                      break;                      break;
246                  case ::gig::dimension_effect1depth:                  case ::gig::dimension_effect1depth:
247                      DimValues[i] = pEngine->ControllerTable[91];                      DimValues[i] = pEngineChannel->ControllerTable[91];
248                      break;                      break;
249                  case ::gig::dimension_effect2depth:                  case ::gig::dimension_effect2depth:
250                      DimValues[i] = pEngine->ControllerTable[92];                      DimValues[i] = pEngineChannel->ControllerTable[92];
251                      break;                      break;
252                  case ::gig::dimension_effect3depth:                  case ::gig::dimension_effect3depth:
253                      DimValues[i] = pEngine->ControllerTable[93];                      DimValues[i] = pEngineChannel->ControllerTable[93];
254                      break;                      break;
255                  case ::gig::dimension_effect4depth:                  case ::gig::dimension_effect4depth:
256                      DimValues[i] = pEngine->ControllerTable[94];                      DimValues[i] = pEngineChannel->ControllerTable[94];
257                      break;                      break;
258                  case ::gig::dimension_effect5depth:                  case ::gig::dimension_effect5depth:
259                      DimValues[i] = pEngine->ControllerTable[95];                      DimValues[i] = pEngineChannel->ControllerTable[95];
260                      break;                      break;
261                  case ::gig::dimension_none:                  case ::gig::dimension_none:
262                      std::cerr << "gig::Voice::Trigger() Error: dimension=none\n" << std::flush;                      std::cerr << "gig::Voice::Trigger() Error: dimension=none\n" << std::flush;
# Line 236  namespace LinuxSampler { namespace gig { Line 265  namespace LinuxSampler { namespace gig {
265                      std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;                      std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;
266              }              }
267          }          }
268          pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);          pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
269    
270            pSample = pDimRgn->pSample; // sample won't change until the voice is finished
271            if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent
272    
273            // select channel mode (mono or stereo)
274            SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
275    
276          // get starting crossfade volume level          // get starting crossfade volume level
277          switch (pDimRgn->AttenuationController.type) {          switch (pDimRgn->AttenuationController.type) {
# Line 244  namespace LinuxSampler { namespace gig { Line 279  namespace LinuxSampler { namespace gig {
279                  CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet                  CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
280                  break;                  break;
281              case ::gig::attenuation_ctrl_t::type_velocity:              case ::gig::attenuation_ctrl_t::type_velocity:
282                  CrossfadeVolume = CrossfadeAttenuation(pNoteOnEvent->Velocity);                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
283                  break;                  break;
284              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
285                  CrossfadeVolume = CrossfadeAttenuation(pEngine->ControllerTable[pDimRgn->AttenuationController.controller_number]);                  CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);
286                  break;                  break;
287              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
288              default:              default:
289                  CrossfadeVolume = 1.0f;                  CrossfadeVolume = 1.0f;
290          }          }
291    
292          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          PanLeft  = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) /  63.0f;
293            PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;
294    
295          Pos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)          Pos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
296    
# Line 292  namespace LinuxSampler { namespace gig { Line 328  namespace LinuxSampler { namespace gig {
328    
329          // calculate initial pitch value          // calculate initial pitch value
330          {          {
331              double pitchbasecents = pDimRgn->FineTune * 10;              double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
332              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
333              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));
334              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
335          }          }
336    
337            Volume = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity) / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
338    
339          Volume = pDimRgn->GetVelocityAttenuation(pNoteOnEvent->Velocity) / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)          Volume *= pDimRgn->SampleAttenuation;
   
340    
341          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
342          {          {
# Line 314  namespace LinuxSampler { namespace gig { Line 350  namespace LinuxSampler { namespace gig {
350                      eg1controllervalue = 0; // TODO: aftertouch not yet supported                      eg1controllervalue = 0; // TODO: aftertouch not yet supported
351                      break;                      break;
352                  case ::gig::eg1_ctrl_t::type_velocity:                  case ::gig::eg1_ctrl_t::type_velocity:
353                      eg1controllervalue = pNoteOnEvent->Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
354                      break;                      break;
355                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
356                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];                      eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
357                      break;                      break;
358              }              }
359              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
# Line 336  namespace LinuxSampler { namespace gig { Line 372  namespace LinuxSampler { namespace gig {
372                            pDimRgn->EG1InfiniteSustain,                            pDimRgn->EG1InfiniteSustain,
373                            pDimRgn->EG1Sustain,                            pDimRgn->EG1Sustain,
374                            pDimRgn->EG1Release + eg1release,                            pDimRgn->EG1Release + eg1release,
375                            Delay);                            // the SSE synthesis implementation requires
376                              // the vca start to be 16 byte aligned
377                              SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ?
378                              Delay & 0xfffffffc : Delay);
379          }          }
380    
381    
     #if ENABLE_FILTER  
382          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
383          {          {
384              // get current value of EG2 controller              // get current value of EG2 controller
# Line 353  namespace LinuxSampler { namespace gig { Line 391  namespace LinuxSampler { namespace gig {
391                      eg2controllervalue = 0; // TODO: aftertouch not yet supported                      eg2controllervalue = 0; // TODO: aftertouch not yet supported
392                      break;                      break;
393                  case ::gig::eg2_ctrl_t::type_velocity:                  case ::gig::eg2_ctrl_t::type_velocity:
394                      eg2controllervalue = pNoteOnEvent->Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
395                      break;                      break;
396                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
397                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];                      eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
398                      break;                      break;
399              }              }
400              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
# Line 377  namespace LinuxSampler { namespace gig { Line 415  namespace LinuxSampler { namespace gig {
415                            pDimRgn->EG2Release + eg2release,                            pDimRgn->EG2Release + eg2release,
416                            Delay);                            Delay);
417          }          }
     #endif // ENABLE_FILTER  
418    
419    
420          // setup EG 3 (VCO EG)          // setup EG 3 (VCO EG)
# Line 418  namespace LinuxSampler { namespace gig { Line 455  namespace LinuxSampler { namespace gig {
455              pLFO1->Trigger(pDimRgn->LFO1Frequency,              pLFO1->Trigger(pDimRgn->LFO1Frequency,
456                            lfo1_internal_depth,                            lfo1_internal_depth,
457                            pDimRgn->LFO1ControlDepth,                            pDimRgn->LFO1ControlDepth,
458                            pEngine->ControllerTable[pLFO1->ExtController],                            pEngineChannel->ControllerTable[pLFO1->ExtController],
459                            pDimRgn->LFO1FlipPhase,                            pDimRgn->LFO1FlipPhase,
460                            pEngine->SampleRate,                            pEngine->SampleRate,
461                            Delay);                            Delay);
462          }          }
463    
464      #if ENABLE_FILTER  
465          // setup LFO 2 (VCF Cutoff LFO)          // setup LFO 2 (VCF Cutoff LFO)
466          {          {
467              uint16_t lfo2_internal_depth;              uint16_t lfo2_internal_depth;
# Line 456  namespace LinuxSampler { namespace gig { Line 493  namespace LinuxSampler { namespace gig {
493              pLFO2->Trigger(pDimRgn->LFO2Frequency,              pLFO2->Trigger(pDimRgn->LFO2Frequency,
494                            lfo2_internal_depth,                            lfo2_internal_depth,
495                            pDimRgn->LFO2ControlDepth,                            pDimRgn->LFO2ControlDepth,
496                            pEngine->ControllerTable[pLFO2->ExtController],                            pEngineChannel->ControllerTable[pLFO2->ExtController],
497                            pDimRgn->LFO2FlipPhase,                            pDimRgn->LFO2FlipPhase,
498                            pEngine->SampleRate,                            pEngine->SampleRate,
499                            Delay);                            Delay);
500          }          }
501      #endif // ENABLE_FILTER  
502    
503          // setup LFO 3 (VCO LFO)          // setup LFO 3 (VCO LFO)
504          {          {
# Line 494  namespace LinuxSampler { namespace gig { Line 531  namespace LinuxSampler { namespace gig {
531              pLFO3->Trigger(pDimRgn->LFO3Frequency,              pLFO3->Trigger(pDimRgn->LFO3Frequency,
532                            lfo3_internal_depth,                            lfo3_internal_depth,
533                            pDimRgn->LFO3ControlDepth,                            pDimRgn->LFO3ControlDepth,
534                            pEngine->ControllerTable[pLFO3->ExtController],                            pEngineChannel->ControllerTable[pLFO3->ExtController],
535                            false,                            false,
536                            pEngine->SampleRate,                            pEngine->SampleRate,
537                            Delay);                            Delay);
538          }          }
539    
540      #if ENABLE_FILTER  
541          #if FORCE_FILTER_USAGE          #if FORCE_FILTER_USAGE
542          FilterLeft.Enabled = FilterRight.Enabled = true;          const bool bUseFilter = true;
543          #else // use filter only if instrument file told so          #else // use filter only if instrument file told so
544          FilterLeft.Enabled = FilterRight.Enabled = pDimRgn->VCFEnabled;          const bool bUseFilter = pDimRgn->VCFEnabled;
545          #endif // FORCE_FILTER_USAGE          #endif // FORCE_FILTER_USAGE
546          if (pDimRgn->VCFEnabled) {          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
547            if (bUseFilter) {
548              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL
549              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;
550              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
# Line 576  namespace LinuxSampler { namespace gig { Line 614  namespace LinuxSampler { namespace gig {
614              FilterRight.SetType(OVERRIDE_FILTER_TYPE);              FilterRight.SetType(OVERRIDE_FILTER_TYPE);
615              #endif // OVERRIDE_FILTER_TYPE              #endif // OVERRIDE_FILTER_TYPE
616    
617              VCFCutoffCtrl.value    = pEngine->ControllerTable[VCFCutoffCtrl.controller];              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
618              VCFResonanceCtrl.value = pEngine->ControllerTable[VCFResonanceCtrl.controller];              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
619    
620              // calculate cutoff frequency              // calculate cutoff frequency
621              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = (!VCFCutoffCtrl.controller)
622                  ? exp((float) (127 - pNoteOnEvent->Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX                  ? exp((float) (127 - itNoteOnEvent->Param.Note.Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX
623                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;
624    
625              // calculate resonance              // calculate resonance
626              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0
627              if (pDimRgn->VCFKeyboardTracking) {              if (pDimRgn->VCFKeyboardTracking) {
628                  resonance += (float) (pNoteOnEvent->Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;                  resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
629              }              }
630              Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)              Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)
631    
632              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;
633              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
634    
             FilterLeft.SetParameters(cutoff,  resonance, pEngine->SampleRate);  
             FilterRight.SetParameters(cutoff, resonance, pEngine->SampleRate);  
   
635              FilterUpdateCounter = -1;              FilterUpdateCounter = -1;
636          }          }
637          else {          else {
638              VCFCutoffCtrl.controller    = 0;              VCFCutoffCtrl.controller    = 0;
639              VCFResonanceCtrl.controller = 0;              VCFResonanceCtrl.controller = 0;
640          }          }
     #endif // ENABLE_FILTER  
641    
642          return 0; // success          return 0; // success
643      }      }
# Line 621  namespace LinuxSampler { namespace gig { Line 655  namespace LinuxSampler { namespace gig {
655       */       */
656      void Voice::Render(uint Samples) {      void Voice::Render(uint Samples) {
657    
658            // select default values for synthesis mode bits
659            SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, (PitchBase * PitchBend) != 1.0f);
660            SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, true);
661            SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
662    
663          // Reset the synthesis parameter matrix          // Reset the synthesis parameter matrix
664          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngine->GlobalVolume);  
665            pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume);
666          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
     #if ENABLE_FILTER  
667          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
668          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
     #endif // ENABLE_FILTER  
   
669    
670          // Apply events to the synthesis parameter matrix          // Apply events to the synthesis parameter matrix
671          ProcessEvents(Samples);          ProcessEvents(Samples);
672    
   
673          // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment          // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment
674          pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, pKillEvent);          pEG1->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);
675      #if ENABLE_FILTER          pEG2->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
676          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);          if (pEG3->Process(Samples)) { // if pitch EG is active
677      #endif // ENABLE_FILTER              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
678          pEG3->Process(Samples);              SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
679            }
680          pLFO1->Process(Samples);          pLFO1->Process(Samples);
     #if ENABLE_FILTER  
681          pLFO2->Process(Samples);          pLFO2->Process(Samples);
682      #endif // ENABLE_FILTER          if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active
683          pLFO3->Process(Samples);              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
684                SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
685            }
     #if ENABLE_FILTER  
         CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters  
     #endif // ENABLE_FILTER  
686    
687            if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
688                CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
689    
690          switch (this->PlaybackState) {          switch (this->PlaybackState) {
691    
692              case playback_state_ram: {              case playback_state_ram: {
693                      if (RAMLoop) InterpolateAndLoop(Samples, (sample_t*) pSample->GetCache().pStart, Delay);                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
694                      else         Interpolate(Samples, (sample_t*) pSample->GetCache().pStart, Delay);  
695                        // render current fragment
696                        Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
697    
698                      if (DiskVoice) {                      if (DiskVoice) {
699                          // check if we reached the allowed limit of the sample RAM cache                          // check if we reached the allowed limit of the sample RAM cache
700                          if (Pos > MaxRAMPos) {                          if (Pos > MaxRAMPos) {
# Line 679  namespace LinuxSampler { namespace gig { Line 717  namespace LinuxSampler { namespace gig {
717                              KillImmediately();                              KillImmediately();
718                              return;                              return;
719                          }                          }
720                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (RTMath::DoubleToInt(Pos) - MaxRAMPos));                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
721                          Pos -= RTMath::DoubleToInt(Pos);                          Pos -= int(Pos);
722                            RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
723                      }                      }
724    
725                        const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
726    
727                      // add silence sample at the end if we reached the end of the stream (for the interpolator)                      // add silence sample at the end if we reached the end of the stream (for the interpolator)
728                      if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (pEngine->MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) {                      if (DiskStreamRef.State == Stream::state_end) {
729                          DiskStreamRef.pStream->WriteSilence((pEngine->MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels);                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
730                          this->PlaybackState = playback_state_end;                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
731                                // remember how many sample words there are before any silence has been added
732                                if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
733                                DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
734                            }
735                      }                      }
736    
737                      sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from                      sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
738                      Interpolate(Samples, ptr, Delay);  
739                      DiskStreamRef.pStream->IncrementReadPos(RTMath::DoubleToInt(Pos) * pSample->Channels);                      // render current audio fragment
740                      Pos -= RTMath::DoubleToInt(Pos);                      Synthesize(Samples, ptr, Delay);
741    
742                        const int iPos = (int) Pos;
743                        const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
744                        DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
745                        Pos -= iPos; // just keep fractional part of Pos
746    
747                        // change state of voice to 'end' if we really reached the end of the sample data
748                        if (RealSampleWordsLeftToRead >= 0) {
749                            RealSampleWordsLeftToRead -= readSampleWords;
750                            if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
751                        }
752                  }                  }
753                  break;                  break;
754    
755              case playback_state_end:              case playback_state_end:
756                  KillImmediately(); // free voice                  std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
757                  break;                  break;
758          }          }
759    
   
760          // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)          // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)
761          pEngine->pSynthesisEvents[Event::destination_vca]->clear();          pEngine->pSynthesisEvents[Event::destination_vca]->clear();
     #if ENABLE_FILTER  
762          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();
763          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();
     #endif // ENABLE_FILTER  
764    
765          // Reset delay          // Reset delay
766          Delay = 0;          Delay = 0;
767    
768          pTriggerEvent = NULL;          itTriggerEvent = Pool<Event>::Iterator();
769    
770          // If release stage finished, let the voice be killed          // If sample stream or release stage finished, kill the voice
771          if (pEG1->GetStage() == EGADSR::stage_end) this->PlaybackState = playback_state_end;          if (PlaybackState == playback_state_end || pEG1->GetStage() == EGADSR::stage_end) KillImmediately();
772      }      }
773    
774      /**      /**
# Line 726  namespace LinuxSampler { namespace gig { Line 779  namespace LinuxSampler { namespace gig {
779          pLFO1->Reset();          pLFO1->Reset();
780          pLFO2->Reset();          pLFO2->Reset();
781          pLFO3->Reset();          pLFO3->Reset();
782            FilterLeft.Reset();
783            FilterRight.Reset();
784          DiskStreamRef.pStream = NULL;          DiskStreamRef.pStream = NULL;
785          DiskStreamRef.hStream = 0;          DiskStreamRef.hStream = 0;
786          DiskStreamRef.State   = Stream::state_unused;          DiskStreamRef.State   = Stream::state_unused;
787          DiskStreamRef.OrderID = 0;          DiskStreamRef.OrderID = 0;
788          Active = false;          PlaybackState = playback_state_end;
789            itTriggerEvent = Pool<Event>::Iterator();
790            itKillEvent    = Pool<Event>::Iterator();
791      }      }
792    
793      /**      /**
# Line 743  namespace LinuxSampler { namespace gig { Line 800  namespace LinuxSampler { namespace gig {
800      void Voice::ProcessEvents(uint Samples) {      void Voice::ProcessEvents(uint Samples) {
801    
802          // dispatch control change events          // dispatch control change events
803          Event* pCCEvent = pEngine->pCCEvents->first();          RTList<Event>::Iterator itCCEvent = pEngine->pCCEvents->first();
804          if (Delay) { // skip events that happened before this voice was triggered          if (Delay) { // skip events that happened before this voice was triggered
805              while (pCCEvent && pCCEvent->FragmentPos() <= Delay) pCCEvent = pEngine->pCCEvents->next();              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
806          }          }
807          while (pCCEvent) {          while (itCCEvent) {
808              if (pCCEvent->Controller) { // if valid MIDI controller              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
809                  #if ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
810                  if (pCCEvent->Controller == VCFCutoffCtrl.controller) {                      *pEngine->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
                     pEngine->pSynthesisEvents[Event::destination_vcfc]->alloc_assign(*pCCEvent);  
811                  }                  }
812                  if (pCCEvent->Controller == VCFResonanceCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
813                      pEngine->pSynthesisEvents[Event::destination_vcfr]->alloc_assign(*pCCEvent);                      *pEngine->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
814                  }                  }
815                  #endif // ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
816                  if (pCCEvent->Controller == pLFO1->ExtController) {                      pLFO1->SendEvent(itCCEvent);
                     pLFO1->SendEvent(pCCEvent);  
817                  }                  }
818                  #if ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO2->ExtController) {
819                  if (pCCEvent->Controller == pLFO2->ExtController) {                      pLFO2->SendEvent(itCCEvent);
                     pLFO2->SendEvent(pCCEvent);  
820                  }                  }
821                  #endif // ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO3->ExtController) {
822                  if (pCCEvent->Controller == pLFO3->ExtController) {                      pLFO3->SendEvent(itCCEvent);
                     pLFO3->SendEvent(pCCEvent);  
823                  }                  }
824                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
825                      pCCEvent->Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
826                      pEngine->pSynthesisEvents[Event::destination_vca]->alloc_assign(*pCCEvent);                      *pEngine->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
827                  }                  }
828              }              }
829    
830              pCCEvent = pEngine->pCCEvents->next();              ++itCCEvent;
831          }          }
832    
833    
834          // process pitch events          // process pitch events
835          {          {
836              RTEList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];              RTList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];
837              Event* pVCOEvent = pVCOEventList->first();              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
838              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
839                  while (pVCOEvent && pVCOEvent->FragmentPos() <= Delay) pVCOEvent = pVCOEventList->next();                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
840              }              }
841              // apply old pitchbend value until first pitch event occurs              // apply old pitchbend value until first pitch event occurs
842              if (this->PitchBend != 1.0) {              if (this->PitchBend != 1.0) {
843                  uint end = (pVCOEvent) ? pVCOEvent->FragmentPos() : Samples;                  uint end = (itVCOEvent) ? itVCOEvent->FragmentPos() : Samples;
844                  for (uint i = Delay; i < end; i++) {                  for (uint i = Delay; i < end; i++) {
845                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
846                  }                  }
847              }              }
848              float pitch;              float pitch;
849              while (pVCOEvent) {              while (itVCOEvent) {
850                  Event* pNextVCOEvent = pVCOEventList->next();                  RTList<Event>::Iterator itNextVCOEvent = itVCOEvent;
851                    ++itNextVCOEvent;
852    
853                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
854                  uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples;                  uint end = (itNextVCOEvent) ? itNextVCOEvent->FragmentPos() : Samples;
855    
856                  pitch = RTMath::CentsToFreqRatio(((double) pVCOEvent->Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents                  pitch = RTMath::CentsToFreqRatio(((double) itVCOEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
857    
858                  // apply pitch value to the pitch parameter sequence                  // apply pitch value to the pitch parameter sequence
859                  for (uint i = pVCOEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCOEvent->FragmentPos(); i < end; i++) {
860                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
861                  }                  }
862    
863                  pVCOEvent = pNextVCOEvent;                  itVCOEvent = itNextVCOEvent;
864                }
865                if (!pVCOEventList->isEmpty()) {
866                    this->PitchBend = pitch;
867                    SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
868                    SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
869              }              }
             if (pVCOEventList->last()) this->PitchBend = pitch;  
870          }          }
871    
872          // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)          // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)
873          {          {
874              RTEList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];              RTList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];
875              Event* pVCAEvent = pVCAEventList->first();              RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
876              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
877                  while (pVCAEvent && pVCAEvent->FragmentPos() <= Delay) pVCAEvent = pVCAEventList->next();                  while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
878              }              }
879              float crossfadevolume;              float crossfadevolume;
880              while (pVCAEvent) {              while (itVCAEvent) {
881                  Event* pNextVCAEvent = pVCAEventList->next();                  RTList<Event>::Iterator itNextVCAEvent = itVCAEvent;
882                    ++itNextVCAEvent;
883    
884                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
885                  uint end = (pNextVCAEvent) ? pNextVCAEvent->FragmentPos() : Samples;                  uint end = (itNextVCAEvent) ? itNextVCAEvent->FragmentPos() : Samples;
886    
887                  crossfadevolume = CrossfadeAttenuation(pVCAEvent->Value);                  crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
888    
889                  float effective_volume = crossfadevolume * this->Volume * pEngine->GlobalVolume;                  float effective_volume = crossfadevolume * this->Volume * pEngineChannel->GlobalVolume;
890    
891                  // apply volume value to the volume parameter sequence                  // apply volume value to the volume parameter sequence
892                  for (uint i = pVCAEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
893                      pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;                      pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;
894                  }                  }
895    
896                  pVCAEvent = pNextVCAEvent;                  itVCAEvent = itNextVCAEvent;
897              }              }
898              if (pVCAEventList->last()) this->CrossfadeVolume = crossfadevolume;              if (!pVCAEventList->isEmpty()) this->CrossfadeVolume = crossfadevolume;
899          }          }
900    
     #if ENABLE_FILTER  
901          // process filter cutoff events          // process filter cutoff events
902          {          {
903              RTEList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];              RTList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];
904              Event* pCutoffEvent = pCutoffEventList->first();              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
905              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
906                  while (pCutoffEvent && pCutoffEvent->FragmentPos() <= Delay) pCutoffEvent = pCutoffEventList->next();                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
907              }              }
908              float cutoff;              float cutoff;
909              while (pCutoffEvent) {              while (itCutoffEvent) {
910                  Event* pNextCutoffEvent = pCutoffEventList->next();                  RTList<Event>::Iterator itNextCutoffEvent = itCutoffEvent;
911                    ++itNextCutoffEvent;
912    
913                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
914                  uint end = (pNextCutoffEvent) ? pNextCutoffEvent->FragmentPos() : Samples;                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
915    
916                  cutoff = exp((float) pCutoffEvent->Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;                  cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;
917    
918                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
919                  for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) {                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
920                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
921                  }                  }
922    
923                  pCutoffEvent = pNextCutoffEvent;                  itCutoffEvent = itNextCutoffEvent;
924              }              }
925              if (pCutoffEventList->last()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time              if (!pCutoffEventList->isEmpty()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time
926          }          }
927    
928          // process filter resonance events          // process filter resonance events
929          {          {
930              RTEList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];              RTList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];
931              Event* pResonanceEvent = pResonanceEventList->first();              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
932              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
933                  while (pResonanceEvent && pResonanceEvent->FragmentPos() <= Delay) pResonanceEvent = pResonanceEventList->next();                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
934              }              }
935              while (pResonanceEvent) {              while (itResonanceEvent) {
936                  Event* pNextResonanceEvent = pResonanceEventList->next();                  RTList<Event>::Iterator itNextResonanceEvent = itResonanceEvent;
937                    ++itNextResonanceEvent;
938    
939                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
940                  uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples;                  uint end = (itNextResonanceEvent) ? itNextResonanceEvent->FragmentPos() : Samples;
941    
942                  // convert absolute controller value to differential                  // convert absolute controller value to differential
943                  int ctrldelta = pResonanceEvent->Value - VCFResonanceCtrl.value;                  int ctrldelta = itResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;
944                  VCFResonanceCtrl.value = pResonanceEvent->Value;                  VCFResonanceCtrl.value = itResonanceEvent->Param.CC.Value;
945    
946                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
947    
948                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
949                  for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) {                  for (uint i = itResonanceEvent->FragmentPos(); i < end; i++) {
950                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
951                  }                  }
952    
953                  pResonanceEvent = pNextResonanceEvent;                  itResonanceEvent = itNextResonanceEvent;
954              }              }
955              if (pResonanceEventList->last()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Value * 0.00787f; // needed for initialization of parameter matrix next time              if (!pResonanceEventList->isEmpty()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Param.CC.Value * 0.00787f; // needed for initialization of parameter matrix next time
956          }          }
     #endif // ENABLE_FILTER  
957      }      }
958    
     #if ENABLE_FILTER  
959      /**      /**
960       * Calculate all necessary, final biquad filter parameters.       * Calculate all necessary, final biquad filter parameters.
961       *       *
962       * @param Samples - number of samples to be rendered in this audio fragment cycle       * @param Samples - number of samples to be rendered in this audio fragment cycle
963       */       */
964      void Voice::CalculateBiquadParameters(uint Samples) {      void Voice::CalculateBiquadParameters(uint Samples) {
         if (!FilterLeft.Enabled) return;  
   
965          biquad_param_t bqbase;          biquad_param_t bqbase;
966          biquad_param_t bqmain;          biquad_param_t bqmain;
967          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
968          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
969          FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);          FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
970            FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
971          pEngine->pBasicFilterParameters[0] = bqbase;          pEngine->pBasicFilterParameters[0] = bqbase;
972          pEngine->pMainFilterParameters[0]  = bqmain;          pEngine->pMainFilterParameters[0]  = bqmain;
973    
974          float* bq;          float* bq;
975          for (int i = 1; i < Samples; i++) {          for (int i = 1; i < Samples; i++) {
976              // recalculate biquad parameters if cutoff or resonance differ from previous sample point              // recalculate biquad parameters if cutoff or resonance differ from previous sample point
977              if (!(i & FILTER_UPDATE_MASK)) if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||              if (!(i & FILTER_UPDATE_MASK)) {
978                                                 pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff) {                  if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
979                  prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff)
980                  prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];                  {
981                  FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
982                        prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
983                        FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
984                        FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
985                    }
986              }              }
987    
988              //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'              //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
989              bq    = (float*) &pEngine->pBasicFilterParameters[i];              bq    = (float*) &pEngine->pBasicFilterParameters[i];
990              bq[0] = bqbase.a1;              bq[0] = bqbase.b0;
991              bq[1] = bqbase.a2;              bq[1] = bqbase.b1;
992              bq[2] = bqbase.b0;              bq[2] = bqbase.b2;
993              bq[3] = bqbase.b1;              bq[3] = bqbase.a1;
994              bq[4] = bqbase.b2;              bq[4] = bqbase.a2;
995    
996              // same as 'pEngine->pMainFilterParameters[i] = bqmain;'              // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
997              bq    = (float*) &pEngine->pMainFilterParameters[i];              bq    = (float*) &pEngine->pMainFilterParameters[i];
998              bq[0] = bqmain.a1;              bq[0] = bqmain.b0;
999              bq[1] = bqmain.a2;              bq[1] = bqmain.b1;
1000              bq[2] = bqmain.b0;              bq[2] = bqmain.b2;
1001              bq[3] = bqmain.b1;              bq[3] = bqmain.a1;
1002              bq[4] = bqmain.b2;              bq[4] = bqmain.a2;
1003          }          }
1004      }      }
     #endif // ENABLE_FILTER  
1005    
1006      /**      /**
1007       *  Interpolates the input audio data (no loop).       *  Synthesizes the current audio fragment for this voice.
1008       *       *
1009       *  @param Samples - number of sample points to be rendered in this audio       *  @param Samples - number of sample points to be rendered in this audio
1010       *                   fragment cycle       *                   fragment cycle
1011       *  @param pSrc    - pointer to input sample data       *  @param pSrc    - pointer to input sample data
1012       *  @param Skip    - number of sample points to skip in output buffer       *  @param Skip    - number of sample points to skip in output buffer
1013       */       */
1014      void Voice::Interpolate(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
1015          int i = Skip;          RunSynthesisFunction(SynthesisMode, *this, Samples, pSrc, Skip);
   
         // FIXME: assuming either mono or stereo  
         if (this->pSample->Channels == 2) { // Stereo Sample  
             while (i < Samples) {  
                 InterpolateOneStep_Stereo(pSrc, i,  
                                           pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                           pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                           pEngine->pBasicFilterParameters[i],  
                                           pEngine->pMainFilterParameters[i]);  
             }  
         }  
         else { // Mono Sample  
             while (i < Samples) {  
                 InterpolateOneStep_Mono(pSrc, i,  
                                         pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                         pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                         pEngine->pBasicFilterParameters[i],  
                                         pEngine->pMainFilterParameters[i]);  
             }  
         }  
     }  
   
     /**  
      *  Interpolates the input audio data, this method honors looping.  
      *  
      *  @param Samples - number of sample points to be rendered in this audio  
      *                   fragment cycle  
      *  @param pSrc    - pointer to input sample data  
      *  @param Skip    - number of sample points to skip in output buffer  
      */  
     void Voice::InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip) {  
         int i = Skip;  
   
         // FIXME: assuming either mono or stereo  
         if (pSample->Channels == 2) { // Stereo Sample  
             if (pSample->LoopPlayCount) {  
                 // render loop (loop count limited)  
                 while (i < Samples && LoopCyclesLeft) {  
                     InterpolateOneStep_Stereo(pSrc, i,  
                                               pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                               pEngine->pBasicFilterParameters[i],  
                                               pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;  
                         LoopCyclesLeft--;  
                     }  
                 }  
                 // render on without loop  
                 while (i < Samples) {  
                     InterpolateOneStep_Stereo(pSrc, i,  
                                               pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                               pEngine->pBasicFilterParameters[i],  
                                               pEngine->pMainFilterParameters[i]);  
                 }  
             }  
             else { // render loop (endless loop)  
                 while (i < Samples) {  
                     InterpolateOneStep_Stereo(pSrc, i,  
                                               pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                               pEngine->pBasicFilterParameters[i],  
                                               pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);  
                     }  
                 }  
             }  
         }  
         else { // Mono Sample  
             if (pSample->LoopPlayCount) {  
                 // render loop (loop count limited)  
                 while (i < Samples && LoopCyclesLeft) {  
                     InterpolateOneStep_Mono(pSrc, i,  
                                             pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                             pEngine->pBasicFilterParameters[i],  
                                             pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;  
                         LoopCyclesLeft--;  
                     }  
                 }  
                 // render on without loop  
                 while (i < Samples) {  
                     InterpolateOneStep_Mono(pSrc, i,  
                                             pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                             pEngine->pBasicFilterParameters[i],  
                                             pEngine->pMainFilterParameters[i]);  
                 }  
             }  
             else { // render loop (endless loop)  
                 while (i < Samples) {  
                     InterpolateOneStep_Mono(pSrc, i,  
                                             pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                             pEngine->pBasicFilterParameters[i],  
                                             pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;  
                     }  
                 }  
             }  
         }  
1016      }      }
1017    
1018      /**      /**
# Line 1083  namespace LinuxSampler { namespace gig { Line 1037  namespace LinuxSampler { namespace gig {
1037       *  of a voice, a kill process cannot be cancalled and is therefore       *  of a voice, a kill process cannot be cancalled and is therefore
1038       *  usually used for voice stealing and key group conflicts.       *  usually used for voice stealing and key group conflicts.
1039       *       *
1040       *  @param pKillEvent - event which caused the voice to be killed       *  @param itKillEvent - event which caused the voice to be killed
1041       */       */
1042      void Voice::Kill(Event* pKillEvent) {      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1043          this->pKillEvent = pKillEvent;          //FIXME: just two sanity checks for debugging, can be removed
1044            if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
1045            if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
1046    
1047            if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1048            this->itKillEvent = itKillEvent;
1049      }      }
1050    
1051  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

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

  ViewVC Help
Powered by ViewVC