/[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 247 by senkov, Sun Sep 19 23:44:23 2004 UTC revision 271 by schoenebeck, Fri Oct 8 20:51:39 2004 UTC
# Line 103  namespace LinuxSampler { namespace gig { Line 103  namespace LinuxSampler { namespace gig {
103       *  Initializes and triggers the voice, a disk stream will be launched if       *  Initializes and triggers the voice, a disk stream will be launched if
104       *  needed.       *  needed.
105       *       *
106       *  @param pNoteOnEvent        - event that caused triggering of this voice       *  @param itNoteOnEvent       - event that caused triggering of this voice
107       *  @param PitchBend           - MIDI detune factor (-8192 ... +8191)       *  @param PitchBend           - MIDI detune factor (-8192 ... +8191)
108       *  @param pInstrument         - points to the loaded instrument which provides sample wave(s) and articulation data       *  @param pInstrument         - points to the loaded instrument which provides sample wave(s) and articulation data
109       *  @param iLayer              - layer number this voice refers to (only if this is a layered sound of course)       *  @param iLayer              - layer number this voice refers to (only if this is a layered sound of course)
110       *  @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)       *  @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)
111       *  @returns 0 on success, a value < 0 if something failed       *  @returns 0 on success, a value < 0 if something failed
112       */       */
113      int Voice::Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice) {      int Voice::Trigger(Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice) {
114          if (!pInstrument) {          if (!pInstrument) {
115             dmsg(1,("voice::trigger: !pInstrument\n"));             dmsg(1,("voice::trigger: !pInstrument\n"));
116             exit(EXIT_FAILURE);             exit(EXIT_FAILURE);
# Line 118  namespace LinuxSampler { namespace gig { Line 118  namespace LinuxSampler { namespace gig {
118    
119          Type            = type_normal;          Type            = type_normal;
120          Active          = true;          Active          = true;
121          MIDIKey         = pNoteOnEvent->Param.Note.Key;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
122          pRegion         = pInstrument->GetRegion(MIDIKey);          pRegion         = pInstrument->GetRegion(MIDIKey);
123          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
124          Delay           = pNoteOnEvent->FragmentPos();          Delay           = itNoteOnEvent->FragmentPos();
125          pTriggerEvent   = pNoteOnEvent;          itTriggerEvent  = itNoteOnEvent;
126          pKillEvent      = NULL;          itKillEvent     = Pool<Event>::Iterator();
127    
128          if (!pRegion) {          if (!pRegion) {
129              std::cerr << "gig::Voice: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;              std::cerr << "gig::Voice: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;
# Line 146  namespace LinuxSampler { namespace gig { Line 146  namespace LinuxSampler { namespace gig {
146                      // 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
147                      if (iLayer == 0)                      if (iLayer == 0)
148                          for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++)                          for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++)
149                              pEngine->LaunchVoice(pNoteOnEvent, iNewLayer, ReleaseTriggerVoice);                              pEngine->LaunchVoice(itNoteOnEvent, iNewLayer, ReleaseTriggerVoice);
150                      break;                      break;
151                  case ::gig::dimension_velocity:                  case ::gig::dimension_velocity:
152                      DimValues[i] = pNoteOnEvent->Param.Note.Velocity;                      DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
153                      break;                      break;
154                  case ::gig::dimension_channelaftertouch:                  case ::gig::dimension_channelaftertouch:
155                      DimValues[i] = 0; //TODO: we currently ignore this dimension                      DimValues[i] = 0; //TODO: we currently ignore this dimension
# Line 159  namespace LinuxSampler { namespace gig { Line 159  namespace LinuxSampler { namespace gig {
159                      DimValues[i] = (uint) ReleaseTriggerVoice;                      DimValues[i] = (uint) ReleaseTriggerVoice;
160                      break;                      break;
161                  case ::gig::dimension_keyboard:                  case ::gig::dimension_keyboard:
162                      DimValues[i] = (uint) pNoteOnEvent->Param.Note.Key;                      DimValues[i] = (uint) itNoteOnEvent->Param.Note.Key;
163                      break;                      break;
164                  case ::gig::dimension_modwheel:                  case ::gig::dimension_modwheel:
165                      DimValues[i] = pEngine->ControllerTable[1];                      DimValues[i] = pEngine->ControllerTable[1];
# Line 245  namespace LinuxSampler { namespace gig { Line 245  namespace LinuxSampler { namespace gig {
245                  CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet                  CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
246                  break;                  break;
247              case ::gig::attenuation_ctrl_t::type_velocity:              case ::gig::attenuation_ctrl_t::type_velocity:
248                  CrossfadeVolume = CrossfadeAttenuation(pNoteOnEvent->Param.Note.Velocity);                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
249                  break;                  break;
250              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
251                  CrossfadeVolume = CrossfadeAttenuation(pEngine->ControllerTable[pDimRgn->AttenuationController.controller_number]);                  CrossfadeVolume = CrossfadeAttenuation(pEngine->ControllerTable[pDimRgn->AttenuationController.controller_number]);
# Line 255  namespace LinuxSampler { namespace gig { Line 255  namespace LinuxSampler { namespace gig {
255                  CrossfadeVolume = 1.0f;                  CrossfadeVolume = 1.0f;
256          }          }
257    
258          const float fpan = float(RTMath::Max(RTMath::Min(pDimRgn->Pan, 63), -64)) / 64.0f;          PanLeft  = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) /  63.0f;
259          PanLeft  = 1.0f - fpan;          PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;
         PanRight = 1.0f + fpan;  
260    
261          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          pSample = pDimRgn->pSample; // sample won't change until the voice is finished
262    
# Line 304  namespace LinuxSampler { namespace gig { Line 303  namespace LinuxSampler { namespace gig {
303          }          }
304    
305    
306          Volume = pDimRgn->GetVelocityAttenuation(pNoteOnEvent->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)          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)
307    
308    
309          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
# Line 319  namespace LinuxSampler { namespace gig { Line 318  namespace LinuxSampler { namespace gig {
318                      eg1controllervalue = 0; // TODO: aftertouch not yet supported                      eg1controllervalue = 0; // TODO: aftertouch not yet supported
319                      break;                      break;
320                  case ::gig::eg1_ctrl_t::type_velocity:                  case ::gig::eg1_ctrl_t::type_velocity:
321                      eg1controllervalue = pNoteOnEvent->Param.Note.Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
322                      break;                      break;
323                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
324                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];
# Line 358  namespace LinuxSampler { namespace gig { Line 357  namespace LinuxSampler { namespace gig {
357                      eg2controllervalue = 0; // TODO: aftertouch not yet supported                      eg2controllervalue = 0; // TODO: aftertouch not yet supported
358                      break;                      break;
359                  case ::gig::eg2_ctrl_t::type_velocity:                  case ::gig::eg2_ctrl_t::type_velocity:
360                      eg2controllervalue = pNoteOnEvent->Param.Note.Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
361                      break;                      break;
362                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
363                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];
# Line 586  namespace LinuxSampler { namespace gig { Line 585  namespace LinuxSampler { namespace gig {
585    
586              // calculate cutoff frequency              // calculate cutoff frequency
587              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = (!VCFCutoffCtrl.controller)
588                  ? exp((float) (127 - pNoteOnEvent->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) * FILTER_CUTOFF_MAX
589                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;
590    
591              // calculate resonance              // calculate resonance
592              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0
593              if (pDimRgn->VCFKeyboardTracking) {              if (pDimRgn->VCFKeyboardTracking) {
594                  resonance += (float) (pNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;                  resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
595              }              }
596              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)
597    
# Line 640  namespace LinuxSampler { namespace gig { Line 639  namespace LinuxSampler { namespace gig {
639    
640    
641          // 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
642          pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, pKillEvent);          pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);
643      #if ENABLE_FILTER      #if ENABLE_FILTER
644          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
645      #endif // ENABLE_FILTER      #endif // ENABLE_FILTER
646          pEG3->Process(Samples);          pEG3->Process(Samples);
647          pLFO1->Process(Samples);          pLFO1->Process(Samples);
# Line 717  namespace LinuxSampler { namespace gig { Line 716  namespace LinuxSampler { namespace gig {
716          // Reset delay          // Reset delay
717          Delay = 0;          Delay = 0;
718    
719          pTriggerEvent = NULL;          itTriggerEvent = Pool<Event>::Iterator();
720    
721          // If release stage finished, let the voice be killed          // If release stage finished, let the voice be killed
722          if (pEG1->GetStage() == EGADSR::stage_end) this->PlaybackState = playback_state_end;          if (pEG1->GetStage() == EGADSR::stage_end) this->PlaybackState = playback_state_end;
# Line 748  namespace LinuxSampler { namespace gig { Line 747  namespace LinuxSampler { namespace gig {
747      void Voice::ProcessEvents(uint Samples) {      void Voice::ProcessEvents(uint Samples) {
748    
749          // dispatch control change events          // dispatch control change events
750          Event* pCCEvent = pEngine->pCCEvents->first();          RTList<Event>::Iterator itCCEvent = pEngine->pCCEvents->first();
751          if (Delay) { // skip events that happened before this voice was triggered          if (Delay) { // skip events that happened before this voice was triggered
752              while (pCCEvent && pCCEvent->FragmentPos() <= Delay) pCCEvent = pEngine->pCCEvents->next();              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
753          }          }
754          while (pCCEvent) {          while (itCCEvent) {
755              if (pCCEvent->Param.CC.Controller) { // if valid MIDI controller              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
756                  #if ENABLE_FILTER                  #if ENABLE_FILTER
757                  if (pCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
758                      pEngine->pSynthesisEvents[Event::destination_vcfc]->alloc_assign(*pCCEvent);                      *pEngine->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
759                  }                  }
760                  if (pCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
761                      pEngine->pSynthesisEvents[Event::destination_vcfr]->alloc_assign(*pCCEvent);                      *pEngine->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
762                  }                  }
763                  #endif // ENABLE_FILTER                  #endif // ENABLE_FILTER
764                  if (pCCEvent->Param.CC.Controller == pLFO1->ExtController) {                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
765                      pLFO1->SendEvent(pCCEvent);                      pLFO1->SendEvent(itCCEvent);
766                  }                  }
767                  #if ENABLE_FILTER                  #if ENABLE_FILTER
768                  if (pCCEvent->Param.CC.Controller == pLFO2->ExtController) {                  if (itCCEvent->Param.CC.Controller == pLFO2->ExtController) {
769                      pLFO2->SendEvent(pCCEvent);                      pLFO2->SendEvent(itCCEvent);
770                  }                  }
771                  #endif // ENABLE_FILTER                  #endif // ENABLE_FILTER
772                  if (pCCEvent->Param.CC.Controller == pLFO3->ExtController) {                  if (itCCEvent->Param.CC.Controller == pLFO3->ExtController) {
773                      pLFO3->SendEvent(pCCEvent);                      pLFO3->SendEvent(itCCEvent);
774                  }                  }
775                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
776                      pCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
777                      pEngine->pSynthesisEvents[Event::destination_vca]->alloc_assign(*pCCEvent);                      *pEngine->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
778                  }                  }
779              }              }
780    
781              pCCEvent = pEngine->pCCEvents->next();              ++itCCEvent;
782          }          }
783    
784    
785          // process pitch events          // process pitch events
786          {          {
787              RTEList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];              RTList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];
788              Event* pVCOEvent = pVCOEventList->first();              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
789              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
790                  while (pVCOEvent && pVCOEvent->FragmentPos() <= Delay) pVCOEvent = pVCOEventList->next();                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
791              }              }
792              // apply old pitchbend value until first pitch event occurs              // apply old pitchbend value until first pitch event occurs
793              if (this->PitchBend != 1.0) {              if (this->PitchBend != 1.0) {
794                  uint end = (pVCOEvent) ? pVCOEvent->FragmentPos() : Samples;                  uint end = (itVCOEvent) ? itVCOEvent->FragmentPos() : Samples;
795                  for (uint i = Delay; i < end; i++) {                  for (uint i = Delay; i < end; i++) {
796                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
797                  }                  }
798              }              }
799              float pitch;              float pitch;
800              while (pVCOEvent) {              while (itVCOEvent) {
801                  Event* pNextVCOEvent = pVCOEventList->next();                  RTList<Event>::Iterator itNextVCOEvent = itVCOEvent;
802                    ++itNextVCOEvent;
803    
804                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
805                  uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples;                  uint end = (itNextVCOEvent) ? itNextVCOEvent->FragmentPos() : Samples;
806    
807                  pitch = RTMath::CentsToFreqRatio(((double) pVCOEvent->Param.Pitch.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
808    
809                  // apply pitch value to the pitch parameter sequence                  // apply pitch value to the pitch parameter sequence
810                  for (uint i = pVCOEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCOEvent->FragmentPos(); i < end; i++) {
811                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
812                  }                  }
813    
814                  pVCOEvent = pNextVCOEvent;                  itVCOEvent = itNextVCOEvent;
815              }              }
816              if (pVCOEventList->last()) this->PitchBend = pitch;              if (!pVCOEventList->isEmpty()) this->PitchBend = pitch;
817          }          }
818    
819          // 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 !)
820          {          {
821              RTEList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];              RTList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];
822              Event* pVCAEvent = pVCAEventList->first();              RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
823              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
824                  while (pVCAEvent && pVCAEvent->FragmentPos() <= Delay) pVCAEvent = pVCAEventList->next();                  while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
825              }              }
826              float crossfadevolume;              float crossfadevolume;
827              while (pVCAEvent) {              while (itVCAEvent) {
828                  Event* pNextVCAEvent = pVCAEventList->next();                  RTList<Event>::Iterator itNextVCAEvent = itVCAEvent;
829                    ++itNextVCAEvent;
830    
831                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
832                  uint end = (pNextVCAEvent) ? pNextVCAEvent->FragmentPos() : Samples;                  uint end = (itNextVCAEvent) ? itNextVCAEvent->FragmentPos() : Samples;
833    
834                  crossfadevolume = CrossfadeAttenuation(pVCAEvent->Param.CC.Value);                  crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
835    
836                  float effective_volume = crossfadevolume * this->Volume * pEngine->GlobalVolume;                  float effective_volume = crossfadevolume * this->Volume * pEngine->GlobalVolume;
837    
838                  // apply volume value to the volume parameter sequence                  // apply volume value to the volume parameter sequence
839                  for (uint i = pVCAEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
840                      pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;                      pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;
841                  }                  }
842    
843                  pVCAEvent = pNextVCAEvent;                  itVCAEvent = itNextVCAEvent;
844              }              }
845              if (pVCAEventList->last()) this->CrossfadeVolume = crossfadevolume;              if (!pVCAEventList->isEmpty()) this->CrossfadeVolume = crossfadevolume;
846          }          }
847    
848      #if ENABLE_FILTER      #if ENABLE_FILTER
849          // process filter cutoff events          // process filter cutoff events
850          {          {
851              RTEList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];              RTList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];
852              Event* pCutoffEvent = pCutoffEventList->first();              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
853              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
854                  while (pCutoffEvent && pCutoffEvent->FragmentPos() <= Delay) pCutoffEvent = pCutoffEventList->next();                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
855              }              }
856              float cutoff;              float cutoff;
857              while (pCutoffEvent) {              while (itCutoffEvent) {
858                  Event* pNextCutoffEvent = pCutoffEventList->next();                  RTList<Event>::Iterator itNextCutoffEvent = itCutoffEvent;
859                    ++itNextCutoffEvent;
860    
861                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
862                  uint end = (pNextCutoffEvent) ? pNextCutoffEvent->FragmentPos() : Samples;                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
863    
864                  cutoff = exp((float) pCutoffEvent->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) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;
865    
866                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
867                  for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) {                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
868                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
869                  }                  }
870    
871                  pCutoffEvent = pNextCutoffEvent;                  itCutoffEvent = itNextCutoffEvent;
872              }              }
873              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
874          }          }
875    
876          // process filter resonance events          // process filter resonance events
877          {          {
878              RTEList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];              RTList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];
879              Event* pResonanceEvent = pResonanceEventList->first();              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
880              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
881                  while (pResonanceEvent && pResonanceEvent->FragmentPos() <= Delay) pResonanceEvent = pResonanceEventList->next();                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
882              }              }
883              while (pResonanceEvent) {              while (itResonanceEvent) {
884                  Event* pNextResonanceEvent = pResonanceEventList->next();                  RTList<Event>::Iterator itNextResonanceEvent = itResonanceEvent;
885                    ++itNextResonanceEvent;
886    
887                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
888                  uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples;                  uint end = (itNextResonanceEvent) ? itNextResonanceEvent->FragmentPos() : Samples;
889    
890                  // convert absolute controller value to differential                  // convert absolute controller value to differential
891                  int ctrldelta = pResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;                  int ctrldelta = itResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;
892                  VCFResonanceCtrl.value = pResonanceEvent->Param.CC.Value;                  VCFResonanceCtrl.value = itResonanceEvent->Param.CC.Value;
893    
894                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
895    
896                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
897                  for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) {                  for (uint i = itResonanceEvent->FragmentPos(); i < end; i++) {
898                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
899                  }                  }
900    
901                  pResonanceEvent = pNextResonanceEvent;                  itResonanceEvent = itNextResonanceEvent;
902              }              }
903              if (pResonanceEventList->last()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Param.CC.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
904          }          }
905      #endif // ENABLE_FILTER      #endif // ENABLE_FILTER
906      }      }
# Line 1048  namespace LinuxSampler { namespace gig { Line 1051  namespace LinuxSampler { namespace gig {
1051       *  of a voice, a kill process cannot be cancalled and is therefore       *  of a voice, a kill process cannot be cancalled and is therefore
1052       *  usually used for voice stealing and key group conflicts.       *  usually used for voice stealing and key group conflicts.
1053       *       *
1054       *  @param pKillEvent - event which caused the voice to be killed       *  @param itKillEvent - event which caused the voice to be killed
1055       */       */
1056      void Voice::Kill(Event* pKillEvent) {      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1057          if (pTriggerEvent && pKillEvent->FragmentPos() <= pTriggerEvent->FragmentPos()) return;          if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1058          this->pKillEvent = pKillEvent;          this->itKillEvent = itKillEvent;
1059      }      }
1060    
1061  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.247  
changed lines
  Added in v.271

  ViewVC Help
Powered by ViewVC