/[svn]/linuxsampler/trunk/src/engines/gig/Voice.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/gig/Voice.cpp

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

revision 830 by persson, Sun Jan 15 18:23:11 2006 UTC revision 877 by persson, Sun Jun 25 13:54:17 2006 UTC
# Line 29  Line 29 
29    
30  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
31    
     const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());  
   
     float Voice::CalculateFilterCutoffCoeff() {  
         return log(CONFIG_FILTER_CUTOFF_MAX / CONFIG_FILTER_CUTOFF_MIN);  
     }  
   
32      Voice::Voice() {      Voice::Voice() {
33          pEngine     = NULL;          pEngine     = NULL;
34          pDiskThread = NULL;          pDiskThread = NULL;
# Line 104  namespace LinuxSampler { namespace gig { Line 98  namespace LinuxSampler { namespace gig {
98          // calculate volume          // calculate volume
99          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
100    
101          Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)          float volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
102    
103          Volume *= pDimRgn->SampleAttenuation;          volume *= pDimRgn->SampleAttenuation;
104    
105          // the volume of release triggered samples depends on note length          // the volume of release triggered samples depends on note length
106          if (Type == type_release_trigger) {          if (Type == type_release_trigger) {
# Line 114  namespace LinuxSampler { namespace gig { Line 108  namespace LinuxSampler { namespace gig {
108                                       pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;                                       pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
109              float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;              float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
110              if (attenuation <= 0) return -1;              if (attenuation <= 0) return -1;
111              Volume *= attenuation;              volume *= attenuation;
112          }          }
113    
114          // select channel mode (mono or stereo)          // select channel mode (mono or stereo)
115          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
116    
117          // get starting crossfade volume level          // get starting crossfade volume level
118            float crossfadeVolume;
119          switch (pDimRgn->AttenuationController.type) {          switch (pDimRgn->AttenuationController.type) {
120              case ::gig::attenuation_ctrl_t::type_channelaftertouch:              case ::gig::attenuation_ctrl_t::type_channelaftertouch:
121                  CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet                  crossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
122                  break;                  break;
123              case ::gig::attenuation_ctrl_t::type_velocity:              case ::gig::attenuation_ctrl_t::type_velocity:
124                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity)];
125                  break;                  break;
126              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
127                  CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number])];
128                  break;                  break;
129              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
130              default:              default:
131                  CrossfadeVolume = 1.0f;                  crossfadeVolume = 1.0f;
132          }          }
133    
134          PanLeft  = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) /  63.0f;          VolumeLeft  = volume * Engine::PanCurve[64 - pDimRgn->Pan];
135          PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;          VolumeRight = volume * Engine::PanCurve[64 + pDimRgn->Pan];
136    
137            float subfragmentRate = pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
138            CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
139            VolumeSmoother.trigger(pEngineChannel->GlobalVolume, subfragmentRate);
140            PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);
141            PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);
142    
143          finalSynthesisParameters.dPos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)          finalSynthesisParameters.dPos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
144          Pos = pDimRgn->SampleStartOffset;          Pos = pDimRgn->SampleStartOffset;
# Line 146  namespace LinuxSampler { namespace gig { Line 147  namespace LinuxSampler { namespace gig {
147          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
148          DiskVoice          = cachedsamples < pSample->SamplesTotal;          DiskVoice          = cachedsamples < pSample->SamplesTotal;
149    
150            const DLS::sample_loop_t& loopinfo = pDimRgn->pSampleLoops[0];
151    
152          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
153              MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)              MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)
154    
155              // check if there's a loop defined which completely fits into the cached (RAM) part of the sample              // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
156              RAMLoop = (pSample->Loops && pSample->LoopEnd <= MaxRAMPos);              RAMLoop = (pDimRgn->SampleLoops && (loopinfo.LoopStart + loopinfo.LoopLength) <= MaxRAMPos);
157    
158              if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {              if (pDiskThread->OrderNewStream(&DiskStreamRef, pDimRgn, MaxRAMPos, !RAMLoop) < 0) {
159                  dmsg(1,("Disk stream order failed!\n"));                  dmsg(1,("Disk stream order failed!\n"));
160                  KillImmediately();                  KillImmediately();
161                  return -1;                  return -1;
# Line 161  namespace LinuxSampler { namespace gig { Line 164  namespace LinuxSampler { namespace gig {
164          }          }
165          else { // RAM only voice          else { // RAM only voice
166              MaxRAMPos = cachedsamples;              MaxRAMPos = cachedsamples;
167              RAMLoop = (pSample->Loops != 0);              RAMLoop = (pDimRgn->SampleLoops != 0);
168              dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));              dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
169          }          }
170          if (RAMLoop) {          if (RAMLoop) {
171              loop.uiTotalCycles = pSample->LoopPlayCount;              loop.uiTotalCycles = pSample->LoopPlayCount;
172              loop.uiCyclesLeft  = pSample->LoopPlayCount;              loop.uiCyclesLeft  = pSample->LoopPlayCount;
173              loop.uiStart       = pSample->LoopStart;              loop.uiStart       = loopinfo.LoopStart;
174              loop.uiEnd         = pSample->LoopEnd;              loop.uiEnd         = loopinfo.LoopStart + loopinfo.LoopLength;
175              loop.uiSize        = pSample->LoopSize;              loop.uiSize        = loopinfo.LoopLength;
176          }          }
177    
178          // calculate initial pitch value          // calculate initial pitch value
# Line 223  namespace LinuxSampler { namespace gig { Line 226  namespace LinuxSampler { namespace gig {
226                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
227          }          }
228    
229    #ifdef CONFIG_INTERPOLATE_VOLUME
230          // setup initial volume in synthesis parameters          // setup initial volume in synthesis parameters
231          fFinalVolume = getVolume() * EG1.getLevel();  #ifdef CONFIG_PROCESS_MUTED_CHANNELS
232          finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * PanLeft;          if (pEngineChannel->GetMute()) {
233          finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight;              finalSynthesisParameters.fFinalVolumeLeft  = 0;
234                finalSynthesisParameters.fFinalVolumeRight = 0;
235            }
236            else
237    #else
238            {
239                float finalVolume = pEngineChannel->GlobalVolume * crossfadeVolume * EG1.getLevel();
240    
241                finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;
242                finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;
243            }
244    #endif
245    #endif
246    
247          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
248          {          {
# Line 316  namespace LinuxSampler { namespace gig { Line 331  namespace LinuxSampler { namespace gig {
331                      pLFO1->ExtController = 0; // no external controller                      pLFO1->ExtController = 0; // no external controller
332                      bLFO1Enabled         = false;                      bLFO1Enabled         = false;
333              }              }
334              if (bLFO1Enabled) pLFO1->trigger(pDimRgn->LFO1Frequency,              if (bLFO1Enabled) {
335                                               start_level_max,                  pLFO1->trigger(pDimRgn->LFO1Frequency,
336                                               lfo1_internal_depth,                                 start_level_max,
337                                               pDimRgn->LFO1ControlDepth,                                 lfo1_internal_depth,
338                                               pDimRgn->LFO1FlipPhase,                                 pDimRgn->LFO1ControlDepth,
339                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 pDimRgn->LFO1FlipPhase,
340                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
341                    pLFO1->update(pLFO1->ExtController ? pEngineChannel->ControllerTable[pLFO1->ExtController] : 0);
342                }
343          }          }
344    
345    
# Line 359  namespace LinuxSampler { namespace gig { Line 377  namespace LinuxSampler { namespace gig {
377                      pLFO2->ExtController = 0; // no external controller                      pLFO2->ExtController = 0; // no external controller
378                      bLFO2Enabled         = false;                      bLFO2Enabled         = false;
379              }              }
380              if (bLFO2Enabled) pLFO2->trigger(pDimRgn->LFO2Frequency,              if (bLFO2Enabled) {
381                                               start_level_max,                  pLFO2->trigger(pDimRgn->LFO2Frequency,
382                                               lfo2_internal_depth,                                 start_level_max,
383                                               pDimRgn->LFO2ControlDepth,                                 lfo2_internal_depth,
384                                               pDimRgn->LFO2FlipPhase,                                 pDimRgn->LFO2ControlDepth,
385                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 pDimRgn->LFO2FlipPhase,
386                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
387                    pLFO2->update(pLFO2->ExtController ? pEngineChannel->ControllerTable[pLFO2->ExtController] : 0);
388                }
389          }          }
390    
391    
# Line 402  namespace LinuxSampler { namespace gig { Line 423  namespace LinuxSampler { namespace gig {
423                      pLFO3->ExtController = 0; // no external controller                      pLFO3->ExtController = 0; // no external controller
424                      bLFO3Enabled         = false;                      bLFO3Enabled         = false;
425              }              }
426              if (bLFO3Enabled) pLFO3->trigger(pDimRgn->LFO3Frequency,              if (bLFO3Enabled) {
427                                               start_level_mid,                  pLFO3->trigger(pDimRgn->LFO3Frequency,
428                                               lfo3_internal_depth,                                 start_level_mid,
429                                               pDimRgn->LFO3ControlDepth,                                 lfo3_internal_depth,
430                                               false,                                 pDimRgn->LFO3ControlDepth,
431                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 false,
432                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
433                    pLFO3->update(pLFO3->ExtController ? pEngineChannel->ControllerTable[pLFO3->ExtController] : 0);
434                }
435          }          }
436    
437    
# Line 507  namespace LinuxSampler { namespace gig { Line 531  namespace LinuxSampler { namespace gig {
531              else {              else {
532                  cvalue = pDimRgn->VCFCutoff;                  cvalue = pDimRgn->VCFCutoff;
533              }              }
534              cutoff *= float(cvalue) * 0.00787402f; // (1 / 127)              cutoff *= float(cvalue);
535              if (cutoff > 1.0) cutoff = 1.0;              if (cutoff > 127.0f) cutoff = 127.0f;
             cutoff = (cutoff < 0.5 ? cutoff * 4826 - 1 : cutoff * 5715 - 449);  
             if (cutoff < 1.0) cutoff = 1.0;  
