/[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 56 by schoenebeck, Tue Apr 27 09:21:58 2004 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 - 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 20  Line 21 
21   *   MA  02111-1307  USA                                                   *   *   MA  02111-1307  USA                                                   *
22   ***************************************************************************/   ***************************************************************************/
23    
24  #include "EGADSR.h"  #include "../../common/Features.h"
25  #include "Manipulator.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    
     // FIXME: no support for layers (nor crossfades) yet  
   
     const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());  
   
     float Voice::CalculateFilterCutoffCoeff() {  
         return log(FILTER_CUTOFF_MIN / FILTER_CUTOFF_MAX);  
     }  
   
32      Voice::Voice() {      Voice::Voice() {
33          pEngine     = NULL;          pEngine     = NULL;
34          pDiskThread = NULL;          pDiskThread = NULL;
35          Active = false;          PlaybackState = playback_state_end;
36          pEG1   = NULL;          pLFO1 = new LFOUnsigned(1.0f);  // amplitude EG (0..1 range)
37          pEG2   = NULL;          pLFO2 = new LFOUnsigned(1.0f);  // filter EG (0..1 range)
38          pEG3   = NULL;          pLFO3 = new LFOSigned(1200.0f); // pitch EG (-1200..+1200 range)
39          pVCAManipulator  = NULL;          KeyGroup = 0;
40          pVCFCManipulator = NULL;          SynthesisMode = 0; // set all mode bits to 0 first
41          pVCOManipulator  = NULL;          // select synthesis implementation (asm core is not supported ATM)
42          pLFO1  = NULL;          #if 0 // CONFIG_ASM && ARCH_X86
43          pLFO2  = NULL;          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
44          pLFO3  = NULL;          #else
45            SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
46            #endif
47            SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, Profiler::isEnabled());
48    
49            finalSynthesisParameters.filterLeft.Reset();
50            finalSynthesisParameters.filterRight.Reset();
51      }      }
52    
53      Voice::~Voice() {      Voice::~Voice() {
         if (pEG1)  delete pEG1;  
         if (pEG2)  delete pEG2;  
         if (pEG3)  delete pEG3;  
54          if (pLFO1) delete pLFO1;          if (pLFO1) delete pLFO1;
55          if (pLFO2) delete pLFO2;          if (pLFO2) delete pLFO2;
56          if (pLFO3) delete pLFO3;          if (pLFO3) delete pLFO3;
         if (pVCAManipulator)  delete pVCAManipulator;  
         if (pVCFCManipulator) delete pVCFCManipulator;  
         if (pVCOManipulator)  delete pVCOManipulator;  
     }  
   
     void Voice::SetOutput(AudioOutputDevice* pAudioOutputDevice) {  
         this->pOutputLeft        = pAudioOutputDevice->Channel(0)->Buffer();  
         this->pOutputRight       = pAudioOutputDevice->Channel(1)->Buffer();  
         this->MaxSamplesPerCycle = pAudioOutputDevice->MaxSamplesPerCycle();  
         this->SampleRate         = pAudioOutputDevice->SampleRate();  
57      }      }
58    
59      void Voice::SetEngine(Engine* pEngine) {      void Voice::SetEngine(Engine* pEngine) {
60          this->pEngine = pEngine;          this->pEngine     = pEngine;
   
         // delete old objects  
         if (pEG1) delete pEG1;  
         if (pEG2) delete pEG2;  
         if (pEG3) delete pEG3;  
         if (pVCAManipulator)  delete pVCAManipulator;  
         if (pVCFCManipulator) delete pVCFCManipulator;  
         if (pVCOManipulator)  delete pVCOManipulator;  
         if (pLFO1) delete pLFO1;  
         if (pLFO2) delete pLFO2;  
         if (pLFO3) delete pLFO3;  
   
         // create new ones  
         pEG1   = new EGADSR(pEngine, Event::destination_vca);  
         pEG2   = new EGADSR(pEngine, Event::destination_vcfc);  
         pEG3   = new EGDecay(pEngine, Event::destination_vco);  
         pVCAManipulator  = new VCAManipulator(pEngine);  
         pVCFCManipulator = new VCFCManipulator(pEngine);  
         pVCOManipulator  = new VCOManipulator(pEngine);  
         pLFO1  = new LFO<gig::VCAManipulator>(0.0f, 1.0f, LFO<VCAManipulator>::propagation_top_down, pVCAManipulator, pEngine->pEventPool);  
         pLFO2  = new LFO<gig::VCFCManipulator>(0.0f, 1.0f, LFO<VCFCManipulator>::propagation_top_down, pVCFCManipulator, pEngine->pEventPool);  
         pLFO3  = new LFO<gig::VCOManipulator>(-1200.0f, 1200.0f, LFO<VCOManipulator>::propagation_middle_balanced, pVCOManipulator, pEngine->pEventPool); // +-1 octave (+-1200 cents) max.  
   
61          this->pDiskThread = pEngine->pDiskThread;          this->pDiskThread = pEngine->pDiskThread;
62          dmsg(1,("Voice::SetEngine()\n"));          dmsg(6,("Voice::SetEngine()\n"));
63      }      }
64    
65      /**      /**
66       *  Initializes and triggers the voice, a disk stream will be launched if       *  Initializes and triggers the voice, a disk stream will be launched if
67       *  needed.       *  needed.
68       *       *
69       *  @param pNoteOnEvent - event that caused triggering of this voice       *  @param pEngineChannel - engine channel on which this voice was ordered
70       *  @param PitchBend    - MIDI detune factor (-8192 ... +8191)       *  @param itNoteOnEvent  - event that caused triggering of this voice
71       *  @param pInstrument  - points to the loaded instrument which provides sample wave(s) and articulation data       *  @param PitchBend      - MIDI detune factor (-8192 ... +8191)
72       *  @returns            0 on success, a value < 0 if something failed       *  @param pDimRgn        - points to the dimension region which provides sample wave(s) and articulation data
73         *  @param VoiceType      - type of this voice
74         *  @param iKeyGroup      - a value > 0 defines a key group in which this voice is member of
75         *  @returns 0 on success, a value < 0 if the voice wasn't triggered
76         *           (either due to an error or e.g. because no region is
77         *           defined for the given key)
78       */       */
79      int Voice::Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument) {      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) {
80          if (!pInstrument) {          this->pEngineChannel = pEngineChannel;
81             dmsg(1,("voice::trigger: !pInstrument\n"));          this->pDimRgn        = pDimRgn;
82             exit(EXIT_FAILURE);          Orphan = false;
83          }  
84            #if CONFIG_DEVMODE
85          Active          = true;          if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
86          MIDIKey         = pNoteOnEvent->Key;              dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
87          pRegion         = pInstrument->GetRegion(MIDIKey);          }
88          PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed          #endif // CONFIG_DEVMODE
89          Pos             = 0;  
90          Delay           = pNoteOnEvent->FragmentPos();          Type            = VoiceType;
91          pTriggerEvent   = pNoteOnEvent;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
92            PlaybackState   = playback_state_init; // mark voice as triggered, but no audio rendered yet
93          if (!pRegion) {          Delay           = itNoteOnEvent->FragmentPos();
94              std::cerr << "Audio Thread: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;          itTriggerEvent  = itNoteOnEvent;
95              Kill();          itKillEvent     = Pool<Event>::Iterator();
96              return -1;          KeyGroup        = iKeyGroup;
97          }          pSample         = pDimRgn->pSample; // sample won't change until the voice is finished
98    
99          //TODO: current MIDI controller values are not taken into account yet          // calculate volume
100          ::gig::DimensionRegion* pDimRgn = NULL;          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
101          for (int i = pRegion->Dimensions - 1; i >= 0; i--) { // Check if instrument has a velocity split  
102              if (pRegion->pDimensionDefinitions[i].dimension == ::gig::dimension_velocity) {          // For 16 bit samples, we downscale by 32768 to convert from
103                  uint DimValues[5] = {0,0,0,0,0};          // int16 value range to DSP value range (which is
104                      DimValues[i] = pNoteOnEvent->Velocity;          // -1.0..1.0). For 24 bit, we downscale from int32.
105                  pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);          float volume = velocityAttenuation / (pSample->BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f);
106    
107            volume *= pDimRgn->SampleAttenuation * pEngineChannel->GlobalVolume * GLOBAL_VOLUME;
108    
109            // the volume of release triggered samples depends on note length
110            if (Type == type_release_trigger) {
111                float noteLength = float(pEngine->FrameTime + Delay -
112                                         pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
113                float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
114                if (attenuation <= 0) return -1;
115                volume *= attenuation;
116            }
117    
118            // select channel mode (mono or stereo)
119            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
124            float crossfadeVolume;
125            switch (pDimRgn->AttenuationController.type) {
126                case ::gig::attenuation_ctrl_t::type_channelaftertouch:
127                    crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[128])];
128                  break;                  break;
129              }              case ::gig::attenuation_ctrl_t::type_velocity:
130          }                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity)];
131          if (!pDimRgn) { // if there was no velocity split                  break;
132              pDimRgn = pRegion->GetDimensionRegionByValue(0,0,0,0,0);              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
133          }                  crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number])];
134                    break;
135                case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
136                default:
137                    crossfadeVolume = 1.0f;
138            }
139    
140            VolumeLeft  = volume * Engine::PanCurve[64 - pDimRgn->Pan];
141            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          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          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 - (MaxSamplesPerCycle << 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                  Kill();                  KillImmediately();
176                  return -1;                  return -1;
177              }              }
178              dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos, (RAMLoop) ? "yes" : "no"));              dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos, (RAMLoop) ? "yes" : "no"));
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 * 10;              double pitchbasecents = pEngineChannel->pInstrument->FineTune + pDimRgn->FineTune + pEngine->ScaleTuning[MIDIKey % 12];
             if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;  
             this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents);  
             this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents  
         }  
