/[svn]/linuxsampler/trunk/src/engines/gig/Voice.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/gig/Voice.cpp

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

revision 799 by persson, Sat Nov 5 10:59:37 2005 UTC revision 831 by persson, Sat Jan 28 16:55:30 2006 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 Christian Schoenebeck                              *   *   Copyright (C) 2005, 2006 Christian Schoenebeck                        *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   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 136  namespace LinuxSampler { namespace gig { Line 136  namespace LinuxSampler { namespace gig {
136                  CrossfadeVolume = 1.0f;                  CrossfadeVolume = 1.0f;
137          }          }
138    
139          PanLeft  = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) /  63.0f;          PanLeft  = Engine::PanCurve[64 - pDimRgn->Pan];
140          PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;          PanRight = Engine::PanCurve[64 + pDimRgn->Pan];
141    
142          finalSynthesisParameters.dPos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)          finalSynthesisParameters.dPos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
143          Pos = pDimRgn->SampleStartOffset;          Pos = pDimRgn->SampleStartOffset;
# Line 223  namespace LinuxSampler { namespace gig { Line 223  namespace LinuxSampler { namespace gig {
223                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
224          }          }
225    
226            // setup initial volume in synthesis parameters
227            fFinalVolume = getVolume() * EG1.getLevel();
228            finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * PanLeft * pEngineChannel->GlobalPanLeft;
229            finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight * pEngineChannel->GlobalPanRight;
230    
231    
232          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
233          {          {
# Line 264  namespace LinuxSampler { namespace gig { Line 269  namespace LinuxSampler { namespace gig {
269    
270          // setup EG 3 (VCO EG)          // setup EG 3 (VCO EG)
271          {          {
272            double eg3depth = RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);              // if portamento mode is on, we dedicate EG3 purely for portamento, otherwise if portamento is off we do as told by the patch
273            EG3.trigger(eg3depth, pDimRgn->EG3Attack, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);              bool  bPortamento = pEngineChannel->PortamentoMode && pEngineChannel->PortamentoPos >= 0.0f;
274                float eg3depth = (bPortamento)
275                                     ? RTMath::CentsToFreqRatio((pEngineChannel->PortamentoPos - (float) MIDIKey) * 100)
276                                     : RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);
277                float eg3time = (bPortamento)
278                                    ? pEngineChannel->PortamentoTime
279                                    : pDimRgn->EG3Attack;
280                EG3.trigger(eg3depth, eg3time, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
281                dmsg(5,("PortamentoPos=%f, depth=%f, time=%f\n", pEngineChannel->PortamentoPos, eg3depth, eg3time));
282          }          }
283    
284    
# Line 690  namespace LinuxSampler { namespace gig { Line 703  namespace LinuxSampler { namespace gig {
703    
704      void Voice::processCrossFadeEvent(RTList<Event>::Iterator& itEvent) {      void Voice::processCrossFadeEvent(RTList<Event>::Iterator& itEvent) {
705          CrossfadeVolume = CrossfadeAttenuation(itEvent->Param.CC.Value);          CrossfadeVolume = CrossfadeAttenuation(itEvent->Param.CC.Value);
706            fFinalVolume = getVolume();
707        }
708    
709        float Voice::getVolume() {
710          #if CONFIG_PROCESS_MUTED_CHANNELS          #if CONFIG_PROCESS_MUTED_CHANNELS
711          const float effectiveVolume = CrossfadeVolume * Volume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume);          return pEngineChannel->GetMute() ? 0 : (Volume * CrossfadeVolume * pEngineChannel->GlobalVolume);
712          #else          #else
713          const float effectiveVolume = CrossfadeVolume * Volume * pEngineChannel->GlobalVolume;          return Volume * CrossfadeVolume * pEngineChannel->GlobalVolume;
714          #endif          #endif
         fFinalVolume = effectiveVolume;  
715      }      }
716    
717      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
# Line 747  namespace LinuxSampler { namespace gig { Line 763  namespace LinuxSampler { namespace gig {
763          uint killPos;          uint killPos;
764          if (itKillEvent) killPos = RTMath::Min(itKillEvent->FragmentPos(), pEngine->MaxFadeOutPos);          if (itKillEvent) killPos = RTMath::Min(itKillEvent->FragmentPos(), pEngine->MaxFadeOutPos);
765    
766            float fFinalPanLeft = PanLeft * pEngineChannel->GlobalPanLeft;
767            float fFinalPanRight = PanRight * pEngineChannel->GlobalPanRight;
768    
769          uint i = Skip;          uint i = Skip;
770          while (i < Samples) {          while (i < Samples) {
771              int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);              int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
772    
773              // initialize all final synthesis parameters              // initialize all final synthesis parameters
774              finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;              finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;
775              #if CONFIG_PROCESS_MUTED_CHANNELS              fFinalVolume    = getVolume();
             fFinalVolume = this->Volume * this->CrossfadeVolume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume);  
             #else  
             fFinalVolume = this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume;  
             #endif  
776              fFinalCutoff    = VCFCutoffCtrl.fvalue;              fFinalCutoff    = VCFCutoffCtrl.fvalue;
777              fFinalResonance = VCFResonanceCtrl.fvalue;              fFinalResonance = VCFResonanceCtrl.fvalue;
778    
# Line 796  namespace LinuxSampler { namespace gig { Line 811  namespace LinuxSampler { namespace gig {
811                      fFinalCutoff *= EG2.getLevel();                      fFinalCutoff *= EG2.getLevel();
812                      break; // noop                      break; // noop
813              }              }
814              if (EG3.active()) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(EG3.render());              if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
815    
816              // process low frequency oscillators              // process low frequency oscillators
817              if (bLFO1Enabled) fFinalVolume *= pLFO1->render();              if (bLFO1Enabled) fFinalVolume *= pLFO1->render();
# Line 817  namespace LinuxSampler { namespace gig { Line 832  namespace LinuxSampler { namespace gig {
832              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
833    
834              // prepare final synthesis parameters structure              // prepare final synthesis parameters structure
             finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * PanLeft;  
             finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight;  
835              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;
836    #ifdef CONFIG_INTERPOLATE_VOLUME
837                finalSynthesisParameters.fFinalVolumeDeltaLeft  =
838                    (fFinalVolume * fFinalPanLeft - finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
839                finalSynthesisParameters.fFinalVolumeDeltaRight =
840                    (fFinalVolume * fFinalPanRight - finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
841    #else
842                finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * fFinalPanLeft;
843                finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * fFinalPanRight;
844    #endif
845              // render audio for one subfragment              // render audio for one subfragment
846              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
847    
848                // stop the rendering if volume EG is finished
849                if (EG1.getSegmentType() == EGADSR::segment_end) break;
850    
851              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
852    
853              // increment envelopes' positions              // increment envelopes' positions
# Line 849  namespace LinuxSampler { namespace gig { Line 873  namespace LinuxSampler { namespace gig {
873          }          }
874      }      }
875    
876        /** @brief Update current portamento position.
877         *
878         * Will be called when portamento mode is enabled to get the final
879         * portamento position of this active voice from where the next voice(s)
880         * might continue to slide on.
881         *
882         * @param itNoteOffEvent - event which causes this voice to die soon
883         */
884        void Voice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
885            const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
886            pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
887        }
888    
889      /**      /**
890       *  Immediately kill the voice. This method should not be used to kill       *  Immediately kill the voice. This method should not be used to kill
891       *  a normal, active voice, because it doesn't take care of things like       *  a normal, active voice, because it doesn't take care of things like

Legend:
Removed from v.799  
changed lines
  Added in v.831

  ViewVC Help
Powered by ViewVC