/[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 738 by schoenebeck, Tue Aug 16 17:14:25 2005 UTC revision 1895 by persson, Sun May 3 12:15:40 2009 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 Christian Schoenebeck                              *   *   Copyright (C) 2005 - 2009 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 23  Line 23 
23    
24  #include "../../common/Features.h"  #include "../../common/Features.h"
25  #include "Synthesizer.h"  #include "Synthesizer.h"
26    #include "Profiler.h"
27    
28  #include "Voice.h"  #include "Voice.h"
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 43  namespace LinuxSampler { namespace gig { Line 38  namespace LinuxSampler { namespace gig {
38          pLFO3 = new LFOSigned(1200.0f); // pitch EG (-1200..+1200 range)          pLFO3 = new LFOSigned(1200.0f); // pitch EG (-1200..+1200 range)
39          KeyGroup = 0;          KeyGroup = 0;
40          SynthesisMode = 0; // set all mode bits to 0 first          SynthesisMode = 0; // set all mode bits to 0 first
41          // select synthesis implementation (currently either pure C++ or MMX+SSE(1))          // select synthesis implementation (asm core is not supported ATM)
42          #if CONFIG_ASM && ARCH_X86          #if 0 // CONFIG_ASM && ARCH_X86
43          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
44          #else          #else
45          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
46          #endif          #endif
47          SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true);          SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, Profiler::isEnabled());
48    
49          FilterLeft.Reset();          finalSynthesisParameters.filterLeft.Reset();
50          FilterRight.Reset();          finalSynthesisParameters.filterRight.Reset();
51      }      }
52    
53      Voice::~Voice() {      Voice::~Voice() {
# Line 84  namespace LinuxSampler { namespace gig { Line 79  namespace LinuxSampler { namespace gig {
79      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) {      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) {
80          this->pEngineChannel = pEngineChannel;          this->pEngineChannel = pEngineChannel;
81          this->pDimRgn        = pDimRgn;          this->pDimRgn        = pDimRgn;
82            Orphan = false;
83    
84          #if CONFIG_DEVMODE          #if CONFIG_DEVMODE
85          if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging          if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
# Line 103  namespace LinuxSampler { namespace gig { Line 99  namespace LinuxSampler { namespace gig {
99          // calculate volume          // calculate volume
100          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
101    
102          Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)          // For 16 bit samples, we downscale by 32768 to convert from
103            // int16 value range to DSP value range (which is
104            // -1.0..1.0). For 24 bit, we downscale from int32.
105            float volume = velocityAttenuation / (pSample->BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
106    
107          Volume *= pDimRgn->SampleAttenuation;          volume *= pDimRgn->SampleAttenuation * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
108    
109          // the volume of release triggered samples depends on note length          // the volume of release triggered samples depends on note length
110          if (Type == type_release_trigger) {          if (Type == type_release_trigger) {
# Line 113  namespace LinuxSampler { namespace gig { Line 112  namespace LinuxSampler { namespace gig {
112                                       pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;                                       pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
113              float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;              float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
114              if (attenuation <= 0) return -1;              if (attenuation <= 0) return -1;
115              Volume *= attenuation;              volume *= attenuation;
116          }          }
117    
118          // select channel mode (mono or stereo)          // select channel mode (mono or stereo)
119          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
120            // select bit depth (16 or 24)
121            SYNTHESIS_MODE_SET_BITDEPTH24(SynthesisMode, pSample->BitDepth == 24);
122    
123          // get starting crossfade volume level          // get starting crossfade volume level
124            float crossfadeVolume;
125          switch (pDimRgn->AttenuationController.type) {          switch (pDimRgn->AttenuationController.type) {
126              case ::gig::attenuation_ctrl_t::type_channelaftertouch:              case ::gig::attenuation_ctrl_t::type_channelaftertouch:
127                  CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[128])];
128                  break;                  break;
129              case ::gig::attenuation_ctrl_t::type_velocity:              case ::gig::attenuation_ctrl_t::type_velocity:
130                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity)];
131                  break;                  break;
132              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
133                  CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number])];
134                  break;                  break;
135              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
136              default:              default:
137                  CrossfadeVolume = 1.0f;                  crossfadeVolume = 1.0f;
138          }          }
139    
140          PanLeft  = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) /  63.0f;          VolumeLeft  = volume * Engine::PanCurve[64 - pDimRgn->Pan];
141          PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;          VolumeRight = volume * Engine::PanCurve[64 + pDimRgn->Pan];
142    
143            float subfragmentRate = pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
144            CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate);
145            VolumeSmoother.trigger(pEngineChannel->MidiVolume, subfragmentRate);
146            PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate);
147            PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate);
148    
149          Pos = 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)
150            Pos = pDimRgn->SampleStartOffset;
151    
152          // 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
153          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
154          DiskVoice          = cachedsamples < pSample->SamplesTotal;          DiskVoice          = cachedsamples < pSample->SamplesTotal;
155    
156            const DLS::sample_loop_t& loopinfo = pDimRgn->pSampleLoops[0];
157    
158          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
159              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)              if (cachedsamples > (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH)) {
160                    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)
161                } else {
162                    // The cache is too small to fit a max sample buffer.
163                    // Setting MaxRAMPos to 0 will probably cause a click
164                    // in the audio, but it's better than not handling
165                    // this case at all, which would have caused the
166                    // unsigned MaxRAMPos to be set to a negative number.
167                    MaxRAMPos = 0;
168                }
169    
170              // 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
171              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {              RAMLoop = (pDimRgn->SampleLoops && (loopinfo.LoopStart + loopinfo.LoopLength) <= MaxRAMPos);
                 RAMLoop        = true;  
                 LoopCyclesLeft = pSample->LoopPlayCount;  
             }  
             else RAMLoop = false;  