196    
197                // GSt behaviour: maximum transpose up is 40 semitones. If
198                // 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          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)              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
207            const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
208    
209          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
210          {          {
# Line 196  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 = pNoteOnEvent->Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
222                      break;                      break;
223                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
224                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];                      eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
225                      break;                      break;
226              }              }
227              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
228    
229              // calculate influence of EG1 controller on EG1's parameters (TODO: needs to be fine tuned)              // calculate influence of EG1 controller on EG1's parameters
230              double eg1attack  = (pDimRgn->EG1ControllerAttackInfluence)  ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerAttackInfluence)  * eg1controllervalue : 0.0;              // (eg1attack is different from the others)
231              double eg1decay   = (pDimRgn->EG1ControllerDecayInfluence)   ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence)   * eg1controllervalue : 0.0;              double eg1attack  = (pDimRgn->EG1ControllerAttackInfluence)  ?
232              double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 0.0;                  1 + 0.031 * (double) (pDimRgn->EG1ControllerAttackInfluence == 1 ?
233                                          1 : 1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 1.0;
234              pEG1->Trigger(pDimRgn->EG1PreAttack,              double eg1decay   = (pDimRgn->EG1ControllerDecayInfluence)   ? 1 + 0.00775 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence)   * eg1controllervalue : 1.0;
235                            pDimRgn->EG1Attack + eg1attack,              double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 1.0;
236                            pDimRgn->EG1Hold,  
237                            pSample->LoopStart,              EG1.trigger(pDimRgn->EG1PreAttack,
238                            pDimRgn->EG1Decay1 + eg1decay,                          pDimRgn->EG1Attack * eg1attack,
239                            pDimRgn->EG1Decay2 + eg1decay,                          pDimRgn->EG1Hold,
240                            pDimRgn->EG1InfiniteSustain,                          pDimRgn->EG1Decay1 * eg1decay * velrelease,
241                            pDimRgn->EG1Sustain,                          pDimRgn->EG1Decay2 * eg1decay * velrelease,
242                            pDimRgn->EG1Release + eg1release,                          pDimRgn->EG1InfiniteSustain,
243                            Delay);                          pDimRgn->EG1Sustain,
244                            pDimRgn->EG1Release * eg1release * velrelease,
245                            velocityAttenuation,
246                            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    
     #if ENABLE_FILTER  
267          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
268          {          {
269              // get current value of EG2 controller              // get current value of EG2 controller
# Line 235  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 = pNoteOnEvent->Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
280                      break;                      break;
281                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
282                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];                      eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
283                      break;                      break;
284              }              }
285              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
286    
287              // calculate influence of EG2 controller on EG2's parameters (TODO: needs to be fine tuned)              // calculate influence of EG2 controller on EG2's parameters
288              double eg2attack  = (pDimRgn->EG2ControllerAttackInfluence)  ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence)  * eg2controllervalue : 0.0;              double eg2attack  = (pDimRgn->EG2ControllerAttackInfluence)  ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence)  * eg2controllervalue : 1.0;
289              double eg2decay   = (pDimRgn->EG2ControllerDecayInfluence)   ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence)   * eg2controllervalue : 0.0;              double eg2decay   = (pDimRgn->EG2ControllerDecayInfluence)   ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence)   * eg2controllervalue : 1.0;
290              double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 0.0001 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 0.0;              double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 1.0;
291    
292              pEG2->Trigger(pDimRgn->EG2PreAttack,              EG2.trigger(pDimRgn->EG2PreAttack,
293                            pDimRgn->EG2Attack + eg2attack,                          pDimRgn->EG2Attack * eg2attack,
294                            false,                          false,
295                            pSample->LoopStart,                          pDimRgn->EG2Decay1 * eg2decay * velrelease,
296                            pDimRgn->EG2Decay1 + eg2decay,                          pDimRgn->EG2Decay2 * eg2decay * velrelease,
297                            pDimRgn->EG2Decay2 + eg2decay,                          pDimRgn->EG2InfiniteSustain,
298                            pDimRgn->EG2InfiniteSustain,                          pDimRgn->EG2Sustain,
299                            pDimRgn->EG2Sustain,                          pDimRgn->EG2Release * eg2release * velrelease,
300                            pDimRgn->EG2Release + eg2release,                          velocityAttenuation,
301                            Delay);                          pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
302          }          }
     #endif // ENABLE_FILTER  
