/[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 244 by schoenebeck, Fri Sep 17 01:01:11 2004 UTC revision 330 by schoenebeck, Wed Dec 29 01:14:15 2004 UTC
# Line 22  Line 22 
22    
23  #include "EGADSR.h"  #include "EGADSR.h"
24  #include "Manipulator.h"  #include "Manipulator.h"
25    #include "../../common/Features.h"
26    #include "Synthesizer.h"
27    
28  #include "Voice.h"  #include "Voice.h"
29    
# Line 45  namespace LinuxSampler { namespace gig { Line 47  namespace LinuxSampler { namespace gig {
47      Voice::Voice() {      Voice::Voice() {
48          pEngine     = NULL;          pEngine     = NULL;
49          pDiskThread = NULL;          pDiskThread = NULL;
50          Active = false;          PlaybackState = playback_state_end;
51          pEG1   = NULL;          pEG1   = NULL;
52          pEG2   = NULL;          pEG2   = NULL;
53          pEG3   = NULL;          pEG3   = NULL;
# Line 56  namespace LinuxSampler { namespace gig { Line 58  namespace LinuxSampler { namespace gig {
58          pLFO2  = NULL;          pLFO2  = NULL;
59          pLFO3  = NULL;          pLFO3  = NULL;
60          KeyGroup = 0;          KeyGroup = 0;
61    
62            // select synthesis implementation (currently either pure C++ or MMX+SSE(1))
63            SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
64            SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true);
65      }      }
66    
67      Voice::~Voice() {      Voice::~Voice() {
# Line 103  namespace LinuxSampler { namespace gig { Line 109  namespace LinuxSampler { namespace gig {
109       *  Initializes and triggers the voice, a disk stream will be launched if       *  Initializes and triggers the voice, a disk stream will be launched if
110       *  needed.       *  needed.
111       *       *
112       *  @param pNoteOnEvent        - event that caused triggering of this voice       *  @param itNoteOnEvent       - event that caused triggering of this voice
113       *  @param PitchBend           - MIDI detune factor (-8192 ... +8191)       *  @param PitchBend           - MIDI detune factor (-8192 ... +8191)
114       *  @param pInstrument         - points to the loaded instrument which provides sample wave(s) and articulation data       *  @param pInstrument         - points to the loaded instrument which provides sample wave(s) and articulation data
115       *  @param iLayer              - layer number this voice refers to (only if this is a layered sound of course)       *  @param iLayer              - layer number this voice refers to (only if this is a layered sound of course)
116       *  @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)       *  @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)
117         *  @param VoiceStealing       - wether the voice is allowed to steal voices for further subvoices
118       *  @returns 0 on success, a value < 0 if something failed       *  @returns 0 on success, a value < 0 if something failed
119       */       */
120      int Voice::Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice) {      int Voice::Trigger(Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) {
121          if (!pInstrument) {          if (!pInstrument) {
122             dmsg(1,("voice::trigger: !pInstrument\n"));             dmsg(1,("voice::trigger: !pInstrument\n"));
123             exit(EXIT_FAILURE);             exit(EXIT_FAILURE);
124          }          }
125            if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // FIXME: should be removed before the final release (purpose: just a sanity check for debugging)
126                dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
127            }
128    
129          Type            = type_normal;          Type            = type_normal;
130          Active          = true;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
         MIDIKey         = pNoteOnEvent->Key;  
131          pRegion         = pInstrument->GetRegion(MIDIKey);          pRegion         = pInstrument->GetRegion(MIDIKey);
132          PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed          PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
133          Delay           = pNoteOnEvent->FragmentPos();          Delay           = itNoteOnEvent->FragmentPos();
134          pTriggerEvent   = pNoteOnEvent;          itTriggerEvent  = itNoteOnEvent;
135          pKillEvent      = NULL;          itKillEvent     = Pool<Event>::Iterator();
136            itChildVoice    = Pool<Voice>::Iterator();
137    
138          if (!pRegion) {          if (!pRegion) {
139              std::cerr << "gig::Voice: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;              std::cerr << "gig::Voice: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;
# Line 146  namespace LinuxSampler { namespace gig { Line 156  namespace LinuxSampler { namespace gig {
156                      // if this is the 1st layer then spawn further voices for all the other layers                      // if this is the 1st layer then spawn further voices for all the other layers
157                      if (iLayer == 0)                      if (iLayer == 0)
158                          for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++)                          for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++)
159                              pEngine->LaunchVoice(pNoteOnEvent, iNewLayer, ReleaseTriggerVoice);                              itChildVoice = pEngine->LaunchVoice(itNoteOnEvent, iNewLayer, ReleaseTriggerVoice, VoiceStealing);
160                      break;                      break;
161                  case ::gig::dimension_velocity:                  case ::gig::dimension_velocity:
162                      DimValues[i] = pNoteOnEvent->Velocity;                      DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
163                      break;                      break;
164                  case ::gig::dimension_channelaftertouch:                  case ::gig::dimension_channelaftertouch:
165                      DimValues[i] = 0; //TODO: we currently ignore this dimension                      DimValues[i] = 0; //TODO: we currently ignore this dimension
# Line 159  namespace LinuxSampler { namespace gig { Line 169  namespace LinuxSampler { namespace gig {
169                      DimValues[i] = (uint) ReleaseTriggerVoice;                      DimValues[i] = (uint) ReleaseTriggerVoice;
170                      break;                      break;
171                  case ::gig::dimension_keyboard:                  case ::gig::dimension_keyboard:
172                      DimValues[i] = (uint) pNoteOnEvent->Key;                      DimValues[i] = (uint) itNoteOnEvent->Param.Note.Key;
173                      break;                      break;
174                  case ::gig::dimension_modwheel:                  case ::gig::dimension_modwheel:
175                      DimValues[i] = pEngine->ControllerTable[1];                      DimValues[i] = pEngine->ControllerTable[1];
# Line 239  namespace LinuxSampler { namespace gig { Line 249  namespace LinuxSampler { namespace gig {
249          }          }
250          pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);          pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);
251    
252            pSample = pDimRgn->pSample; // sample won't change until the voice is finished
253    
254            // select channel mode (mono or stereo)
255            SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
256    
257          // get starting crossfade volume level          // get starting crossfade volume level
258          switch (pDimRgn->AttenuationController.type) {          switch (pDimRgn->AttenuationController.type) {
259              case ::gig::attenuation_ctrl_t::type_channelaftertouch:              case ::gig::attenuation_ctrl_t::type_channelaftertouch:
260                  CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet                  CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
261                  break;                  break;
262              case ::gig::attenuation_ctrl_t::type_velocity:              case ::gig::attenuation_ctrl_t::type_velocity:
263                  CrossfadeVolume = CrossfadeAttenuation(pNoteOnEvent->Velocity);                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
264                  break;                  break;
265              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
266                  CrossfadeVolume = CrossfadeAttenuation(pEngine->ControllerTable[pDimRgn->AttenuationController.controller_number]);                  CrossfadeVolume = CrossfadeAttenuation(pEngine->ControllerTable[pDimRgn->AttenuationController.controller_number]);
# Line 255  namespace LinuxSampler { namespace gig { Line 270  namespace LinuxSampler { namespace gig {
270                  CrossfadeVolume = 1.0f;                  CrossfadeVolume = 1.0f;
271          }          }
272    
273          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          PanLeft  = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) /  63.0f;
274            PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;
275    
276          Pos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)          Pos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
277    
# Line 299  namespace LinuxSampler { namespace gig { Line 315  namespace LinuxSampler { namespace gig {
315              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
316          }          }
317    
318            Volume = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity) / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
         Volume = pDimRgn->GetVelocityAttenuation(pNoteOnEvent->Velocity) / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)  
   
