/[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 841 by persson, Sat Mar 4 16:23:53 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 104  namespace LinuxSampler { namespace gig { Line 104  namespace LinuxSampler { namespace gig {
104          // calculate volume          // calculate volume
105          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
106    
107          Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)          float volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
108    
109          Volume *= pDimRgn->SampleAttenuation;          volume *= pDimRgn->SampleAttenuation;
110    
111          // the volume of release triggered samples depends on note length          // the volume of release triggered samples depends on note length
112          if (Type == type_release_trigger) {          if (Type == type_release_trigger) {
# Line 114  namespace LinuxSampler { namespace gig { Line 114  namespace LinuxSampler { namespace gig {
114                                       pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;                                       pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
115              float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;              float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
116              if (attenuation <= 0) return -1;              if (attenuation <= 0) return -1;
117              Volume *= attenuation;              volume *= attenuation;
118          }          }
119    
120          // select channel mode (mono or stereo)          // select channel mode (mono or stereo)
121          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
122    
123          // get starting crossfade volume level          // get starting crossfade volume level
124            float crossfadeVolume;
125          switch (pDimRgn->AttenuationController.type) {          switch (pDimRgn->AttenuationController.type) {
126              case ::gig::attenuation_ctrl_t::type_channelaftertouch:              case ::gig::attenuation_ctrl_t::type_channelaftertouch:
127                  CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet                  crossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
128                  break;                  break;
129              case ::gig::attenuation_ctrl_t::type_velocity:              case ::gig::attenuation_ctrl_t::type_velocity:
130                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity)];
131                  break;                  break;
132              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
133                  CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number])];
134                  break;                  break;
135              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
136              default:              default:
137                  CrossfadeVolume = 1.0f;                  crossfadeVolume = 1.0f;
138          }          }
139    
140          PanLeft  = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) /  63.0f;          VolumeLeft  = volume * Engine::PanCurve[64 - pDimRgn->Pan];
141          PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;          VolumeRight = volume * Engine::PanCurve[64 + pDimRgn->Pan];
142    
143            float subfragmentRate = pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
144            CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
145            VolumeSmoother.trigger(pEngineChannel->GlobalVolume, subfragmentRate);
146            PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);
147            PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);
148    
149          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)
150          Pos = pDimRgn->SampleStartOffset;          Pos = pDimRgn->SampleStartOffset;
# Line 223  namespace LinuxSampler { namespace gig { Line 230  namespace LinuxSampler { namespace gig {
230                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
231          }          }
232    
233    #ifdef CONFIG_INTERPOLATE_VOLUME
234            // setup initial volume in synthesis parameters
235    #ifdef CONFIG_PROCESS_MUTED_CHANNELS
236            if (pEngineChannel->GetMute()) {
237                finalSynthesisParameters.fFinalVolumeLeft  = 0;
238                finalSynthesisParameters.fFinalVolumeRight = 0;
239            }
240            else
241    #else
242            {
243                float finalVolume = pEngineChannel->GlobalVolume * crossfadeVolume * EG1.getLevel();
244    
245                finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;
246                finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;
247            }
248    #endif
249    #endif
250    
251          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
252          {          {
# Line 264  namespace LinuxSampler { namespace gig { Line 288  namespace LinuxSampler { namespace gig {
288    
289          // setup EG 3 (VCO EG)          // setup EG 3 (VCO EG)
290          {          {
291            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
292            EG3.trigger(eg3depth, pDimRgn->EG3Attack, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);              bool  bPortamento = pEngineChannel->PortamentoMode && pEngineChannel->PortamentoPos >= 0.0f;
293                float eg3depth = (bPortamento)
294                                     ? RTMath::CentsToFreqRatio((pEngineChannel->PortamentoPos - (float) MIDIKey) * 100)
295                                     : RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);
296                float eg3time = (bPortamento)
297                                    ? pEngineChannel->PortamentoTime
298                                    : pDimRgn->EG3Attack;
299                EG3.trigger(eg3depth, eg3time, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
300                dmsg(5,("PortamentoPos=%f, depth=%f, time=%f\n", pEngineChannel->PortamentoPos, eg3depth, eg3time));
301          }          }
302    
303    
# Line 303  namespace LinuxSampler { namespace gig { Line 335  namespace LinuxSampler { namespace gig {
335                      pLFO1->ExtController = 0; // no external controller                      pLFO1->ExtController = 0; // no external controller
336                      bLFO1Enabled         = false;                      bLFO1Enabled         = false;
337              }              }
338              if (bLFO1Enabled) pLFO1->trigger(pDimRgn->LFO1Frequency,              if (bLFO1Enabled) {
339                                               start_level_max,                  pLFO1->trigger(pDimRgn->LFO1Frequency,
340                                               lfo1_internal_depth,                                 start_level_max,
341                                               pDimRgn->LFO1ControlDepth,                                 lfo1_internal_depth,
342                                               pDimRgn->LFO1FlipPhase,                                 pDimRgn->LFO1ControlDepth,
343                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 pDimRgn->LFO1FlipPhase,
344                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
345                    pLFO1->update(pLFO1->ExtController ? pEngineChannel->ControllerTable[pLFO1->ExtController] : 0);
346                }
347          }          }
348    
349    
# Line 346  namespace LinuxSampler { namespace gig { Line 381  namespace LinuxSampler { namespace gig {
381                      pLFO2->ExtController = 0; // no external controller                      pLFO2->ExtController = 0; // no external controller
382                      bLFO2Enabled         = false;                      bLFO2Enabled         = false;
383              }              }
384              if (bLFO2Enabled) pLFO2->trigger(pDimRgn->LFO2Frequency,              if (bLFO2Enabled) {
385                                               start_level_max,                  pLFO2->trigger(pDimRgn->LFO2Frequency,
386                                               lfo2_internal_depth,                                 start_level_max,
387                                               pDimRgn->LFO2ControlDepth,                                 lfo2_internal_depth,
388                                               pDimRgn->LFO2FlipPhase,                                 pDimRgn->LFO2ControlDepth,
389                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 pDimRgn->LFO2FlipPhase,
390                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
391                    pLFO2->update(pLFO2->ExtController ? pEngineChannel->ControllerTable[pLFO2->ExtController] : 0);
392                }
393          }          }
394    
395    
# Line 389  namespace LinuxSampler { namespace gig { Line 427  namespace LinuxSampler { namespace gig {
427                      pLFO3->ExtController = 0; // no external controller                      pLFO3->ExtController = 0; // no external controller
428                      bLFO3Enabled         = false;                      bLFO3Enabled         = false;
429              }              }
430              if (bLFO3Enabled) pLFO3->trigger(pDimRgn->LFO3Frequency,              if (bLFO3Enabled) {
431                                               start_level_mid,                  pLFO3->trigger(pDimRgn->LFO3Frequency,
432                                               lfo3_internal_depth,                                 start_level_mid,
433                                               pDimRgn->LFO3ControlDepth,                                 lfo3_internal_depth,
434                                               false,                                 pDimRgn->LFO3ControlDepth,
435                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 false,
436                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
437                    pLFO3->update(pLFO3->ExtController ? pEngineChannel->ControllerTable[pLFO3->ExtController] : 0);
438                }
439          }          }
440    
441    
# Line 632  namespace LinuxSampler { namespace gig { Line 673  namespace LinuxSampler { namespace gig {
673       * for the given time.       * for the given time.
674       *       *
675       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
676       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
677       */       */
678      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
679          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
# Line 651  namespace LinuxSampler { namespace gig { Line 692  namespace LinuxSampler { namespace gig {
692       * the given time.       * the given time.
693       *       *
694       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
695       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
696       */       */
697      void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {      void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
698          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
# Line 674  namespace LinuxSampler { namespace gig { Line 715  namespace LinuxSampler { namespace gig {
715                  }                  }
716                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
717                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {
718                      processCrossFadeEvent(itEvent);                      CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
719                    }
720                    if (itEvent->Param.CC.Controller == 7) { // volume
721                        VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value] * CONFIG_GLOBAL_ATTENUATION);
722                    } else if (itEvent->Param.CC.Controller == 10) { // panpot
723                        PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]);
724                        PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]);
725                  }                  }
726              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
727                  processPitchEvent(itEvent);                  processPitchEvent(itEvent);
# Line 688  namespace LinuxSampler { namespace gig { Line 735  namespace LinuxSampler { namespace gig {
735          PitchBend = pitch;          PitchBend = pitch;
736      }      }
737    
     void Voice::processCrossFadeEvent(RTList<Event>::Iterator& itEvent) {  
         CrossfadeVolume = CrossfadeAttenuation(itEvent->Param.CC.Value);  
         #if CONFIG_PROCESS_MUTED_CHANNELS  
         const float effectiveVolume = CrossfadeVolume * Volume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume);  
         #else  
         const float effectiveVolume = CrossfadeVolume * Volume * pEngineChannel->GlobalVolume;  
         #endif  
         fFinalVolume = effectiveVolume;  
     }  
   