303    
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            pEG3->Trigger(eg3depth, pDimRgn->EG3Attack, Delay);              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 279  namespace LinuxSampler { namespace gig { Line 324  namespace LinuxSampler { namespace gig {
324                  case ::gig::lfo1_ctrl_internal:                  case ::gig::lfo1_ctrl_internal:
325                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;
326                      pLFO1->ExtController = 0; // no external controller                      pLFO1->ExtController = 0; // no external controller
327                        bLFO1Enabled         = (lfo1_internal_depth > 0);
328                      break;                      break;
329                  case ::gig::lfo1_ctrl_modwheel:                  case ::gig::lfo1_ctrl_modwheel:
330                      lfo1_internal_depth  = 0;                      lfo1_internal_depth  = 0;
331                      pLFO1->ExtController = 1; // MIDI controller 1                      pLFO1->ExtController = 1; // MIDI controller 1
332                        bLFO1Enabled         = (pDimRgn->LFO1ControlDepth > 0);
333                      break;                      break;
334                  case ::gig::lfo1_ctrl_breath:                  case ::gig::lfo1_ctrl_breath:
335                      lfo1_internal_depth  = 0;                      lfo1_internal_depth  = 0;
336                      pLFO1->ExtController = 2; // MIDI controller 2                      pLFO1->ExtController = 2; // MIDI controller 2
337                        bLFO1Enabled         = (pDimRgn->LFO1ControlDepth > 0);
338                      break;                      break;
339                  case ::gig::lfo1_ctrl_internal_modwheel:                  case ::gig::lfo1_ctrl_internal_modwheel:
340                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;
341                      pLFO1->ExtController = 1; // MIDI controller 1                      pLFO1->ExtController = 1; // MIDI controller 1
342                        bLFO1Enabled         = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0);
343                      break;                      break;
344                  case ::gig::lfo1_ctrl_internal_breath:                  case ::gig::lfo1_ctrl_internal_breath:
345                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;                      lfo1_internal_depth  = pDimRgn->LFO1InternalDepth;
346                      pLFO1->ExtController = 2; // MIDI controller 2                      pLFO1->ExtController = 2; // MIDI controller 2
347                        bLFO1Enabled         = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0);
348                      break;                      break;
349                  default:                  default:
350                      lfo1_internal_depth  = 0;                      lfo1_internal_depth  = 0;
351                      pLFO1->ExtController = 0; // no external controller                      pLFO1->ExtController = 0; // no external controller
352                        bLFO1Enabled         = false;
353                }
354                if (bLFO1Enabled) {
355                    pLFO1->trigger(pDimRgn->LFO1Frequency,
356                                   start_level_min,
357                                   lfo1_internal_depth,
358                                   pDimRgn->LFO1ControlDepth,
359                                   pDimRgn->LFO1FlipPhase,
360                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
361                    pLFO1->update(pLFO1->ExtController ? pEngineChannel->ControllerTable[pLFO1->ExtController] : 0);
362              }              }
             pLFO1->Trigger(pDimRgn->LFO1Frequency,  
                           lfo1_internal_depth,  
                           pDimRgn->LFO1ControlDepth,  
                           pEngine->ControllerTable[pLFO1->ExtController],  
                           pDimRgn->LFO1FlipPhase,  
                           this->SampleRate,  
                           Delay);  
363          }          }
364    
365      #if ENABLE_FILTER  
366          // setup LFO 2 (VCF Cutoff LFO)          // setup LFO 2 (VCF Cutoff LFO)
367          {          {
368              uint16_t lfo2_internal_depth;              uint16_t lfo2_internal_depth;
# Line 317  namespace LinuxSampler { namespace gig { Line 370  namespace LinuxSampler { namespace gig {
370                  case ::gig::lfo2_ctrl_internal:                  case ::gig::lfo2_ctrl_internal:
371                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;
372                      pLFO2->ExtController = 0; // no external controller                      pLFO2->ExtController = 0; // no external controller
373                        bLFO2Enabled         = (lfo2_internal_depth > 0);
374                      break;                      break;
375                  case ::gig::lfo2_ctrl_modwheel:                  case ::gig::lfo2_ctrl_modwheel:
376                      lfo2_internal_depth  = 0;                      lfo2_internal_depth  = 0;
377                      pLFO2->ExtController = 1; // MIDI controller 1                      pLFO2->ExtController = 1; // MIDI controller 1
378                        bLFO2Enabled         = (pDimRgn->LFO2ControlDepth > 0);
379                      break;                      break;
380                  case ::gig::lfo2_ctrl_foot:                  case ::gig::lfo2_ctrl_foot:
381                      lfo2_internal_depth  = 0;                      lfo2_internal_depth  = 0;
382                      pLFO2->ExtController = 4; // MIDI controller 4                      pLFO2->ExtController = 4; // MIDI controller 4
383                        bLFO2Enabled         = (pDimRgn->LFO2ControlDepth > 0);
384                      break;                      break;
385                  case ::gig::lfo2_ctrl_internal_modwheel:                  case ::gig::lfo2_ctrl_internal_modwheel:
386                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;
387                      pLFO2->ExtController = 1; // MIDI controller 1                      pLFO2->ExtController = 1; // MIDI controller 1
388                        bLFO2Enabled         = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
389                      break;                      break;
390                  case ::gig::lfo2_ctrl_internal_foot:                  case ::gig::lfo2_ctrl_internal_foot:
391                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;
392                      pLFO2->ExtController = 4; // MIDI controller 4                      pLFO2->ExtController = 4; // MIDI controller 4
393                        bLFO2Enabled         = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
394                      break;                      break;
395                  default:                  default:
396                      lfo2_internal_depth  = 0;                      lfo2_internal_depth  = 0;
397                      pLFO2->ExtController = 0; // no external controller                      pLFO2->ExtController = 0; // no external controller
398                        bLFO2Enabled         = false;
399                }
400                if (bLFO2Enabled) {
401                    pLFO2->trigger(pDimRgn->LFO2Frequency,
402                                   start_level_max,
403                                   lfo2_internal_depth,
404                                   pDimRgn->LFO2ControlDepth,
405                                   pDimRgn->LFO2FlipPhase,
406                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
407                    pLFO2->update(pLFO2->ExtController ? pEngineChannel->ControllerTable[pLFO2->ExtController] : 0);
408              }              }
             pLFO2->Trigger(pDimRgn->LFO2Frequency,  
                           lfo2_internal_depth,  
                           pDimRgn->LFO2ControlDepth,  
                           pEngine->ControllerTable[pLFO2->ExtController],  
                           pDimRgn->LFO2FlipPhase,  
                           Delay);  
409          }          }
410      #endif // ENABLE_FILTER  
411    
412          // setup LFO 3 (VCO LFO)          // setup LFO 3 (VCO LFO)
413          {          {
# Line 354  namespace LinuxSampler { namespace gig { Line 416  namespace LinuxSampler { namespace gig {
416                  case ::gig::lfo3_ctrl_internal:                  case ::gig::lfo3_ctrl_internal:
417                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
418                      pLFO3->ExtController = 0; // no external controller                      pLFO3->ExtController = 0; // no external controller
419                        bLFO3Enabled         = (lfo3_internal_depth > 0);
420                      break;                      break;
421                  case ::gig::lfo3_ctrl_modwheel:                  case ::gig::lfo3_ctrl_modwheel:
422                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
423                      pLFO3->ExtController = 1; // MIDI controller 1                      pLFO3->ExtController = 1; // MIDI controller 1
424                        bLFO3Enabled         = (pDimRgn->LFO3ControlDepth > 0);
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         = 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;
433                      pLFO3->ExtController = 1; // MIDI controller 1                      pLFO3->ExtController = 1; // MIDI controller 1
434                        bLFO3Enabled         = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0);
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);
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;
445                }
446                if (bLFO3Enabled) {
447                    pLFO3->trigger(pDimRgn->LFO3Frequency,
448                                   start_level_mid,
449                                   lfo3_internal_depth,
450                                   pDimRgn->LFO3ControlDepth,
451                                   false,
452                                   pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
453                    pLFO3->update(pLFO3->ExtController ? pEngineChannel->ControllerTable[pLFO3->ExtController] : 0);
454              }              }
             pLFO3->Trigger(pDimRgn->LFO3Frequency,  
                           lfo3_internal_depth,  
                           pDimRgn->LFO3ControlDepth,  
                           pEngine->ControllerTable[pLFO3->ExtController],  
                           false,  
                           this->SampleRate,  
                           Delay);  
