/[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 332 by senkov, Sat Jan 1 03:06:06 2005 UTC revision 687 by schoenebeck, Tue Jul 12 22:37:21 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 34  namespace LinuxSampler { namespace gig { Line 35  namespace LinuxSampler { namespace gig {
35      const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());      const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());
36    
37      float Voice::CalculateFilterCutoffCoeff() {      float Voice::CalculateFilterCutoffCoeff() {
38          return log(FILTER_CUTOFF_MIN / FILTER_CUTOFF_MAX);          return log(CONFIG_FILTER_CUTOFF_MIN / CONFIG_FILTER_CUTOFF_MAX);
39      }      }
40    
41      int Voice::CalculateFilterUpdateMask() {      int Voice::CalculateFilterUpdateMask() {
42          if (FILTER_UPDATE_PERIOD <= 0) return 0;          if (CONFIG_FILTER_UPDATE_STEPS <= 0) return 0;
43          int power_of_two;          int power_of_two;
44          for (power_of_two = 0; 1<<power_of_two < FILTER_UPDATE_PERIOD; power_of_two++);          for (power_of_two = 0; 1<<power_of_two < CONFIG_FILTER_UPDATE_STEPS; power_of_two++);
45          return (1 << power_of_two) - 1;          return (1 << power_of_two) - 1;
46      }      }
47    
# 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          SynthesisMode = 0; // set all mode bits to 0 first
   
63          // select synthesis implementation (currently either pure C++ or MMX+SSE(1))          // select synthesis implementation (currently either pure C++ or MMX+SSE(1))
64            #if CONFIG_ASM && ARCH_X86
65          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());          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);          SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true);
70    
71            FilterLeft.Reset();
72            FilterRight.Reset();
73      }      }
74    
75      Voice::~Voice() {      Voice::~Voice() {
# Line 110  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 itNoteOnEvent       - 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 pDimRgn        - points to the dimension region which provides sample wave(s) and articulation data
124       *  @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)       *  @param VoiceType      - type of this voice
125       *  @param VoiceStealing       - wether the voice is allowed to steal voices for further subvoices       *  @param iKeyGroup      - a value > 0 defines a key group in which this voice is member of
126       *  @returns 0 on success, a value < 0 if something failed       *  @returns 0 on success, a value < 0 if the voice wasn't triggered
127         *           (either due to an error or e.g. because no region is
128         *           defined for the given key)
129       */       */
130      int Voice::Trigger(Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) {      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) {
131          if (!pInstrument) {          this->pEngineChannel = pEngineChannel;
132             dmsg(1,("voice::trigger: !pInstrument\n"));          this->pDimRgn        = pDimRgn;
133             exit(EXIT_FAILURE);  
134          }          #if CONFIG_DEVMODE
135          if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // FIXME: should be removed before the final release (purpose: just a sanity check for debugging)          if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
136              dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));              dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
137          }          }
138            #endif // CONFIG_DEVMODE
139    
140          Type            = type_normal;          Type            = VoiceType;
141          MIDIKey         = itNoteOnEvent->Param.Note.Key;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
142          pRegion         = pInstrument->GetRegion(MIDIKey);          PlaybackState   = playback_state_init; // mark voice as triggered, but no audio rendered yet
         PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed  
143          Delay           = itNoteOnEvent->FragmentPos();          Delay           = itNoteOnEvent->FragmentPos();
144          itTriggerEvent  = itNoteOnEvent;          itTriggerEvent  = itNoteOnEvent;
145          itKillEvent     = Pool<Event>::Iterator();          itKillEvent     = Pool<Event>::Iterator();
146          itChildVoice    = Pool<Voice>::Iterator();          KeyGroup        = iKeyGroup;
147            pSample         = pDimRgn->pSample; // sample won't change until the voice is finished
148    
149          if (!pRegion) {          // calculate volume
150              std::cerr << "gig::Voice: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
             KillImmediately();  
             return -1;  
         }  
