/[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 2879 by schoenebeck, Tue Apr 19 14:07:53 2016 UTC revision 2963 by schoenebeck, Sun Jul 17 18:41:21 2016 UTC
# Line 143  namespace LinuxSampler { Line 143  namespace LinuxSampler {
143          VolumeLeft  = volume * pKeyInfo->PanLeft;          VolumeLeft  = volume * pKeyInfo->PanLeft;
144          VolumeRight = volume * pKeyInfo->PanRight;          VolumeRight = volume * pKeyInfo->PanRight;
145    
146          float subfragmentRate = GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;          // this rate is used for rather mellow volume fades
147            const float subfragmentRate = GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
148            // this rate is used for very fast volume fades
149            const float quickRampRate = RTMath::Min(subfragmentRate, GetEngine()->SampleRate * 0.001f /* 1ms */);
150          CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);          CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
151    
152          VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);          VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);
153            NoteVolumeSmoother.trigger(pNote ? pNote->Override.Volume : 1.f, quickRampRate);
154    
155          // 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
156          long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;          long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;
# Line 185  namespace LinuxSampler { Line 190  namespace LinuxSampler {
190          }          }
191    
192          Pitch = CalculatePitchInfo(PitchBend);          Pitch = CalculatePitchInfo(PitchBend);
193            NotePitch = (pNote) ? pNote->Override.Pitch : 1.0f;
194            NoteCutoff = (pNote) ? pNote->Override.Cutoff : 1.0f;
195            NoteResonance = (pNote) ? pNote->Override.Resonance : 1.0f;
196    
197          // 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
198          const double velrelease = 1 / GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);          const double velrelease = 1 / GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
# Line 196  namespace LinuxSampler { Line 204  namespace LinuxSampler {
204              // calculate influence of EG1 controller on EG1's parameters              // calculate influence of EG1 controller on EG1's parameters
205              EGInfo egInfo = CalculateEG1ControllerInfluence(eg1controllervalue);              EGInfo egInfo = CalculateEG1ControllerInfluence(eg1controllervalue);
206    
207                if (pNote) {
208                    egInfo.Attack  *= pNote->Override.Attack;
209                    egInfo.Decay   *= pNote->Override.Decay;
210                    egInfo.Release *= pNote->Override.Release;
211                }
212    
213              TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);              TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);
214          } else {          } else {
215              pSignalUnitRack->Trigger();              pSignalUnitRack->Trigger();
216          }          }
217    
218          uint8_t pan = MIDIPan;          const uint8_t pan = (pSignalUnitRack) ? pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan) : MIDIPan;
219          if (pSignalUnitRack) pan = pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan);          NotePanLeft  = (pNote) ? AbstractEngine::PanCurveValueNorm(pNote->Override.Pan, 0 /*left*/ ) : 1.f;
220          PanLeftSmoother.trigger(AbstractEngine::PanCurve[128 - pan], subfragmentRate);          NotePanRight = (pNote) ? AbstractEngine::PanCurveValueNorm(pNote->Override.Pan, 1 /*right*/) : 1.f;
221          PanRightSmoother.trigger(AbstractEngine::PanCurve[pan], subfragmentRate);          PanLeftSmoother.trigger(
222                AbstractEngine::PanCurve[128 - pan] * NotePanLeft,
223                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)
224            );
225            PanRightSmoother.trigger(
226                AbstractEngine::PanCurve[pan] * NotePanRight,
227                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)
228            );
229    
230  #ifdef CONFIG_INTERPOLATE_VOLUME  #ifdef CONFIG_INTERPOLATE_VOLUME
231          // setup initial volume in synthesis parameters          // setup initial volume in synthesis parameters
# Line 430  namespace LinuxSampler { Line 451  namespace LinuxSampler {
451              processCCEvents(itCCEvent, iSubFragmentEnd);              processCCEvents(itCCEvent, iSubFragmentEnd);
452              uint8_t pan = MIDIPan;              uint8_t pan = MIDIPan;
453              if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan);              if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CalculatePan(MIDIPan);
               
             PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan]);  
             PanRightSmoother.update(AbstractEngine::PanCurve[pan]);  