455          }          }
456    
457      #if ENABLE_FILTER  
458          #if FORCE_FILTER_USAGE          #if CONFIG_FORCE_FILTER
459          FilterLeft.Enabled = FilterRight.Enabled = true;          const bool bUseFilter = true;
460          #else // use filter only if instrument file told so          #else // use filter only if instrument file told so
461          FilterLeft.Enabled = FilterRight.Enabled = pDimRgn->VCFEnabled;          const bool bUseFilter = pDimRgn->VCFEnabled;
462          #endif // FORCE_FILTER_USAGE          #endif // CONFIG_FORCE_FILTER
463          if (pDimRgn->VCFEnabled) {          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
464              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL          if (bUseFilter) {
465              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;              #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
466                VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
467              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
468              switch (pDimRgn->VCFCutoffController) {              switch (pDimRgn->VCFCutoffController) {
469                  case ::gig::vcf_cutoff_ctrl_modwheel:                  case ::gig::vcf_cutoff_ctrl_modwheel:
# Line 422  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;
502                      break;                      break;
503              }              }
504              #endif // OVERRIDE_FILTER_CUTOFF_CTRL              #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
505    
506              #ifdef OVERRIDE_FILTER_RES_CTRL              #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
507              VCFResonanceCtrl.controller = OVERRIDE_FILTER_RES_CTRL;              VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
508              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
509              switch (pDimRgn->VCFResonanceController) {              switch (pDimRgn->VCFResonanceController) {
510                  case ::gig::vcf_res_ctrl_genpurpose3:                  case ::gig::vcf_res_ctrl_genpurpose3:
# Line 450  namespace LinuxSampler { namespace gig { Line 523  namespace LinuxSampler { namespace gig {
523                  default:                  default:
524                      VCFResonanceCtrl.controller = 0;                      VCFResonanceCtrl.controller = 0;
525              }              }
526              #endif // OVERRIDE_FILTER_RES_CTRL              #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
527    
528              #ifndef 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(OVERRIDE_FILTER_TYPE);              finalSynthesisParameters.filterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
533              FilterRight.SetType(OVERRIDE_FILTER_TYPE);              finalSynthesisParameters.filterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
534              #endif // OVERRIDE_FILTER_TYPE              #endif // CONFIG_OVERRIDE_FILTER_TYPE
535    
536              VCFCutoffCtrl.value    = pEngine->ControllerTable[VCFCutoffCtrl.controller];              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
537              VCFResonanceCtrl.value = pEngine->ControllerTable[VCFResonanceCtrl.controller];              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
538    
539              // calculate cutoff frequency              // calculate cutoff frequency
540              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = pDimRgn->GetVelocityCutoff(itNoteOnEvent->Param.Note.Velocity);
                 ? exp((float) (127 - pNoteOnEvent->Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX  
                 : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;  
   
             // calculate resonance  
             float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0  
541              if (pDimRgn->VCFKeyboardTracking) {              if (pDimRgn->VCFKeyboardTracking) {
542                  resonance += (float) (pNoteOnEvent->Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;                  cutoff *= exp((itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.057762265f); // (ln(2) / 12)
543              }              }
544              Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)              CutoffBase = cutoff;
545    
546              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;              int cvalue;
547              VCFResonanceCtrl.fvalue = resonance;              if (VCFCutoffCtrl.controller) {
548                    cvalue = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
549                    if (pDimRgn->VCFCutoffControllerInvert) cvalue = 127 - cvalue;
550                    // VCFVelocityScale in this case means Minimum cutoff
551                    if (cvalue < pDimRgn->VCFVelocityScale) cvalue = pDimRgn->VCFVelocityScale;
552                }
553                else {
554                    cvalue = pDimRgn->VCFCutoff;
555                }
556                cutoff *= float(cvalue);
557                if (cutoff > 127.0f) cutoff = 127.0f;
558    
559              FilterLeft.SetParameters(cutoff,  resonance, SampleRate);              // calculate resonance
560              FilterRight.SetParameters(cutoff, resonance, SampleRate);              float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : pDimRgn->VCFResonance);
561    
562              FilterUpdateCounter = -1;              VCFCutoffCtrl.fvalue    = cutoff;
563                VCFResonanceCtrl.fvalue = resonance;
564          }          }
565          else {          else {
566              VCFCutoffCtrl.controller    = 0;              VCFCutoffCtrl.controller    = 0;
567              VCFResonanceCtrl.controller = 0;              VCFResonanceCtrl.controller = 0;
568          }          }
     #endif // ENABLE_FILTER  
   
         // ************************************************  
         // TODO: ARTICULATION DATA HANDLING IS MISSING HERE  
         // ************************************************  
569    
570          return 0; // success          return 0; // success
571      }      }
# Line 509  namespace LinuxSampler { namespace gig { Line 583  namespace LinuxSampler { namespace gig {
583       */       */
584      void Voice::Render(uint Samples) {      void Voice::Render(uint Samples) {
585    
586          // Reset the synthesis parameter matrix          // select default values for synthesis mode bits
587          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume);          SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
         pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);  
     #if ENABLE_FILTER  
         pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);  
         pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);  
     #endif // ENABLE_FILTER  
   
   
         // Apply events to the synthesis parameter matrix  
         ProcessEvents(Samples);  
   
   
         // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment  
         pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);  
     #if ENABLE_FILTER  
         pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);  
     #endif // ENABLE_FILTER  
         pEG3->Process(Samples);  
         pLFO1->Process(Samples);  
     #if ENABLE_FILTER  
         pLFO2->Process(Samples);  
     #endif // ENABLE_FILTER  
         pLFO3->Process(Samples);  
   
