/[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 2205 by iliev, Mon Jul 11 17:52:01 2011 UTC revision 2327 by persson, Sat Mar 10 16:16:14 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            MIDIPan         = pEngineChannel->ControllerTable[10];
116            if (MIDIPan == 0 && pEngineChannel->GlobalPanRight == 1) MIDIPan = 64; // workaround used to determine whether the MIDI pan has not been set
117          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
118          Delay           = itNoteOnEvent->FragmentPos();          Delay           = itNoteOnEvent->FragmentPos();
119          itTriggerEvent  = itNoteOnEvent;          itTriggerEvent  = itNoteOnEvent;
# Line 135  namespace LinuxSampler { Line 150  namespace LinuxSampler {
150          PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);          PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);
151          PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);          PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);
152    
         finalSynthesisParameters.dPos = RgnInfo.SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)  
         Pos = RgnInfo.SampleStartOffset;  
   
153          // 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
154          long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;          long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;
155          DiskVoice          = cachedsamples < SmplInfo.TotalFrameCount;          DiskVoice          = cachedsamples < SmplInfo.TotalFrameCount;
156    
157            SetSampleStartOffset();
158    
159          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
160              if (cachedsamples > (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH)) {              if (cachedsamples > (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH)) {
161                  MaxRAMPos = cachedsamples - (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / SmplInfo.ChannelCount; //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 - (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / SmplInfo.ChannelCount; //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)
# Line 178  namespace LinuxSampler { Line 192  namespace LinuxSampler {
192          // 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
193          const double velrelease = 1 / GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);          const double velrelease = 1 / GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
194    
195          if (GetSignalUnitRack() == NULL) { // setup EG 1 (VCA EG)          if (pSignalUnitRack == NULL) { // setup EG 1 (VCA EG)
196              // get current value of EG1 controller              // get current value of EG1 controller
197              double eg1controllervalue = GetEG1ControllerValue(itNoteOnEvent->Param.Note.Velocity);              double eg1controllervalue = GetEG1ControllerValue(itNoteOnEvent->Param.Note.Velocity);
198    
# Line 187  namespace LinuxSampler { Line 201  namespace LinuxSampler {
201    
202              TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);              TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);
203          } else {          } else {
204              GetSignalUnitRack()->Trigger();              pSignalUnitRack->Trigger();
205          }          }
206    
207  #ifdef CONFIG_INTERPOLATE_VOLUME  #ifdef CONFIG_INTERPOLATE_VOLUME
# Line 201  namespace LinuxSampler { Line 215  namespace LinuxSampler {
215      #else      #else
216          {          {
217              float finalVolume;              float finalVolume;
218              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
219                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pEG1->getLevel();                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pEG1->getLevel();
220              } else {              } else {
221                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * GetSignalUnitRack()->GetEndpointUnit()->GetVolume();                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pSignalUnitRack->GetEndpointUnit()->GetVolume();
222              }              }
223    
224              finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;              finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;
# Line 213  namespace LinuxSampler { Line 227  namespace LinuxSampler {
227      #endif      #endif
228  #endif  #endif
229    
230          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
231              // setup EG 2 (VCF Cutoff EG)              // setup EG 2 (VCF Cutoff EG)
232              {              {
233                  // get current value of EG2 controller                  // get current value of EG2 controller
# Line 292  namespace LinuxSampler { Line 306  namespace LinuxSampler {
306              VCFCutoffCtrl.controller    = 0;              VCFCutoffCtrl.controller    = 0;
307              VCFResonanceCtrl.controller = 0;              VCFResonanceCtrl.controller = 0;
308          }          }
309            
310            const bool bEq =
311                pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
312    
313            if (bEq) {
314                pEq->GetInChannelLeft()->Clear();
315                pEq->GetInChannelRight()->Clear();
316                pEq->RenderAudio(GetEngine()->pAudioOutputDevice->MaxSamplesPerCycle());
317            }
318    
319          return 0; // success          return 0; // success
320      }      }
321        
322        void AbstractVoice::SetSampleStartOffset() {
323            finalSynthesisParameters.dPos = RgnInfo.SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
324            Pos = RgnInfo.SampleStartOffset;
325        }
326    
327      /**      /**
328       *  Synthesizes the current audio fragment for this voice.       *  Synthesizes the current audio fragment for this voice.
# Line 305  namespace LinuxSampler { Line 333  namespace LinuxSampler {
333       *  @param Skip    - number of sample points to skip in output buffer       *  @param Skip    - number of sample points to skip in output buffer
334       */       */
335      void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {      void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
336            bool delay = false; // Whether the voice playback should be delayed for this call
337            
338            if (pSignalUnitRack != NULL) {
339                uint delaySteps = pSignalUnitRack->GetEndpointUnit()->DelayTrigger();
340                if (delaySteps > 0) { // delay on the endpoint unit means delay of the voice playback
341                    if (delaySteps >= Samples) {
342                        pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(Samples);
343                        delay = true;
344                    } else {
345                        pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(delaySteps);
346                        Samples -= delaySteps;
347                        Skip += delaySteps;
348                    }
349                }
350            }
351            
352          AbstractEngineChannel* pChannel = pEngineChannel;          AbstractEngineChannel* pChannel = pEngineChannel;
353          MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey);          MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey);
354    
355          const bool bVoiceRequiresDedicatedRouting =          const bool bVoiceRequiresDedicatedRouting =
356              pEngineChannel->GetFxSendCount() > 0 &&              pEngineChannel->GetFxSendCount() > 0 &&
357              (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);              (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend);
358            
359            const bool bEq =
360                pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && pEq->HasSupport();
361    
362          if (bVoiceRequiresDedicatedRouting) {          if (bEq) {
363                pEq->GetInChannelLeft()->Clear();
364                pEq->GetInChannelRight()->Clear();
365                finalSynthesisParameters.pOutLeft  = &pEq->GetInChannelLeft()->Buffer()[Skip];
366                finalSynthesisParameters.pOutRight = &pEq->GetInChannelRight()->Buffer()[Skip];
367                pSignalUnitRack->UpdateEqSettings(pEq);
368            } else if (bVoiceRequiresDedicatedRouting) {
369              finalSynthesisParameters.pOutLeft  = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];              finalSynthesisParameters.pOutLeft  = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip];
370              finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];              finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip];
371          } else {          } else {
# Line 352  namespace LinuxSampler { Line 405  namespace LinuxSampler {
405                  // drivers that use Samples < MaxSamplesPerCycle).                  // drivers that use Samples < MaxSamplesPerCycle).
406                  // End the EG1 here, at pos 0, with a shorter max fade                  // End the EG1 here, at pos 0, with a shorter max fade
407                  // out time.                  // out time.
408                  if (GetSignalUnitRack() == NULL) {                  if (pSignalUnitRack == NULL) {
409                      pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                      pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
410                  } else {                  } else {
411                      // TODO:                      pSignalUnitRack->EnterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
412                  }                  }
413                  itKillEvent = Pool<Event>::Iterator();                  itKillEvent = Pool<Event>::Iterator();
414              } else {              } else {
# Line 373  namespace LinuxSampler { Line 426  namespace LinuxSampler {
426    
427              // process MIDI control change and pitchbend events for this subfragment              // process MIDI control change and pitchbend events for this subfragment
428              processCCEvents(itCCEvent, iSubFragmentEnd);              processCCEvents(itCCEvent, iSubFragmentEnd);
429                uint8_t pan = MIDIPan;
430                if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CaluclatePan(pan);
431                
432                PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan]);
433                PanRightSmoother.update(AbstractEngine::PanCurve[pan]);
434    
435              finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend;              finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend;
436              float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();              float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
# Line 383  namespace LinuxSampler { Line 441  namespace LinuxSampler {
441              // process transition events (note on, note off & sustain pedal)              // process transition events (note on, note off & sustain pedal)
442              processTransitionEvents(itNoteEvent, iSubFragmentEnd);              processTransitionEvents(itNoteEvent, iSubFragmentEnd);
443              processGroupEvents(itGroupEvent, iSubFragmentEnd);              processGroupEvents(itGroupEvent, iSubFragmentEnd);
444                
445              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
446                  // if the voice was killed in this subfragment, or if the                  // if the voice was killed in this subfragment, or if the
447                  // filter EG is finished, switch EG1 to fade out stage                  // filter EG is finished, switch EG1 to fade out stage
448                  if ((itKillEvent && killPos <= iSubFragmentEnd) ||                  if ((itKillEvent && killPos <= iSubFragmentEnd) ||
# Line 430  namespace LinuxSampler { Line 488  namespace LinuxSampler {
488                  if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();                  if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
489                  if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());                  if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
490              } else {              } else {
491                  // if the voice was killed in this subfragment, or if the                  // if the voice was killed in this subfragment, enter fade out stage
492                  // filter EG is finished, switch EG1 to fade out stage                  if (itKillEvent && killPos <= iSubFragmentEnd) {
493                  /*if ((itKillEvent && killPos <= iSubFragmentEnd) ||                      pSignalUnitRack->EnterFadeOutStage();
494                      (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&                      itKillEvent = Pool<Event>::Iterator();
495                      pEG2->getSegmentType() == EG::segment_end)) {                  }
496                    
497                    // if the filter EG is finished, switch EG1 to fade out stage
498                    /*if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
499                        pEG2->getSegmentType() == EG::segment_end) {
500                      pEG1->enterFadeOutStage();                      pEG1->enterFadeOutStage();
501                      itKillEvent = Pool<Event>::Iterator();                      itKillEvent = Pool<Event>::Iterator();
502                  }*/                  }*/
503                  // TODO: ^^^                  // TODO: ^^^
504    
505                  fFinalVolume   *= GetSignalUnitRack()->GetEndpointUnit()->GetVolume();                  fFinalVolume   *= pSignalUnitRack->GetEndpointUnit()->GetVolume();
506                  fFinalCutoff    = GetSignalUnitRack()->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);                  fFinalCutoff    = pSignalUnitRack->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);
507                  fFinalResonance = GetSignalUnitRack()->GetEndpointUnit()->CalculateResonance(fFinalResonance);                  fFinalResonance = pSignalUnitRack->GetEndpointUnit()->CalculateResonance(fFinalResonance);
508                                    
509                  finalSynthesisParameters.fFinalPitch =                  finalSynthesisParameters.fFinalPitch =
510                      GetSignalUnitRack()->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);                      pSignalUnitRack->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);
511                                            
512              }              }
513                            
# Line 481  namespace LinuxSampler { Line 543  namespace LinuxSampler {
543                  fFinalVolume * VolumeRight * PanRightSmoother.render();                  fFinalVolume * VolumeRight * PanRightSmoother.render();
544  #endif  #endif
545              // render audio for one subfragment              // render audio for one subfragment
546              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);              if (!delay) RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
547    
548              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
549                  // stop the rendering if volume EG is finished                  // stop the rendering if volume EG is finished
550                  if (pEG1->getSegmentType() == EG::segment_end) break;                  if (pEG1->getSegmentType() == EG::segment_end) break;
551              } else {              } else {
552                  // stop the rendering if the endpoint unit is not active                  // stop the rendering if the endpoint unit is not active
553                  if (!GetSignalUnitRack()->GetEndpointUnit()->Active()) break;                  if (!pSignalUnitRack->GetEndpointUnit()->Active()) break;
554              }              }
555    
556              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
557    
558              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
559                  // increment envelopes' positions                  // increment envelopes' positions
560                  if (pEG1->active()) {                  if (pEG1->active()) {
561    
# Line 518  namespace LinuxSampler { Line 580  namespace LinuxSampler {
580                      }*/                      }*/
581                  // TODO: ^^^                  // TODO: ^^^
582                                    
583                  GetSignalUnitRack()->Increment();                  if (!delay) pSignalUnitRack->Increment();
584              }              }
585    
586              Pos = newPos;              Pos = newPos;
587              i = iSubFragmentEnd;              i = iSubFragmentEnd;
588          }          }
589            
590            if (delay) return;
591    
592          if (bVoiceRequiresDedicatedRouting) {          if (bVoiceRequiresDedicatedRouting) {
593                if (bEq) {
594                    pEq->RenderAudio(Samples);
595                    pEq->GetOutChannelLeft()->CopyTo(GetEngine()->pDedicatedVoiceChannelLeft, Samples);
596                    pEq->GetOutChannelRight()->CopyTo(GetEngine()->pDedicatedVoiceChannelRight, Samples);
597                }
598              optional<float> effectSendLevels[2] = {              optional<float> effectSendLevels[2] = {
599                  pMidiKeyInfo->ReverbSend,                  pMidiKeyInfo->ReverbSend,
600                  pMidiKeyInfo->ChorusSend                  pMidiKeyInfo->ChorusSend
601              };              };
602              GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);              GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples);
603            } else if (bEq) {
604                pEq->RenderAudio(Samples);
605                pEq->GetOutChannelLeft()->MixTo(pChannel->pChannelLeft, Samples);
606                pEq->GetOutChannelRight()->MixTo(pChannel->pChannelRight, Samples);
607          }          }
608      }      }
609    
# Line 550  namespace LinuxSampler { Line 623  namespace LinuxSampler {
623                  if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {                  if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
624                      processResonanceEvent(itEvent);                      processResonanceEvent(itEvent);
625                  }                  }
626                  if (GetSignalUnitRack() == NULL) {                  if (pSignalUnitRack == NULL) {
627                      if (itEvent->Param.CC.Controller == pLFO1->ExtController) {                      if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
628                          pLFO1->update(itEvent->Param.CC.Value);                          pLFO1->update(itEvent->Param.CC.Value);
629                      }                      }
# Line 564  namespace LinuxSampler { Line 637  namespace LinuxSampler {
637                  if (itEvent->Param.CC.Controller == 7) { // volume                  if (itEvent->Param.CC.Controller == 7) { // volume
638                      VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);                      VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]);
639                  } else if (itEvent->Param.CC.Controller == 10) { // panpot                  } else if (itEvent->Param.CC.Controller == 10) { // panpot
640                      PanLeftSmoother.update(AbstractEngine::PanCurve[128 - itEvent->Param.CC.Value]);                      MIDIPan = itEvent->Param.CC.Value;
                     PanRightSmoother.update(AbstractEngine::PanCurve[itEvent->Param.CC.Value]);  
641                  }                  }
642              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
643                  processPitchEvent(itEvent);                  processPitchEvent(itEvent);
644              }              }
645    
646              ProcessCCEvent(itEvent);              ProcessCCEvent(itEvent);
647              if (GetSignalUnitRack() != NULL) {              if (pSignalUnitRack != NULL) {
648                  GetSignalUnitRack()->ProcessCCEvent(itEvent);                  pSignalUnitRack->ProcessCCEvent(itEvent);
649              }              }
650          }          }
651      }      }
# Line 606  namespace LinuxSampler { Line 678  namespace LinuxSampler {
678                  if (itEvent->Type == Event::type_release) {                  if (itEvent->Type == Event::type_release) {
679                      EnterReleaseStage();                      EnterReleaseStage();
680                  } else if (itEvent->Type == Event::type_cancel_release) {                  } else if (itEvent->Type == Event::type_cancel_release) {
681                      if (GetSignalUnitRack() == NULL) {                      if (pSignalUnitRack == NULL) {
682                          pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
683                          pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
684                      } else {                      } else {
685                          GetSignalUnitRack()->CancelRelease();                          pSignalUnitRack->CancelRelease();
686                      }                      }
687                  }                  }
688              }              }
# Line 638  namespace LinuxSampler { Line 710  namespace LinuxSampler {
710       * @param itNoteOffEvent - event which causes this voice to die soon       * @param itNoteOffEvent - event which causes this voice to die soon
711       */       */
712      void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {      void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
713          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
714              const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());              const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
715              pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;              pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
716          } else {          } else {
# Line 705  namespace LinuxSampler { Line 777  namespace LinuxSampler {
777      }      }
778    
779      void AbstractVoice::EnterReleaseStage() {      void AbstractVoice::EnterReleaseStage() {
780          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
781              pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);              pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
782              pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);              pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
783          } else {          } else {
784              GetSignalUnitRack()->EnterReleaseStage();              pSignalUnitRack->EnterReleaseStage();
785          }          }
786      }      }
787    
788      bool AbstractVoice::EG1Finished() {      bool AbstractVoice::EG1Finished() {
789          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
790              return pEG1->getSegmentType() == EG::segment_end;              return pEG1->getSegmentType() == EG::segment_end;
791          } else {          } else {
792              return !GetSignalUnitRack()->GetEndpointUnit()->Active();              return !pSignalUnitRack->GetEndpointUnit()->Active();
793          }          }
794      }      }
795    

Legend:
Removed from v.2205  
changed lines
  Added in v.2327

  ViewVC Help
Powered by ViewVC