172    
173              if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {              if (pDiskThread->OrderNewStream(&DiskStreamRef, pDimRgn, MaxRAMPos, !RAMLoop) < 0) {
174                  dmsg(1,("Disk stream order failed!\n"));                  dmsg(1,("Disk stream order failed!\n"));
175                  KillImmediately();                  KillImmediately();
176                  return -1;                  return -1;
# Line 163  namespace LinuxSampler { namespace gig { Line 179  namespace LinuxSampler { namespace gig {
179          }          }
180          else { // RAM only voice          else { // RAM only voice
181              MaxRAMPos = cachedsamples;              MaxRAMPos = cachedsamples;
182              if (pSample->Loops) {              RAMLoop = (pDimRgn->SampleLoops != 0);
                 RAMLoop        = true;  
                 LoopCyclesLeft = pSample->LoopPlayCount;  
             }  
             else RAMLoop = false;  
183              dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));              dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
184          }          }
185            if (RAMLoop) {
186                loop.uiTotalCycles = pSample->LoopPlayCount;
187                loop.uiCyclesLeft  = pSample->LoopPlayCount;
188                loop.uiStart       = loopinfo.LoopStart;
189                loop.uiEnd         = loopinfo.LoopStart + loopinfo.LoopLength;
190                loop.uiSize        = loopinfo.LoopLength;
191            }
192    
193          // calculate initial pitch value          // calculate initial pitch value
194          {          {
195              double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];              double pitchbasecents = pEngineChannel->pInstrument->FineTune + pDimRgn->FineTune + pEngine->ScaleTuning[MIDIKey % 12];
196              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;  
197              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->SampleRate));              // GSt behaviour: maximum transpose up is 40 semitones. If
198              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents              // MIDI key is more than 40 semitones above unity note,
199                // the transpose is not done.
200                if (pDimRgn->PitchTrack && (MIDIKey - (int) pDimRgn->UnityNote) < 40) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
201    
202                this->PitchBase = RTMath::CentsToFreqRatioUnlimited(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->SampleRate));
203                this->PitchBend = RTMath::CentsToFreqRatio(PitchBend / 8192.0 * 100.0 * pEngineChannel->pInstrument->PitchbendRange);
204          }          }
205    
206          // 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
# Line 192  namespace LinuxSampler { namespace gig { Line 215  namespace LinuxSampler { namespace gig {
215                      eg1controllervalue = 0;                      eg1controllervalue = 0;
216                      break;                      break;
217                  case ::gig::eg1_ctrl_t::type_channelaftertouch:                  case ::gig::eg1_ctrl_t::type_channelaftertouch:
218                      eg1controllervalue = 0; // TODO: aftertouch not yet supported                      eg1controllervalue = pEngineChannel->ControllerTable[128];
219                      break;                      break;
220                  case ::gig::eg1_ctrl_t::type_velocity:                  case ::gig::eg1_ctrl_t::type_velocity:
221                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
# Line 214  namespace LinuxSampler { namespace gig { Line 237  namespace LinuxSampler { namespace gig {
237              EG1.trigger(pDimRgn->EG1PreAttack,              EG1.trigger(pDimRgn->EG1PreAttack,
238                          pDimRgn->EG1Attack * eg1attack,                          pDimRgn->EG1Attack * eg1attack,
239                          pDimRgn->EG1Hold,                          pDimRgn->EG1Hold,
                         pSample->LoopStart,  
240                          pDimRgn->EG1Decay1 * eg1decay * velrelease,                          pDimRgn->EG1Decay1 * eg1decay * velrelease,
241                          pDimRgn->EG1Decay2 * eg1decay * velrelease,                          pDimRgn->EG1Decay2 * eg1decay * velrelease,
242                          pDimRgn->EG1InfiniteSustain,                          pDimRgn->EG1InfiniteSustain,
# Line 224  namespace LinuxSampler { namespace gig { Line 246  namespace LinuxSampler { namespace gig {
246                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
247          }          }
248    
249    #ifdef CONFIG_INTERPOLATE_VOLUME
250            // setup initial volume in synthesis parameters
251    #ifdef CONFIG_PROCESS_MUTED_CHANNELS
252            if (pEngineChannel->GetMute()) {
253                finalSynthesisParameters.fFinalVolumeLeft  = 0;
254                finalSynthesisParameters.fFinalVolumeRight = 0;
255            }
256            else
257    #else
258            {
259                float finalVolume = pEngineChannel->MidiVolume * crossfadeVolume * EG1.getLevel();
260    
261                finalSynthesisParameters.fFinalVolumeLeft  = finalVolume * VolumeLeft  * pEngineChannel->GlobalPanLeft;
262                finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight;
263            }
264    #endif
265    #endif
266    
267          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
268          {          {
# Line 234  namespace LinuxSampler { namespace gig { Line 273  namespace LinuxSampler { namespace gig {
273                      eg2controllervalue = 0;                      eg2controllervalue = 0;
274                      break;                      break;
275                  case ::gig::eg2_ctrl_t::type_channelaftertouch:                  case ::gig::eg2_ctrl_t::type_channelaftertouch:
276                      eg2controllervalue = 0; // TODO: aftertouch not yet supported                      eg2controllervalue = pEngineChannel->ControllerTable[128];
277                      break;                      break;
278                  case ::gig::eg2_ctrl_t::type_velocity:                  case ::gig::eg2_ctrl_t::type_velocity:
279                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
# Line 253  namespace LinuxSampler { namespace gig { Line 292  namespace LinuxSampler { namespace gig {
292              EG2.trigger(pDimRgn->EG2PreAttack,              EG2.trigger(pDimRgn->EG2PreAttack,
293                          pDimRgn->EG2Attack * eg2attack,                          pDimRgn->EG2Attack * eg2attack,
294                          false,                          false,
                         pSample->LoopStart,  
295                          pDimRgn->EG2Decay1 * eg2decay * velrelease,                          pDimRgn->EG2Decay1 * eg2decay * velrelease,
296                          pDimRgn->EG2Decay2 * eg2decay * velrelease,                          pDimRgn->EG2Decay2 * eg2decay * velrelease,
297                          pDimRgn->EG2InfiniteSustain,                          pDimRgn->EG2InfiniteSustain,
# Line 266  namespace LinuxSampler { namespace gig { Line 304  namespace LinuxSampler { namespace gig {
304    
305          // setup EG 3 (VCO EG)          // setup EG 3 (VCO EG)
306          {          {
307            double eg3depth = RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);              // if portamento mode is on, we dedicate EG3 purely for portamento, otherwise if portamento is off we do as told by the patch
308            EG3.trigger(eg3depth, pDimRgn->EG3Attack, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);              bool  bPortamento = pEngineChannel->PortamentoMode && pEngineChannel->PortamentoPos >= 0.0f;
309                float eg3depth = (bPortamento)
310                                     ? RTMath::CentsToFreqRatio((pEngineChannel->PortamentoPos - (float) MIDIKey) * 100)
311                                     : RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);
312                float eg3time = (bPortamento)
313                                    ? pEngineChannel->PortamentoTime
314                                    : pDimRgn->EG3Attack;
315                EG3.trigger(eg3depth, eg3time, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
316                dmsg(5,("PortamentoPos=%f, depth=%f, time=%f\n", pEngineChannel->PortamentoPos, eg3depth, eg3time));
317          }          }
318    
319    
# Line 305  namespace LinuxSampler { namespace gig { Line 351  namespace LinuxSampler { namespace gig {
351                      pLFO1->ExtController = 0; // no external controller                      pLFO1->ExtController = 0; // no external controller
352                      bLFO1Enabled         = false;                      bLFO1Enabled         = false;
353              }              }
354              if (bLFO1Enabled) pLFO1->trigger(pDimRgn->LFO1Frequency,              if (bLFO1Enabled) {
355                                               start_level_max,                  pLFO1->trigger(pDimRgn->LFO1Frequency,
356                                               lfo1_internal_depth,                                 start_level_min,
357                                               pDimRgn->LFO1ControlDepth,                                 lfo1_internal_depth,
358                                               pDimRgn->LFO1FlipPhase,                                 pDimRgn->LFO1ControlDepth,
359                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 pDimRgn->LFO1FlipPhase,
360                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
361                    pLFO1->update(pLFO1->ExtController ? pEngineChannel->ControllerTable[pLFO1->ExtController] : 0);
362                }
363          }          }
364    
365    
# Line 348  namespace LinuxSampler { namespace gig { Line 397  namespace LinuxSampler { namespace gig {
397                      pLFO2->ExtController = 0; // no external controller                      pLFO2->ExtController = 0; // no external controller
398                      bLFO2Enabled         = false;                      bLFO2Enabled         = false;
399              }              }
400              if (bLFO2Enabled) pLFO2->trigger(pDimRgn->LFO2Frequency,              if (bLFO2Enabled) {
401                                               start_level_max,                  pLFO2->trigger(pDimRgn->LFO2Frequency,
402                                               lfo2_internal_depth,                                 start_level_max,
403                                               pDimRgn->LFO2ControlDepth,                                 lfo2_internal_depth,
404                                               pDimRgn->LFO2FlipPhase,                                 pDimRgn->LFO2ControlDepth,
405                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 pDimRgn->LFO2FlipPhase,
406                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
407                    pLFO2->update(pLFO2->ExtController ? pEngineChannel->ControllerTable[pLFO2->ExtController] : 0);
408                }
409          }          }
410    
411    
# Line 373  namespace LinuxSampler { namespace gig { Line 425  namespace LinuxSampler { namespace gig {
425                      break;                      break;
426                  case ::gig::lfo3_ctrl_aftertouch:                  case ::gig::lfo3_ctrl_aftertouch:
427                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
428                      pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet                      pLFO3->ExtController = 128;
429                      bLFO3Enabled         = false; // see TODO comment in line above                      bLFO3Enabled         = true;
430                      break;                      break;
431                  case ::gig::lfo3_ctrl_internal_modwheel:                  case ::gig::lfo3_ctrl_internal_modwheel:
432                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
# Line 383  namespace LinuxSampler { namespace gig { Line 435  namespace LinuxSampler { namespace gig {
435                      break;                      break;
436                  case ::gig::lfo3_ctrl_internal_aftertouch:                  case ::gig::lfo3_ctrl_internal_aftertouch:
437                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
438                      pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet                      pLFO1->ExtController = 128;
439                      bLFO3Enabled         = (lfo3_internal_depth > 0 /*|| pDimRgn->LFO3ControlDepth > 0*/); // see TODO comment in line above                      bLFO3Enabled         = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0);
440                      break;                      break;
441                  default:                  default:
442                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
443                      pLFO3->ExtController = 0; // no external controller                      pLFO3->ExtController = 0; // no external controller
444                      bLFO3Enabled         = false;                      bLFO3Enabled         = false;
445              }              }
446              if (bLFO3Enabled) pLFO3->trigger(pDimRgn->LFO3Frequency,              if (bLFO3Enabled) {
447                                               start_level_mid,                  pLFO3->trigger(pDimRgn->LFO3Frequency,
448                                               lfo3_internal_depth,                                 start_level_mid,
449                                               pDimRgn->LFO3ControlDepth,                                 lfo3_internal_depth,
450                                               false,                                 pDimRgn->LFO3ControlDepth,
451                                               pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                                 false,
452                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
453                    pLFO3->update(pLFO3->ExtController ? pEngineChannel->ControllerTable[pLFO3->ExtController] : 0);
454                }
455          }          }
456    
457    
# Line 438  namespace LinuxSampler { namespace gig { Line 493  namespace LinuxSampler { namespace gig {
493                  case ::gig::vcf_cutoff_ctrl_genpurpose8:                  case ::gig::vcf_cutoff_ctrl_genpurpose8:
494                      VCFCutoffCtrl.controller = 83;                      VCFCutoffCtrl.controller = 83;
495                      break;                      break;
496                  case ::gig::vcf_cutoff_ctrl_aftertouch: //TODO: not implemented yet                  case ::gig::vcf_cutoff_ctrl_aftertouch:
497                        VCFCutoffCtrl.controller = 128;
498                        break;
499                  case ::gig::vcf_cutoff_ctrl_none:                  case ::gig::vcf_cutoff_ctrl_none:
500                  default:                  default:
501                      VCFCutoffCtrl.controller = 0;                      VCFCutoffCtrl.controller = 0;
# Line 469  namespace LinuxSampler { namespace gig { Line 526  namespace LinuxSampler { namespace gig {
526              #endif // CONFIG_OVERRIDE_RESONANCE_CTRL              #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
527    
528              #ifndef CONFIG_OVERRIDE_FILTER_TYPE              #ifndef CONFIG_OVERRIDE_FILTER_TYPE
529              FilterLeft.SetType(pDimRgn->VCFType);              finalSynthesisParameters.filterLeft.SetType(pDimRgn->VCFType);
530              FilterRight.SetType(pDimRgn->VCFType);              finalSynthesisParameters.filterRight.SetType(pDimRgn->VCFType);
531              #else // override filter type              #else // override filter type
532              FilterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);              finalSynthesisParameters.filterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
533              FilterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);              finalSynthesisParameters.filterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
534              #endif // CONFIG_OVERRIDE_FILTER_TYPE              #endif // CONFIG_OVERRIDE_FILTER_TYPE
535    
536              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
# Line 490  namespace LinuxSampler { namespace gig { Line 547  namespace LinuxSampler { namespace gig {
547              if (VCFCutoffCtrl.controller) {              if (VCFCutoffCtrl.controller) {
548                  cvalue = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];                  cvalue = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
549                  if (pDimRgn->VCFCutoffControllerInvert) cvalue = 127 - cvalue;                  if (pDimRgn->VCFCutoffControllerInvert) cvalue = 127 - cvalue;
550                    // VCFVelocityScale in this case means Minimum cutoff
551                  if (cvalue < pDimRgn->VCFVelocityScale) cvalue = pDimRgn->VCFVelocityScale;                  if (cvalue < pDimRgn->VCFVelocityScale) cvalue = pDimRgn->VCFVelocityScale;
552              }              }
553              else {              else {
554                  cvalue = pDimRgn->VCFCutoff;                  cvalue = pDimRgn->VCFCutoff;
555              }              }
556              cutoff *= float(cvalue) * 0.00787402f; // (1 / 127)              cutoff *= float(cvalue);
557              if (cutoff > 1.0) cutoff = 1.0;              if (cutoff > 127.0f) cutoff = 127.0f;
             cutoff = exp(cutoff * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MIN;  
558    
559              // calculate resonance              // calculate resonance
560              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0              float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : pDimRgn->VCFResonance);
             if (pDimRgn->VCFKeyboardTracking) {  
                 resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;  
             }  
             Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)  