588    
589          switch (this->PlaybackState) {          switch (this->PlaybackState) {
590    
591                case playback_state_init:
592                    this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
593                    // no break - continue with playback_state_ram
594    
595              case playback_state_ram: {              case playback_state_ram: {
596                      if (RAMLoop) InterpolateAndLoop(Samples, (sample_t*) pSample->GetCache().pStart, Delay);                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
597                      else         Interpolate(Samples, (sample_t*) pSample->GetCache().pStart, Delay);  
598                        // render current fragment
599                        Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
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 559  namespace LinuxSampler { namespace gig { Line 616  namespace LinuxSampler { namespace gig {
616                          DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);                          DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
617                          if (!DiskStreamRef.pStream) {                          if (!DiskStreamRef.pStream) {
618                              std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;                              std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;
619                              Kill();                              KillImmediately();
620                              return;                              return;
621                          }                          }
622                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (RTMath::DoubleToInt(Pos) - MaxRAMPos));                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(finalSynthesisParameters.dPos) - MaxRAMPos));
623                          Pos -= RTMath::DoubleToInt(Pos);                          finalSynthesisParameters.dPos -= int(finalSynthesisParameters.dPos);
624                            RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
625                      }                      }
626    
627                        const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
628    
629                      // 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)
630                      if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) {                      if (DiskStreamRef.State == Stream::state_end) {
631                          DiskStreamRef.pStream->WriteSilence((MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels);                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
632                          this->PlaybackState = playback_state_end;                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
633                                // remember how many sample words there are before any silence has been added
634                                if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
635                                DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
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                      Interpolate(Samples, ptr, Delay);  
641                      DiskStreamRef.pStream->IncrementReadPos(RTMath::DoubleToInt(Pos) * pSample->Channels);                      // render current audio fragment
642                      Pos -= RTMath::DoubleToInt(Pos);                      Synthesize(Samples, ptr, Delay);
643    
644                        const int iPos = (int) finalSynthesisParameters.dPos;
645                        const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
646                        DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
647                        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
650                        if (RealSampleWordsLeftToRead >= 0) {
651                            RealSampleWordsLeftToRead -= readSampleWords;
652                            if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
653                        }
654                  }                  }
655                  break;                  break;
656    
657              case playback_state_end:              case playback_state_end:
658                  Kill(); // free voice                  std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
659                  break;                  break;
660          }          }
661    
   
     #if ENABLE_FILTER  
         // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)  
         pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();  
         pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();  
     #endif // ENABLE_FILTER  
   
