/[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 1181 by schoenebeck, Sat May 12 16:03: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          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 114  namespace LinuxSampler { namespace gig { Line 112  namespace LinuxSampler { namespace gig {
112                                       pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;                                       pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
113              float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;              float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
114              if (attenuation <= 0) return -1;              if (attenuation <= 0) return -1;
115              Volume *= attenuation;              volume *= attenuation;
116          }          }
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;
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 = 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->MidiVolume, 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 146  namespace LinuxSampler { namespace gig { Line 153  namespace LinuxSampler { namespace gig {
153          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
154          DiskVoice          = cachedsamples < pSample->SamplesTotal;          DiskVoice          = cachedsamples < pSample->SamplesTotal;
155    
156            const DLS::sample_loop_t& loopinfo = pDimRgn->pSampleLoops[0];
157    
158          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
159              MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)              MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)
160    
161              // check if there's a loop defined which completely fits into the cached (RAM) part of the sample              // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
162              RAMLoop = (pSample->Loops && pSample->LoopEnd <= MaxRAMPos);              RAMLoop = (pDimRgn->SampleLoops && (loopinfo.LoopStart + loopinfo.LoopLength) <= MaxRAMPos);
163    
164              if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {              if (pDiskThread->OrderNewStream(&DiskStreamRef, pDimRgn, MaxRAMPos, !RAMLoop) < 0) {
165                  dmsg(1,("Disk stream order failed!\n"));                  dmsg(1,("Disk stream order failed!\n"));
166                  KillImmediately();                  KillImmediately();
167                  return -1;                  return -1;
# Line 161  namespace LinuxSampler { namespace gig { Line 170  namespace LinuxSampler { namespace gig {
170          }          }
171          else { // RAM only voice          else { // RAM only voice
172              MaxRAMPos = cachedsamples;              MaxRAMPos = cachedsamples;
173              RAMLoop = (pSample->Loops != 0);              RAMLoop = (pDimRgn->SampleLoops != 0);
174              dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));              dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
175          }          }
176          if (RAMLoop) {          if (RAMLoop) {
177              loop.uiTotalCycles = pSample->LoopPlayCount;              loop.uiTotalCycles = pSample->LoopPlayCount;
178              loop.uiCyclesLeft  = pSample->LoopPlayCount;              loop.uiCyclesLeft  = pSample->LoopPlayCount;
179              loop.uiStart       = pSample->LoopStart;              loop.uiStart       = loopinfo.LoopStart;
180              loop.uiEnd         = pSample->LoopEnd;              loop.uiEnd         = loopinfo.LoopStart + loopinfo.LoopLength;
181              loop.uiSize        = pSample->LoopSize;              loop.uiSize        = loopinfo.LoopLength;
182          }          }
183    
184          // calculate initial pitch value          // calculate initial pitch value
# Line 192  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 223  namespace LinuxSampler { namespace gig { Line 232  namespace LinuxSampler { namespace gig {
232                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
233          }          }
234    
235    #ifdef CONFIG_INTERPOLATE_VOLUME
236          // setup initial volume in synthesis parameters          // setup initial volume in synthesis parameters
237          fFinalVolume = getVolume() * EG1.getLevel();  #ifdef CONFIG_PROCESS_MUTED_CHANNELS
238          finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * PanLeft;          if (pEngineChannel->GetMute()) {
239          finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight;              finalSynthesisParameters.fFinalVolumeLeft  = 0;
240                finalSynthesisParameters.fFinalVolumeRight = 0;
241            }
242            else
243    #else
244            {
245                float finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * EG1.getLevel();
246    
247                finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;
248                finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;
249            }
250    #endif
251    #endif
252    
253          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
254          {          {
# Line 238  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 316  namespace LinuxSampler { namespace gig { Line 337  namespace LinuxSampler { namespace gig {
337                      pLFO1->ExtController = 0; // no external controller                      pLFO1->ExtController = 0; // no external controller
338                      bLFO1Enabled         = false;                      bLFO1Enabled         = false;
339              }              }
340              if (bLFO1Enabled) pLFO1->trigger(pDimRgn->LFO1Frequency,              if (bLFO1Enabled) {
341                                               start_level_max,                  pLFO1->trigger(pDimRgn->LFO1Frequency,
342                                               lfo1_internal_depth,                                 start_level_min,
343                                               pDimRgn->LFO1ControlDepth,                                 lfo1_internal_depth,
344                                               pDimRgn->LFO1FlipPhase,                                 pDimRgn->LFO1ControlDepth,
345                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 pDimRgn->LFO1FlipPhase,
346                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
347                    pLFO1->update(pLFO1->ExtController ? pEngineChannel->ControllerTable[pLFO1->ExtController] : 0);
348                }
349          }          }
350    
351    
# Line 359  namespace LinuxSampler { namespace gig { Line 383  namespace LinuxSampler { namespace gig {
383                      pLFO2->ExtController = 0; // no external controller                      pLFO2->ExtController = 0; // no external controller
384                      bLFO2Enabled         = false;                      bLFO2Enabled         = false;
385              }              }
386              if (bLFO2Enabled) pLFO2->trigger(pDimRgn->LFO2Frequency,              if (bLFO2Enabled) {
387                                               start_level_max,                  pLFO2->trigger(pDimRgn->LFO2Frequency,
388                                               lfo2_internal_depth,                                 start_level_max,
389                                               pDimRgn->LFO2ControlDepth,                                 lfo2_internal_depth,
390                                               pDimRgn->LFO2FlipPhase,                                 pDimRgn->LFO2ControlDepth,
391                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 pDimRgn->LFO2FlipPhase,
392                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
393                    pLFO2->update(pLFO2->ExtController ? pEngineChannel->ControllerTable[pLFO2->ExtController] : 0);
394                }
395          }          }
396    
397    
# Line 384  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 394  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;
429                      pLFO3->ExtController = 0; // no external controller                      pLFO3->ExtController = 0; // no external controller
430                      bLFO3Enabled         = false;                      bLFO3Enabled         = false;
431              }              }
432              if (bLFO3Enabled) pLFO3->trigger(pDimRgn->LFO3Frequency,              if (bLFO3Enabled) {
433                                               start_level_mid,                  pLFO3->trigger(pDimRgn->LFO3Frequency,
434                                               lfo3_internal_depth,                                 start_level_mid,
435                                               pDimRgn->LFO3ControlDepth,                                 lfo3_internal_depth,
436                                               false,                                 pDimRgn->LFO3ControlDepth,
437                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 false,
438                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
439                    pLFO3->update(pLFO3->ExtController ? pEngineChannel->ControllerTable[pLFO3->ExtController] : 0);
440                }
441          }          }
442    
443    
# Line 449  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 483  namespace LinuxSampler { namespace gig { Line 515  namespace LinuxSampler { namespace gig {
515              finalSynthesisParameters.filterLeft.SetType(pDimRgn->VCFType);              finalSynthesisParameters.filterLeft.SetType(pDimRgn->VCFType);
516              finalSynthesisParameters.filterRight.SetType(pDimRgn->VCFType);              finalSynthesisParameters.filterRight.SetType(pDimRgn->VCFType);
517              #else // override filter type              #else // override filter type
518              FilterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);              finalSynthesisParameters.filterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
519              FilterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);              finalSynthesisParameters.filterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
520              #endif // CONFIG_OVERRIDE_FILTER_TYPE              #endif // CONFIG_OVERRIDE_FILTER_TYPE
521    
522              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
# Line 507  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 592  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 645  namespace LinuxSampler { namespace gig { Line 675  namespace LinuxSampler { namespace gig {
675       * for the given time.       * for the given time.
676       *       *
677       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
678       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
679       */       */
680      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
681          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
# Line 664  namespace LinuxSampler { namespace gig { Line 694  namespace LinuxSampler { namespace gig {
694       * the given time.       * the given time.
695       *       *
696       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
697       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
698       */       */
699      void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {      void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
700          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
# Line 687  namespace LinuxSampler { namespace gig { Line 717  namespace LinuxSampler { namespace gig {
717                  }                  }
718                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
719                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {
720                      processCrossFadeEvent(itEvent);                      CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
721                    }
722                    if (itEvent->Param.CC.Controller == 7) { // volume
723                        VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value]);
724                    } else if (itEvent->Param.CC.Controller == 10) { // panpot
725                        PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]);
726                        PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]);
727                  }                  }
728              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
729                  processPitchEvent(itEvent);                  processPitchEvent(itEvent);
# Line 701  namespace LinuxSampler { namespace gig { Line 737  namespace LinuxSampler { namespace gig {
737          PitchBend = pitch;          PitchBend = pitch;
738      }      }
739    
     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  
     }  
   
