/[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 830 by persson, Sun Jan 15 18:23:11 2006 UTC revision 841 by persson, Sat Mar 4 16:23:53 2006 UTC
# 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          // setup initial volume in synthesis parameters
235          fFinalVolume = getVolume() * EG1.getLevel();  #ifdef CONFIG_PROCESS_MUTED_CHANNELS
236          finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * PanLeft;          if (pEngineChannel->GetMute()) {
237          finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight;              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 316  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 359  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 402  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 645  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 664  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 687  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 701  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);  
         fFinalVolume = getVolume();  
     }  
   
     float Voice::getVolume() {  
         #if CONFIG_PROCESS_MUTED_CHANNELS  
         return pEngineChannel->GetMute() ? 0 : (Volume * CrossfadeVolume * pEngineChannel->GlobalVolume);  
         #else  
         return Volume * CrossfadeVolume * pEngineChannel->GlobalVolume;  
         #endif  
     }  
   
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 769  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;
             fFinalVolume    = getVolume();  
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 832  namespace LinuxSampler { namespace gig { Line 857  namespace LinuxSampler { namespace gig {
857              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;
858  #ifdef CONFIG_INTERPOLATE_VOLUME  #ifdef CONFIG_INTERPOLATE_VOLUME
859              finalSynthesisParameters.fFinalVolumeDeltaLeft  =              finalSynthesisParameters.fFinalVolumeDeltaLeft  =
860                  (fFinalVolume * PanLeft - finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;                  (fFinalVolume * VolumeLeft  * PanLeftSmoother.render() -
861                     finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
862              finalSynthesisParameters.fFinalVolumeDeltaRight =              finalSynthesisParameters.fFinalVolumeDeltaRight =
863                  (fFinalVolume * PanRight - finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;                  (fFinalVolume * VolumeRight * PanRightSmoother.render() -
864                     finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
865  #else  #else
866              finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * PanLeft;              finalSynthesisParameters.fFinalVolumeLeft  =
867              finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight;                  fFinalVolume * VolumeLeft  * PanLeftSmoother.render();
868                finalSynthesisParameters.fFinalVolumeRight =
869                    fFinalVolume * VolumeRight * PanRightSmoother.render();
870  #endif  #endif
871              // render audio for one subfragment              // render audio for one subfragment
872              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);

Legend:
Removed from v.830  
changed lines
  Added in v.841

  ViewVC Help
Powered by ViewVC