319    
320          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
321          {          {
# Line 315  namespace LinuxSampler { namespace gig { Line 329  namespace LinuxSampler { namespace gig {
329                      eg1controllervalue = 0; // TODO: aftertouch not yet supported                      eg1controllervalue = 0; // TODO: aftertouch not yet supported
330                      break;                      break;
331                  case ::gig::eg1_ctrl_t::type_velocity:                  case ::gig::eg1_ctrl_t::type_velocity:
332                      eg1controllervalue = pNoteOnEvent->Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
333                      break;                      break;
334                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
335                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];
# Line 341  namespace LinuxSampler { namespace gig { Line 355  namespace LinuxSampler { namespace gig {
355          }          }
356    
357    
     #if ENABLE_FILTER  
358          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
359          {          {
360              // get current value of EG2 controller              // get current value of EG2 controller
# Line 354  namespace LinuxSampler { namespace gig { Line 367  namespace LinuxSampler { namespace gig {
367                      eg2controllervalue = 0; // TODO: aftertouch not yet supported                      eg2controllervalue = 0; // TODO: aftertouch not yet supported
368                      break;                      break;
369                  case ::gig::eg2_ctrl_t::type_velocity:                  case ::gig::eg2_ctrl_t::type_velocity:
370                      eg2controllervalue = pNoteOnEvent->Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
371                      break;                      break;
372                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
373                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];
# Line 378  namespace LinuxSampler { namespace gig { Line 391  namespace LinuxSampler { namespace gig {
391                            pDimRgn->EG2Release + eg2release,                            pDimRgn->EG2Release + eg2release,
392                            Delay);                            Delay);
393          }          }
     #endif // ENABLE_FILTER  