561    
562              VCFCutoffCtrl.fvalue    = cutoff - CONFIG_FILTER_CUTOFF_MIN;              VCFCutoffCtrl.fvalue    = cutoff;
563              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
564          }          }
565          else {          else {
# Line 547  namespace LinuxSampler { namespace gig { Line 600  namespace LinuxSampler { namespace gig {
600    
601                      if (DiskVoice) {                      if (DiskVoice) {
602                          // check if we reached the allowed limit of the sample RAM cache                          // check if we reached the allowed limit of the sample RAM cache
603                          if (Pos > MaxRAMPos) {                          if (finalSynthesisParameters.dPos > MaxRAMPos) {
604                              dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", Pos));                              dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", finalSynthesisParameters.dPos));
605                              this->PlaybackState = playback_state_disk;                              this->PlaybackState = playback_state_disk;
606                          }                          }
607                      }                      } else if (finalSynthesisParameters.dPos >= pSample->GetCache().Size / pSample->FrameSize) {
                     else if (Pos >= pSample->GetCache().Size / pSample->FrameSize) {  
608                          this->PlaybackState = playback_state_end;                          this->PlaybackState = playback_state_end;
609                      }                      }
610                  }                  }
# Line 567  namespace LinuxSampler { namespace gig { Line 619  namespace LinuxSampler { namespace gig {
619                              KillImmediately();                              KillImmediately();
620                              return;                              return;
621                          }                          }
622                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(finalSynthesisParameters.dPos) - MaxRAMPos));
623                          Pos -= int(Pos);                          finalSynthesisParameters.dPos -= int(finalSynthesisParameters.dPos);
624                          RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet                          RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
625                      }                      }
626    
# Line 584  namespace LinuxSampler { namespace gig { Line 636  namespace LinuxSampler { namespace gig {
636                          }                          }
637                      }                      }
638    
639                      sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from                      sample_t* ptr = (sample_t*)DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
640    
641                      // render current audio fragment                      // render current audio fragment
642                      Synthesize(Samples, ptr, Delay);                      Synthesize(Samples, ptr, Delay);
643    
644                      const int iPos = (int) Pos;                      const int iPos = (int) finalSynthesisParameters.dPos;
645                      const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read                      const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
646                      DiskStreamRef.pStream->IncrementReadPos(readSampleWords);                      DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
647                      Pos -= iPos; // just keep fractional part of Pos                      finalSynthesisParameters.dPos -= iPos; // just keep fractional part of playback position
648    
649                      // change state of voice to 'end' if we really reached the end of the sample data                      // change state of voice to 'end' if we really reached the end of the sample data
650                      if (RealSampleWordsLeftToRead >= 0) {                      if (RealSampleWordsLeftToRead >= 0) {
# Line 607  namespace LinuxSampler { namespace gig { Line 659  namespace LinuxSampler { namespace gig {
659                  break;                  break;
660          }          }
661    
         // Reset synthesis event lists  
         pEngineChannel->pEvents->clear();  
   