662          // Reset delay          // Reset delay
663          Delay = 0;          Delay = 0;
664    
665          pTriggerEvent = NULL;          itTriggerEvent = Pool<Event>::Iterator();
666    
667          // If release stage finished, let the voice be killed          // If sample stream or release stage finished, kill the voice
668          if (pEG1->GetStage() == EGADSR::stage_end) this->PlaybackState = playback_state_end;          if (PlaybackState == playback_state_end || EG1.getSegmentType() == EGADSR::segment_end) KillImmediately();
669      }      }
670    
671      /**      /**
# Line 605  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          pLFO1->Reset();          finalSynthesisParameters.filterLeft.Reset();
677          pLFO2->Reset();          finalSynthesisParameters.filterRight.Reset();
         pLFO3->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;
681          DiskStreamRef.OrderID = 0;          DiskStreamRef.OrderID = 0;
682          Active = false;          PlaybackState = playback_state_end;
683            itTriggerEvent = Pool<Event>::Iterator();
684            itKillEvent    = Pool<Event>::Iterator();
685      }      }
686    
687      /**      /**
688       *  Process the control change event lists of the engine for the current       * Process given list of MIDI note on, note off and sustain pedal events
689       *  audio fragment. Event values will be applied to the synthesis parameter       * for the given time.
      *  matrix.  
690       *       *
691       *  @param Samples - number of samples to be rendered in this audio fragment cycle       * @param itEvent - iterator pointing to the next event to be processed
692         * @param End     - youngest time stamp where processing should be stopped
693       */       */
694      void Voice::ProcessEvents(uint Samples) {      void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
695            for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
696          // dispatch control change events              if (itEvent->Type == Event::type_release) {
697          Event* pCCEvent = pEngine->pCCEvents->first();                  EG1.update(EGADSR::event_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
698          if (Delay) { // skip events that happened before this voice was triggered                  EG2.update(EGADSR::event_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
699              while (pCCEvent && pCCEvent->FragmentPos() <= Delay) pCCEvent = pEngine->pCCEvents->next();              } else if (itEvent->Type == Event::type_cancel_release) {
700                    EG1.update(EGADSR::event_cancel_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
701                    EG2.update(EGADSR::event_cancel_release, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
702                }
703          }          }
704          while (pCCEvent) {      }
705              if (pCCEvent->Controller) { // if valid MIDI controller  
706                  #if ENABLE_FILTER      /**
707                  if (pCCEvent->Controller == VCFCutoffCtrl.controller) {       * Process given list of MIDI control change and pitch bend events for
708                      pEngine->pSynthesisEvents[Event::destination_vcfc]->alloc_assign(*pCCEvent);       * the given time.
709         *
710         * @param itEvent - iterator pointing to the next event to be processed
711         * @param End     - youngest time stamp where processing should be stopped
712         */
713        void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
714            for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
715                if (itEvent->Type == Event::type_control_change &&
716                    itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
717                    if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
718                        processCutoffEvent(itEvent);
719                    }
720                    if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
721                        processResonanceEvent(itEvent);
722                  }                  }
723                  if (pCCEvent->Controller == VCFResonanceCtrl.controller) {                  if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
724                      pEngine->pSynthesisEvents[Event::destination_vcfr]->alloc_assign(*pCCEvent);                      pLFO1->update(itEvent->Param.CC.Value);
725                  }                  }
726                  #endif // ENABLE_FILTER                  if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
727                  if (pCCEvent->Controller == pLFO1->ExtController) {                      pLFO2->update(itEvent->Param.CC.Value);
                     pLFO1->SendEvent(pCCEvent);  
728                  }                  }
729                  #if ENABLE_FILTER                  if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
730                  if (pCCEvent->Controller == pLFO2->ExtController) {                      pLFO3->update(itEvent->Param.CC.Value);
                     pLFO2->SendEvent(pCCEvent);  
731                  }                  }
732                  #endif // ENABLE_FILTER                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
733                  if (pCCEvent->Controller == pLFO3->ExtController) {                      itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {
734                      pLFO3->SendEvent(pCCEvent);                      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
743                    processPitchEvent(itEvent);
744              }              }
   
             pCCEvent = pEngine->pCCEvents->next();  
