/[svn]/linuxsampler/trunk/src/engines/common/AbstractVoice.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/common/AbstractVoice.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2935 by schoenebeck, Sun Jul 10 14:24:13 2016 UTC revision 3246 by schoenebeck, Sun May 28 22:22:56 2017 UTC
# Line 4  Line 4 
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck    *   *   Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck    *
6   *   Copyright (C) 2005-2008 Christian Schoenebeck                         *   *   Copyright (C) 2005-2008 Christian Schoenebeck                         *
7   *   Copyright (C) 2009-2015 Christian Schoenebeck and Grigor Iliev        *   *   Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev        *
8     *   Copyright (C) 2013-2017 Christian Schoenebeck and Andreas Persson     *
9   *                                                                         *   *                                                                         *
10   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
11   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 128  namespace LinuxSampler { Line 129  namespace LinuxSampler {
129          AboutToTrigger();          AboutToTrigger();
130    
131          // calculate volume          // calculate volume
132          const double velocityAttenuation = GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);          const double velocityAttenuation = GetVelocityAttenuation(MIDIVelocity());
133          float volume = CalculateVolume(velocityAttenuation) * pKeyInfo->Volume;          float volume = CalculateVolume(velocityAttenuation) * pKeyInfo->Volume;
134          if (volume <= 0) return -1;          if (volume <= 0) return -1;
135    
# Line 138  namespace LinuxSampler { Line 139  namespace LinuxSampler {
139          SYNTHESIS_MODE_SET_BITDEPTH24(SynthesisMode, SmplInfo.BitDepth == 24);          SYNTHESIS_MODE_SET_BITDEPTH24(SynthesisMode, SmplInfo.BitDepth == 24);
140    
141          // get starting crossfade volume level          // get starting crossfade volume level
142          float crossfadeVolume = CalculateCrossfadeVolume(itNoteOnEvent->Param.Note.Velocity);          float crossfadeVolume = CalculateCrossfadeVolume(MIDIVelocity());
143    
144          VolumeLeft  = volume * pKeyInfo->PanLeft;          VolumeLeft  = volume * pKeyInfo->PanLeft;
145          VolumeRight = volume * pKeyInfo->PanRight;          VolumeRight = volume * pKeyInfo->PanRight;
146    
147          float subfragmentRate = GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          // this rate is used for rather mellow volume fades
148            const float subfragmentRate = GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
149            // this rate is used for very fast volume fades
150            const float quickRampRate = RTMath::Min(subfragmentRate, GetEngine()->SampleRate * 0.001f /* approx. 13ms */);
151          CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);          CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
152    
153          VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);          VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);
154          NoteVolumeSmoother.trigger(pNote ? pNote->Override.Volume : 1.f, subfragmentRate);          NoteVolume.setCurveOnly(pNote ? pNote->Override.VolumeCurve : DEFAULT_FADE_CURVE);
155            NoteVolume.setCurrentValue(pNote ? pNote->Override.Volume : 1.f);
156            NoteVolume.setDefaultDuration(pNote ? pNote->Override.VolumeTime : DEFAULT_NOTE_VOLUME_TIME_S);
157    
158          // Check if the sample needs disk streaming or is too short for that          // Check if the sample needs disk streaming or is too short for that
159          long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;          long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;
# Line 186  namespace LinuxSampler { Line 193  namespace LinuxSampler {
193          }          }
194    
195          Pitch = CalculatePitchInfo(PitchBend);          Pitch = CalculatePitchInfo(PitchBend);
196          NotePitch = (pNote) ? pNote->Override.Pitch : 1.0f;          NotePitch.setCurveOnly(pNote ? pNote->Override.PitchCurve : DEFAULT_FADE_CURVE);
197            NotePitch.setCurrentValue(pNote ? pNote->Override.Pitch : 1.0f);
198            NotePitch.setDefaultDuration(pNote ? pNote->Override.PitchTime : DEFAULT_NOTE_PITCH_TIME_S);
199          NoteCutoff = (pNote) ? pNote->Override.Cutoff : 1.0f;          NoteCutoff = (pNote) ? pNote->Override.Cutoff : 1.0f;
200          NoteResonance = (pNote) ? pNote->Override.Resonance : 1.0f;          NoteResonance = (pNote) ? pNote->Override.Resonance : 1.0f;
201    
202          // the length of the decay and release curves are dependent on the velocity          // the length of the decay and release curves are dependent on the velocity
203          const double velrelease = 1 / GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);          const double velrelease = 1 / GetVelocityRelease(MIDIVelocity());
204    
205          if (pSignalUnitRack == NULL) { // setup EG 1 (VCA EG)          if (pSignalUnitRack == NULL) { // setup EG 1 (VCA EG)
206              // get current value of EG1 controller              // get current value of EG1 controller
207              double eg1controllervalue = GetEG1ControllerValue(itNoteOnEvent->Param.Note.Velocity);              double eg1controllervalue = GetEG1ControllerValue(MIDIVelocity());
208    
209              // calculate influence of EG1 controller on EG1's parameters              // calculate influence of EG1 controller on EG1's parameters
210              EGInfo egInfo = CalculateEG1ControllerInfluence(eg1controllervalue);              EGInfo egInfo = CalculateEG1ControllerInfluence(eg1controllervalue);
211    
212              TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);              if (pNote) {
213                    egInfo.Attack  *= pNote->Override.Attack;
214                    egInfo.Decay   *= pNote->Override.Decay;
215                    egInfo.Release *= pNote->Override.Release;
216                }
217    
218                TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, MIDIVelocity());
219          } else {          } else {
220              pSignalUnitRack->Trigger();              pSignalUnitRack->Trigger();
221          }          }
# Line 210  namespace LinuxSampler { Line 225  namespace LinuxSampler {
225          NotePanRight = (pNote) ? AbstractEngine::PanCurveValueNorm(pNote->Override.Pan, 1 /*right*/) : 1.f;          NotePanRight = (pNote) ? AbstractEngine::PanCurveValueNorm(pNote->Override.Pan, 1 /*right*/) : 1.f;
226          PanLeftSmoother.trigger(          PanLeftSmoother.trigger(
227              AbstractEngine::PanCurve[128 - pan] * NotePanLeft,              AbstractEngine::PanCurve[128 - pan] * NotePanLeft,
228              subfragmentRate              quickRampRate //NOTE: maybe we should have 2 separate pan smoothers, one for MIDI CC10 (with slow rate) and one for instrument script change_pan() calls (with fast rate)
229          );          );
230          PanRightSmoother.trigger(          PanRightSmoother.trigger(
231              AbstractEngine::PanCurve[pan] * NotePanRight,              AbstractEngine::PanCurve[pan] * NotePanRight,
232              subfragmentRate              quickRampRate //NOTE: maybe we should have 2 separate pan smoothers, one for MIDI CC10 (with slow rate) and one for instrument script change_pan() calls (with fast rate)
233          );          );
234    
235  #ifdef CONFIG_INTERPOLATE_VOLUME  #ifdef CONFIG_INTERPOLATE_VOLUME
# Line 244  namespace LinuxSampler { Line 259  namespace LinuxSampler {
259              // setup EG 2 (VCF Cutoff EG)              // setup EG 2 (VCF Cutoff EG)
260              {              {
261                  // get current value of EG2 controller                  // get current value of EG2 controller
262                  double eg2controllervalue = GetEG2ControllerValue(itNoteOnEvent->Param.Note.Velocity);                  double eg2controllervalue = GetEG2ControllerValue(MIDIVelocity());
263    
264                  // calculate influence of EG2 controller on EG2's parameters                  // calculate influence of EG2 controller on EG2's parameters
265                  EGInfo egInfo = CalculateEG2ControllerInfluence(eg2controllervalue);                  EGInfo egInfo = CalculateEG2ControllerInfluence(eg2controllervalue);
266    
267                  TriggerEG2(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);                  TriggerEG2(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, MIDIVelocity());
268              }              }
269    
270    
# Line 308  namespace LinuxSampler { Line 323  namespace LinuxSampler {
323              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
324    
325              // calculate cutoff frequency              // calculate cutoff frequency
326              CutoffBase = CalculateCutoffBase(itNoteOnEvent->Param.Note.Velocity);              CutoffBase = CalculateCutoffBase(MIDIVelocity());
327    
328              VCFCutoffCtrl.fvalue = CalculateFinalCutoff(CutoffBase);              VCFCutoffCtrl.fvalue = CalculateFinalCutoff(CutoffBase);
329    
# Line 409  namespace LinuxSampler { Line 424  namespace LinuxSampler {
424              }              }
425          }          }
426    
427          uint killPos;          uint killPos = 0;
428          if (itKillEvent) {          if (itKillEvent) {
429              int maxFadeOutPos = Samples - GetEngine()->GetMinFadeOutSamples();              int maxFadeOutPos = Samples - GetEngine()->GetMinFadeOutSamples();
430              if (maxFadeOutPos < 0) {              if (maxFadeOutPos < 0) {
# Line 445  namespace LinuxSampler { Line 460  namespace LinuxSampler {
460              PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan] * NotePanLeft);              PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan] * NotePanLeft);
461              PanRightSmoother.update(AbstractEngine::PanCurve[pan]      * NotePanRight);              PanRightSmoother.update(AbstractEngine::PanCurve[pan]      * NotePanRight);
462    
463              finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend * NotePitch;              finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend * NotePitch.render();
464    
465              float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render() * NoteVolumeSmoother.render();              float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render() * NoteVolume.render();
466  #ifdef CONFIG_PROCESS_MUTED_CHANNELS  #ifdef CONFIG_PROCESS_MUTED_CHANNELS
467              if (pChannel->GetMute()) fFinalVolume = 0;              if (pChannel->GetMute()) fFinalVolume = 0;
468  #endif  #endif
# Line 633  namespace LinuxSampler { Line 648  namespace LinuxSampler {
648       */       */
649      void AbstractVoice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {      void AbstractVoice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
650          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
651              if (itEvent->Type == Event::type_control_change && itEvent->Param.CC.Controller) { // if (valid) MIDI control change event              if ((itEvent->Type == Event::type_control_change || itEvent->Type == Event::type_channel_pressure)
652                    && itEvent->Param.CC.Controller) // if (valid) MIDI control change event
653                {
654                  if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {                  if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
655                      ProcessCutoffEvent(itEvent);                      ProcessCutoffEvent(itEvent);
656                  }                  }
657                  if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {                  if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
658                      processResonanceEvent(itEvent);                      processResonanceEvent(itEvent);
659                  }                  }
660                    if (itEvent->Param.CC.Controller == CTRL_TABLE_IDX_AFTERTOUCH ||
661                        itEvent->Type == Event::type_channel_pressure)
662                    {
663                        ProcessChannelPressureEvent(itEvent);
664                    }
665                  if (pSignalUnitRack == NULL) {                  if (pSignalUnitRack == NULL) {
666                      if (itEvent->Param.CC.Controller == pLFO1->ExtController) {                      if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
667                          pLFO1->update(itEvent->Param.CC.Value);                          pLFO1->updateByMIDICtrlValue(itEvent->Param.CC.Value);
668                      }                      }
669                      if (itEvent->Param.CC.Controller == pLFO2->ExtController) {                      if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
670                          pLFO2->update(itEvent->Param.CC.Value);                          pLFO2->updateByMIDICtrlValue(itEvent->Param.CC.Value);
671                      }                      }
672                      if (itEvent->Param.CC.Controller == pLFO3->ExtController) {                      if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
673                          pLFO3->update(itEvent->Param.CC.Value);                          pLFO3->updateByMIDICtrlValue(itEvent->Param.CC.Value);
674                      }                      }
675                  }                  }
676                  if (itEvent->Param.CC.Controller == 7) { // volume                  if (itEvent->Param.CC.Controller == 7) { // volume
# Line 658  namespace LinuxSampler { Line 680  namespace LinuxSampler {
680                  }                  }
681              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
682                  processPitchEvent(itEvent);                  processPitchEvent(itEvent);
             } else if (itEvent->Type == Event::type_channel_pressure) {  
                 ProcessChannelPressureEvent(itEvent);  
683              } else if (itEvent->Type == Event::type_note_pressure) {              } else if (itEvent->Type == Event::type_note_pressure) {
684                  ProcessPolyphonicKeyPressureEvent(itEvent);                  ProcessPolyphonicKeyPressureEvent(itEvent);
685              }              }
# Line 696  namespace LinuxSampler { Line 716  namespace LinuxSampler {
716          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
717              // some voice types ignore note off              // some voice types ignore note off
718              if (!(Type & (Voice::type_one_shot | Voice::type_release_trigger | Voice::type_controller_triggered))) {              if (!(Type & (Voice::type_one_shot | Voice::type_release_trigger | Voice::type_controller_triggered))) {
719                  if (itEvent->Type == Event::type_release) {                  if (itEvent->Type == Event::type_release_key) {
720                      EnterReleaseStage();                      EnterReleaseStage();
721                  } else if (itEvent->Type == Event::type_cancel_release) {                  } else if (itEvent->Type == Event::type_cancel_release_key) {
722                      if (pSignalUnitRack == NULL) {                      if (pSignalUnitRack == NULL) {
723                          pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
724                          pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
# Line 707  namespace LinuxSampler { Line 727  namespace LinuxSampler {
727                      }                      }
728                  }                  }
729              }              }
730                // process stop-note events (caused by built-in instrument script function note_off())
731                if (itEvent->Type == Event::type_release_note && pNote &&
732                    pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
733                {
734                    EnterReleaseStage();
735                }
736                // process kill-note events (caused by built-in instrument script function fade_out())
737                if (itEvent->Type == Event::type_kill_note && pNote &&
738                    pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
739                {
740                    Kill(itEvent);
741                }
742              // process synthesis parameter events (caused by built-in realt-time instrument script functions)              // process synthesis parameter events (caused by built-in realt-time instrument script functions)
743              if (itEvent->Type == Event::type_note_synth_param && pNote &&              if (itEvent->Type == Event::type_note_synth_param && pNote &&
744                  pEngineChannel->pEngine->NoteByID( itEvent->Param.NoteSynthParam.NoteID ) == pNote)                  pEngineChannel->pEngine->NoteByID( itEvent->Param.NoteSynthParam.NoteID ) == pNote)
745              {              {
746                  switch (itEvent->Param.NoteSynthParam.Type) {                  switch (itEvent->Param.NoteSynthParam.Type) {
747                      case Event::synth_param_volume:                      case Event::synth_param_volume:
748                          NoteVolumeSmoother.update(itEvent->Param.NoteSynthParam.AbsValue);                          NoteVolume.fadeTo(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
749                            break;
750                        case Event::synth_param_volume_time:
751                            NoteVolume.setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
752                            break;
753                        case Event::synth_param_volume_curve:
754                            NoteVolume.setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
755                          break;                          break;
756                      case Event::synth_param_pitch:                      case Event::synth_param_pitch:
757                          NotePitch = itEvent->Param.NoteSynthParam.AbsValue;                          NotePitch.fadeTo(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
758                            break;
759                        case Event::synth_param_pitch_time:
760                            NotePitch.setDefaultDuration(itEvent->Param.NoteSynthParam.AbsValue);
761                            break;
762                        case Event::synth_param_pitch_curve:
763                            NotePitch.setCurve((fade_curve_t)itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
764                          break;                          break;
765                      case Event::synth_param_pan:                      case Event::synth_param_pan:
766                          NotePanLeft  = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 0 /*left*/);                          NotePanLeft  = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 0 /*left*/);
# Line 728  namespace LinuxSampler { Line 772  namespace LinuxSampler {
772                      case Event::synth_param_resonance:                      case Event::synth_param_resonance:
773                          NoteResonance = itEvent->Param.NoteSynthParam.AbsValue;                          NoteResonance = itEvent->Param.NoteSynthParam.AbsValue;
774                          break;                          break;
775                        case Event::synth_param_amp_lfo_depth:
776                            pLFO1->setScriptDepthFactor(itEvent->Param.NoteSynthParam.AbsValue);
777                            break;
778                        case Event::synth_param_amp_lfo_freq:
779                            pLFO1->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
780                            break;
781                        case Event::synth_param_pitch_lfo_depth:
782                            pLFO3->setScriptDepthFactor(itEvent->Param.NoteSynthParam.AbsValue);
783                            break;
784                        case Event::synth_param_pitch_lfo_freq:
785                            pLFO3->setScriptFrequencyFactor(itEvent->Param.NoteSynthParam.AbsValue, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
786                            break;
787    
788                        case Event::synth_param_attack:
789                        case Event::synth_param_decay:
790                        case Event::synth_param_release:
791                            break; // noop
792                  }                  }
793              }              }
794          }          }

Legend:
Removed from v.2935  
changed lines
  Added in v.3246

  ViewVC Help
Powered by ViewVC