662          // Reset delay          // Reset delay
663          Delay = 0;          Delay = 0;
664    
# Line 624  namespace LinuxSampler { namespace gig { Line 673  namespace LinuxSampler { namespace gig {
673       *  suspended / not running.       *  suspended / not running.
674       */       */
675      void Voice::Reset() {      void Voice::Reset() {
676          FilterLeft.Reset();          finalSynthesisParameters.filterLeft.Reset();
677          FilterRight.Reset();          finalSynthesisParameters.filterRight.Reset();
678          DiskStreamRef.pStream = NULL;          DiskStreamRef.pStream = NULL;
679          DiskStreamRef.hStream = 0;          DiskStreamRef.hStream = 0;
680          DiskStreamRef.State   = Stream::state_unused;          DiskStreamRef.State   = Stream::state_unused;
# Line 640  namespace LinuxSampler { namespace gig { Line 689  namespace LinuxSampler { namespace gig {
689       * for the given time.       * for the given time.
690       *       *
691       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
692       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
693       */       */
694      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
695          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
696              if (itEvent->Type == Event::type_release) {              if (itEvent->Type == Event::type_release) {
697                  EG1.update(EGADSR::event_release, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  EG1.update(EGADSR::event_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
698                  EG2.update(EGADSR::event_release, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  EG2.update(EGADSR::event_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
699              } else if (itEvent->Type == Event::type_cancel_release) {              } else if (itEvent->Type == Event::type_cancel_release) {
700                  EG1.update(EGADSR::event_cancel_release, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  EG1.update(EGADSR::event_cancel_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
701                  EG2.update(EGADSR::event_cancel_release, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  EG2.update(EGADSR::event_cancel_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
702              }              }
703          }          }
704      }      }
# Line 659  namespace LinuxSampler { namespace gig { Line 708  namespace LinuxSampler { namespace gig {
708       * the given time.       * the given time.
709       *       *
710       * @param itEvent - iterator pointing to the next event to be processed       * @param itEvent - iterator pointing to the next event to be processed
711       * @param End     - youngest time stamp where processing should be stopped       * @param End     - youngest time stamp where processing should be stopped
712       */       */
713      void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {      void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
714          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {          for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
# Line 682  namespace LinuxSampler { namespace gig { Line 731  namespace LinuxSampler { namespace gig {
731                  }                  }
732                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
733                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {
734                      processCrossFadeEvent(itEvent);                      CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
735                    }
736                    if (itEvent->Param.CC.Controller == 7) { // volume
737                        VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value]);
738                    } else if (itEvent->Param.CC.Controller == 10) { // panpot
739                        PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]);
740                        PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]);
741                  }                  }
742              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event              } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
743                  processPitchEvent(itEvent);                  processPitchEvent(itEvent);
# Line 691  namespace LinuxSampler { namespace gig { Line 746  namespace LinuxSampler { namespace gig {
746      }      }
747    
748      void Voice::processPitchEvent(RTList<Event>::Iterator& itEvent) {      void Voice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
749          const float pitch = RTMath::CentsToFreqRatio(((double) itEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents          PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch / 8192.0 * 100.0 * pEngineChannel->pInstrument->PitchbendRange);
         fFinalPitch *= pitch;  
     }  
   
     void Voice::processCrossFadeEvent(RTList<Event>::Iterator& itEvent) {  
         CrossfadeVolume = CrossfadeAttenuation(itEvent->Param.CC.Value);  
         #if CONFIG_PROCESS_MUTED_CHANNELS  
         const float effectiveVolume = CrossfadeVolume * Volume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume);  
         #else  
         const float effectiveVolume = CrossfadeVolume * Volume * pEngineChannel->GlobalVolume;  
         #endif  
         fFinalVolume = effectiveVolume;  
750      }      }
751    
752      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {      void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
# Line 711  namespace LinuxSampler { namespace gig { Line 755  namespace LinuxSampler { namespace gig {
755          VCFCutoffCtrl.value == ccvalue;          VCFCutoffCtrl.value == ccvalue;
756          if (pDimRgn->VCFCutoffControllerInvert)  ccvalue = 127 - ccvalue;          if (pDimRgn->VCFCutoffControllerInvert)  ccvalue = 127 - ccvalue;
757          if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;          if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;
758          float cutoff = CutoffBase * float(ccvalue) * 0.00787402f; // (1 / 127)          float cutoff = CutoffBase * float(ccvalue);
759          if (cutoff > 1.0) cutoff = 1.0;          if (cutoff > 127.0f) cutoff = 127.0f;
760          cutoff = exp(cutoff * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MIN - CONFIG_FILTER_CUTOFF_MIN;  
761          VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time          VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
762          fFinalCutoff = cutoff;          fFinalCutoff = cutoff;
763      }      }
# Line 722  namespace LinuxSampler { namespace gig { Line 766  namespace LinuxSampler { namespace gig {
766          // convert absolute controller value to differential          // convert absolute controller value to differential
767          const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;          const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
768          VCFResonanceCtrl.value = itEvent->Param.CC.Value;          VCFResonanceCtrl.value = itEvent->Param.CC.Value;
769          const float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0          const float resonancedelta = (float) ctrldelta;
770          fFinalResonance += resonancedelta;          fFinalResonance += resonancedelta;
771          // needed for initialization of parameter          // needed for initialization of parameter
772          VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value * 0.00787f;          VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
773      }      }
774    
775      /**      /**
# Line 737  namespace LinuxSampler { namespace gig { Line 781  namespace LinuxSampler { namespace gig {
781       *  @param Skip    - number of sample points to skip in output buffer       *  @param Skip    - number of sample points to skip in output buffer
782       */       */
783      void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
784            finalSynthesisParameters.pOutLeft  = &pEngineChannel->pChannelLeft->Buffer()[Skip];
785            finalSynthesisParameters.pOutRight = &pEngineChannel->pChannelRight->Buffer()[Skip];
786            finalSynthesisParameters.pSrc      = pSrc;
787    
788          RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();          RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();
789          RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first();          RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first();
790                    
791          if (Skip) { // skip events that happened before this voice was triggered          if (itTriggerEvent) { // skip events that happened before this voice was triggered
792              while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;              while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
793              while (itNoteEvent && itNoteEvent->FragmentPos() <= Skip) ++itNoteEvent;              // we can't simply compare the timestamp here, because note events
794                // might happen on the same time stamp, so we have to deal on the
795                // actual sequence the note events arrived instead (see bug #112)
796                for (; itNoteEvent; ++itNoteEvent) {
797                    if (itTriggerEvent == itNoteEvent) {
798                        ++itNoteEvent;
799                        break;
800                    }
801                }
802          }          }
803            
804            uint killPos;
805            if (itKillEvent) {
806                int maxFadeOutPos = Samples - pEngine->MinFadeOutSamples;
807                if (maxFadeOutPos < 0) {
808                    // There's not enough space in buffer to do a fade out
809                    // from max volume (this can only happen for audio
810                    // drivers that use Samples < MaxSamplesPerCycle).
811                    // End the EG1 here, at pos 0, with a shorter max fade
812                    // out time.
813                    EG1.enterFadeOutStage(Samples / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
814                    itKillEvent = Pool<Event>::Iterator();
815                } else {
816                    killPos = RTMath::Min(itKillEvent->FragmentPos(), maxFadeOutPos);
817                }
818            }
819    
820          uint i = Skip;          uint i = Skip;
821          while (i < Samples) {          while (i < Samples) {
822              int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);              int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
823                
824              // initialize all final synthesis parameters              // initialize all final synthesis parameters
             fFinalPitch = PitchBase * PitchBend;  
             #if CONFIG_PROCESS_MUTED_CHANNELS  
             fFinalVolume = this->Volume * this->CrossfadeVolume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume));  
             #else  
             fFinalVolume = this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume;  
             #endif  