745          }          }
746        }
747    
748        void Voice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
749            PitchBend = RTMath::CentsToFreqRatio(itEvent->Param.Pitch.Pitch / 8192.0 * 100.0 * pEngineChannel->pInstrument->PitchbendRange);
750        }
751    
752        void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
753            int ccvalue = itEvent->Param.CC.Value;
754            if (VCFCutoffCtrl.value == ccvalue) return;
755            VCFCutoffCtrl.value == ccvalue;
756            if (pDimRgn->VCFCutoffControllerInvert)  ccvalue = 127 - ccvalue;
757            if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;
758            float cutoff = CutoffBase * float(ccvalue);
759            if (cutoff > 127.0f) cutoff = 127.0f;
760    
761          // process pitch events          VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
762          {          fFinalCutoff = cutoff;
763              RTEList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];      }
764              Event* pVCOEvent = pVCOEventList->first();  
765              if (Delay) { // skip events that happened before this voice was triggered      void Voice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
766                  while (pVCOEvent && pVCOEvent->FragmentPos() <= Delay) pVCOEvent = pVCOEventList->next();          // convert absolute controller value to differential
767              }          const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
768              // apply old pitchbend value until first pitch event occurs          VCFResonanceCtrl.value = itEvent->Param.CC.Value;
769              if (this->PitchBend != 1.0) {          const float resonancedelta = (float) ctrldelta;
770                  uint end = (pVCOEvent) ? pVCOEvent->FragmentPos() : Samples;          fFinalResonance += resonancedelta;
771                  for (uint i = Delay; i < end; i++) {          // needed for initialization of parameter
772                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;          VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value;
773                  }      }
             }  
             float pitch;  
             while (pVCOEvent) {  
                 Event* pNextVCOEvent = pVCOEventList->next();  
774    
775                  // calculate the influence length of this event (in sample points)      /**
776                  uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples;       *  Synthesizes the current audio fragment for this voice.
777         *
778         *  @param Samples - number of sample points to be rendered in this audio
779         *                   fragment cycle
780         *  @param pSrc    - pointer to input sample data
781         *  @param Skip    - number of sample points to skip in output buffer
782         */
783        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                  pitch = RTMath::CentsToFreqRatio(((double) pVCOEvent->Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents          RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();
789            RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first();
790    
791                  // apply pitch value to the pitch parameter sequence          if (itTriggerEvent) { // skip events that happened before this voice was triggered
792                  for (uint i = pVCOEvent->FragmentPos(); i < end; i++) {              while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
793                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;              // 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                  pVCOEvent = pNextVCOEvent;          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              }              }
             if (pVCOEventList->last()) this->PitchBend = pitch;  
818          }          }
819    
820            uint i = Skip;
821            while (i < Samples) {
822                int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
823    
824      #if ENABLE_FILTER              // initialize all final synthesis parameters
825          // process filter cutoff events              fFinalCutoff    = VCFCutoffCtrl.fvalue;
826          {              fFinalResonance = VCFResonanceCtrl.fvalue;
             RTEList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];  
             Event* pCutoffEvent = pCutoffEventList->first();  
             if (Delay) { // skip events that happened before this voice was triggered  
                 while (pCutoffEvent && pCutoffEvent->FragmentPos() <= Delay) pCutoffEvent = pCutoffEventList->next();  
             }  
             float cutoff;  
             while (pCutoffEvent) {  
                 Event* pNextCutoffEvent = pCutoffEventList->next();  
827    
828                  // calculate the influence length of this event (in sample points)              // process MIDI control change and pitchbend events for this subfragment
829                  uint end = (pNextCutoffEvent) ? pNextCutoffEvent->FragmentPos() : Samples;              processCCEvents(itCCEvent, iSubFragmentEnd);
830    
831                  cutoff = exp((float) pCutoffEvent->Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;              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                  // apply cutoff frequency to the cutoff parameter sequence              // process transition events (note on, note off & sustain pedal)
838                  for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) {              processTransitionEvents(itNoteEvent, iSubFragmentEnd);
                     pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;  
                 }  
839    
840                  pCutoffEvent = pNextCutoffEvent;              // 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              }              }
             if (pCutoffEventList->last()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time  
         }  
848    
849          // process filter resonance events              // process envelope generators
850          {              switch (EG1.getSegmentType()) {
851              RTEList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];                  case EGADSR::segment_lin:
852              Event* pResonanceEvent = pResonanceEventList->first();                      fFinalVolume *= EG1.processLin();
853              if (Delay) { // skip events that happened before this voice was triggered                      break;
854                  while (pResonanceEvent && pResonanceEvent->FragmentPos() <= Delay) pResonanceEvent = pResonanceEventList->next();                  case EGADSR::segment_exp:
855                        fFinalVolume *= EG1.processExp();
856                        break;
857                    case EGADSR::segment_end:
858                        fFinalVolume *= EG1.getLevel();
859                        break; // noop
860              }              }
861              while (pResonanceEvent) {              switch (EG2.getSegmentType()) {
862                  Event* pNextResonanceEvent = pResonanceEventList->next();                  case EGADSR::segment_lin:
863                        fFinalCutoff *= EG2.processLin();
864                        break;
865                    case EGADSR::segment_exp:
866                        fFinalCutoff *= EG2.processExp();
867                        break;
868                    case EGADSR::segment_end:
869                        fFinalCutoff *= EG2.getLevel();
870                        break; // noop
871                }
872                if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render();
873    
874                // process low frequency oscillators
875                if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render());
876                if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
877                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
883                if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
884                    finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
885                    finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
886                }
887    
888                // do we need resampling?
889                const float __PLUS_ONE_CENT  = 1.000577789506554859250142541782224725466f;
890                const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
891                const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
892                                                   finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
893                SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
894    
895                  // calculate the influence length of this event (in sample points)              // prepare final synthesis parameters structure
896                  uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples;              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
911                RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
912    
913                  // convert absolute controller value to differential              // stop the rendering if volume EG is finished
914                  int ctrldelta = pResonanceEvent->Value - VCFResonanceCtrl.value;              if (EG1.getSegmentType() == EGADSR::segment_end) break;
                 VCFResonanceCtrl.value = pResonanceEvent->Value;  
915    
916                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0              const double newPos = Pos + (iSubFragmentEnd - i) * finalSynthesisParameters.fFinalPitch;
917    
918                  // apply cutoff frequency to the cutoff parameter sequence              // increment envelopes' positions
919                  for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) {              if (EG1.active()) {
920                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;  
921                    // 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                  pResonanceEvent = pNextResonanceEvent;                  EG1.increment(1);
927                    if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
928                }
929                if (EG2.active()) {
930                    EG2.increment(1);
931                    if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
932              }              }
933              if (pResonanceEventList->last()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Value * 0.00787f; // needed for initialization of parameter matrix next time              EG3.increment(1);
934                if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
935    
936                Pos = newPos;
937                i = iSubFragmentEnd;
938          }          }
     #endif // ENABLE_FILTER  
939      }      }
940    
941      /**      /** @brief Update current portamento position.
      *  Interpolates the input audio data (no loop).  
942       *       *
943       *  @param Samples - number of sample points to be rendered in this audio       * Will be called when portamento mode is enabled to get the final
944       *                   fragment cycle       * portamento position of this active voice from where the next voice(s)
945       *  @param pSrc    - pointer to input sample data       * might continue to slide on.
946       *  @param Skip    - number of sample points to skip in output buffer       *
947         * @param itNoteOffEvent - event which causes this voice to die soon
948       */       */
949      void Voice::Interpolate(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent) {
950          int i = Skip;          const float fFinalEG3Level = EG3.level(itNoteOffEvent->FragmentPos());
951            pEngineChannel->PortamentoPos = (float) MIDIKey + RTMath::FreqRatioToCents(fFinalEG3Level) * 0.01f;
         // 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->pSynthesisParameters[Event::destination_vcfc][i],  
                                           pEngine->pSynthesisParameters[Event::destination_vcfr][i]);  
             }  
         }  
         else { // Mono Sample  
             while (i < Samples) {  
                 InterpolateOneStep_Mono(pSrc, i,  
                                         pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                         pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                         pEngine->pSynthesisParameters[Event::destination_vcfc][i],  
                                         pEngine->pSynthesisParameters[Event::destination_vcfr][i]);  
             }  
         }  