536    
537              // calculate resonance              // calculate resonance
538              float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : pDimRgn->VCFResonance) * 0.00787f; // 0.0..1.0              float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : pDimRgn->VCFResonance);
539    
540              VCFCutoffCtrl.fvalue    = cutoff - 1.0;              VCFCutoffCtrl.fvalue    = cutoff;
541              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
542          }          }
543          else {          else {
# Line 645  namespace LinuxSampler { namespace gig { Line 667  namespace LinuxSampler { namespace gig {
667       * for the given time.       * for the given time.
668       *       *
669       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
670       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
671       */       */
672      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
673          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
# Line 664  namespace LinuxSampler { namespace gig { Line 686  namespace LinuxSampler { namespace gig {
686       * the given time.       * the given time.
687       *       *
688       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
689       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
690       */       */
691      void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {      void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
692          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
# Line 687  namespace LinuxSampler { namespace gig { Line 709  namespace LinuxSampler { namespace gig {
709                  }                  }
710                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
711                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {
712                      processCrossFadeEvent(itEvent);                      CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
713                    }
714                    if (itEvent->Param.CC.Controller == 7) { // volume
715                        VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value] * CONFIG_GLOBAL_ATTENUATION);
716                    } else if (itEvent->Param.CC.Controller == 10) { // panpot
717                        PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]);
718                        PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]);
719                  }                  }
720              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
721                  processPitchEvent(itEvent);                  processPitchEvent(itEvent);
# Line 701  namespace LinuxSampler { namespace gig { Line 729  namespace LinuxSampler { namespace gig {
729          PitchBend = pitch;          PitchBend = pitch;
730      }      }
731    
     void Voice::processCrossFadeEvent(RTList<Event>::Iterator& itEvent) {  
         CrossfadeVolume = CrossfadeAttenuation(itEvent->Param.CC.Value);  
         fFinalVolume = getVolume();  
     }  
   
     float Voice::getVolume() {  
         #if CONFIG_PROCESS_MUTED_CHANNELS  
         return pEngineChannel->GetMute() ? 0 : (Volume * CrossfadeVolume * pEngineChannel->GlobalVolume);  
         #else  
         return Volume * CrossfadeVolume * pEngineChannel->GlobalVolume;  
         #endif  
     }  
   
