/[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 865 by persson, Sun May 14 07:15:52 2006 UTC revision 1038 by persson, Sat Feb 3 15:33:00 2007 UTC
# Line 29  Line 29 
29    
30  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
31    
     const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());  
   
     float Voice::CalculateFilterCutoffCoeff() {  
         return log(CONFIG_FILTER_CUTOFF_MAX / CONFIG_FILTER_CUTOFF_MIN);  
     }  
   
32      Voice::Voice() {      Voice::Voice() {
33          pEngine     = NULL;          pEngine     = NULL;
34          pDiskThread = NULL;          pDiskThread = NULL;
# Line 85  namespace LinuxSampler { namespace gig { Line 79  namespace LinuxSampler { namespace gig {
79      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) {      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) {
80          this->pEngineChannel = pEngineChannel;          this->pEngineChannel = pEngineChannel;
81          this->pDimRgn        = pDimRgn;          this->pDimRgn        = pDimRgn;
82            Orphan = false;
83    
84          #if CONFIG_DEVMODE          #if CONFIG_DEVMODE
85          if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging          if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
# Line 104  namespace LinuxSampler { namespace gig { Line 99  namespace LinuxSampler { namespace gig {
99          // calculate volume          // calculate volume
100          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
101    
102          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)          // For 16 bit samples, we downscale by 32768 to convert from
103            // int16 value range to DSP value range (which is
104            // -1.0..1.0). For 24 bit, we downscale from int32.
105            float volume = velocityAttenuation / (pSample->BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
106    
107          volume *= pDimRgn->SampleAttenuation;          volume *= pDimRgn->SampleAttenuation * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
108    
109          // the volume of release triggered samples depends on note length          // the volume of release triggered samples depends on note length
110          if (Type == type_release_trigger) {          if (Type == type_release_trigger) {
# Line 119  namespace LinuxSampler { namespace gig { Line 117  namespace LinuxSampler { namespace gig {
117    
118          // select channel mode (mono or stereo)          // select channel mode (mono or stereo)
119          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
120            // select bit depth (16 or 24)
121            SYNTHESIS_MODE_SET_BITDEPTH24(SynthesisMode, pSample->BitDepth == 24);
122    
123          // get starting crossfade volume level          // get starting crossfade volume level
124          float crossfadeVolume;          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 = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[128])];
128                  break;                  break;
129              case ::gig::attenuation_ctrl_t::type_velocity:              case ::gig::attenuation_ctrl_t::type_velocity:
130                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity)];                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity)];
# Line 142  namespace LinuxSampler { namespace gig { Line 142  namespace LinuxSampler { namespace gig {
142    
143          float subfragmentRate = pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          float subfragmentRate = pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
144          CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);          CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
145          VolumeSmoother.trigger(pEngineChannel->GlobalVolume, subfragmentRate);          VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);
146          PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);          PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);
147          PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);          PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);
148    
# Line 201  namespace LinuxSampler { namespace gig { Line 201  namespace LinuxSampler { namespace gig {
201                      eg1controllervalue = 0;                      eg1controllervalue = 0;
202                      break;                      break;
203                  case ::gig::eg1_ctrl_t::type_channelaftertouch:                  case ::gig::eg1_ctrl_t::type_channelaftertouch:
204                      eg1controllervalue = 0; // TODO: aftertouch not yet supported                      eg1controllervalue = pEngineChannel->ControllerTable[128];
205                      break;                      break;
206                  case ::gig::eg1_ctrl_t::type_velocity:                  case ::gig::eg1_ctrl_t::type_velocity:
207                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
# Line 242  namespace LinuxSampler { namespace gig { Line 242  namespace LinuxSampler { namespace gig {
242          else          else
243  #else  #else
244          {          {
245              float finalVolume = pEngineChannel->GlobalVolume * crossfadeVolume * EG1.getLevel();              float finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * EG1.getLevel();
246    
247              finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;              finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;
248              finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;              finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;
# Line 259  namespace LinuxSampler { namespace gig { Line 259  namespace LinuxSampler { namespace gig {
259                      eg2controllervalue = 0;                      eg2controllervalue = 0;
260                      break;                      break;
261                  case ::gig::eg2_ctrl_t::type_channelaftertouch:                  case ::gig::eg2_ctrl_t::type_channelaftertouch:
262                      eg2controllervalue = 0; // TODO: aftertouch not yet supported                      eg2controllervalue = pEngineChannel->ControllerTable[128];
263                      break;                      break;
264                  case ::gig::eg2_ctrl_t::type_velocity:                  case ::gig::eg2_ctrl_t::type_velocity:
265                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
# Line 339  namespace LinuxSampler { namespace gig { Line 339  namespace LinuxSampler { namespace gig {
339              }              }
340              if (bLFO1Enabled) {              if (bLFO1Enabled) {
341                  pLFO1->trigger(pDimRgn->LFO1Frequency,                  pLFO1->trigger(pDimRgn->LFO1Frequency,
342                                 start_level_max,                                 start_level_min,
343                                 lfo1_internal_depth,                                 lfo1_internal_depth,
344                                 pDimRgn->LFO1ControlDepth,                                 pDimRgn->LFO1ControlDepth,
345                                 pDimRgn->LFO1FlipPhase,                                 pDimRgn->LFO1FlipPhase,
# Line 411  namespace LinuxSampler { namespace gig { Line 411  namespace LinuxSampler { namespace gig {
411                      break;                      break;
412                  case ::gig::lfo3_ctrl_aftertouch:                  case ::gig::lfo3_ctrl_aftertouch:
413                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
414                      pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet                      pLFO3->ExtController = 128;
415                      bLFO3Enabled         = false; // see TODO comment in line above                      bLFO3Enabled         = true;
416                      break;                      break;
417                  case ::gig::lfo3_ctrl_internal_modwheel:                  case ::gig::lfo3_ctrl_internal_modwheel:
418                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
# Line 421  namespace LinuxSampler { namespace gig { Line 421  namespace LinuxSampler { namespace gig {
421                      break;                      break;
422                  case ::gig::lfo3_ctrl_internal_aftertouch:                  case ::gig::lfo3_ctrl_internal_aftertouch:
423                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
424                      pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet                      pLFO1->ExtController = 128;
425                      bLFO3Enabled         = (lfo3_internal_depth > 0 /*|| pDimRgn->LFO3ControlDepth > 0*/); // see TODO comment in line above                      bLFO3Enabled         = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0);
426                      break;                      break;
427                  default:                  default:
428                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
# Line 479  namespace LinuxSampler { namespace gig { Line 479  namespace LinuxSampler { namespace gig {
479                  case ::gig::vcf_cutoff_ctrl_genpurpose8:                  case ::gig::vcf_cutoff_ctrl_genpurpose8:
480                      VCFCutoffCtrl.controller = 83;                      VCFCutoffCtrl.controller = 83;
481                      break;                      break;
482                  case ::gig::vcf_cutoff_ctrl_aftertouch: //TODO: not implemented yet                  case ::gig::vcf_cutoff_ctrl_aftertouch:
483                        VCFCutoffCtrl.controller = 128;
484                        break;
485                  case ::gig::vcf_cutoff_ctrl_none:                  case ::gig::vcf_cutoff_ctrl_none:
486                  default:                  default:
487                      VCFCutoffCtrl.controller = 0;                      VCFCutoffCtrl.controller = 0;
# Line 537  namespace LinuxSampler { namespace gig { Line 539  namespace LinuxSampler { namespace gig {
539              else {              else {
540                  cvalue = pDimRgn->VCFCutoff;                  cvalue = pDimRgn->VCFCutoff;
541              }              }
542              cutoff *= float(cvalue) * 0.00787402f; // (1 / 127)              cutoff *= float(cvalue);
543              if (cutoff > 1.0) cutoff = 1.0;              if (cutoff > 127.0f) cutoff = 127.0f;
             cutoff = (cutoff < 0.5 ? cutoff * 4826 - 1 : cutoff * 5715 - 449);  
             if (cutoff < 1.0) cutoff = 1.0;  
544    
545              // calculate resonance              // calculate resonance
546              float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : pDimRgn->VCFResonance) * 0.00787f; // 0.0..1.0              float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : pDimRgn->VCFResonance);
547    
548              VCFCutoffCtrl.fvalue    = cutoff - 1.0;              VCFCutoffCtrl.fvalue    = cutoff;
549              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
550          }          }
551          else {          else {
# Line 622  namespace LinuxSampler { namespace gig { Line 622  namespace LinuxSampler { namespace gig {
622                          }                          }
623                      }                      }
624    
625                      sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from                      sample_t* ptr = (sample_t*)DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
626    
627                      // render current audio fragment                      // render current audio fragment
628                      Synthesize(Samples, ptr, Delay);                      Synthesize(Samples, ptr, Delay);
# Line 720  namespace LinuxSampler { namespace gig { Line 720  namespace LinuxSampler { namespace gig {
720                      CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);                      CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
721                  }                  }
722                  if (itEvent->Param.CC.Controller == 7) { // volume                  if (itEvent->Param.CC.Controller == 7) { // volume
723                      VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value] * CONFIG_GLOBAL_ATTENUATION);                      VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value]);
724                  } else if (itEvent->Param.CC.Controller == 10) { // panpot                  } else if (itEvent->Param.CC.Controller == 10) { // panpot
725                      PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]);                      PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]);
726                      PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]);                      PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]);
# Line 743  namespace LinuxSampler { namespace gig { Line 743  namespace LinuxSampler { namespace gig {
743          VCFCutoffCtrl.value == ccvalue;          VCFCutoffCtrl.value == ccvalue;
744          if (pDimRgn->VCFCutoffControllerInvert)  ccvalue = 127 - ccvalue;          if (pDimRgn->VCFCutoffControllerInvert)  ccvalue = 127 - ccvalue;
745          if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;          if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;
746          float cutoff = CutoffBase * float(ccvalue) * 0.00787402f; // (1 / 127)          float cutoff = CutoffBase * float(ccvalue);
747          if (cutoff > 1.0) cutoff = 1.0;          if (cutoff > 127.0f) cutoff = 127.0f;
         cutoff = (cutoff < 0.5 ? cutoff * 4826 - 1 : cutoff * 5715 - 449);  
         if (cutoff < 1.0) cutoff = 1.0;  