738      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
739          int ccvalue = itEvent->Param.CC.Value;          int ccvalue = itEvent->Param.CC.Value;
740          if (VCFCutoffCtrl.value == ccvalue) return;          if (VCFCutoffCtrl.value == ccvalue) return;
# Line 753  namespace LinuxSampler { namespace gig { Line 790  namespace LinuxSampler { namespace gig {
790    
791              // initialize all final synthesis parameters              // initialize all final synthesis parameters
792              finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;              finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;
             #if CONFIG_PROCESS_MUTED_CHANNELS  
             fFinalVolume = this->Volume * this->CrossfadeVolume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume);  
             #else  
             fFinalVolume = this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume;  
             #endif  
793              fFinalCutoff    = VCFCutoffCtrl.fvalue;              fFinalCutoff    = VCFCutoffCtrl.fvalue;
794              fFinalResonance = VCFResonanceCtrl.fvalue;              fFinalResonance = VCFResonanceCtrl.fvalue;
795    
796              // process MIDI control change and pitchbend events for this subfragment              // process MIDI control change and pitchbend events for this subfragment
797              processCCEvents(itCCEvent, iSubFragmentEnd);              processCCEvents(itCCEvent, iSubFragmentEnd);
798    
799                float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
800    #ifdef CONFIG_PROCESS_MUTED_CHANNELS
801                if (pEngineChannel->GetMute()) fFinalVolume = 0;
802    #endif
803    
804              // process transition events (note on, note off & sustain pedal)              // process transition events (note on, note off & sustain pedal)
805              processTransitionEvents(itNoteEvent, iSubFragmentEnd);              processTransitionEvents(itNoteEvent, iSubFragmentEnd);
806    
# Line 796  namespace LinuxSampler { namespace gig { Line 833  namespace LinuxSampler { namespace gig {
833                      fFinalCutoff *= EG2.getLevel();                      fFinalCutoff *= EG2.getLevel();
834                      break; // noop                      break; // noop
835              }              }
836              if (EG3.active()) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(EG3.render());              if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
837    
838              // process low frequency oscillators              // process low frequency oscillators
839              if (bLFO1Enabled) fFinalVolume *= pLFO1->render();              if (bLFO1Enabled) fFinalVolume *= pLFO1->render();
# Line 817  namespace LinuxSampler { namespace gig { Line 854  namespace LinuxSampler { namespace gig {
854              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
855    
856              // prepare final synthesis parameters structure              // prepare final synthesis parameters structure
             finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * PanLeft;  
             finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight;  
