/[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 2115 by persson, Thu Aug 12 15:36:15 2010 UTC revision 2175 by persson, Mon Apr 25 08:12:36 2011 UTC
# Line 4  Line 4 
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-2008 Christian Schoenebeck                         *   *   Copyright (C) 2005-2008 Christian Schoenebeck                         *
7   *   Copyright (C) 2009-2010 Christian Schoenebeck and Grigor Iliev        *   *   Copyright (C) 2009-2011 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 28  namespace LinuxSampler { Line 28  namespace LinuxSampler {
28    
29      AbstractVoice::AbstractVoice() {      AbstractVoice::AbstractVoice() {
30          pEngineChannel = NULL;          pEngineChannel = NULL;
31          pLFO1 = new LFOUnsigned(1.0f);  // amplitude EG (0..1 range)          pLFO1 = new LFOUnsigned(1.0f);  // amplitude LFO (0..1 range)
32          pLFO2 = new LFOUnsigned(1.0f);  // filter EG (0..1 range)          pLFO2 = new LFOUnsigned(1.0f);  // filter LFO (0..1 range)
33          pLFO3 = new LFOSigned(1200.0f); // pitch EG (-1200..+1200 range)          pLFO3 = new LFOSigned(1200.0f); // pitch LFO (-1200..+1200 range)
34          PlaybackState = playback_state_end;          PlaybackState = playback_state_end;
35          SynthesisMode = 0; // set all mode bits to 0 first          SynthesisMode = 0; // set all mode bits to 0 first
36          // select synthesis implementation (asm core is not supported ATM)          // select synthesis implementation (asm core is not supported ATM)
# Line 103  namespace LinuxSampler { Line 103  namespace LinuxSampler {
103          Delay           = itNoteOnEvent->FragmentPos();          Delay           = itNoteOnEvent->FragmentPos();
104          itTriggerEvent  = itNoteOnEvent;          itTriggerEvent  = itNoteOnEvent;
105          itKillEvent     = Pool<Event>::Iterator();          itKillEvent     = Pool<Event>::Iterator();
106            MidiKeyBase* pKeyInfo = GetMidiKeyInfo(MIDIKey);
107    
108          pGroupEvents = iKeyGroup ? pEngineChannel->ActiveKeyGroups[iKeyGroup] : 0;          pGroupEvents = iKeyGroup ? pEngineChannel->ActiveKeyGroups[iKeyGroup] : 0;
109    
# Line 112  namespace LinuxSampler { Line 113  namespace LinuxSampler {
113    
114          // calculate volume          // calculate volume
115          const double velocityAttenuation = GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);          const double velocityAttenuation = GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
116          float volume = CalculateVolume(velocityAttenuation);          float volume = CalculateVolume(velocityAttenuation) * pKeyInfo->Volume;
117          if (volume <= 0) return -1;          if (volume <= 0) return -1;
118    
119          // select channel mode (mono or stereo)          // select channel mode (mono or stereo)
# Line 123  namespace LinuxSampler { Line 124  namespace LinuxSampler {
124          // get starting crossfade volume level          // get starting crossfade volume level
125          float crossfadeVolume = CalculateCrossfadeVolume(itNoteOnEvent->Param.Note.Velocity);          float crossfadeVolume = CalculateCrossfadeVolume(itNoteOnEvent->Param.Note.Velocity);
126    
127          VolumeLeft  = volume * AbstractEngine::PanCurve[64 - RgnInfo.Pan];          VolumeLeft  = volume * pKeyInfo->PanLeft  * AbstractEngine::PanCurve[64 - RgnInfo.Pan];
128          VolumeRight = volume * AbstractEngine::PanCurve[64 + RgnInfo.Pan];          VolumeRight = volume * pKeyInfo->PanRight * AbstractEngine::PanCurve[64 + RgnInfo.Pan];
129    
130          float subfragmentRate = GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          float subfragmentRate = GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
131          CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);          CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
# Line 212  namespace LinuxSampler { Line 213  namespace LinuxSampler {
213              // calculate influence of EG2 controller on EG2's parameters              // calculate influence of EG2 controller on EG2's parameters
214              EGInfo egInfo = CalculateEG2ControllerInfluence(eg2controllervalue);              EGInfo egInfo = CalculateEG2ControllerInfluence(eg2controllervalue);
215    
216              EG2.trigger (              TriggerEG2(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);
                 uint(RgnInfo.EG2PreAttack),  
                 RgnInfo.EG2Attack * egInfo.Attack,  
                 false,  
                 RgnInfo.EG2Decay1 * egInfo.Decay * velrelease,  
                 RgnInfo.EG2Decay2 * egInfo.Decay * velrelease,  
                 RgnInfo.EG2InfiniteSustain,  
                 uint(RgnInfo.EG2Sustain),  
                 RgnInfo.EG2Release * egInfo.Release * velrelease,  
                 velocityAttenuation,  
                 GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE  
             );  
217          }          }
218    
219    
# Line 306  namespace LinuxSampler { Line 296  namespace LinuxSampler {
296       */       */
297      void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {      void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
298          AbstractEngineChannel* pChannel = pEngineChannel;          AbstractEngineChannel* pChannel = pEngineChannel;
299          finalSynthesisParameters.pOutLeft  = &pChannel->pChannelLeft->Buffer()[Skip];          MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey);
300          finalSynthesisParameters.pOutRight = &pChannel->pChannelRight->Buffer()[Skip];  
301          finalSynthesisParameters.pSrc      = pSrc;          const bool bVoiceRequiresDedicatedRouting =
302                pEngineChannel->GetFxSendCount() > 0 &&
303                (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);
304    
305            if (bVoiceRequiresDedicatedRouting) {
306                finalSynthesisParameters.pOutLeft  = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];
307                finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];
308            } else {
309                finalSynthesisParameters.pOutLeft  = &pChannel->pChannelLeft->Buffer()[Skip];
310                finalSynthesisParameters.pOutRight = &pChannel->pChannelRight->Buffer()[Skip];
311            }
312            finalSynthesisParameters.pSrc = pSrc;
313    
314          RTList<Event>::Iterator itCCEvent = pChannel->pEvents->first();          RTList<Event>::Iterator itCCEvent = pChannel->pEvents->first();
315          RTList<Event>::Iterator itNoteEvent;          RTList<Event>::Iterator itNoteEvent;
# Line 373  namespace LinuxSampler { Line 374  namespace LinuxSampler {
374              // filter EG is finished, switch EG1 to fade out stage              // filter EG is finished, switch EG1 to fade out stage
375              if ((itKillEvent && killPos <= iSubFragmentEnd) ||              if ((itKillEvent && killPos <= iSubFragmentEnd) ||
376                  (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&                  (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
377                   EG2.getSegmentType() == gig::EGADSR::segment_end)) {                   pEG2->getSegmentType() == EG::segment_end)) {
378                  pEG1->enterFadeOutStage();                  pEG1->enterFadeOutStage();
379                  itKillEvent = Pool<Event>::Iterator();                  itKillEvent = Pool<Event>::Iterator();
380              }              }
# Line 393  namespace LinuxSampler { Line 394  namespace LinuxSampler {
394                      fFinalVolume *= pEG1->processPow();                      fFinalVolume *= pEG1->processPow();
395                      break;                      break;
396              }              }
397              switch (EG2.getSegmentType()) {              switch (pEG2->getSegmentType()) {
398                  case gig::EGADSR::segment_lin:                  case EG::segment_lin:
399                      fFinalCutoff *= EG2.processLin();                      fFinalCutoff *= pEG2->processLin();
400                      break;                      break;
401                  case gig::EGADSR::segment_exp:                  case EG::segment_exp:
402                      fFinalCutoff *= EG2.processExp();                      fFinalCutoff *= pEG2->processExp();
403                      break;                      break;
404                  case gig::EGADSR::segment_end:                  case EG::segment_end:
405                      fFinalCutoff *= EG2.getLevel();                      fFinalCutoff *= pEG2->getLevel();
406                      break; // noop                      break; // noop
407                    case EG::segment_pow:
408                        fFinalCutoff *= pEG2->processPow();
409                        break;
410              }              }
411              if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();              if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
412    
# Line 461  namespace LinuxSampler { Line 465  namespace LinuxSampler {
465                  pEG1->increment(1);                  pEG1->increment(1);
466                  if (!pEG1->toStageEndLeft()) pEG1->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  if (!pEG1->toStageEndLeft()) pEG1->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
467              }              }
468              if (EG2.active()) {              if (pEG2->active()) {
469                  EG2.increment(1);                  pEG2->increment(1);
470                  if (!EG2.toStageEndLeft()) EG2.update(gig::EGADSR::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  if (!pEG2->toStageEndLeft()) pEG2->update(EG::event_stage_end, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
471              }              }
472              EG3.increment(1);              EG3.increment(1);
473              if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached              if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
# Line 471  namespace LinuxSampler { Line 475  namespace LinuxSampler {
475              Pos = newPos;              Pos = newPos;
476              i = iSubFragmentEnd;              i = iSubFragmentEnd;
477          }          }
478    
479            if (bVoiceRequiresDedicatedRouting) {
480                optional<float> effectSendLevels[2] = {
481                    pMidiKeyInfo->ReverbSend,
482                    pMidiKeyInfo->ChorusSend
483                };
484                GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);
485            }
486      }      }
487    
488      /**      /**
# Line 541  namespace LinuxSampler { Line 553  namespace LinuxSampler {
553                      EnterReleaseStage();                      EnterReleaseStage();
554                  } else if (itEvent->Type == Event::type_cancel_release) {                  } else if (itEvent->Type == Event::type_cancel_release) {
555                      pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                      pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
556                      EG2.update(gig::EGADSR::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                      pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
557                  }                  }
558              }              }
559          }          }
# Line 632  namespace LinuxSampler { Line 644  namespace LinuxSampler {
644    
645      void AbstractVoice::EnterReleaseStage() {      void AbstractVoice::EnterReleaseStage() {
646          pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);          pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
647          EG2.update(gig::EGADSR::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);          pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
648      }      }
649    
650  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.2115  
changed lines
  Added in v.2175

  ViewVC Help
Powered by ViewVC