/[svn]/linuxsampler/trunk/src/engines/common/AbstractVoice.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/common/AbstractVoice.cpp

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

revision 2032 by persson, Fri Nov 20 20:13:08 2009 UTC revision 2061 by persson, Tue Feb 23 18:32:31 2010 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-2009 Christian Schoenebeck                         *   *   Copyright (C) 2005-2008 Christian Schoenebeck                         *
7   *   Copyright (C) 2009 Grigor Iliev                                       *   *   Copyright (C) 2009-2010 Christian Schoenebeck and Grigor Iliev        *
8   *                                                                         *   *                                                                         *
9   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
10   *   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 51  namespace LinuxSampler { Line 51  namespace LinuxSampler {
51          if (pLFO2) delete pLFO2;          if (pLFO2) delete pLFO2;
52          if (pLFO3) delete pLFO3;          if (pLFO3) delete pLFO3;
53      }      }
54        
55      /**      /**
56       *  Resets voice variables. Should only be called if rendering process is       *  Resets voice variables. Should only be called if rendering process is
57       *  suspended / not running.       *  suspended / not running.
# Line 183  namespace LinuxSampler { Line 183  namespace LinuxSampler {
183              // calculate influence of EG1 controller on EG1's parameters              // calculate influence of EG1 controller on EG1's parameters
184              EGInfo egInfo = CalculateEG1ControllerInfluence(eg1controllervalue);              EGInfo egInfo = CalculateEG1ControllerInfluence(eg1controllervalue);
185    
186              EG1.trigger (              TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);
                 RgnInfo.EG1PreAttack,  
                 RgnInfo.EG1Attack * egInfo.Attack,  
                 RgnInfo.EG1Hold,  
                 RgnInfo.EG1Decay1 * egInfo.Decay * velrelease,  
                 RgnInfo.EG1Decay2 * egInfo.Decay * velrelease,  
                 RgnInfo.EG1InfiniteSustain,  
                 RgnInfo.EG1Sustain,  
                 RgnInfo.EG1Release * egInfo.Release * velrelease,  
                 velocityAttenuation,  
                 GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE  
             );  
187          }          }
188    
189  #ifdef CONFIG_INTERPOLATE_VOLUME  #ifdef CONFIG_INTERPOLATE_VOLUME
# Line 207  namespace LinuxSampler { Line 196  namespace LinuxSampler {
196          else          else
197      #else      #else
198          {          {
199              float finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * EG1.getLevel();              float finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pEG1->getLevel();
200    
201              finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;              finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;
202              finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;              finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;
# Line 224  namespace LinuxSampler { Line 213  namespace LinuxSampler {
213              EGInfo egInfo = CalculateEG2ControllerInfluence(eg2controllervalue);              EGInfo egInfo = CalculateEG2ControllerInfluence(eg2controllervalue);
214    
215              EG2.trigger (              EG2.trigger (
216                  RgnInfo.EG2PreAttack,                  uint(RgnInfo.EG2PreAttack),
217                  RgnInfo.EG2Attack * egInfo.Attack,                  RgnInfo.EG2Attack * egInfo.Attack,
218                  false,                  false,
219                  RgnInfo.EG2Decay1 * egInfo.Decay * velrelease,                  RgnInfo.EG2Decay1 * egInfo.Decay * velrelease,
220                  RgnInfo.EG2Decay2 * egInfo.Decay * velrelease,                  RgnInfo.EG2Decay2 * egInfo.Decay * velrelease,
221                  RgnInfo.EG2InfiniteSustain,                  RgnInfo.EG2InfiniteSustain,
222                  RgnInfo.EG2Sustain,                  uint(RgnInfo.EG2Sustain),
223                  RgnInfo.EG2Release * egInfo.Release * velrelease,                  RgnInfo.EG2Release * egInfo.Release * velrelease,
224                  velocityAttenuation,                  velocityAttenuation,
225                  GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE                  GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE
# Line 347  namespace LinuxSampler { Line 336  namespace LinuxSampler {
336                  // drivers that use Samples < MaxSamplesPerCycle).                  // drivers that use Samples < MaxSamplesPerCycle).
337                  // End the EG1 here, at pos 0, with a shorter max fade                  // End the EG1 here, at pos 0, with a shorter max fade
338                  // out time.                  // out time.
339                  EG1.enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
340                  itKillEvent = Pool<Event>::Iterator();                  itKillEvent = Pool<Event>::Iterator();
341              } else {              } else {
342                  killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);                  killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
# Line 379  namespace LinuxSampler { Line 368  namespace LinuxSampler {
368              if ((itKillEvent && killPos <= iSubFragmentEnd) ||              if ((itKillEvent && killPos <= iSubFragmentEnd) ||
369                  (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&                  (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
370                   EG2.getSegmentType() == gig::EGADSR::segment_end)) {                   EG2.getSegmentType() == gig::EGADSR::segment_end)) {
371                  EG1.enterFadeOutStage();                  pEG1->enterFadeOutStage();
372                  itKillEvent = Pool<Event>::Iterator();                  itKillEvent = Pool<Event>::Iterator();
373              }              }
374    
375              // process envelope generators              // process envelope generators
376              switch (EG1.getSegmentType()) {              switch (pEG1->getSegmentType()) {
377                  case gig::EGADSR::segment_lin:                  case EG::segment_lin:
378                      fFinalVolume *= EG1.processLin();                      fFinalVolume *= pEG1->processLin();
379                      break;                      break;
380                  case gig::EGADSR::segment_exp:                  case EG::segment_exp:
381                      fFinalVolume *= EG1.processExp();                      fFinalVolume *= pEG1->processExp();
382                      break;                      break;
383                  case gig::EGADSR::segment_end:                  case EG::segment_end:
384                      fFinalVolume *= EG1.getLevel();                      fFinalVolume *= pEG1->getLevel();
385                      break; // noop                      break; // noop
386                    case EG::segment_pow:
387                        fFinalVolume *= pEG1->processPow();
388                        break;
389              }              }
390              switch (EG2.getSegmentType()) {              switch (EG2.getSegmentType()) {
391                  case gig::EGADSR::segment_lin:                  case gig::EGADSR::segment_lin:
# Line 448  namespace LinuxSampler { Line 440  namespace LinuxSampler {
440              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
441    
442              // stop the rendering if volume EG is finished              // stop the rendering if volume EG is finished
443              if (EG1.getSegmentType() == gig::EGADSR::segment_end) break;              if (pEG1->getSegmentType() == EG::segment_end) break;
444    
445              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
446    
447              // increment envelopes' positions              // increment envelopes' positions
448              if (EG1.active()) {              if (pEG1->active()) {
449    
450                  // if sample has a loop and loop start has been reached in this subfragment, send a special event to EG1 to let it finish the attack hold stage                  // if sample has a loop and loop start has been reached in this subfragment, send a special event to EG1 to let it finish the attack hold stage
451                  if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {                  if (SmplInfo.HasLoops && Pos <= SmplInfo.LoopStart && SmplInfo.LoopStart < newPos) {
452                      EG1.update(gig::EGADSR::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                      pEG1->update(EG::event_hold_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
453                  }                  }
454    
455                  EG1.increment(1);                  pEG1->increment(1);
456                  if (!EG1.toStageEndLeft()) EG1.update(gig::EGADSR::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  if (!pEG1->toStageEndLeft()) pEG1->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
457              }              }
458              if (EG2.active()) {              if (EG2.active()) {
459                  EG2.increment(1);                  EG2.increment(1);
# Line 474  namespace LinuxSampler { Line 466  namespace LinuxSampler {
466              i = iSubFragmentEnd;              i = iSubFragmentEnd;
467          }          }
468      }      }
469        
470      /**      /**
471       * Process given list of MIDI control change and pitch bend events for       * Process given list of MIDI control change and pitch bend events for
472       * the given time.       * the given time.
# Line 538  namespace LinuxSampler { Line 530  namespace LinuxSampler {
530      void AbstractVoice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {      void AbstractVoice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
531          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
532              if (itEvent->Type == Event::type_release) {              if (itEvent->Type == Event::type_release) {
533                  EG1.update(gig::EGADSR::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
534                  EG2.update(gig::EGADSR::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  EG2.update(gig::EGADSR::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
535              } else if (itEvent->Type == Event::type_cancel_release) {              } else if (itEvent->Type == Event::type_cancel_release) {
536                  EG1.update(gig::EGADSR::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
537                  EG2.update(gig::EGADSR::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  EG2.update(gig::EGADSR::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
538              }              }
539          }          }
# Line 608  namespace LinuxSampler { Line 600  namespace LinuxSampler {
600              float noteLength = float(GetEngine()->FrameTime + Delay -              float noteLength = float(GetEngine()->FrameTime + Delay -
601                  GetNoteOnTime(MIDIKey) ) / GetEngine()->SampleRate;                  GetNoteOnTime(MIDIKey) ) / GetEngine()->SampleRate;
602    
603              float attenuation = 1 - 0.01053 * (256 >> RgnInfo.ReleaseTriggerDecay) * noteLength;              volume *= GetReleaseTriggerAttenuation(noteLength);
             volume *= attenuation;  
604          }          }
605    
606          return volume;          return volume;
607      }      }
608    
609        float AbstractVoice::GetReleaseTriggerAttenuation(float noteLength) {
610            return 1 - RgnInfo.ReleaseTriggerDecay * noteLength;
611        }
612  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.2032  
changed lines
  Added in v.2061

  ViewVC Help
Powered by ViewVC