/[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 2205 by iliev, Mon Jul 11 17:52:01 2011 UTC revision 2217 by iliev, Tue Jul 26 15:51:30 2011 UTC
# Line 26  Line 26 
26    
27  namespace LinuxSampler {  namespace LinuxSampler {
28    
29      AbstractVoice::AbstractVoice() {      AbstractVoice::AbstractVoice(SignalUnitRack* pRack): pSignalUnitRack(pRack) {
30          pEngineChannel = NULL;          pEngineChannel = NULL;
31          pLFO1 = new LFOUnsigned(1.0f);  // amplitude LFO (0..1 range)          pLFO1 = new LFOUnsigned(1.0f);  // amplitude LFO (0..1 range)
32          pLFO2 = new LFOUnsigned(1.0f);  // filter LFO (0..1 range)          pLFO2 = new LFOUnsigned(1.0f);  // filter LFO (0..1 range)
# Line 135  namespace LinuxSampler { Line 135  namespace LinuxSampler {
135          PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);          PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);
136          PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);          PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);
137    
         finalSynthesisParameters.dPos = RgnInfo.SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)  
         Pos = RgnInfo.SampleStartOffset;  
   
138          // 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
139          long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;          long cachedsamples = GetSampleCacheSize() / SmplInfo.FrameSize;
140          DiskVoice          = cachedsamples < SmplInfo.TotalFrameCount;          DiskVoice          = cachedsamples < SmplInfo.TotalFrameCount;
141    
142            SetSampleStartOffset();
143    
144          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
145              if (cachedsamples > (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH)) {              if (cachedsamples > (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH)) {
146                  MaxRAMPos = cachedsamples - (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / SmplInfo.ChannelCount; //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 - (GetEngine()->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / SmplInfo.ChannelCount; //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)
# Line 178  namespace LinuxSampler { Line 177  namespace LinuxSampler {
177          // 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
178          const double velrelease = 1 / GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);          const double velrelease = 1 / GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
179    
180          if (GetSignalUnitRack() == NULL) { // setup EG 1 (VCA EG)          if (pSignalUnitRack == NULL) { // setup EG 1 (VCA EG)
181              // get current value of EG1 controller              // get current value of EG1 controller
182              double eg1controllervalue = GetEG1ControllerValue(itNoteOnEvent->Param.Note.Velocity);              double eg1controllervalue = GetEG1ControllerValue(itNoteOnEvent->Param.Note.Velocity);
183    
# Line 187  namespace LinuxSampler { Line 186  namespace LinuxSampler {
186    
187              TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);              TriggerEG1(egInfo, velrelease, velocityAttenuation, GetEngine()->SampleRate, itNoteOnEvent->Param.Note.Velocity);
188          } else {          } else {
189              GetSignalUnitRack()->Trigger();              pSignalUnitRack->Trigger();
190          }          }
191    
192  #ifdef CONFIG_INTERPOLATE_VOLUME  #ifdef CONFIG_INTERPOLATE_VOLUME
# Line 201  namespace LinuxSampler { Line 200  namespace LinuxSampler {
200      #else      #else
201          {          {
202              float finalVolume;              float finalVolume;
203              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
204                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pEG1->getLevel();                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pEG1->getLevel();
205              } else {              } else {
206                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * GetSignalUnitRack()->GetEndpointUnit()->GetVolume();                  finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * pSignalUnitRack->GetEndpointUnit()->GetVolume();
207              }              }
208    
209              finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;              finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;
# Line 213  namespace LinuxSampler { Line 212  namespace LinuxSampler {
212      #endif      #endif
213  #endif  #endif
214    
215          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
216              // setup EG 2 (VCF Cutoff EG)              // setup EG 2 (VCF Cutoff EG)
217              {              {
218                  // get current value of EG2 controller                  // get current value of EG2 controller
# Line 295  namespace LinuxSampler { Line 294  namespace LinuxSampler {
294    
295          return 0; // success          return 0; // success
296      }      }
297        
298        void AbstractVoice::SetSampleStartOffset() {
299            finalSynthesisParameters.dPos = RgnInfo.SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
300            Pos = RgnInfo.SampleStartOffset;
301        }
302    
303      /**      /**
304       *  Synthesizes the current audio fragment for this voice.       *  Synthesizes the current audio fragment for this voice.
# Line 352  namespace LinuxSampler { Line 356  namespace LinuxSampler {
356                  // drivers that use Samples < MaxSamplesPerCycle).                  // drivers that use Samples < MaxSamplesPerCycle).
357                  // End the EG1 here, at pos 0, with a shorter max fade                  // End the EG1 here, at pos 0, with a shorter max fade
358                  // out time.                  // out time.
359                  if (GetSignalUnitRack() == NULL) {                  if (pSignalUnitRack == NULL) {
360                      pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                      pEG1->enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
361                  } else {                  } else {
362                      // TODO:                      // TODO:
# Line 384  namespace LinuxSampler { Line 388  namespace LinuxSampler {
388              processTransitionEvents(itNoteEvent, iSubFragmentEnd);              processTransitionEvents(itNoteEvent, iSubFragmentEnd);
389              processGroupEvents(itGroupEvent, iSubFragmentEnd);              processGroupEvents(itGroupEvent, iSubFragmentEnd);
390    
391              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
392                  // if the voice was killed in this subfragment, or if the                  // if the voice was killed in this subfragment, or if the
393                  // filter EG is finished, switch EG1 to fade out stage                  // filter EG is finished, switch EG1 to fade out stage
394                  if ((itKillEvent && killPos <= iSubFragmentEnd) ||                  if ((itKillEvent && killPos <= iSubFragmentEnd) ||
# Line 440  namespace LinuxSampler { Line 444  namespace LinuxSampler {
444                  }*/                  }*/
445                  // TODO: ^^^                  // TODO: ^^^
446    
447                  fFinalVolume   *= GetSignalUnitRack()->GetEndpointUnit()->GetVolume();                  fFinalVolume   *= pSignalUnitRack->GetEndpointUnit()->GetVolume();
448                  fFinalCutoff    = GetSignalUnitRack()->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);                  fFinalCutoff    = pSignalUnitRack->GetEndpointUnit()->CalculateFilterCutoff(fFinalCutoff);
449                  fFinalResonance = GetSignalUnitRack()->GetEndpointUnit()->CalculateResonance(fFinalResonance);                  fFinalResonance = pSignalUnitRack->GetEndpointUnit()->CalculateResonance(fFinalResonance);
450                                    
451                  finalSynthesisParameters.fFinalPitch =                  finalSynthesisParameters.fFinalPitch =
452                      GetSignalUnitRack()->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);                      pSignalUnitRack->GetEndpointUnit()->CalculatePitch(finalSynthesisParameters.fFinalPitch);
453                                            
454              }              }
455                            
# Line 483  namespace LinuxSampler { Line 487  namespace LinuxSampler {
487              // render audio for one subfragment              // render audio for one subfragment
488              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
489    
490              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
491                  // stop the rendering if volume EG is finished                  // stop the rendering if volume EG is finished
492                  if (pEG1->getSegmentType() == EG::segment_end) break;                  if (pEG1->getSegmentType() == EG::segment_end) break;
493              } else {              } else {
494                  // stop the rendering if the endpoint unit is not active                  // stop the rendering if the endpoint unit is not active
495                  if (!GetSignalUnitRack()->GetEndpointUnit()->Active()) break;                  if (!pSignalUnitRack->GetEndpointUnit()->Active()) break;
496              }              }
497    
498              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
499    
500              if (GetSignalUnitRack() == NULL) {              if (pSignalUnitRack == NULL) {
501                  // increment envelopes' positions                  // increment envelopes' positions
502                  if (pEG1->active()) {                  if (pEG1->active()) {
503    
# Line 518  namespace LinuxSampler { Line 522  namespace LinuxSampler {
522                      }*/                      }*/
523                  // TODO: ^^^                  // TODO: ^^^
524                                    
525                  GetSignalUnitRack()->Increment();                  pSignalUnitRack->Increment();
526              }              }
527    
528              Pos = newPos;              Pos = newPos;
# Line 550  namespace LinuxSampler { Line 554  namespace LinuxSampler {
554                  if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {                  if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
555                      processResonanceEvent(itEvent);                      processResonanceEvent(itEvent);
556                  }                  }
557                  if (GetSignalUnitRack() == NULL) {                  if (pSignalUnitRack == NULL) {
558                      if (itEvent->Param.CC.Controller == pLFO1->ExtController) {                      if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
559                          pLFO1->update(itEvent->Param.CC.Value);                          pLFO1->update(itEvent->Param.CC.Value);
560                      }                      }
# Line 572  namespace LinuxSampler { Line 576  namespace LinuxSampler {
576              }              }
577    
578              ProcessCCEvent(itEvent);              ProcessCCEvent(itEvent);
579              if (GetSignalUnitRack() != NULL) {              if (pSignalUnitRack != NULL) {
580                  GetSignalUnitRack()->ProcessCCEvent(itEvent);                  pSignalUnitRack->ProcessCCEvent(itEvent);
581              }              }
582          }          }
583      }      }
# Line 606  namespace LinuxSampler { Line 610  namespace LinuxSampler {
610                  if (itEvent->Type == Event::type_release) {                  if (itEvent->Type == Event::type_release) {
611                      EnterReleaseStage();                      EnterReleaseStage();
612                  } else if (itEvent->Type == Event::type_cancel_release) {                  } else if (itEvent->Type == Event::type_cancel_release) {
613                      if (GetSignalUnitRack() == NULL) {                      if (pSignalUnitRack == NULL) {
614                          pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEG1->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
615                          pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEG2->update(EG::event_cancel_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
616                      } else {                      } else {
617                          GetSignalUnitRack()->CancelRelease();                          pSignalUnitRack->CancelRelease();
618                      }                      }
619                  }                  }
620              }              }
# Line 638  namespace LinuxSampler { Line 642  namespace LinuxSampler {
642       * @param itNoteOffEvent - event which causes this voice to die soon       * @param itNoteOffEvent - event which causes this voice to die soon
643       */       */
644      void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {      void AbstractVoice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
645          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
646              const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());              const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
647              pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;              pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
648          } else {          } else {
# Line 705  namespace LinuxSampler { Line 709  namespace LinuxSampler {
709      }      }
710    
711      void AbstractVoice::EnterReleaseStage() {      void AbstractVoice::EnterReleaseStage() {
712          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
713              pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);              pEG1->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
714              pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);              pEG2->update(EG::event_release, GetEngine()->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
715          } else {          } else {
716              GetSignalUnitRack()->EnterReleaseStage();              pSignalUnitRack->EnterReleaseStage();
717          }          }
718      }      }
719    
720      bool AbstractVoice::EG1Finished() {      bool AbstractVoice::EG1Finished() {
721          if (GetSignalUnitRack() == NULL) {          if (pSignalUnitRack == NULL) {
722              return pEG1->getSegmentType() == EG::segment_end;              return pEG1->getSegmentType() == EG::segment_end;
723          } else {          } else {
724              return !GetSignalUnitRack()->GetEndpointUnit()->Active();              return !pSignalUnitRack->GetEndpointUnit()->Active();
725          }          }
726      }      }
727    

Legend:
Removed from v.2205  
changed lines
  Added in v.2217

  ViewVC Help
Powered by ViewVC