394    
395    
396          // setup EG 3 (VCO EG)          // setup EG 3 (VCO EG)
# Line 425  namespace LinuxSampler { namespace gig { Line 437  namespace LinuxSampler { namespace gig {
437                            Delay);                            Delay);
438          }          }
439    
440      #if ENABLE_FILTER  
441          // setup LFO 2 (VCF Cutoff LFO)          // setup LFO 2 (VCF Cutoff LFO)
442          {          {
443              uint16_t lfo2_internal_depth;              uint16_t lfo2_internal_depth;
# Line 462  namespace LinuxSampler { namespace gig { Line 474  namespace LinuxSampler { namespace gig {
474                            pEngine->SampleRate,                            pEngine->SampleRate,
475                            Delay);                            Delay);
476          }          }
477      #endif // ENABLE_FILTER  
478    
479          // setup LFO 3 (VCO LFO)          // setup LFO 3 (VCO LFO)
480          {          {
# Line 501  namespace LinuxSampler { namespace gig { Line 513  namespace LinuxSampler { namespace gig {
513                            Delay);                            Delay);
514          }          }
515    
516      #if ENABLE_FILTER  
517          #if FORCE_FILTER_USAGE          #if FORCE_FILTER_USAGE
518          FilterLeft.Enabled = FilterRight.Enabled = true;          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, true);
519          #else // use filter only if instrument file told so          #else // use filter only if instrument file told so
520          FilterLeft.Enabled = FilterRight.Enabled = pDimRgn->VCFEnabled;          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, pDimRgn->VCFEnabled);
521          #endif // FORCE_FILTER_USAGE          #endif // FORCE_FILTER_USAGE
522          if (pDimRgn->VCFEnabled) {          if (pDimRgn->VCFEnabled) {
523              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL
# Line 582  namespace LinuxSampler { namespace gig { Line 594  namespace LinuxSampler { namespace gig {
594    
595              // calculate cutoff frequency              // calculate cutoff frequency
596              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = (!VCFCutoffCtrl.controller)
597                  ? exp((float) (127 - pNoteOnEvent->Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX                  ? exp((float) (127 - itNoteOnEvent->Param.Note.Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX
598                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;
599    
600              // calculate resonance              // calculate resonance
601              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0
602              if (pDimRgn->VCFKeyboardTracking) {              if (pDimRgn->VCFKeyboardTracking) {
603                  resonance += (float) (pNoteOnEvent->Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;                  resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
604              }              }
605              Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)              Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)
606    
607              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;
608              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
609    
             FilterLeft.SetParameters(cutoff,  resonance, pEngine->SampleRate);  
             FilterRight.SetParameters(cutoff, resonance, pEngine->SampleRate);  
   
610              FilterUpdateCounter = -1;              FilterUpdateCounter = -1;
611          }          }
612          else {          else {
613              VCFCutoffCtrl.controller    = 0;              VCFCutoffCtrl.controller    = 0;
614              VCFResonanceCtrl.controller = 0;              VCFResonanceCtrl.controller = 0;
615          }          }
     #endif // ENABLE_FILTER  
616    
617          return 0; // success          return 0; // success
618      }      }
# Line 622  namespace LinuxSampler { namespace gig { Line 630  namespace LinuxSampler { namespace gig {
630       */       */
631      void Voice::Render(uint Samples) {      void Voice::Render(uint Samples) {
632    
633            // select default values for synthesis mode bits
634            SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, (PitchBase * PitchBend) != 1.0f);
635            SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, true);
636            SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
637    
638          // Reset the synthesis parameter matrix          // Reset the synthesis parameter matrix
639    
640          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngine->GlobalVolume);          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngine->GlobalVolume);
641          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
     #if ENABLE_FILTER  
642          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
643          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
     #endif // ENABLE_FILTER  
   
