/[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 831 by persson, Sat Jan 28 16:55:30 2006 UTC revision 832 by persson, Sun Feb 5 10:24:05 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  = Engine::PanCurve[64 - pDimRgn->Pan];          VolumeLeft  = volume * Engine::PanCurve[64 - pDimRgn->Pan];
141          PanRight = Engine::PanCurve[64 + pDimRgn->Pan];          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 * pEngineChannel->GlobalPanLeft;          if (pEngineChannel->GetMute()) {
237          finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight * pEngineChannel->GlobalPanRight;              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 645  namespace LinuxSampler { namespace gig { Line 664  namespace LinuxSampler { namespace gig {
664       * for the given time.       * for the given time.
665       *       *
666       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
667       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
668       */       */
669      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
670          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
# Line 664  namespace LinuxSampler { namespace gig { Line 683  namespace LinuxSampler { namespace gig {
683       * the given time.       * the given time.
684       *       *
685       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
686       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
687       */       */
688      void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {      void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
689          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
# Line 687  namespace LinuxSampler { namespace gig { Line 706  namespace LinuxSampler { namespace gig {
706                  }                  }
707                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
708                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {
709                      processCrossFadeEvent(itEvent);                      CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
710                    }
711                    if (itEvent->Param.CC.Controller == 7) { // volume
712                        VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value] * CONFIG_GLOBAL_ATTENUATION);
713                    } else if (itEvent->Param.CC.Controller == 10) { // panpot
714                        PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]);
715                        PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]);
716                  }                  }
717              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
718                  processPitchEvent(itEvent);                  processPitchEvent(itEvent);
# Line 701  namespace LinuxSampler { namespace gig { Line 726  namespace LinuxSampler { namespace gig {
726          PitchBend = pitch;          PitchBend = pitch;
727      }      }
728    
     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  
     }  
   
729      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
730          int ccvalue = itEvent->Param.CC.Value;          int ccvalue = itEvent->Param.CC.Value;
731          if (VCFCutoffCtrl.value == ccvalue) return;          if (VCFCutoffCtrl.value == ccvalue) return;
# Line 763  namespace LinuxSampler { namespace gig { Line 775  namespace LinuxSampler { namespace gig {
775          uint killPos;          uint killPos;
776          if (itKillEvent) killPos = RTMath::Min(itKillEvent->FragmentPos(), pEngine->MaxFadeOutPos);          if (itKillEvent) killPos = RTMath::Min(itKillEvent->FragmentPos(), pEngine->MaxFadeOutPos);
777    
         float fFinalPanLeft = PanLeft * pEngineChannel->GlobalPanLeft;  
         float fFinalPanRight = PanRight * pEngineChannel->GlobalPanRight;  
   
778          uint i = Skip;          uint i = Skip;
779          while (i < Samples) {          while (i < Samples) {
780              int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);              int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
781    
782              // initialize all final synthesis parameters              // initialize all final synthesis parameters
783              finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;              finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;
             fFinalVolume    = getVolume();  
784              fFinalCutoff    = VCFCutoffCtrl.fvalue;              fFinalCutoff    = VCFCutoffCtrl.fvalue;
785              fFinalResonance = VCFResonanceCtrl.fvalue;              fFinalResonance = VCFResonanceCtrl.fvalue;
786    
787              // process MIDI control change and pitchbend events for this subfragment              // process MIDI control change and pitchbend events for this subfragment
788              processCCEvents(itCCEvent, iSubFragmentEnd);              processCCEvents(itCCEvent, iSubFragmentEnd);
789    
790                float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
791    #ifdef CONFIG_PROCESS_MUTED_CHANNELS
792                if (pEngineChannel->GetMute()) fFinalVolume = 0;
793    #endif
794    
795              // process transition events (note on, note off & sustain pedal)              // process transition events (note on, note off & sustain pedal)
796              processTransitionEvents(itNoteEvent, iSubFragmentEnd);              processTransitionEvents(itNoteEvent, iSubFragmentEnd);
797    
# Line 835  namespace LinuxSampler { namespace gig { Line 848  namespace LinuxSampler { namespace gig {
848              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;
849  #ifdef CONFIG_INTERPOLATE_VOLUME  #ifdef CONFIG_INTERPOLATE_VOLUME
850              finalSynthesisParameters.fFinalVolumeDeltaLeft  =              finalSynthesisParameters.fFinalVolumeDeltaLeft  =
851                  (fFinalVolume * fFinalPanLeft - finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;                  (fFinalVolume * VolumeLeft  * PanLeftSmoother.render() -
852                     finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
853              finalSynthesisParameters.fFinalVolumeDeltaRight =              finalSynthesisParameters.fFinalVolumeDeltaRight =
854                  (fFinalVolume * fFinalPanRight - finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;                  (fFinalVolume * VolumeRight * PanRightSmoother.render() -
855                     finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
856  #else  #else
857              finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * fFinalPanLeft;              finalSynthesisParameters.fFinalVolumeLeft  =
858              finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * fFinalPanRight;                  fFinalVolume * VolumeLeft  * PanLeftSmoother.render();
859                finalSynthesisParameters.fFinalVolumeRight =
860                    fFinalVolume * VolumeRight * PanRightSmoother.render();
861  #endif  #endif
862              // render audio for one subfragment              // render audio for one subfragment
863              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);

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

  ViewVC Help
Powered by ViewVC