732      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
733          int ccvalue = itEvent->Param.CC.Value;          int ccvalue = itEvent->Param.CC.Value;
734          if (VCFCutoffCtrl.value == ccvalue) return;          if (VCFCutoffCtrl.value == ccvalue) return;
735          VCFCutoffCtrl.value == ccvalue;          VCFCutoffCtrl.value == ccvalue;
736          if (pDimRgn->VCFCutoffControllerInvert)  ccvalue = 127 - ccvalue;          if (pDimRgn->VCFCutoffControllerInvert)  ccvalue = 127 - ccvalue;
737          if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;          if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;
738          float cutoff = CutoffBase * float(ccvalue) * 0.00787402f; // (1 / 127)          float cutoff = CutoffBase * float(ccvalue);
739          if (cutoff > 1.0) cutoff = 1.0;          if (cutoff > 127.0f) cutoff = 127.0f;
         cutoff = (cutoff < 0.5 ? cutoff * 4826 - 1 : cutoff * 5715 - 449);  
         if (cutoff < 1.0) cutoff = 1.0;  
740    
741          VCFCutoffCtrl.fvalue = cutoff - 1.0; // needed for initialization of fFinalCutoff next time          VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
742          fFinalCutoff = cutoff;          fFinalCutoff = cutoff;
743      }      }
744    
# Line 733  namespace LinuxSampler { namespace gig { Line 746  namespace LinuxSampler { namespace gig {
746          // convert absolute controller value to differential          // convert absolute controller value to differential
747          const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;          const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
748          VCFResonanceCtrl.value = itEvent->Param.CC.Value;          VCFResonanceCtrl.value = itEvent->Param.CC.Value;
749          const float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0          const float resonancedelta = (float) ctrldelta;
750          fFinalResonance += resonancedelta;          fFinalResonance += resonancedelta;
751          // needed for initialization of parameter          // needed for initialization of parameter
752          VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value * 0.00787f;          VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
753      }      }
754    
755      /**      /**
# Line 769  namespace LinuxSampler { namespace gig { Line 782  namespace LinuxSampler { namespace gig {
782    
783              // initialize all final synthesis parameters              // initialize all final synthesis parameters
784              finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;              finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;
             fFinalVolume    = getVolume();  
785              fFinalCutoff    = VCFCutoffCtrl.fvalue;              fFinalCutoff    = VCFCutoffCtrl.fvalue;
786              fFinalResonance = VCFResonanceCtrl.fvalue;              fFinalResonance = VCFResonanceCtrl.fvalue;
787    
788              // process MIDI control change and pitchbend events for this subfragment              // process MIDI control change and pitchbend events for this subfragment
789              processCCEvents(itCCEvent, iSubFragmentEnd);              processCCEvents(itCCEvent, iSubFragmentEnd);
790    
791                float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
792    #ifdef CONFIG_PROCESS_MUTED_CHANNELS
793                if (pEngineChannel->GetMute()) fFinalVolume = 0;
794    #endif
795    
796              // process transition events (note on, note off & sustain pedal)              // process transition events (note on, note off & sustain pedal)
797              processTransitionEvents(itNoteEvent, iSubFragmentEnd);              processTransitionEvents(itNoteEvent, iSubFragmentEnd);
798    
# Line 817  namespace LinuxSampler { namespace gig { Line 834  namespace LinuxSampler { namespace gig {
834    
835              // if filter enabled then update filter coefficients              // if filter enabled then update filter coefficients
836              if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {              if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
837                  finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff + 1.0, fFinalResonance, pEngine->SampleRate);                  finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
838                  finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff + 1.0, fFinalResonance, pEngine->SampleRate);                  finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
839              }              }
840    
841              // do we need resampling?              // do we need resampling?
# Line 832  namespace LinuxSampler { namespace gig { Line 849  namespace LinuxSampler { namespace gig {
849              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;              finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;
850  #ifdef CONFIG_INTERPOLATE_VOLUME  #ifdef CONFIG_INTERPOLATE_VOLUME
851              finalSynthesisParameters.fFinalVolumeDeltaLeft  =              finalSynthesisParameters.fFinalVolumeDeltaLeft  =
852                  (fFinalVolume * PanLeft - finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;                  (fFinalVolume * VolumeLeft  * PanLeftSmoother.render() -
853                     finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
854              finalSynthesisParameters.fFinalVolumeDeltaRight =              finalSynthesisParameters.fFinalVolumeDeltaRight =
855                  (fFinalVolume * PanRight - finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;                  (fFinalVolume * VolumeRight * PanRightSmoother.render() -
856                     finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
857  #else  #else
858              finalSynthesisParameters.fFinalVolumeLeft  = fFinalVolume * PanLeft;              finalSynthesisParameters.fFinalVolumeLeft  =
859              finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight;                  fFinalVolume * VolumeLeft  * PanLeftSmoother.render();
860                finalSynthesisParameters.fFinalVolumeRight =
861                    fFinalVolume * VolumeRight * PanRightSmoother.render();
862  #endif  #endif
863              // render audio for one subfragment              // render audio for one subfragment
864              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
# Line 851  namespace LinuxSampler { namespace gig { Line 872  namespace LinuxSampler { namespace gig {
872              if (EG1.active()) {              if (EG1.active()) {
873    
874                  // if sample has a loop and loop start has been reached in this subfragment, send a special event to EG1 to let it finish the attack hold stage                  // if sample has a loop and loop start has been reached in this subfragment, send a special event to EG1 to let it finish the attack hold stage
875                  if (pSample->Loops && Pos <= pSample->LoopStart && pSample->LoopStart < newPos) {                  if (pDimRgn->SampleLoops && Pos <= pDimRgn->pSampleLoops[0].LoopStart && pDimRgn->pSampleLoops[0].LoopStart < newPos) {
876                      EG1.update(EGADSR::event_hold_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                      EG1.update(EGADSR::event_hold_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
877                  }                  }
878    

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

  ViewVC Help
Powered by ViewVC