644    
645          // Apply events to the synthesis parameter matrix          // Apply events to the synthesis parameter matrix
646          ProcessEvents(Samples);          ProcessEvents(Samples);
647    
   
648          // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment          // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment
649          pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, pKillEvent);          pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);
650      #if ENABLE_FILTER          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
651          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);          if (pEG3->Process(Samples)) { // if pitch EG is active
652      #endif // ENABLE_FILTER              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
653          pEG3->Process(Samples);              SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
654            }
655          pLFO1->Process(Samples);          pLFO1->Process(Samples);
     #if ENABLE_FILTER  
656          pLFO2->Process(Samples);          pLFO2->Process(Samples);
657      #endif // ENABLE_FILTER          if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active
658          pLFO3->Process(Samples);              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
659                SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
660            }
     #if ENABLE_FILTER  
         CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters  
     #endif // ENABLE_FILTER  
661    
662            if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
663                    CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
664    
665          switch (this->PlaybackState) {          switch (this->PlaybackState) {
666    
667              case playback_state_ram: {              case playback_state_ram: {
668                      if (RAMLoop) InterpolateAndLoop(Samples, (sample_t*) pSample->GetCache().pStart, Delay);                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
669                      else         Interpolate(Samples, (sample_t*) pSample->GetCache().pStart, Delay);  
670                        // render current fragment
671                        Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
672    
673                      if (DiskVoice) {                      if (DiskVoice) {
674                          // check if we reached the allowed limit of the sample RAM cache                          // check if we reached the allowed limit of the sample RAM cache
675                          if (Pos > MaxRAMPos) {                          if (Pos > MaxRAMPos) {
# Line 680  namespace LinuxSampler { namespace gig { Line 692  namespace LinuxSampler { namespace gig {
692                              KillImmediately();                              KillImmediately();
693                              return;                              return;
694                          }                          }
695                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (RTMath::DoubleToInt(Pos) - MaxRAMPos));                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
696                          Pos -= RTMath::DoubleToInt(Pos);                          Pos -= int(Pos);
697                            RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
698                      }                      }
699    
700                        const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
701    
702                      // add silence sample at the end if we reached the end of the stream (for the interpolator)                      // add silence sample at the end if we reached the end of the stream (for the interpolator)
703                      if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (pEngine->MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) {                      if (DiskStreamRef.State == Stream::state_end) {
704                          DiskStreamRef.pStream->WriteSilence((pEngine->MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels);                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
705                          this->PlaybackState = playback_state_end;                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
706                                // remember how many sample words there are before any silence has been added
707                                if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
708                                DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
709                            }
710                      }                      }
711    
712                      sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from                      sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
713                      Interpolate(Samples, ptr, Delay);  
714                      DiskStreamRef.pStream->IncrementReadPos(RTMath::DoubleToInt(Pos) * pSample->Channels);                      // render current audio fragment
715                      Pos -= RTMath::DoubleToInt(Pos);                      Synthesize(Samples, ptr, Delay);
716    
717                        const int iPos = (int) Pos;
718                        const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
719                        DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
720                        Pos -= iPos; // just keep fractional part of Pos
721    
722                        // change state of voice to 'end' if we really reached the end of the sample data
723                        if (RealSampleWordsLeftToRead >= 0) {
724                            RealSampleWordsLeftToRead -= readSampleWords;
725                            if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
726                        }
727                  }                  }
728                  break;                  break;
729    
730              case playback_state_end:              case playback_state_end:
731                  KillImmediately(); // free voice                  std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
732                  break;                  break;
733          }          }
734    
   
735          // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)          // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)
736          pEngine->pSynthesisEvents[Event::destination_vca]->clear();          pEngine->pSynthesisEvents[Event::destination_vca]->clear();
     #if ENABLE_FILTER  
737          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();
738          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();
     #endif // ENABLE_FILTER  