952      }      }
953    
954      /**      /**
955       *  Interpolates the input audio data, this method honors looping.       *  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
957         *  fading down the volume level to avoid clicks and regular processing
958         *  until the kill event actually occured!
959       *       *
960       *  @param Samples - number of sample points to be rendered in this audio       * If it's necessary to know when the voice's disk stream was actually
961       *                   fragment cycle       * deleted, then one can set the optional @a bRequestNotification
962       *  @param pSrc    - pointer to input sample data       * parameter and this method will then return the handle of the disk
963       *  @param Skip    - number of sample points to skip in output buffer       * 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::InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip) {      Stream::Handle Voice::KillImmediately(bool bRequestNotification) {
977          int i = Skip;          Stream::Handle hStream = Stream::INVALID_HANDLE;
978            if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
979          // FIXME: assuming either mono or stereo              pDiskThread->OrderDeletionOfStream(&DiskStreamRef, bRequestNotification);
980          if (pSample->Channels == 2) { // Stereo Sample              hStream = DiskStreamRef.hStream;
             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->pSynthesisParameters[Event::destination_vcfc][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vcfr][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->pSynthesisParameters[Event::destination_vcfc][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vcfr][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->pSynthesisParameters[Event::destination_vcfc][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vcfr][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->pSynthesisParameters[Event::destination_vcfc][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vcfr][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->pSynthesisParameters[Event::destination_vcfc][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vcfr][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->pSynthesisParameters[Event::destination_vcfc][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vcfr][i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;  
                     }  
                 }  
             }  
981          }          }
982            Reset();
983            return hStream;
984      }      }
985    
986      /**      /**
987       *  Immediately kill the voice.       *  Kill the voice in regular sense. Let the voice render audio until
988         *  the kill event actually occured and then fade down the volume level
989         *  very quickly and let the voice die finally. Unlike a normal release
990         *  of a voice, a kill process cannot be cancalled and is therefore
991         *  usually used for voice stealing and key group conflicts.
992         *
993         *  @param itKillEvent - event which caused the voice to be killed
994       */       */
995      void Voice::Kill() {      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
996          if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {          #if CONFIG_DEVMODE
997              pDiskThread->OrderDeletionOfStream(&DiskStreamRef);          if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
998          }          if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
999          Reset();          #endif // CONFIG_DEVMODE
1000    
1001            if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1002            this->itKillEvent = itKillEvent;
1003      }      }
1004    
1005  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

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

  ViewVC Help
Powered by ViewVC