151    
152          KeyGroup = pRegion->KeyGroup;          Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
153    
154          // get current dimension values to select the right dimension region          Volume *= pDimRgn->SampleAttenuation;
155          //FIXME: controller values for selecting the dimension region here are currently not sample accurate  
156          uint DimValues[5] = {0,0,0,0,0};          // the volume of release triggered samples depends on note length
157          for (int i = pRegion->Dimensions - 1; i >= 0; i--) {          if (Type == type_release_trigger) {
158              switch (pRegion->pDimensionDefinitions[i].dimension) {              float noteLength = float(pEngine->FrameTime + Delay -
159                  case ::gig::dimension_samplechannel:                                       pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
160                      DimValues[i] = 0; //TODO: we currently ignore this dimension              float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
161                      break;              if (attenuation <= 0) return -1;
162                  case ::gig::dimension_layer:              Volume *= attenuation;
                     DimValues[i] = iLayer;  
                     // if this is the 1st layer then spawn further voices for all the other layers  
                     if (iLayer == 0)  
                         for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++)  
                             itChildVoice = pEngine->LaunchVoice(itNoteOnEvent, iNewLayer, ReleaseTriggerVoice, VoiceStealing);  
                     break;  
                 case ::gig::dimension_velocity:  
                     DimValues[i] = itNoteOnEvent->Param.Note.Velocity;  
                     break;  
                 case ::gig::dimension_channelaftertouch:  
                     DimValues[i] = 0; //TODO: we currently ignore this dimension  
                     break;  
                 case ::gig::dimension_releasetrigger:  
                     Type = (ReleaseTriggerVoice) ? type_release_trigger : (!iLayer) ? type_release_trigger_required : type_normal;  
                     DimValues[i] = (uint) ReleaseTriggerVoice;  
                     break;  
                 case ::gig::dimension_keyboard:  
                     DimValues[i] = (uint) itNoteOnEvent->Param.Note.Key;  
                     break;  
                 case ::gig::dimension_modwheel:  
                     DimValues[i] = pEngine->ControllerTable[1];  
                     break;  
                 case ::gig::dimension_breath:  
                     DimValues[i] = pEngine->ControllerTable[2];  
                     break;  
                 case ::gig::dimension_foot:  
                     DimValues[i] = pEngine->ControllerTable[4];  
                     break;  
                 case ::gig::dimension_portamentotime:  
                     DimValues[i] = pEngine->ControllerTable[5];  
                     break;  
                 case ::gig::dimension_effect1:  
                     DimValues[i] = pEngine->ControllerTable[12];  
                     break;  
                 case ::gig::dimension_effect2:  
                     DimValues[i] = pEngine->ControllerTable[13];  
                     break;  
                 case ::gig::dimension_genpurpose1:  
                     DimValues[i] = pEngine->ControllerTable[16];  
                     break;  
                 case ::gig::dimension_genpurpose2:  
                     DimValues[i] = pEngine->ControllerTable[17];  
                     break;  
                 case ::gig::dimension_genpurpose3:  
                     DimValues[i] = pEngine->ControllerTable[18];  
                     break;  
                 case ::gig::dimension_genpurpose4:  
                     DimValues[i] = pEngine->ControllerTable[19];  
                     break;  
                 case ::gig::dimension_sustainpedal:  
                     DimValues[i] = pEngine->ControllerTable[64];  
                     break;  
                 case ::gig::dimension_portamento:  
                     DimValues[i] = pEngine->ControllerTable[65];  
                     break;  
                 case ::gig::dimension_sostenutopedal:  
                     DimValues[i] = pEngine->ControllerTable[66];  
                     break;  
                 case ::gig::dimension_softpedal:  
                     DimValues[i] = pEngine->ControllerTable[67];  
                     break;  
                 case ::gig::dimension_genpurpose5:  
                     DimValues[i] = pEngine->ControllerTable[80];  
                     break;  
                 case ::gig::dimension_genpurpose6:  
                     DimValues[i] = pEngine->ControllerTable[81];  
                     break;  
                 case ::gig::dimension_genpurpose7:  
                     DimValues[i] = pEngine->ControllerTable[82];  
                     break;  
                 case ::gig::dimension_genpurpose8:  
                     DimValues[i] = pEngine->ControllerTable[83];  
                     break;  
                 case ::gig::dimension_effect1depth:  
                     DimValues[i] = pEngine->ControllerTable[91];  
                     break;  
                 case ::gig::dimension_effect2depth:  
                     DimValues[i] = pEngine->ControllerTable[92];  
                     break;  
                 case ::gig::dimension_effect3depth:  
                     DimValues[i] = pEngine->ControllerTable[93];  
                     break;  
                 case ::gig::dimension_effect4depth:  
                     DimValues[i] = pEngine->ControllerTable[94];  
                     break;  
                 case ::gig::dimension_effect5depth:  
                     DimValues[i] = pEngine->ControllerTable[95];  
                     break;  
                 case ::gig::dimension_none:  
                     std::cerr << "gig::Voice::Trigger() Error: dimension=none\n" << std::flush;  
                     break;  
                 default:  
                     std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;  
             }  
163          }          }
         pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);  
   
         pSample = pDimRgn->pSample; // sample won't change until the voice is finished  