739    
740          // Reset delay          // Reset delay
741          Delay = 0;          Delay = 0;
742    
743          pTriggerEvent = NULL;          itTriggerEvent = Pool<Event>::Iterator();
744    
745          // If release stage finished, let the voice be killed          // If sample stream or release stage finished, kill the voice
746          if (pEG1->GetStage() == EGADSR::stage_end) this->PlaybackState = playback_state_end;          if (PlaybackState == playback_state_end || pEG1->GetStage() == EGADSR::stage_end) KillImmediately();
747      }      }
748    
749      /**      /**
# Line 727  namespace LinuxSampler { namespace gig { Line 754  namespace LinuxSampler { namespace gig {
754          pLFO1->Reset();          pLFO1->Reset();
755          pLFO2->Reset();          pLFO2->Reset();
756          pLFO3->Reset();          pLFO3->Reset();
757            FilterLeft.Reset();
758            FilterRight.Reset();
759          DiskStreamRef.pStream = NULL;          DiskStreamRef.pStream = NULL;
760          DiskStreamRef.hStream = 0;          DiskStreamRef.hStream = 0;
761          DiskStreamRef.State   = Stream::state_unused;          DiskStreamRef.State   = Stream::state_unused;
762          DiskStreamRef.OrderID = 0;          DiskStreamRef.OrderID = 0;
763          Active = false;          PlaybackState = playback_state_end;
764            itTriggerEvent = Pool<Event>::Iterator();
765            itKillEvent    = Pool<Event>::Iterator();
766      }      }
767    
768      /**      /**
# Line 744  namespace LinuxSampler { namespace gig { Line 775  namespace LinuxSampler { namespace gig {
775      void Voice::ProcessEvents(uint Samples) {      void Voice::ProcessEvents(uint Samples) {
776    
777          // dispatch control change events          // dispatch control change events
778          Event* pCCEvent = pEngine->pCCEvents->first();          RTList<Event>::Iterator itCCEvent = pEngine->pCCEvents->first();
779          if (Delay) { // skip events that happened before this voice was triggered          if (Delay) { // skip events that happened before this voice was triggered
780              while (pCCEvent && pCCEvent->FragmentPos() <= Delay) pCCEvent = pEngine->pCCEvents->next();              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
781          }          }
782          while (pCCEvent) {          while (itCCEvent) {
783              if (pCCEvent->Controller) { // if valid MIDI controller              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
784                  #if ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
785                  if (pCCEvent->Controller == VCFCutoffCtrl.controller) {                      *pEngine->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
                     pEngine->pSynthesisEvents[Event::destination_vcfc]->alloc_assign(*pCCEvent);  
786                  }                  }
787                  if (pCCEvent->Controller == VCFResonanceCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
788                      pEngine->pSynthesisEvents[Event::destination_vcfr]->alloc_assign(*pCCEvent);                      *pEngine->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
789                  }                  }
790                  #endif // ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
791                  if (pCCEvent->Controller == pLFO1->ExtController) {                      pLFO1->SendEvent(itCCEvent);
                     pLFO1->SendEvent(pCCEvent);  
792                  }                  }
793                  #if ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO2->ExtController) {
794                  if (pCCEvent->Controller == pLFO2->ExtController) {                      pLFO2->SendEvent(itCCEvent);
                     pLFO2->SendEvent(pCCEvent);  
795                  }                  }
796                  #endif // ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO3->ExtController) {
797                  if (pCCEvent->Controller == pLFO3->ExtController) {                      pLFO3->SendEvent(itCCEvent);
                     pLFO3->SendEvent(pCCEvent);  
798                  }                  }
799                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
800                      pCCEvent->Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
801                      pEngine->pSynthesisEvents[Event::destination_vca]->alloc_assign(*pCCEvent);                      *pEngine->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
802                  }                  }
803              }              }
804    
805              pCCEvent = pEngine->pCCEvents->next();              ++itCCEvent;
806          }          }
807    
808    
809          // process pitch events          // process pitch events
810          {          {
811              RTEList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];              RTList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];
812              Event* pVCOEvent = pVCOEventList->first();              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
813              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
814                  while (pVCOEvent && pVCOEvent->FragmentPos() <= Delay) pVCOEvent = pVCOEventList->next();                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
815              }              }
816              // apply old pitchbend value until first pitch event occurs              // apply old pitchbend value until first pitch event occurs
817              if (this->PitchBend != 1.0) {              if (this->PitchBend != 1.0) {
818                  uint end = (pVCOEvent) ? pVCOEvent->FragmentPos() : Samples;                  uint end = (itVCOEvent) ? itVCOEvent->FragmentPos() : Samples;
819                  for (uint i = Delay; i < end; i++) {                  for (uint i = Delay; i < end; i++) {
820                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
821                  }                  }
822              }              }
823              float pitch;              float pitch;
824              while (pVCOEvent) {              while (itVCOEvent) {
825                  Event* pNextVCOEvent = pVCOEventList->next();                  RTList<Event>::Iterator itNextVCOEvent = itVCOEvent;
826                    ++itNextVCOEvent;
827    
828                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
829                  uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples;                  uint end = (itNextVCOEvent) ? itNextVCOEvent->FragmentPos() : Samples;
830    
831                  pitch = RTMath::CentsToFreqRatio(((double) pVCOEvent->Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents                  pitch = RTMath::CentsToFreqRatio(((double) itVCOEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
832    
833                  // apply pitch value to the pitch parameter sequence                  // apply pitch value to the pitch parameter sequence
834                  for (uint i = pVCOEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCOEvent->FragmentPos(); i < end; i++) {
835                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
836                  }                  }
837    
838                  pVCOEvent = pNextVCOEvent;                  itVCOEvent = itNextVCOEvent;
839                }
840                if (!pVCOEventList->isEmpty()) {
841                    this->PitchBend = pitch;
842                    SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
843                    SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
844              }              }
             if (pVCOEventList->last()) this->PitchBend = pitch;  
845          }          }
846    
847          // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)          // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)
848          {          {
849              RTEList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];              RTList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];
850              Event* pVCAEvent = pVCAEventList->first();              RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
851              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
852                  while (pVCAEvent && pVCAEvent->FragmentPos() <= Delay) pVCAEvent = pVCAEventList->next();                  while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
853              }              }
854              float crossfadevolume;              float crossfadevolume;
855              while (pVCAEvent) {              while (itVCAEvent) {
856                  Event* pNextVCAEvent = pVCAEventList->next();                  RTList<Event>::Iterator itNextVCAEvent = itVCAEvent;
857                    ++itNextVCAEvent;
858    
859                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
860                  uint end = (pNextVCAEvent) ? pNextVCAEvent->FragmentPos() : Samples;                  uint end = (itNextVCAEvent) ? itNextVCAEvent->FragmentPos() : Samples;
861    
862                  crossfadevolume = CrossfadeAttenuation(pVCAEvent->Value);                  crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
863    
864                  float effective_volume = crossfadevolume * this->Volume * pEngine->GlobalVolume;                  float effective_volume = crossfadevolume * this->Volume * pEngine->GlobalVolume;
865    
866                  // apply volume value to the volume parameter sequence                  // apply volume value to the volume parameter sequence
867                  for (uint i = pVCAEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
868                      pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;                      pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;
869                  }                  }
870    
871                  pVCAEvent = pNextVCAEvent;                  itVCAEvent = itNextVCAEvent;
872              }              }
873              if (pVCAEventList->last()) this->CrossfadeVolume = crossfadevolume;              if (!pVCAEventList->isEmpty()) this->CrossfadeVolume = crossfadevolume;
874          }          }
875    
     #if ENABLE_FILTER  
876          // process filter cutoff events          // process filter cutoff events
877          {          {
878              RTEList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];              RTList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];
879              Event* pCutoffEvent = pCutoffEventList->first();              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
880              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
881                  while (pCutoffEvent && pCutoffEvent->FragmentPos() <= Delay) pCutoffEvent = pCutoffEventList->next();                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
882              }              }
883              float cutoff;              float cutoff;
884              while (pCutoffEvent) {              while (itCutoffEvent) {
885                  Event* pNextCutoffEvent = pCutoffEventList->next();                  RTList<Event>::Iterator itNextCutoffEvent = itCutoffEvent;
886                    ++itNextCutoffEvent;
887    
888                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
889                  uint end = (pNextCutoffEvent) ? pNextCutoffEvent->FragmentPos() : Samples;                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
890    
891                  cutoff = exp((float) pCutoffEvent->Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;                  cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;
892    
893                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
894                  for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) {                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
895                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
896                  }                  }
897    
898                  pCutoffEvent = pNextCutoffEvent;                  itCutoffEvent = itNextCutoffEvent;
899              }              }
900              if (pCutoffEventList->last()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time              if (!pCutoffEventList->isEmpty()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time
901          }          }
902    
903          // process filter resonance events          // process filter resonance events
904          {          {
905              RTEList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];              RTList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];
906              Event* pResonanceEvent = pResonanceEventList->first();              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
907              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
908                  while (pResonanceEvent && pResonanceEvent->FragmentPos() <= Delay) pResonanceEvent = pResonanceEventList->next();                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
909              }              }
910              while (pResonanceEvent) {              while (itResonanceEvent) {
911                  Event* pNextResonanceEvent = pResonanceEventList->next();                  RTList<Event>::Iterator itNextResonanceEvent = itResonanceEvent;
912                    ++itNextResonanceEvent;
913    
914                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
915                  uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples;                  uint end = (itNextResonanceEvent) ? itNextResonanceEvent->FragmentPos() : Samples;
916    
917                  // convert absolute controller value to differential                  // convert absolute controller value to differential
918                  int ctrldelta = pResonanceEvent->Value - VCFResonanceCtrl.value;                  int ctrldelta = itResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;
919                  VCFResonanceCtrl.value = pResonanceEvent->Value;                  VCFResonanceCtrl.value = itResonanceEvent->Param.CC.Value;
920    
921                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
922    
923                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
924                  for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) {                  for (uint i = itResonanceEvent->FragmentPos(); i < end; i++) {
925                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
926                  }                  }
927    
928                  pResonanceEvent = pNextResonanceEvent;                  itResonanceEvent = itNextResonanceEvent;
929              }              }
930              if (pResonanceEventList->last()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Value * 0.00787f; // needed for initialization of parameter matrix next time              if (!pResonanceEventList->isEmpty()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Param.CC.Value * 0.00787f; // needed for initialization of parameter matrix next time
931          }          }
     #endif // ENABLE_FILTER  
932      }      }
933    
     #if ENABLE_FILTER  
934      /**      /**
935       * Calculate all necessary, final biquad filter parameters.       * Calculate all necessary, final biquad filter parameters.
936       *       *
937       * @param Samples - number of samples to be rendered in this audio fragment cycle       * @param Samples - number of samples to be rendered in this audio fragment cycle
938       */       */
939      void Voice::CalculateBiquadParameters(uint Samples) {      void Voice::CalculateBiquadParameters(uint Samples) {
         if (!FilterLeft.Enabled) return;  
   
940          biquad_param_t bqbase;          biquad_param_t bqbase;
941          biquad_param_t bqmain;          biquad_param_t bqmain;
942          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
943          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
944          FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);          FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
945            FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
946          pEngine->pBasicFilterParameters[0] = bqbase;          pEngine->pBasicFilterParameters[0] = bqbase;
947          pEngine->pMainFilterParameters[0]  = bqmain;          pEngine->pMainFilterParameters[0]  = bqmain;
948    
949          float* bq;          float* bq;
950          for (int i = 1; i < Samples; i++) {          for (int i = 1; i < Samples; i++) {
951              // recalculate biquad parameters if cutoff or resonance differ from previous sample point              // recalculate biquad parameters if cutoff or resonance differ from previous sample point
952              if (!(i & FILTER_UPDATE_MASK)) if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||              if (!(i & FILTER_UPDATE_MASK)) {
953                                                 pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff) {                  if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
954                  prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff)
955                  prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];                  {
956                  FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
957                        prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
958                        FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
959                        FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
960                    }
961              }              }
962    
963              //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'              //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
964              bq    = (float*) &pEngine->pBasicFilterParameters[i];              bq    = (float*) &pEngine->pBasicFilterParameters[i];
965              bq[0] = bqbase.a1;              bq[0] = bqbase.b0;
966              bq[1] = bqbase.a2;              bq[1] = bqbase.b1;
967              bq[2] = bqbase.b0;              bq[2] = bqbase.b2;
968              bq[3] = bqbase.b1;              bq[3] = bqbase.a1;
969              bq[4] = bqbase.b2;              bq[4] = bqbase.a2;
970    
971              // same as 'pEngine->pMainFilterParameters[i] = bqmain;'              // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
972              bq    = (float*) &pEngine->pMainFilterParameters[i];              bq    = (float*) &pEngine->pMainFilterParameters[i];
973              bq[0] = bqmain.a1;              bq[0] = bqmain.b0;
974              bq[1] = bqmain.a2;              bq[1] = bqmain.b1;
975              bq[2] = bqmain.b0;              bq[2] = bqmain.b2;
976              bq[3] = bqmain.b1;              bq[3] = bqmain.a1;
977              bq[4] = bqmain.b2;              bq[4] = bqmain.a2;
978          }          }
979      }      }
     #endif // ENABLE_FILTER  