857              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;
858    #ifdef CONFIG_INTERPOLATE_VOLUME
859                finalSynthesisParameters.fFinalVolumeDeltaLeft  =
860                    (fFinalVolume * VolumeLeft  * PanLeftSmoother.render() -
861                     finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
862                finalSynthesisParameters.fFinalVolumeDeltaRight =
863                    (fFinalVolume * VolumeRight * PanRightSmoother.render() -
864                     finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
865    #else
866                finalSynthesisParameters.fFinalVolumeLeft  =
867                    fFinalVolume * VolumeLeft  * PanLeftSmoother.render();
868                finalSynthesisParameters.fFinalVolumeRight =
869                    fFinalVolume * VolumeRight * PanRightSmoother.render();
870    #endif
871              // render audio for one subfragment              // render audio for one subfragment
872              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
873    
874                // stop the rendering if volume EG is finished
875                if (EG1.getSegmentType() == EGADSR::segment_end) break;
876    
877              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
878    
879              // increment envelopes' positions              // increment envelopes' positions
# Line 849  namespace LinuxSampler { namespace gig { Line 899  namespace LinuxSampler { namespace gig {
899          }          }
900      }      }
901    
902        /** @brief Update current portamento position.
903         *
904         * Will be called when portamento mode is enabled to get the final
905         * portamento position of this active voice from where the next voice(s)
906         * might continue to slide on.
907         *
908         * @param itNoteOffEvent - event which causes this voice to die soon
909         */
910        void Voice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
911            const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
912            pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
913        }
914    
915      /**      /**
916       *  Immediately kill the voice. This method should not be used to kill       *  Immediately kill the voice. This method should not be used to kill
917       *  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.841

  ViewVC Help
Powered by ViewVC