454    
455              finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend;              PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan] * NotePanLeft);
456              float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();              PanRightSmoother.update(AbstractEngine::PanCurve[pan]      * NotePanRight);
457    
458                finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend * NotePitch;
459    
460                float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render() * NoteVolumeSmoother.render();
461  #ifdef CONFIG_PROCESS_MUTED_CHANNELS  #ifdef CONFIG_PROCESS_MUTED_CHANNELS
462              if (pChannel->GetMute()) fFinalVolume = 0;              if (pChannel->GetMute()) fFinalVolume = 0;
463  #endif  #endif
# Line 512  namespace LinuxSampler { Line 534  namespace LinuxSampler {
534                      pSignalUnitRack->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);                      pSignalUnitRack->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);
535                                            
536              }              }
537                
538                fFinalCutoff    *= NoteCutoff;
539                fFinalResonance *= NoteResonance;
540    
541              // limit the pitch so we don't read outside the buffer              // limit the pitch so we don't read outside the buffer
542              finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));              finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
543    
# Line 671  namespace LinuxSampler { Line 696  namespace LinuxSampler {
696      }      }
697    
698      /**      /**
699       * Process given list of MIDI note on, note off and sustain pedal events       * Process given list of MIDI note on, note off, sustain pedal events and
700       * for the given time.       * note synthesis parameter events for the given time.
701       *       *
702       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
703       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
# Line 681  namespace LinuxSampler { Line 706  namespace LinuxSampler {
706          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
707              // some voice types ignore note off              // some voice types ignore note off
708              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))) {
709                  if (itEvent->Type == Event::type_release) {                  if (itEvent->Type == Event::type_release_key) {
710                      EnterReleaseStage();                      EnterReleaseStage();
711                  } else if (itEvent->Type == Event::type_cancel_release) {                  } else if (itEvent->Type == Event::type_cancel_release_key) {
712                      if (pSignalUnitRack == NULL) {                      if (pSignalUnitRack == NULL) {
713                          pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
714                          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 692  namespace LinuxSampler { Line 717  namespace LinuxSampler {
717                      }                      }
718                  }                  }
719              }              }
720                // process stop-note events (caused by built-in instrument script function note_off())
721                if (itEvent->Type == Event::type_release_note && pNote &&
722                    pEngineChannel->pEngine->NoteByID( itEvent->Param.Note.ID ) == pNote)
723                {
724                    EnterReleaseStage();
725                }
726                // process synthesis parameter events (caused by built-in realt-time instrument script functions)
727                if (itEvent->Type == Event::type_note_synth_param && pNote &&
728                    pEngineChannel->pEngine->NoteByID( itEvent->Param.NoteSynthParam.NoteID ) == pNote)
729                {
730                    switch (itEvent->Param.NoteSynthParam.Type) {
731                        case Event::synth_param_volume:
732                            NoteVolumeSmoother.update(itEvent->Param.NoteSynthParam.AbsValue);
733                            break;
734                        case Event::synth_param_pitch:
735                            NotePitch = itEvent->Param.NoteSynthParam.AbsValue;
736                            break;
737                        case Event::synth_param_pan:
738                            NotePanLeft  = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 0 /*left*/);
739                            NotePanRight = AbstractEngine::PanCurveValueNorm(itEvent->Param.NoteSynthParam.AbsValue, 1 /*right*/);
740                            break;
741                        case Event::synth_param_cutoff:
742                            NoteCutoff = itEvent->Param.NoteSynthParam.AbsValue;
743                            break;
744                        case Event::synth_param_resonance:
745                            NoteResonance = itEvent->Param.NoteSynthParam.AbsValue;
746                            break;
747                    }
748                }
749          }          }
750      }      }
751    

Legend:
Removed from v.2879  
changed lines
  Added in v.2963

  ViewVC Help
Powered by ViewVC