/[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 2218 by iliev, Thu Jul 28 08:05:57 2011 UTC revision 2322 by iliev, Sun Feb 26 09:09:19 2012 UTC
# 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 100  namespace LinuxSampler { Line 112  namespace LinuxSampler {
112          Type            = VoiceType;          Type            = VoiceType;
113          MIDIKey         = itNoteOnEvent->Param.Note.Key;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
114          MIDIVelocity    = itNoteOnEvent->Param.Note.Velocity;          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 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      }      }
# Line 310  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 378  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 388  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 (pSignalUnitRack == 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
# Line 435  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                  }*/                  }*/
# Line 486  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 (pSignalUnitRack == NULL) {              if (pSignalUnitRack == NULL) {
549                  // stop the rendering if volume EG is finished                  // stop the rendering if volume EG is finished
# Line 523  namespace LinuxSampler { Line 580  namespace LinuxSampler {
580                      }*/                      }*/
581                  // TODO: ^^^                  // TODO: ^^^
582                                    
583                  pSignalUnitRack->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 569  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);

Legend:
Removed from v.2218  
changed lines
  Added in v.2322

  ViewVC Help
Powered by ViewVC