980    
981      /**      /**
982       *  Interpolates the input audio data (no loop).       *  Synthesizes the current audio fragment for this voice.
983       *       *
984       *  @param Samples - number of sample points to be rendered in this audio       *  @param Samples - number of sample points to be rendered in this audio
985       *                   fragment cycle       *                   fragment cycle
986       *  @param pSrc    - pointer to input sample data       *  @param pSrc    - pointer to input sample data
987       *  @param Skip    - number of sample points to skip in output buffer       *  @param Skip    - number of sample points to skip in output buffer
988       */       */
989      void Voice::Interpolate(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
990          int i = Skip;          RunSynthesisFunction(SynthesisMode, *this, Samples, pSrc, Skip);
   
         // FIXME: assuming either mono or stereo  
         if (this->pSample->Channels == 2) { // Stereo Sample  
             while (i < Samples) {  
                 InterpolateOneStep_Stereo(pSrc, i,  
                                           pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                           pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                           pEngine->pBasicFilterParameters[i],  
                                           pEngine->pMainFilterParameters[i]);  
             }  
         }  
         else { // Mono Sample  
             while (i < Samples) {  
                 InterpolateOneStep_Mono(pSrc, i,  
                                         pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                         pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                         pEngine->pBasicFilterParameters[i],  
                                         pEngine->pMainFilterParameters[i]);  
             }  
         }  
     }  
   
     /**  
      *  Interpolates the input audio data, this method honors looping.  
      *  
      *  @param Samples - number of sample points to be rendered in this audio  
      *                   fragment cycle  
      *  @param pSrc    - pointer to input sample data  
      *  @param Skip    - number of sample points to skip in output buffer  
      */  
     void Voice::InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip) {  
         int i = Skip;  
   
         // FIXME: assuming either mono or stereo  
         if (pSample->Channels == 2) { // Stereo Sample  
             if (pSample->LoopPlayCount) {  
                 // render loop (loop count limited)  
                 while (i < Samples && LoopCyclesLeft) {  
                     InterpolateOneStep_Stereo(pSrc, i,  
                                               pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                               pEngine->pBasicFilterParameters[i],  
                                               pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;  
                         LoopCyclesLeft--;  
                     }  
                 }  
                 // render on without loop  
                 while (i < Samples) {  
                     InterpolateOneStep_Stereo(pSrc, i,  
                                               pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                               pEngine->pBasicFilterParameters[i],  
                                               pEngine->pMainFilterParameters[i]);  
                 }  
             }  
             else { // render loop (endless loop)  
                 while (i < Samples) {  
                     InterpolateOneStep_Stereo(pSrc, i,  
                                               pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                               pEngine->pBasicFilterParameters[i],  
                                               pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);  
                     }  
                 }  
             }  
         }  
         else { // Mono Sample  
             if (pSample->LoopPlayCount) {  
                 // render loop (loop count limited)  
                 while (i < Samples && LoopCyclesLeft) {  
                     InterpolateOneStep_Mono(pSrc, i,  
                                             pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                             pEngine->pBasicFilterParameters[i],  
                                             pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;  
                         LoopCyclesLeft--;  
                     }  
                 }  
                 // render on without loop  
                 while (i < Samples) {  
                     InterpolateOneStep_Mono(pSrc, i,  
                                             pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                             pEngine->pBasicFilterParameters[i],  
                                             pEngine->pMainFilterParameters[i]);  
                 }  
             }  
             else { // render loop (endless loop)  
                 while (i < Samples) {  
                     InterpolateOneStep_Mono(pSrc, i,  
                                             pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                             pEngine->pBasicFilterParameters[i],  
                                             pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;  
                     }  
                 }  
             }  
         }  
991      }      }
992    
993      /**      /**
# Line 1084  namespace LinuxSampler { namespace gig { Line 1012  namespace LinuxSampler { namespace gig {
1012       *  of a voice, a kill process cannot be cancalled and is therefore       *  of a voice, a kill process cannot be cancalled and is therefore
1013       *  usually used for voice stealing and key group conflicts.       *  usually used for voice stealing and key group conflicts.
1014       *       *
1015       *  @param pKillEvent - event which caused the voice to be killed       *  @param itKillEvent - event which caused the voice to be killed
1016       */       */
1017      void Voice::Kill(Event* pKillEvent) {      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1018          if (pTriggerEvent && pKillEvent->FragmentPos() <= pTriggerEvent->FragmentPos()) return;          //FIXME: just two sanity checks for debugging, can be removed
1019          this->pKillEvent = pKillEvent;          if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
1020            if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
1021    
1022            if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1023            this->itKillEvent = itKillEvent;
1024      }      }
1025    
1026  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.244  
changed lines
  Added in v.330

  ViewVC Help
Powered by ViewVC