825              fFinalCutoff    = VCFCutoffCtrl.fvalue;              fFinalCutoff    = VCFCutoffCtrl.fvalue;
826              fFinalResonance = VCFResonanceCtrl.fvalue;              fFinalResonance = VCFResonanceCtrl.fvalue;
827                
828              // process MIDI control change and pitchbend events for this subfragment              // process MIDI control change and pitchbend events for this subfragment
829              processCCEvents(itCCEvent, iSubFragmentEnd);              processCCEvents(itCCEvent, iSubFragmentEnd);
830    
831                finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;
832                float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render();
833    #ifdef CONFIG_PROCESS_MUTED_CHANNELS
834                if (pEngineChannel->GetMute()) fFinalVolume = 0;
835    #endif
836    
837              // process transition events (note on, note off & sustain pedal)              // process transition events (note on, note off & sustain pedal)
838              processTransitionEvents(itNoteEvent, iSubFragmentEnd);              processTransitionEvents(itNoteEvent, iSubFragmentEnd);
839                
840                // if the voice was killed in this subfragment, or if the
841                // filter EG is finished, switch EG1 to fade out stage
842                if ((itKillEvent && killPos <= iSubFragmentEnd) ||
843                    (SYNTHESIS_MODE_GET_FILTER(SynthesisMode) &&
844                     EG2.getSegmentType() == EGADSR::segment_end)) {
845                    EG1.enterFadeOutStage();
846                    itKillEvent = Pool<Event>::Iterator();
847                }
848    
849              // process envelope generators              // process envelope generators
850              switch (EG1.getSegmentType()) {              switch (EG1.getSegmentType()) {
851                  case EGADSR::segment_lin:                  case EGADSR::segment_lin:
# Line 788  namespace LinuxSampler { namespace gig { Line 869  namespace LinuxSampler { namespace gig {
869                      fFinalCutoff *= EG2.getLevel();                      fFinalCutoff *= EG2.getLevel();
870                      break; // noop                      break; // noop
871              }              }
872              fFinalPitch *= RTMath::CentsToFreqRatio(EG3.render());              if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
873                
874              // process low frequency oscillators              // process low frequency oscillators
875              if (bLFO1Enabled) fFinalVolume *= pLFO1->render();              if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
876              if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();              if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
877              if (bLFO3Enabled) fFinalPitch  *= RTMath::CentsToFreqRatio(pLFO3->render());              if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
878    
879                // limit the pitch so we don't read outside the buffer
880                finalSynthesisParameters.fFinalPitch = RTMath::Min(finalSynthesisParameters.fFinalPitch, float(1 << CONFIG_MAX_PITCH));
881    
882              // if filter enabled then update filter coefficients              // if filter enabled then update filter coefficients
883              if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {              if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
884                  FilterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);                  finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
885                  FilterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);                  finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
886              }              }
887    
888              // how many steps do we calculate for this next subfragment              // do we need resampling?
889              const int steps = iSubFragmentEnd - i;              const float __PLUS_ONE_CENT  = 1.000577789506554859250142541782224725466f;
890                            const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
891              // select the appropriate synthesis mode              const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
892              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, fFinalPitch != 1.0f);                                                 finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
893                            SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
894    
895                // prepare final synthesis parameters structure
896                finalSynthesisParameters.uiToGo            = iSubFragmentEnd - i;
897    #ifdef CONFIG_INTERPOLATE_VOLUME
898                finalSynthesisParameters.fFinalVolumeDeltaLeft  =
899                    (fFinalVolume * VolumeLeft  * PanLeftSmoother.render() -
900                     finalSynthesisParameters.fFinalVolumeLeft) / finalSynthesisParameters.uiToGo;
901                finalSynthesisParameters.fFinalVolumeDeltaRight =
902                    (fFinalVolume * VolumeRight * PanRightSmoother.render() -
903                     finalSynthesisParameters.fFinalVolumeRight) / finalSynthesisParameters.uiToGo;
904    #else
905                finalSynthesisParameters.fFinalVolumeLeft  =
906                    fFinalVolume * VolumeLeft  * PanLeftSmoother.render();
907                finalSynthesisParameters.fFinalVolumeRight =
908                    fFinalVolume * VolumeRight * PanRightSmoother.render();
909    #endif
910              // render audio for one subfragment              // render audio for one subfragment
911              RunSynthesisFunction(SynthesisMode, *this, iSubFragmentEnd, pSrc, i);              RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
912    
913                // stop the rendering if volume EG is finished
914                if (EG1.getSegmentType() == EGADSR::segment_end) break;
915    
916              // increment envelopes' positions                          const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
917    
918                // increment envelopes' positions
919              if (EG1.active()) {              if (EG1.active()) {
920                  EG1.increment(steps);  
921                  if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  // 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
922                    if (pDimRgn->SampleLoops && Pos <= pDimRgn->pSampleLoops[0].LoopStart && pDimRgn->pSampleLoops[0].LoopStart < newPos) {
923                        EG1.update(EGADSR::event_hold_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
924                    }
925    
926                    EG1.increment(1);
927                    if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
928              }              }
929              if (EG2.active()) {              if (EG2.active()) {
930                  EG2.increment(steps);                  EG2.increment(1);
931                  if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);                  if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
932              }              }
933              EG3.increment(steps);              EG3.increment(1);
934              if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached              if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
935    
936                Pos = newPos;
937                i = iSubFragmentEnd;
938          }          }
939      }      }
940    
941        /** @brief Update current portamento position.
942         *
943         * Will be called when portamento mode is enabled to get the final
944         * portamento position of this active voice from where the next voice(s)
945         * might continue to slide on.
946         *
947         * @param itNoteOffEvent - event which causes this voice to die soon
948         */
949        void Voice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
950            const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
951            pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
952        }
953    
954      /**      /**
955       *  Immediately kill the voice. This method should not be used to kill       *  Immediately kill the voice. This method should not be used to kill
956       *  a normal, active voice, because it doesn't take care of things like       *  a normal, active voice, because it doesn't take care of things like
957       *  fading down the volume level to avoid clicks and regular processing       *  fading down the volume level to avoid clicks and regular processing
958       *  until the kill event actually occured!       *  until the kill event actually occured!
959       *       *
960       *  @see Kill()       * If it's necessary to know when the voice's disk stream was actually
961         * deleted, then one can set the optional @a bRequestNotification
962         * parameter and this method will then return the handle of the disk
963         * stream (unique identifier) and one can use this handle to poll the
964         * disk thread if this stream has been deleted. In any case this method
965         * will return immediately and will not block until the stream actually
966         * was deleted.
967         *
968         * @param bRequestNotification - (optional) whether the disk thread shall
969         *                                provide a notification once it deleted
970         *                               the respective disk stream
971         *                               (default=false)
972         * @returns handle to the voice's disk stream or @c Stream::INVALID_HANDLE
973         *          if the voice did not use a disk stream at all
974         * @see Kill()
975       */       */
976      void Voice::KillImmediately() {      Stream::Handle Voice::KillImmediately(bool bRequestNotification) {
977            Stream::Handle hStream = Stream::INVALID_HANDLE;
978          if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {          if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
979              pDiskThread->OrderDeletionOfStream(&DiskStreamRef);              pDiskThread->OrderDeletionOfStream(&DiskStreamRef, bRequestNotification);
980                hStream = DiskStreamRef.hStream;
981          }          }
982          Reset();          Reset();
983            return hStream;
984      }      }
985    
986      /**      /**

Legend:
Removed from v.738  
changed lines
  Added in v.1895

  ViewVC Help
Powered by ViewVC