748    
749          VCFCutoffCtrl.fvalue = cutoff - 1.0; // needed for initialization of fFinalCutoff next time          VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
750          fFinalCutoff = cutoff;          fFinalCutoff = cutoff;
751      }      }
752    
# Line 756  namespace LinuxSampler { namespace gig { Line 754  namespace LinuxSampler { namespace gig {
754          // convert absolute controller value to differential          // convert absolute controller value to differential
755          const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;          const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
756          VCFResonanceCtrl.value = itEvent->Param.CC.Value;          VCFResonanceCtrl.value = itEvent->Param.CC.Value;
757          const float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0          const float resonancedelta = (float) ctrldelta;
758          fFinalResonance += resonancedelta;          fFinalResonance += resonancedelta;
759          // needed for initialization of parameter          // needed for initialization of parameter
760          VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value * 0.00787f;          VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
761      }      }
762    
763      /**      /**
# Line 771  namespace LinuxSampler { namespace gig { Line 769  namespace LinuxSampler { namespace gig {
769       *  @param Skip    - number of sample points to skip in output buffer       *  @param Skip    - number of sample points to skip in output buffer
770       */       */
771      void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
772          finalSynthesisParameters.pOutLeft  = &pEngineChannel->pOutputLeft[Skip];          finalSynthesisParameters.pOutLeft  = &pEngineChannel->pChannelLeft->Buffer()[Skip];
773          finalSynthesisParameters.pOutRight = &pEngineChannel->pOutputRight[Skip];          finalSynthesisParameters.pOutRight = &pEngineChannel->pChannelRight->Buffer()[Skip];
774          finalSynthesisParameters.pSrc      = pSrc;          finalSynthesisParameters.pSrc      = pSrc;
775    
776          RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();          RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();
# Line 806  namespace LinuxSampler { namespace gig { Line 804  namespace LinuxSampler { namespace gig {
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    
807              // if the voice was killed in this subfragment switch EG1 to fade out stage              // if the voice was killed in this subfragment, or if the
808              if (itKillEvent && killPos <= iSubFragmentEnd) {              // filter EG is finished, switch EG1 to fade out stage
809                if ((itKillEvent && killPos <= iSubFragmentEnd) ||
810                    (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
811                     EG2.getSegmentType() == EGADSR::segment_end)) {
812                  EG1.enterFadeOutStage();                  EG1.enterFadeOutStage();
813                  itKillEvent = Pool<Event>::Iterator();                  itKillEvent = Pool<Event>::Iterator();
814              }              }
# Line 838  namespace LinuxSampler { namespace gig { Line 839  namespace LinuxSampler { namespace gig {
839              if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();              if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
840    
841              // process low frequency oscillators              // process low frequency oscillators
842              if (bLFO1Enabled) fFinalVolume *= pLFO1->render();              if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
843              if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();              if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
844              if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());              if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
845    
846              // if filter enabled then update filter coefficients              // if filter enabled then update filter coefficients
847              if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {              if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
848                  finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff + 1.0, fFinalResonance, pEngine->SampleRate);                  finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
849                  finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff + 1.0, fFinalResonance, pEngine->SampleRate);                  finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
850              }              }
851    
852              // do we need resampling?              // do we need resampling?

Legend:
Removed from v.865  
changed lines
  Added in v.1038

  ViewVC Help
Powered by ViewVC