164    
165          // select channel mode (mono or stereo)          // select channel mode (mono or stereo)
166          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
# Line 264  namespace LinuxSampler { namespace gig { Line 174  namespace LinuxSampler { namespace gig {
174                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
175                  break;                  break;
176              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
177                  CrossfadeVolume = CrossfadeAttenuation(pEngine->ControllerTable[pDimRgn->AttenuationController.controller_number]);                  CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);
178                  break;                  break;
179              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
180              default:              default:
# Line 281  namespace LinuxSampler { namespace gig { Line 191  namespace LinuxSampler { namespace gig {
191          DiskVoice          = cachedsamples < pSample->SamplesTotal;          DiskVoice          = cachedsamples < pSample->SamplesTotal;
192    
193          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
194              MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)              MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)
195    
196              // check if there's a loop defined which completely fits into the cached (RAM) part of the sample              // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
197              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
# Line 310  namespace LinuxSampler { namespace gig { Line 220  namespace LinuxSampler { namespace gig {
220    
221          // calculate initial pitch value          // calculate initial pitch value
222          {          {
223              double pitchbasecents = pDimRgn->FineTune * 10 + (int) pEngine->ScaleTuning[MIDIKey % 12];              double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
224              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
225              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));
226              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
227          }          }
228    
229          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)          // the length of the decay and release curves are dependent on the velocity
230            const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
231    
232          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
233          {          {
# Line 333  namespace LinuxSampler { namespace gig { Line 244  namespace LinuxSampler { namespace gig {
244                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
245                      break;                      break;
246                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
247                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];                      eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
248                      break;                      break;
249              }              }
250              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
# Line 347  namespace LinuxSampler { namespace gig { Line 258  namespace LinuxSampler { namespace gig {
258                            pDimRgn->EG1Attack + eg1attack,                            pDimRgn->EG1Attack + eg1attack,
259                            pDimRgn->EG1Hold,                            pDimRgn->EG1Hold,
260                            pSample->LoopStart,                            pSample->LoopStart,
261                            pDimRgn->EG1Decay1 + eg1decay,                            (pDimRgn->EG1Decay1 + eg1decay) * velrelease,
262                            pDimRgn->EG1Decay2 + eg1decay,                            (pDimRgn->EG1Decay2 + eg1decay) * velrelease,
263                            pDimRgn->EG1InfiniteSustain,                            pDimRgn->EG1InfiniteSustain,
264                            pDimRgn->EG1Sustain,                            pDimRgn->EG1Sustain,
265                            pDimRgn->EG1Release + eg1release,                            (pDimRgn->EG1Release + eg1release) * velrelease,
266                            Delay);                            // the SSE synthesis implementation requires
267                              // the vca start to be 16 byte aligned
268                              SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ?
269                              Delay & 0xfffffffc : Delay,
270                              velocityAttenuation);
271          }          }
272    
273    
# Line 371  namespace LinuxSampler { namespace gig { Line 286  namespace LinuxSampler { namespace gig {
286                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
287                      break;                      break;
288                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
289                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];                      eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
290                      break;                      break;
291              }              }
292              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
# Line 385  namespace LinuxSampler { namespace gig { Line 300  namespace LinuxSampler { namespace gig {
300                            pDimRgn->EG2Attack + eg2attack,                            pDimRgn->EG2Attack + eg2attack,
301                            false,                            false,
302                            pSample->LoopStart,                            pSample->LoopStart,
303                            pDimRgn->EG2Decay1 + eg2decay,                            (pDimRgn->EG2Decay1 + eg2decay) * velrelease,
304                            pDimRgn->EG2Decay2 + eg2decay,                            (pDimRgn->EG2Decay2 + eg2decay) * velrelease,
305                            pDimRgn->EG2InfiniteSustain,                            pDimRgn->EG2InfiniteSustain,
306                            pDimRgn->EG2Sustain,                            pDimRgn->EG2Sustain,
307                            pDimRgn->EG2Release + eg2release,                            (pDimRgn->EG2Release + eg2release) * velrelease,
308                            Delay);                            Delay,
309                              velocityAttenuation);
310          }          }
311    
312    
# Line 408  namespace LinuxSampler { namespace gig { Line 324  namespace LinuxSampler { namespace gig {
324                  case ::gig::lfo1_ctrl_internal:                  case ::gig::lfo1_ctrl_internal:
325                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;
326                      pLFO1->ExtController = 0; // no external controller                      pLFO1->ExtController = 0; // no external controller
327                        bLFO1Enabled         = (lfo1_internal_depth > 0);
328                      break;                      break;
329                  case ::gig::lfo1_ctrl_modwheel:                  case ::gig::lfo1_ctrl_modwheel:
330                      lfo1_internal_depth  = 0;                      lfo1_internal_depth  = 0;
331                      pLFO1->ExtController = 1; // MIDI controller 1                      pLFO1->ExtController = 1; // MIDI controller 1
332                        bLFO1Enabled         = (pDimRgn->LFO1ControlDepth > 0);
333                      break;                      break;
334                  case ::gig::lfo1_ctrl_breath:                  case ::gig::lfo1_ctrl_breath:
335                      lfo1_internal_depth  = 0;                      lfo1_internal_depth  = 0;
336                      pLFO1->ExtController = 2; // MIDI controller 2                      pLFO1->ExtController = 2; // MIDI controller 2
337                        bLFO1Enabled         = (pDimRgn->LFO1ControlDepth > 0);
338                      break;                      break;
339                  case ::gig::lfo1_ctrl_internal_modwheel:                  case ::gig::lfo1_ctrl_internal_modwheel:
340                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;
341                      pLFO1->ExtController = 1; // MIDI controller 1                      pLFO1->ExtController = 1; // MIDI controller 1
342                        bLFO1Enabled         = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0);
343                      break;                      break;
344                  case ::gig::lfo1_ctrl_internal_breath:                  case ::gig::lfo1_ctrl_internal_breath:
345                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;
346                      pLFO1->ExtController = 2; // MIDI controller 2                      pLFO1->ExtController = 2; // MIDI controller 2
347                        bLFO1Enabled         = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0);
348                      break;                      break;
349                  default:                  default:
350                      lfo1_internal_depth  = 0;                      lfo1_internal_depth  = 0;
351                      pLFO1->ExtController = 0; // no external controller                      pLFO1->ExtController = 0; // no external controller
352                        bLFO1Enabled         = false;
353              }              }
354              pLFO1->Trigger(pDimRgn->LFO1Frequency,              if (bLFO1Enabled) pLFO1->Trigger(pDimRgn->LFO1Frequency,
355                            lfo1_internal_depth,                                               lfo1_internal_depth,
356                            pDimRgn->LFO1ControlDepth,                                               pDimRgn->LFO1ControlDepth,
357                            pEngine->ControllerTable[pLFO1->ExtController],                                               pEngineChannel->ControllerTable[pLFO1->ExtController],
358                            pDimRgn->LFO1FlipPhase,                                               pDimRgn->LFO1FlipPhase,
359                            pEngine->SampleRate,                                               pEngine->SampleRate,
360                            Delay);                                               Delay);
361          }          }
362    
363    
# Line 446  namespace LinuxSampler { namespace gig { Line 368  namespace LinuxSampler { namespace gig {
368                  case ::gig::lfo2_ctrl_internal:                  case ::gig::lfo2_ctrl_internal:
369                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;
370                      pLFO2->ExtController = 0; // no external controller                      pLFO2->ExtController = 0; // no external controller
371                        bLFO2Enabled         = (lfo2_internal_depth > 0);
372                      break;                      break;
373                  case ::gig::lfo2_ctrl_modwheel:                  case ::gig::lfo2_ctrl_modwheel:
374                      lfo2_internal_depth  = 0;                      lfo2_internal_depth  = 0;
375                      pLFO2->ExtController = 1; // MIDI controller 1                      pLFO2->ExtController = 1; // MIDI controller 1
376                        bLFO2Enabled         = (pDimRgn->LFO2ControlDepth > 0);
377                      break;                      break;
378                  case ::gig::lfo2_ctrl_foot:                  case ::gig::lfo2_ctrl_foot:
379                      lfo2_internal_depth  = 0;                      lfo2_internal_depth  = 0;
380                      pLFO2->ExtController = 4; // MIDI controller 4                      pLFO2->ExtController = 4; // MIDI controller 4
381                        bLFO2Enabled         = (pDimRgn->LFO2ControlDepth > 0);
382                      break;                      break;
383                  case ::gig::lfo2_ctrl_internal_modwheel:                  case ::gig::lfo2_ctrl_internal_modwheel:
384                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;
385                      pLFO2->ExtController = 1; // MIDI controller 1                      pLFO2->ExtController = 1; // MIDI controller 1
386                        bLFO2Enabled         = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
387                      break;                      break;
388                  case ::gig::lfo2_ctrl_internal_foot:                  case ::gig::lfo2_ctrl_internal_foot:
389                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;
390                      pLFO2->ExtController = 4; // MIDI controller 4                      pLFO2->ExtController = 4; // MIDI controller 4
391                        bLFO2Enabled         = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
392                      break;                      break;
393                  default:                  default:
394                      lfo2_internal_depth  = 0;                      lfo2_internal_depth  = 0;
395                      pLFO2->ExtController = 0; // no external controller                      pLFO2->ExtController = 0; // no external controller
396                        bLFO2Enabled         = false;
397              }              }
398              pLFO2->Trigger(pDimRgn->LFO2Frequency,              if (bLFO2Enabled) pLFO2->Trigger(pDimRgn->LFO2Frequency,
399                            lfo2_internal_depth,                                               lfo2_internal_depth,
400                            pDimRgn->LFO2ControlDepth,                                               pDimRgn->LFO2ControlDepth,
401                            pEngine->ControllerTable[pLFO2->ExtController],                                               pEngineChannel->ControllerTable[pLFO2->ExtController],
402                            pDimRgn->LFO2FlipPhase,                                               pDimRgn->LFO2FlipPhase,
403                            pEngine->SampleRate,                                               pEngine->SampleRate,
404                            Delay);                                               Delay);
405          }          }
406    
407    
# Line 484  namespace LinuxSampler { namespace gig { Line 412  namespace LinuxSampler { namespace gig {
412                  case ::gig::lfo3_ctrl_internal:                  case ::gig::lfo3_ctrl_internal:
413                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
414                      pLFO3->ExtController = 0; // no external controller                      pLFO3->ExtController = 0; // no external controller
415                        bLFO3Enabled         = (lfo3_internal_depth > 0);
416                      break;                      break;
417                  case ::gig::lfo3_ctrl_modwheel:                  case ::gig::lfo3_ctrl_modwheel:
418                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
419                      pLFO3->ExtController = 1; // MIDI controller 1                      pLFO3->ExtController = 1; // MIDI controller 1
420                        bLFO3Enabled         = (pDimRgn->LFO3ControlDepth > 0);
421                      break;                      break;
422                  case ::gig::lfo3_ctrl_aftertouch:                  case ::gig::lfo3_ctrl_aftertouch:
423                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
424                      pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet                      pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet
425                        bLFO3Enabled         = false; // see TODO comment in line above
426                      break;                      break;
427                  case ::gig::lfo3_ctrl_internal_modwheel:                  case ::gig::lfo3_ctrl_internal_modwheel:
428                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
429                      pLFO3->ExtController = 1; // MIDI controller 1                      pLFO3->ExtController = 1; // MIDI controller 1
430                        bLFO3Enabled         = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0);
431                      break;                      break;
432                  case ::gig::lfo3_ctrl_internal_aftertouch:                  case ::gig::lfo3_ctrl_internal_aftertouch:
433                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
434                      pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet                      pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet
435                        bLFO3Enabled         = (lfo3_internal_depth > 0 /*|| pDimRgn->LFO3ControlDepth > 0*/); // see TODO comment in line above
436                      break;                      break;
437                  default:                  default:
438                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
439                      pLFO3->ExtController = 0; // no external controller                      pLFO3->ExtController = 0; // no external controller
440                        bLFO3Enabled         = false;
441              }              }
442              pLFO3->Trigger(pDimRgn->LFO3Frequency,              if (bLFO3Enabled) pLFO3->Trigger(pDimRgn->LFO3Frequency,
443                            lfo3_internal_depth,                                               lfo3_internal_depth,
444                            pDimRgn->LFO3ControlDepth,                                               pDimRgn->LFO3ControlDepth,
445                            pEngine->ControllerTable[pLFO3->ExtController],                                               pEngineChannel->ControllerTable[pLFO3->ExtController],
446                            false,                                               false,
447                            pEngine->SampleRate,                                               pEngine->SampleRate,
448                            Delay);                                               Delay);
449          }          }
450    
451    
452          #if FORCE_FILTER_USAGE          #if CONFIG_FORCE_FILTER
453          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, true);          const bool bUseFilter = true;
454          #else // use filter only if instrument file told so          #else // use filter only if instrument file told so
455          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, pDimRgn->VCFEnabled);          const bool bUseFilter = pDimRgn->VCFEnabled;
456          #endif // FORCE_FILTER_USAGE          #endif // CONFIG_FORCE_FILTER
457          if (pDimRgn->VCFEnabled) {          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
458              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL          if (bUseFilter) {
459              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;              #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
460                VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
461              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
462              switch (pDimRgn->VCFCutoffController) {              switch (pDimRgn->VCFCutoffController) {
463                  case ::gig::vcf_cutoff_ctrl_modwheel:                  case ::gig::vcf_cutoff_ctrl_modwheel:
# Line 558  namespace LinuxSampler { namespace gig { Line 493  namespace LinuxSampler { namespace gig {
493                      VCFCutoffCtrl.controller = 0;                      VCFCutoffCtrl.controller = 0;
494                      break;                      break;
495              }              }
496              #endif // OVERRIDE_FILTER_CUTOFF_CTRL              #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
497    
498              #ifdef OVERRIDE_FILTER_RES_CTRL              #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
499              VCFResonanceCtrl.controller = OVERRIDE_FILTER_RES_CTRL;              VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
500              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
501              switch (pDimRgn->VCFResonanceController) {              switch (pDimRgn->VCFResonanceController) {
502                  case ::gig::vcf_res_ctrl_genpurpose3:                  case ::gig::vcf_res_ctrl_genpurpose3:
# Line 580  namespace LinuxSampler { namespace gig { Line 515  namespace LinuxSampler { namespace gig {
515                  default:                  default:
516                      VCFResonanceCtrl.controller = 0;                      VCFResonanceCtrl.controller = 0;
517              }              }
518              #endif // OVERRIDE_FILTER_RES_CTRL              #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
519    
520              #ifndef OVERRIDE_FILTER_TYPE              #ifndef CONFIG_OVERRIDE_FILTER_TYPE
521              FilterLeft.SetType(pDimRgn->VCFType);              FilterLeft.SetType(pDimRgn->VCFType);
522              FilterRight.SetType(pDimRgn->VCFType);              FilterRight.SetType(pDimRgn->VCFType);
523              #else // override filter type              #else // override filter type
524              FilterLeft.SetType(OVERRIDE_FILTER_TYPE);              FilterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
525              FilterRight.SetType(OVERRIDE_FILTER_TYPE);              FilterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
526              #endif // OVERRIDE_FILTER_TYPE              #endif // CONFIG_OVERRIDE_FILTER_TYPE
527    
528              VCFCutoffCtrl.value    = pEngine->ControllerTable[VCFCutoffCtrl.controller];              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
529              VCFResonanceCtrl.value = pEngine->ControllerTable[VCFResonanceCtrl.controller];              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
530    
531              // calculate cutoff frequency              // calculate cutoff frequency
532              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = (!VCFCutoffCtrl.controller)
533                  ? exp((float) (127 - itNoteOnEvent->Param.Note.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) * CONFIG_FILTER_CUTOFF_MAX
534                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX;
535    
536              // calculate resonance              // calculate resonance
537              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0
# Line 605  namespace LinuxSampler { namespace gig { Line 540  namespace LinuxSampler { namespace gig {
540              }              }
541              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)
542    
543              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;              VCFCutoffCtrl.fvalue    = cutoff - CONFIG_FILTER_CUTOFF_MIN;
544              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
545    
546              FilterUpdateCounter = -1;              FilterUpdateCounter = -1;
# Line 638  namespace LinuxSampler { namespace gig { Line 573  namespace LinuxSampler { namespace gig {
573    
574          // Reset the synthesis parameter matrix          // Reset the synthesis parameter matrix
575    
576          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngine->GlobalVolume);          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume);
577          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
578          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
579          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
# Line 647  namespace LinuxSampler { namespace gig { Line 582  namespace LinuxSampler { namespace gig {
582          ProcessEvents(Samples);          ProcessEvents(Samples);
583    
584          // 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
585          pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);          pEG1->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);
586          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);          pEG2->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
587          if (pEG3->Process(Samples)) { // if pitch EG is active          if (pEG3->Process(Samples)) { // if pitch EG is active
588              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
589              SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);              SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
590          }          }
591          pLFO1->Process(Samples);          if (bLFO1Enabled) pLFO1->Process(Samples);
592          pLFO2->Process(Samples);          if (bLFO2Enabled) pLFO2->Process(Samples);
593          if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active          if (bLFO3Enabled) {
594              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);              if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active
595              SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);                  SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
596                    SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
597                }
598          }          }
599    
600          if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))          if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
601                  CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters              CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
602    
603          switch (this->PlaybackState) {          switch (this->PlaybackState) {
604    
605                case playback_state_init:
606                    this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
607                    // no break - continue with playback_state_ram
608    
609              case playback_state_ram: {              case playback_state_ram: {
610                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
611    
# Line 702  namespace LinuxSampler { namespace gig { Line 643  namespace LinuxSampler { namespace gig {
643    
644                      // 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)
645                      if (DiskStreamRef.State == Stream::state_end) {                      if (DiskStreamRef.State == Stream::state_end) {
646                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
647                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
648                              // remember how many sample words there are before any silence has been added                              // remember how many sample words there are before any silence has been added
649                              if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;                              if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
# Line 734  namespace LinuxSampler { namespace gig { Line 675  namespace LinuxSampler { namespace gig {
675          }          }
676    
677          // 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)
678          pEngine->pSynthesisEvents[Event::destination_vca]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vca]->clear();
679          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->clear();
680          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->clear();
681    
682          // Reset delay          // Reset delay
683          Delay = 0;          Delay = 0;
# Line 776  namespace LinuxSampler { namespace gig { Line 717  namespace LinuxSampler { namespace gig {
717      void Voice::ProcessEvents(uint Samples) {      void Voice::ProcessEvents(uint Samples) {
718    
719          // dispatch control change events          // dispatch control change events
720          RTList<Event>::Iterator itCCEvent = pEngine->pCCEvents->first();          RTList<Event>::Iterator itCCEvent = pEngineChannel->pCCEvents->first();
721          if (Delay) { // skip events that happened before this voice was triggered          if (Delay) { // skip events that happened before this voice was triggered
722              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
723          }          }
724          while (itCCEvent) {          while (itCCEvent) {
725              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
726                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
727                      *pEngine->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;                      *pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
728                  }                  }
729                  if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
730                      *pEngine->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;                      *pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
731                  }                  }
732                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
733                      pLFO1->SendEvent(itCCEvent);                      pLFO1->SendEvent(itCCEvent);
# Line 799  namespace LinuxSampler { namespace gig { Line 740  namespace LinuxSampler { namespace gig {
740                  }                  }
741                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
742                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
743                      *pEngine->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;                      *pEngineChannel->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
744                  }                  }
745              }              }
746    
# Line 809  namespace LinuxSampler { namespace gig { Line 750  namespace LinuxSampler { namespace gig {
750    
751          // process pitch events          // process pitch events
752          {          {
753              RTList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];              RTList<Event>* pVCOEventList = pEngineChannel->pSynthesisEvents[Event::destination_vco];
754              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
755              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
756                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
# Line 847  namespace LinuxSampler { namespace gig { Line 788  namespace LinuxSampler { namespace gig {
788    
789          // 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 !)
790          {          {
791              RTList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];              RTList<Event>* pVCAEventList = pEngineChannel->pSynthesisEvents[Event::destination_vca];
792              RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();              RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
793              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
794                  while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;                  while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
# Line 862  namespace LinuxSampler { namespace gig { Line 803  namespace LinuxSampler { namespace gig {
803    
804                  crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);                  crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
805    
806                  float effective_volume = crossfadevolume * this->Volume * pEngine->GlobalVolume;                  float effective_volume = crossfadevolume * this->Volume * pEngineChannel->GlobalVolume;
807    
808                  // apply volume value to the volume parameter sequence                  // apply volume value to the volume parameter sequence
809                  for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
# Line 876  namespace LinuxSampler { namespace gig { Line 817  namespace LinuxSampler { namespace gig {
817    
818          // process filter cutoff events          // process filter cutoff events
819          {          {
820              RTList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];              RTList<Event>* pCutoffEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfc];
821              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
822              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
823                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
# Line 889  namespace LinuxSampler { namespace gig { Line 830  namespace LinuxSampler { namespace gig {
830                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
831                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
832    
833                  cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;                  cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX - CONFIG_FILTER_CUTOFF_MIN;
834    
835                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
836                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
# Line 903  namespace LinuxSampler { namespace gig { Line 844  namespace LinuxSampler { namespace gig {
844    
845          // process filter resonance events          // process filter resonance events
846          {          {
847              RTList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];              RTList<Event>* pResonanceEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfr];
848              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
849              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
850                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
# Line 942  namespace LinuxSampler { namespace gig { Line 883  namespace LinuxSampler { namespace gig {
883          biquad_param_t bqmain;          biquad_param_t bqmain;
884          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
885          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
886          FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);          FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
887          FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);          FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
888          pEngine->pBasicFilterParameters[0] = bqbase;          pEngine->pBasicFilterParameters[0] = bqbase;
889          pEngine->pMainFilterParameters[0]  = bqmain;          pEngine->pMainFilterParameters[0]  = bqmain;
890    
# Line 956  namespace LinuxSampler { namespace gig { Line 897  namespace LinuxSampler { namespace gig {
897                  {                  {
898                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
899                      prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];                      prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
900                      FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);                      FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
901                      FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);                      FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
902                  }                  }
903              }              }
904    
# Line 1016  namespace LinuxSampler { namespace gig { Line 957  namespace LinuxSampler { namespace gig {
957       *  @param itKillEvent - event which caused the voice to be killed       *  @param itKillEvent - event which caused the voice to be killed
958       */       */
959      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
960          //FIXME: just two sanity checks for debugging, can be removed          #if CONFIG_DEVMODE
961          if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));          if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
962          if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));          if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
963            #endif // CONFIG_DEVMODE
964    
965          if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;          if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
966          this->itKillEvent = itKillEvent;          this->itKillEvent = itKillEvent;

Legend:
Removed from v.332  
changed lines
  Added in v.687

  ViewVC Help
Powered by ViewVC