740      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
741          int ccvalue = itEvent->Param.CC.Value;          int ccvalue = itEvent->Param.CC.Value;
742          if (VCFCutoffCtrl.value == ccvalue) return;          if (VCFCutoffCtrl.value == ccvalue) return;
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 733  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 748  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 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    
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 811  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?
# Line 832  namespace LinuxSampler { namespace gig { Line 860  namespace LinuxSampler { namespace gig {
860              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;
861  #ifdef CONFIG_INTERPOLATE_VOLUME  #ifdef CONFIG_INTERPOLATE_VOLUME
862              finalSynthesisParameters.fFinalVolumeDeltaLeft  =              finalSynthesisParameters.fFinalVolumeDeltaLeft  =
863                  (fFinalVolume * PanLeft - finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;                  (fFinalVolume * VolumeLeft  * PanLeftSmoother.render() -
864                     finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
865              finalSynthesisParameters.fFinalVolumeDeltaRight =              finalSynthesisParameters.fFinalVolumeDeltaRight =
866                  (fFinalVolume * PanRight - finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;                  (fFinalVolume * VolumeRight * PanRightSmoother.render() -
867                     finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
868  #else  #else
869              finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * PanLeft;              finalSynthesisParameters.fFinalVolumeLeft  =
870              finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight;                  fFinalVolume * VolumeLeft  * PanLeftSmoother.render();
871                finalSynthesisParameters.fFinalVolumeRight =
872                    fFinalVolume * VolumeRight * PanRightSmoother.render();
873  #endif  #endif
874              // render audio for one subfragment              // render audio for one subfragment
875              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
# Line 851  namespace LinuxSampler { namespace gig { Line 883  namespace LinuxSampler { namespace gig {
883              if (EG1.active()) {              if (EG1.active()) {
884    
885                  // if sample has a loop and loop start has been reached in this subfragment, send a special event to EG1 to let it finish the attack hold stage                  // if sample has a loop and loop start has been reached in this subfragment, send a special event to EG1 to let it finish the attack hold stage
886                  if (pSample->Loops && Pos <= pSample->LoopStart && pSample->LoopStart < newPos) {                  if (pDimRgn->SampleLoops && Pos <= pDimRgn->pSampleLoops[0].LoopStart && pDimRgn->pSampleLoops[0].LoopStart < newPos) {
887                      EG1.update(EGADSR::event_hold_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                      EG1.update(EGADSR::event_hold_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
888                  }                  }
889    

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

  ViewVC Help
Powered by ViewVC