/[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 2216 by iliev, Mon Jul 25 17:21:16 2011 UTC revision 2382 by persson, Sun Dec 2 16:30:42 2012 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-2011 Christian Schoenebeck and Grigor Iliev        *   *   Copyright (C) 2009-2012 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 26  Line 26 
26    
27  namespace LinuxSampler {  namespace LinuxSampler {
28    
29      AbstractVoice::AbstractVoice() {      AbstractVoice::AbstractVoice(SignalUnitRack* pRack): pSignalUnitRack(pRack) {
30          pEngineChannel = NULL;          pEngineChannel = NULL;
31          pLFO1 = new LFOUnsigned(1.0f);  // amplitude LFO (0..1 range)          pLFO1 = new LFOUnsigned(1.0f);  // amplitude LFO (0..1 range)
32          pLFO2 = new LFOUnsigned(1.0f);  // filter LFO (0..1 range)          pLFO2 = new LFOUnsigned(1.0f);  // filter LFO (0..1 range)
# Line 43  namespace LinuxSampler { Line 43  namespace LinuxSampler {
43    
44          finalSynthesisParameters.filterLeft.Reset();          finalSynthesisParameters.filterLeft.Reset();
45          finalSynthesisParameters.filterRight.Reset();          finalSynthesisParameters.filterRight.Reset();
46            
47            pEq          = NULL;
48            bEqSupport   = false;
49      }      }
50    
51      AbstractVoice::~AbstractVoice() {      AbstractVoice::~AbstractVoice() {
52          if (pLFO1) delete pLFO1;          if (pLFO1) delete pLFO1;
53          if (pLFO2) delete pLFO2;          if (pLFO2) delete pLFO2;
54          if (pLFO3) delete pLFO3;          if (pLFO3) delete pLFO3;
55            
56            if(pEq != NULL) delete pEq;
57        }
58                
59        void AbstractVoice::CreateEq() {
60            if(!bEqSupport) return;
61            if(pEq != NULL) delete pEq;
62            pEq = new EqSupport;
63            pEq->InitEffect(GetEngine()->pAudioOutputDevice);
64      }      }
65    
66      /**      /**
# Line 99  namespace LinuxSampler { Line 111  namespace LinuxSampler {
111    
112          Type            = VoiceType;          Type            = VoiceType;
113          MIDIKey         = itNoteOnEvent->Param.Note.Key;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
114            MIDIVelocity    = itNoteOnEvent->Param.Note.Velocity;
115          PlaybackState   = playback_state_init; // mark voice as triggered, but no audio rendered yet          PlaybackState   = playback_state_init; // mark voice as triggered, but no audio rendered yet
116          Delay           = itNoteOnEvent->FragmentPos();          Delay           = itNoteOnEvent->FragmentPos();
117          itTriggerEvent  = itNoteOnEvent;          itTriggerEvent  = itNoteOnEvent;
# Line 111  namespace LinuxSampler { Line 124  namespace LinuxSampler {
124          RgnInfo    = GetRegionInfo();          RgnInfo    = GetRegionInfo();
125          InstrInfo  = GetInstrumentInfo();          InstrInfo  = GetInstrumentInfo();
126                    
127            MIDIPan    = CalculatePan(pEngineChannel->iLastPanRequest);
128    
129          AboutToTrigger();          AboutToTrigger();
130    
131          // calculate volume          // calculate volume
# Line 126  namespace LinuxSampler { Line 141  namespace LinuxSampler {
141          // get starting crossfade volume level          // get starting crossfade volume level
142          float crossfadeVolume = CalculateCrossfadeVolume(itNoteOnEvent->Param.Note.Velocity);          float crossfadeVolume = CalculateCrossfadeVolume(itNoteOnEvent->Param.Note.Velocity);
143    
144          VolumeLeft  = volume * pKeyInfo->PanLeft  * AbstractEngine::PanCurve[64 - RgnInfo.Pan];          VolumeLeft  = volume * pKeyInfo->PanLeft;
145          VolumeRight = volume * pKeyInfo->PanRight * AbstractEngine::PanCurve[64 + RgnInfo.Pan];          VolumeRight = volume * pKeyInfo->PanRight;
146    
147          float subfragmentRate = GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          float subfragmentRate = GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
148          CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);          CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
149          VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);          VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);
         PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);  
         PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);  
150    
151          // Check if the sample needs disk streaming or is too short for that          // Check if the sample needs disk streaming or is too short for that
152          long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;          long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;
# Line 177  namespace LinuxSampler { Line 190  namespace LinuxSampler {
190          // the length of the decay and release curves are dependent on the velocity          // the length of the decay and release curves are dependent on the velocity
191          const double velrelease = 1 / GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);          const double velrelease = 1 / GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
192    
193          if (GetSignalUnitRack() == NULL) { // setup EG 1 (VCA EG)          if (pSignalUnitRack == NULL) { // setup EG 1 (VCA EG)
194              // get current value of EG1 controller              // get current value of EG1 controller
195              double eg1controllervalue = GetEG1ControllerValue(itNoteOnEvent->Param.Note.Velocity);              double eg1controllervalue = GetEG1ControllerValue(itNoteOnEvent->Param.Note.Velocity);
196    
# Line 186  namespace LinuxSampler { Line 199  namespace LinuxSampler {
199    
200              TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);              TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);
201          } else {          } else {
202              GetSignalUnitRack()->Trigger();              pSignalUnitRack->Trigger();
203          }          }
204    
205            uint8_t pan = MIDIPan;
206            if (pSignalUnitRack) pan = pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan);
207            PanLeftSmoother.trigger(AbstractEngine::PanCurve[128 - pan], subfragmentRate);
208            PanRightSmoother.trigger(AbstractEngine::PanCurve[pan], subfragmentRate);
209    
210  #ifdef CONFIG_INTERPOLATE_VOLUME  #ifdef CONFIG_INTERPOLATE_VOLUME
211          // setup initial volume in synthesis parameters          // setup initial volume in synthesis parameters
212      #ifdef CONFIG_PROCESS_MUTED_CHANNELS      #ifdef CONFIG_PROCESS_MUTED_CHANNELS
# Line 200  namespace LinuxSampler { Line 218  namespace LinuxSampler {
218      #else      #else
219          {          {
220              float finalVolume;              float finalVolume;
221              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
222                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pEG1->getLevel();                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pEG1->getLevel();
223              } else {              } else {
224                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * GetSignalUnitRack()->GetEndpointUnit()->GetVolume();                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pSignalUnitRack->GetEndpointUnit()->GetVolume();
225              }              }
226    
227              finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;              finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * PanLeftSmoother.render();
228              finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;              finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * PanRightSmoother.render();
229          }          }
230      #endif      #endif
231  #endif  #endif
232    
233          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
234              // setup EG 2 (VCF Cutoff EG)              // setup EG 2 (VCF Cutoff EG)
235              {              {
236                  // get current value of EG2 controller                  // get current value of EG2 controller
# Line 291  namespace LinuxSampler { Line 309  namespace LinuxSampler {
309              VCFCutoffCtrl.controller    = 0;              VCFCutoffCtrl.controller    = 0;
310              VCFResonanceCtrl.controller = 0;              VCFResonanceCtrl.controller = 0;
311          }          }
312            
313            const bool bEq =
314                pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
315    
316            if (bEq) {
317                pEq->GetInChannelLeft()->Clear();
318                pEq->GetInChannelRight()->Clear();
319                pEq->RenderAudio(GetEngine()->pAudioOutputDevice->MaxSamplesPerCycle());
320            }
321    
322          return 0; // success          return 0; // success
323      }      }
# Line 309  namespace LinuxSampler { Line 336  namespace LinuxSampler {
336       *  @param Skip    - number of sample points to skip in output buffer       *  @param Skip    - number of sample points to skip in output buffer
337       */       */
338      void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {      void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
339            bool delay = false; // Whether the voice playback should be delayed for this call
340            
341            if (pSignalUnitRack != NULL) {
342                uint delaySteps = pSignalUnitRack->GetEndpointUnit()->DelayTrigger();
343                if (delaySteps > 0) { // delay on the endpoint unit means delay of the voice playback
344                    if (delaySteps >= Samples) {
345                        pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(Samples);
346                        delay = true;
347                    } else {
348                        pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(delaySteps);
349                        Samples -= delaySteps;
350                        Skip += delaySteps;
351                    }
352                }
353            }
354            
355          AbstractEngineChannel* pChannel = pEngineChannel;          AbstractEngineChannel* pChannel = pEngineChannel;
356          MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey);          MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey);
357    
358          const bool bVoiceRequiresDedicatedRouting =          const bool bVoiceRequiresDedicatedRouting =
359              pEngineChannel->GetFxSendCount() > 0 &&              pEngineChannel->GetFxSendCount() > 0 &&
360              (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);              (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);
361            
362            const bool bEq =
363                pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
364    
365          if (bVoiceRequiresDedicatedRouting) {          if (bEq) {
366                pEq->GetInChannelLeft()->Clear();
367                pEq->GetInChannelRight()->Clear();
368                finalSynthesisParameters.pOutLeft  = &pEq->GetInChannelLeft()->Buffer()[Skip];
369                finalSynthesisParameters.pOutRight = &pEq->GetInChannelRight()->Buffer()[Skip];
370                pSignalUnitRack->UpdateEqSettings(pEq);
371            } else if (bVoiceRequiresDedicatedRouting) {
372              finalSynthesisParameters.pOutLeft  = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];              finalSynthesisParameters.pOutLeft  = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];
373              finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];              finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];
374          } else {          } else {
# Line 330  namespace LinuxSampler { Line 382  namespace LinuxSampler {
382          GetFirstEventOnKey(MIDIKey, itNoteEvent);          GetFirstEventOnKey(MIDIKey, itNoteEvent);
383    
384          RTList<Event>::Iterator itGroupEvent;          RTList<Event>::Iterator itGroupEvent;
385          if (pGroupEvents) itGroupEvent = pGroupEvents->first();          if (pGroupEvents && !Orphan) itGroupEvent = pGroupEvents->first();
386    
387          if (itTriggerEvent) { // skip events that happened before this voice was triggered          if (itTriggerEvent) { // skip events that happened before this voice was triggered
388              while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;              while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
# Line 356  namespace LinuxSampler { Line 408  namespace LinuxSampler {
408                  // drivers that use Samples < MaxSamplesPerCycle).                  // drivers that use Samples < MaxSamplesPerCycle).
409                  // End the EG1 here, at pos 0, with a shorter max fade                  // End the EG1 here, at pos 0, with a shorter max fade
410                  // out time.                  // out time.
411                  if (GetSignalUnitRack() == NULL) {                  if (pSignalUnitRack == NULL) {
412                      pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                      pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
413                  } else {                  } else {
414                      // TODO:                      pSignalUnitRack->EnterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
415                  }                  }
416                  itKillEvent = Pool<Event>::Iterator();                  itKillEvent = Pool<Event>::Iterator();
417              } else {              } else {
# Line 377  namespace LinuxSampler { Line 429  namespace LinuxSampler {
429    
430              // process MIDI control change and pitchbend events for this subfragment              // process MIDI control change and pitchbend events for this subfragment
431              processCCEvents(itCCEvent, iSubFragmentEnd);              processCCEvents(itCCEvent, iSubFragmentEnd);
432                uint8_t pan = MIDIPan;
433                if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan);
434                
435                PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan]);
436                PanRightSmoother.update(AbstractEngine::PanCurve[pan]);
437    
438              finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend;              finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend;
439              float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();              float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
# Line 387  namespace LinuxSampler { Line 444  namespace LinuxSampler {
444              // process transition events (note on, note off & sustain pedal)              // process transition events (note on, note off & sustain pedal)
445              processTransitionEvents(itNoteEvent, iSubFragmentEnd);              processTransitionEvents(itNoteEvent, iSubFragmentEnd);
446              processGroupEvents(itGroupEvent, iSubFragmentEnd);              processGroupEvents(itGroupEvent, iSubFragmentEnd);
447                
448              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
449                  // if the voice was killed in this subfragment, or if the                  // if the voice was killed in this subfragment, or if the
450                  // filter EG is finished, switch EG1 to fade out stage                  // filter EG is finished, switch EG1 to fade out stage
451                  if ((itKillEvent && killPos <= iSubFragmentEnd) ||                  if ((itKillEvent && killPos <= iSubFragmentEnd) ||
# Line 434  namespace LinuxSampler { Line 491  namespace LinuxSampler {
491                  if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();                  if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
492                  if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());                  if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
493              } else {              } else {
494                  // if the voice was killed in this subfragment, or if the                  // if the voice was killed in this subfragment, enter fade out stage
495                  // filter EG is finished, switch EG1 to fade out stage                  if (itKillEvent && killPos <= iSubFragmentEnd) {
496                  /*if ((itKillEvent && killPos <= iSubFragmentEnd) ||                      pSignalUnitRack->EnterFadeOutStage();
497                      (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&                      itKillEvent = Pool<Event>::Iterator();
498                      pEG2->getSegmentType() == EG::segment_end)) {                  }
499                    
500                    // if the filter EG is finished, switch EG1 to fade out stage
501                    /*if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
502                        pEG2->getSegmentType() == EG::segment_end) {
503                      pEG1->enterFadeOutStage();                      pEG1->enterFadeOutStage();
504                      itKillEvent = Pool<Event>::Iterator();                      itKillEvent = Pool<Event>::Iterator();
505                  }*/                  }*/
506                  // TODO: ^^^                  // TODO: ^^^
507    
508                  fFinalVolume   *= GetSignalUnitRack()->GetEndpointUnit()->GetVolume();                  fFinalVolume   *= pSignalUnitRack->GetEndpointUnit()->GetVolume();
509                  fFinalCutoff    = GetSignalUnitRack()->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);                  fFinalCutoff    = pSignalUnitRack->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);
510                  fFinalResonance = GetSignalUnitRack()->GetEndpointUnit()->CalculateResonance(fFinalResonance);                  fFinalResonance = pSignalUnitRack->GetEndpointUnit()->CalculateResonance(fFinalResonance);
511                                    
512                  finalSynthesisParameters.fFinalPitch =                  finalSynthesisParameters.fFinalPitch =
513                      GetSignalUnitRack()->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);                      pSignalUnitRack->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);
514                                            
515              }              }
516                            
# Line 485  namespace LinuxSampler { Line 546  namespace LinuxSampler {
546                  fFinalVolume * VolumeRight * PanRightSmoother.render();                  fFinalVolume * VolumeRight * PanRightSmoother.render();
547  #endif  #endif
548              // render audio for one subfragment              // render audio for one subfragment
549              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);              if (!delay) RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
550    
551              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
552                  // stop the rendering if volume EG is finished                  // stop the rendering if volume EG is finished
553                  if (pEG1->getSegmentType() == EG::segment_end) break;                  if (pEG1->getSegmentType() == EG::segment_end) break;
554              } else {              } else {
555                  // stop the rendering if the endpoint unit is not active                  // stop the rendering if the endpoint unit is not active
556                  if (!GetSignalUnitRack()->GetEndpointUnit()->Active()) break;                  if (!pSignalUnitRack->GetEndpointUnit()->Active()) break;
557              }              }
558    
559              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
560    
561              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
562                  // increment envelopes' positions                  // increment envelopes' positions
563                  if (pEG1->active()) {                  if (pEG1->active()) {
564    
# Line 522  namespace LinuxSampler { Line 583  namespace LinuxSampler {
583                      }*/                      }*/
584                  // TODO: ^^^                  // TODO: ^^^
585                                    
586                  GetSignalUnitRack()->Increment();                  if (!delay) pSignalUnitRack->Increment();
587              }              }
588    
589              Pos = newPos;              Pos = newPos;
590              i = iSubFragmentEnd;              i = iSubFragmentEnd;
591          }          }
592            
593            if (delay) return;
594    
595          if (bVoiceRequiresDedicatedRouting) {          if (bVoiceRequiresDedicatedRouting) {
596                if (bEq) {
597                    pEq->RenderAudio(Samples);
598                    pEq->GetOutChannelLeft()->CopyTo(GetEngine()->pDedicatedVoiceChannelLeft, Samples);
599                    pEq->GetOutChannelRight()->CopyTo(GetEngine()->pDedicatedVoiceChannelRight, Samples);
600                }
601              optional<float> effectSendLevels[2] = {              optional<float> effectSendLevels[2] = {
602                  pMidiKeyInfo->ReverbSend,                  pMidiKeyInfo->ReverbSend,
603                  pMidiKeyInfo->ChorusSend                  pMidiKeyInfo->ChorusSend
604              };              };
605              GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);              GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);
606            } else if (bEq) {
607                pEq->RenderAudio(Samples);
608                pEq->GetOutChannelLeft()->MixTo(pChannel->pChannelLeft, Samples);
609                pEq->GetOutChannelRight()->MixTo(pChannel->pChannelRight, Samples);
610          }          }
611      }      }
612    
# Line 554  namespace LinuxSampler { Line 626  namespace LinuxSampler {
626                  if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {                  if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
627                      processResonanceEvent(itEvent);                      processResonanceEvent(itEvent);
628                  }                  }
629                  if (GetSignalUnitRack() == NULL) {                  if (pSignalUnitRack == NULL) {
630                      if (itEvent->Param.CC.Controller == pLFO1->ExtController) {                      if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
631                          pLFO1->update(itEvent->Param.CC.Value);                          pLFO1->update(itEvent->Param.CC.Value);
632                      }                      }
# Line 568  namespace LinuxSampler { Line 640  namespace LinuxSampler {
640                  if (itEvent->Param.CC.Controller == 7) { // volume                  if (itEvent->Param.CC.Controller == 7) { // volume
641                      VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);                      VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);
642                  } else if (itEvent->Param.CC.Controller == 10) { // panpot                  } else if (itEvent->Param.CC.Controller == 10) { // panpot
643                      PanLeftSmoother.update(AbstractEngine::PanCurve[128 - itEvent->Param.CC.Value]);                      MIDIPan = CalculatePan(itEvent->Param.CC.Value);
                     PanRightSmoother.update(AbstractEngine::PanCurve[itEvent->Param.CC.Value]);  
644                  }                  }
645              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
646                  processPitchEvent(itEvent);                  processPitchEvent(itEvent);
647              }              }
648    
649              ProcessCCEvent(itEvent);              ProcessCCEvent(itEvent);
650              if (GetSignalUnitRack() != NULL) {              if (pSignalUnitRack != NULL) {
651                  GetSignalUnitRack()->ProcessCCEvent(itEvent);                  pSignalUnitRack->ProcessCCEvent(itEvent);
652              }              }
653          }          }
654      }      }
# Line 610  namespace LinuxSampler { Line 681  namespace LinuxSampler {
681                  if (itEvent->Type == Event::type_release) {                  if (itEvent->Type == Event::type_release) {
682                      EnterReleaseStage();                      EnterReleaseStage();
683                  } else if (itEvent->Type == Event::type_cancel_release) {                  } else if (itEvent->Type == Event::type_cancel_release) {
684                      if (GetSignalUnitRack() == NULL) {                      if (pSignalUnitRack == NULL) {
685                          pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
686                          pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
687                      } else {                      } else {
688                          GetSignalUnitRack()->CancelRelease();                          pSignalUnitRack->CancelRelease();
689                      }                      }
690                  }                  }
691              }              }
# Line 642  namespace LinuxSampler { Line 713  namespace LinuxSampler {
713       * @param itNoteOffEvent - event which causes this voice to die soon       * @param itNoteOffEvent - event which causes this voice to die soon
714       */       */
715      void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {      void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
716          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
717              const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());              const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
718              pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;              pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
719          } else {          } else {
# Line 709  namespace LinuxSampler { Line 780  namespace LinuxSampler {
780      }      }
781    
782      void AbstractVoice::EnterReleaseStage() {      void AbstractVoice::EnterReleaseStage() {
783          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
784              pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);              pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
785              pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);              pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
786          } else {          } else {
787              GetSignalUnitRack()->EnterReleaseStage();              pSignalUnitRack->EnterReleaseStage();
788          }          }
789      }      }
790    
791      bool AbstractVoice::EG1Finished() {      bool AbstractVoice::EG1Finished() {
792          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
793              return pEG1->getSegmentType() == EG::segment_end;              return pEG1->getSegmentType() == EG::segment_end;
794          } else {          } else {
795              return !GetSignalUnitRack()->GetEndpointUnit()->Active();              return !pSignalUnitRack->GetEndpointUnit()->Active();
796          }          }
797      }      }
798    

Legend:
Removed from v.2216  
changed lines
  Added in v.2382

  ViewVC Help
Powered by ViewVC