/[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 64 by schoenebeck, Thu May 6 20:06:20 2004 UTC revision 687 by schoenebeck, Tue Jul 12 22:37:21 2005 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6     *   Copyright (C) 2005 Christian Schoenebeck                              *
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 22  Line 23 
23    
24  #include "EGADSR.h"  #include "EGADSR.h"
25  #include "Manipulator.h"  #include "Manipulator.h"
26    #include "../../common/Features.h"
27    #include "Synthesizer.h"
28    
29  #include "Voice.h"  #include "Voice.h"
30    
31  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
32    
     // FIXME: no support for layers (nor crossfades) yet  
   
33      const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());      const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());
34    
35        const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());
36    
37      float Voice::CalculateFilterCutoffCoeff() {      float Voice::CalculateFilterCutoffCoeff() {
38          return log(FILTER_CUTOFF_MIN / FILTER_CUTOFF_MAX);          return log(CONFIG_FILTER_CUTOFF_MIN / CONFIG_FILTER_CUTOFF_MAX);
39        }
40    
41        int Voice::CalculateFilterUpdateMask() {
42            if (CONFIG_FILTER_UPDATE_STEPS <= 0) return 0;
43            int power_of_two;
44            for (power_of_two = 0; 1<<power_of_two < CONFIG_FILTER_UPDATE_STEPS; power_of_two++);
45            return (1 << power_of_two) - 1;
46      }      }
47    
48      Voice::Voice() {      Voice::Voice() {
49          pEngine     = NULL;          pEngine     = NULL;
50          pDiskThread = NULL;          pDiskThread = NULL;
51          Active = false;          PlaybackState = playback_state_end;
52          pEG1   = NULL;          pEG1   = NULL;
53          pEG2   = NULL;          pEG2   = NULL;
54          pEG3   = NULL;          pEG3   = NULL;
# Line 48  namespace LinuxSampler { namespace gig { Line 58  namespace LinuxSampler { namespace gig {
58          pLFO1  = NULL;          pLFO1  = NULL;
59          pLFO2  = NULL;          pLFO2  = NULL;
60          pLFO3  = NULL;          pLFO3  = NULL;
61            KeyGroup = 0;
62            SynthesisMode = 0; // set all mode bits to 0 first
63            // select synthesis implementation (currently either pure C++ or MMX+SSE(1))
64            #if CONFIG_ASM && ARCH_X86
65            SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
66            #else
67            SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
68            #endif
69            SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true);
70    
71            FilterLeft.Reset();
72            FilterRight.Reset();
73      }      }
74    
75      Voice::~Voice() {      Voice::~Voice() {
# Line 62  namespace LinuxSampler { namespace gig { Line 84  namespace LinuxSampler { namespace gig {
84          if (pVCOManipulator)  delete pVCOManipulator;          if (pVCOManipulator)  delete pVCOManipulator;
85      }      }
86    
     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();  
     }  
   
87      void Voice::SetEngine(Engine* pEngine) {      void Voice::SetEngine(Engine* pEngine) {
88          this->pEngine = pEngine;          this->pEngine = pEngine;
89    
# Line 102  namespace LinuxSampler { namespace gig { Line 117  namespace LinuxSampler { namespace gig {
117       *  Initializes and triggers the voice, a disk stream will be launched if       *  Initializes and triggers the voice, a disk stream will be launched if
118       *  needed.       *  needed.
119       *       *
120       *  @param pNoteOnEvent - event that caused triggering of this voice       *  @param pEngineChannel - engine channel on which this voice was ordered
121       *  @param PitchBend    - MIDI detune factor (-8192 ... +8191)       *  @param itNoteOnEvent  - event that caused triggering of this voice
122       *  @param pInstrument  - points to the loaded instrument which provides sample wave(s) and articulation data       *  @param PitchBend      - MIDI detune factor (-8192 ... +8191)
123       *  @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
124         *  @param VoiceType      - type of this voice
125         *  @param iKeyGroup      - a value > 0 defines a key group in which this voice is member of
126         *  @returns 0 on success, a value < 0 if the voice wasn't triggered
127         *           (either due to an error or e.g. because no region is
128         *           defined for the given key)
129       */       */
130      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) {
131          if (!pInstrument) {          this->pEngineChannel = pEngineChannel;
132             dmsg(1,("voice::trigger: !pInstrument\n"));          this->pDimRgn        = pDimRgn;
133             exit(EXIT_FAILURE);  
134          }          #if CONFIG_DEVMODE
135            if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
136          Active          = true;              dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
137          MIDIKey         = pNoteOnEvent->Key;          }
138          pRegion         = pInstrument->GetRegion(MIDIKey);          #endif // CONFIG_DEVMODE
139          PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed  
140          Pos             = 0;          Type            = VoiceType;
141          Delay           = pNoteOnEvent->FragmentPos();          MIDIKey         = itNoteOnEvent->Param.Note.Key;
142          pTriggerEvent   = pNoteOnEvent;          PlaybackState   = playback_state_init; // mark voice as triggered, but no audio rendered yet
143            Delay           = itNoteOnEvent->FragmentPos();
144          if (!pRegion) {          itTriggerEvent  = itNoteOnEvent;
145              std::cerr << "Audio Thread: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;          itKillEvent     = Pool<Event>::Iterator();
146              Kill();          KeyGroup        = iKeyGroup;
147              return -1;          pSample         = pDimRgn->pSample; // sample won't change until the voice is finished
148          }  
149            // calculate volume
150          //TODO: current MIDI controller values are not taken into account yet          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
151          ::gig::DimensionRegion* pDimRgn = NULL;  
152          for (int i = pRegion->Dimensions - 1; i >= 0; i--) { // Check if instrument has a velocity split          Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
153              if (pRegion->pDimensionDefinitions[i].dimension == ::gig::dimension_velocity) {  
154                  uint DimValues[5] = {0,0,0,0,0};          Volume *= pDimRgn->SampleAttenuation;
155                      DimValues[i] = pNoteOnEvent->Velocity;  
156                  pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);          // the volume of release triggered samples depends on note length
157            if (Type == type_release_trigger) {
158                float noteLength = float(pEngine->FrameTime + Delay -
159                                         pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
160                float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
161                if (attenuation <= 0) return -1;
162                Volume *= attenuation;
163            }
164    
165            // select channel mode (mono or stereo)
166            SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
167    
168            // get starting crossfade volume level
169            switch (pDimRgn->AttenuationController.type) {
170                case ::gig::attenuation_ctrl_t::type_channelaftertouch:
171                    CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
172                  break;                  break;
173              }              case ::gig::attenuation_ctrl_t::type_velocity:
174          }                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
175          if (!pDimRgn) { // if there was no velocity split                  break;
176              pDimRgn = pRegion->GetDimensionRegionByValue(0,0,0,0,0);              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
177                    CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);
178                    break;
179                case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
180                default:
181                    CrossfadeVolume = 1.0f;
182          }          }
183    
184          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          PanLeft  = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) /  63.0f;
185            PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;
186    
187            Pos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
188    
189          // 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
190          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
191          DiskVoice          = cachedsamples < pSample->SamplesTotal;          DiskVoice          = cachedsamples < pSample->SamplesTotal;
192    
193          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
194              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)              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)
195    
196              // 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
197              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
# Line 159  namespace LinuxSampler { namespace gig { Line 202  namespace LinuxSampler { namespace gig {
202    
203              if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {              if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {
204                  dmsg(1,("Disk stream order failed!\n"));                  dmsg(1,("Disk stream order failed!\n"));
205                  Kill();                  KillImmediately();
206                  return -1;                  return -1;
207              }              }
208              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"));
# Line 177  namespace LinuxSampler { namespace gig { Line 220  namespace LinuxSampler { namespace gig {
220    
221          // calculate initial pitch value          // calculate initial pitch value
222          {          {
223              double pitchbasecents = pDimRgn->FineTune * 10;              double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
224              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
225              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents);              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));
226              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
227          }          }
228    
229            // the length of the decay and release curves are dependent on the velocity
230          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)          const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
   
231    
232          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
233          {          {
# Line 199  namespace LinuxSampler { namespace gig { Line 241  namespace LinuxSampler { namespace gig {
241                      eg1controllervalue = 0; // TODO: aftertouch not yet supported                      eg1controllervalue = 0; // TODO: aftertouch not yet supported
242                      break;                      break;
243                  case ::gig::eg1_ctrl_t::type_velocity:                  case ::gig::eg1_ctrl_t::type_velocity:
244                      eg1controllervalue = pNoteOnEvent->Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
245                      break;                      break;
246                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
247                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];                      eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
248                      break;                      break;
249              }              }
250              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
# Line 216  namespace LinuxSampler { namespace gig { Line 258  namespace LinuxSampler { namespace gig {
258                            pDimRgn->EG1Attack + eg1attack,                            pDimRgn->EG1Attack + eg1attack,
259                            pDimRgn->EG1Hold,                            pDimRgn->EG1Hold,
260                            pSample->LoopStart,                            pSample->LoopStart,
261                            pDimRgn->EG1Decay1 + eg1decay,                            (pDimRgn->EG1Decay1 + eg1decay) * velrelease,
262                            pDimRgn->EG1Decay2 + eg1decay,                            (pDimRgn->EG1Decay2 + eg1decay) * velrelease,
263                            pDimRgn->EG1InfiniteSustain,                            pDimRgn->EG1InfiniteSustain,
264                            pDimRgn->EG1Sustain,                            pDimRgn->EG1Sustain,
265                            pDimRgn->EG1Release + eg1release,                            (pDimRgn->EG1Release + eg1release) * velrelease,
266                            Delay);                            // the SSE synthesis implementation requires
267                              // the vca start to be 16 byte aligned
268                              SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ?
269                              Delay & 0xfffffffc : Delay,
270                              velocityAttenuation);
271          }          }
272    
273    
     #if ENABLE_FILTER  
274          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
275          {          {
276              // get current value of EG2 controller              // get current value of EG2 controller
# Line 238  namespace LinuxSampler { namespace gig { Line 283  namespace LinuxSampler { namespace gig {
283                      eg2controllervalue = 0; // TODO: aftertouch not yet supported                      eg2controllervalue = 0; // TODO: aftertouch not yet supported
284                      break;                      break;
285                  case ::gig::eg2_ctrl_t::type_velocity:                  case ::gig::eg2_ctrl_t::type_velocity:
286                      eg2controllervalue = pNoteOnEvent->Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
287                      break;                      break;
288                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
289                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];                      eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
290                      break;                      break;
291              }              }
292              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
# Line 255  namespace LinuxSampler { namespace gig { Line 300  namespace LinuxSampler { namespace gig {
300                            pDimRgn->EG2Attack + eg2attack,                            pDimRgn->EG2Attack + eg2attack,
301                            false,                            false,
302                            pSample->LoopStart,                            pSample->LoopStart,
303                            pDimRgn->EG2Decay1 + eg2decay,                            (pDimRgn->EG2Decay1 + eg2decay) * velrelease,
304                            pDimRgn->EG2Decay2 + eg2decay,                            (pDimRgn->EG2Decay2 + eg2decay) * velrelease,
305                            pDimRgn->EG2InfiniteSustain,                            pDimRgn->EG2InfiniteSustain,
306                            pDimRgn->EG2Sustain,                            pDimRgn->EG2Sustain,
307                            pDimRgn->EG2Release + eg2release,                            (pDimRgn->EG2Release + eg2release) * velrelease,
308                            Delay);                            Delay,
309                              velocityAttenuation);
310          }          }
     #endif // ENABLE_FILTER  
311    
312    
313          // setup EG 3 (VCO EG)          // setup EG 3 (VCO EG)
# 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              pLFO1->Trigger(pDimRgn->LFO1Frequency,              if (bLFO1Enabled) pLFO1->Trigger(pDimRgn->LFO1Frequency,
355                            lfo1_internal_depth,                                               lfo1_internal_depth,
356                            pDimRgn->LFO1ControlDepth,                                               pDimRgn->LFO1ControlDepth,
357                            pEngine->ControllerTable[pLFO1->ExtController],                                               pEngineChannel->ControllerTable[pLFO1->ExtController],
358                            pDimRgn->LFO1FlipPhase,                                               pDimRgn->LFO1FlipPhase,
359                            this->SampleRate,                                               pEngine->SampleRate,
360                            Delay);                                               Delay);
361          }          }
362    
363      #if ENABLE_FILTER  
364          // setup LFO 2 (VCF Cutoff LFO)          // setup LFO 2 (VCF Cutoff LFO)
365          {          {
366              uint16_t lfo2_internal_depth;              uint16_t lfo2_internal_depth;
# Line 317  namespace LinuxSampler { namespace gig { Line 368  namespace LinuxSampler { namespace gig {
368                  case ::gig::lfo2_ctrl_internal:                  case ::gig::lfo2_ctrl_internal:
369                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;
370                      pLFO2->ExtController = 0; // no external controller                      pLFO2->ExtController = 0; // no external controller
371                        bLFO2Enabled         = (lfo2_internal_depth > 0);
372                      break;                      break;
373                  case ::gig::lfo2_ctrl_modwheel:                  case ::gig::lfo2_ctrl_modwheel:
374                      lfo2_internal_depth  = 0;                      lfo2_internal_depth  = 0;
375                      pLFO2->ExtController = 1; // MIDI controller 1                      pLFO2->ExtController = 1; // MIDI controller 1
376                        bLFO2Enabled         = (pDimRgn->LFO2ControlDepth > 0);
377                      break;                      break;
378                  case ::gig::lfo2_ctrl_foot:                  case ::gig::lfo2_ctrl_foot:
379                      lfo2_internal_depth  = 0;                      lfo2_internal_depth  = 0;
380                      pLFO2->ExtController = 4; // MIDI controller 4                      pLFO2->ExtController = 4; // MIDI controller 4
381                        bLFO2Enabled         = (pDimRgn->LFO2ControlDepth > 0);
382                      break;                      break;
383                  case ::gig::lfo2_ctrl_internal_modwheel:                  case ::gig::lfo2_ctrl_internal_modwheel:
384                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;
385                      pLFO2->ExtController = 1; // MIDI controller 1                      pLFO2->ExtController = 1; // MIDI controller 1
386                        bLFO2Enabled         = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
387                      break;                      break;
388                  case ::gig::lfo2_ctrl_internal_foot:                  case ::gig::lfo2_ctrl_internal_foot:
389                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;                      lfo2_internal_depth  = pDimRgn->LFO2InternalDepth;
390                      pLFO2->ExtController = 4; // MIDI controller 4                      pLFO2->ExtController = 4; // MIDI controller 4
391                        bLFO2Enabled         = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
392                      break;                      break;
393                  default:                  default:
394                      lfo2_internal_depth  = 0;                      lfo2_internal_depth  = 0;
395                      pLFO2->ExtController = 0; // no external controller                      pLFO2->ExtController = 0; // no external controller
396                        bLFO2Enabled         = false;
397              }              }
398              pLFO2->Trigger(pDimRgn->LFO2Frequency,              if (bLFO2Enabled) pLFO2->Trigger(pDimRgn->LFO2Frequency,
399                            lfo2_internal_depth,                                               lfo2_internal_depth,
400                            pDimRgn->LFO2ControlDepth,                                               pDimRgn->LFO2ControlDepth,
401                            pEngine->ControllerTable[pLFO2->ExtController],                                               pEngineChannel->ControllerTable[pLFO2->ExtController],
402                            pDimRgn->LFO2FlipPhase,                                               pDimRgn->LFO2FlipPhase,
403                            Delay);                                               pEngine->SampleRate,
404                                                 Delay);
405          }          }
406      #endif // ENABLE_FILTER  
407    
408          // setup LFO 3 (VCO LFO)          // setup LFO 3 (VCO LFO)
409          {          {
# Line 354  namespace LinuxSampler { namespace gig { Line 412  namespace LinuxSampler { namespace gig {
412                  case ::gig::lfo3_ctrl_internal:                  case ::gig::lfo3_ctrl_internal:
413                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
414                      pLFO3->ExtController = 0; // no external controller                      pLFO3->ExtController = 0; // no external controller
415                        bLFO3Enabled         = (lfo3_internal_depth > 0);
416                      break;                      break;
417                  case ::gig::lfo3_ctrl_modwheel:                  case ::gig::lfo3_ctrl_modwheel:
418                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
419                      pLFO3->ExtController = 1; // MIDI controller 1                      pLFO3->ExtController = 1; // MIDI controller 1
420                        bLFO3Enabled         = (pDimRgn->LFO3ControlDepth > 0);
421                      break;                      break;
422                  case ::gig::lfo3_ctrl_aftertouch:                  case ::gig::lfo3_ctrl_aftertouch:
423                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
424                      pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet                      pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet
425                        bLFO3Enabled         = false; // see TODO comment in line above
426                      break;                      break;
427                  case ::gig::lfo3_ctrl_internal_modwheel:                  case ::gig::lfo3_ctrl_internal_modwheel:
428                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
429                      pLFO3->ExtController = 1; // MIDI controller 1                      pLFO3->ExtController = 1; // MIDI controller 1
430                        bLFO3Enabled         = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0);
431                      break;                      break;
432                  case ::gig::lfo3_ctrl_internal_aftertouch:                  case ::gig::lfo3_ctrl_internal_aftertouch:
433                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;                      lfo3_internal_depth  = pDimRgn->LFO3InternalDepth;
434                      pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet                      pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet
435                        bLFO3Enabled         = (lfo3_internal_depth > 0 /*|| pDimRgn->LFO3ControlDepth > 0*/); // see TODO comment in line above
436                      break;                      break;
437                  default:                  default:
438                      lfo3_internal_depth  = 0;                      lfo3_internal_depth  = 0;
439                      pLFO3->ExtController = 0; // no external controller                      pLFO3->ExtController = 0; // no external controller
440                        bLFO3Enabled         = false;
441              }              }
442              pLFO3->Trigger(pDimRgn->LFO3Frequency,              if (bLFO3Enabled) pLFO3->Trigger(pDimRgn->LFO3Frequency,
443                            lfo3_internal_depth,                                               lfo3_internal_depth,
444                            pDimRgn->LFO3ControlDepth,                                               pDimRgn->LFO3ControlDepth,
445                            pEngine->ControllerTable[pLFO3->ExtController],                                               pEngineChannel->ControllerTable[pLFO3->ExtController],
446                            false,                                               false,
447                            this->SampleRate,                                               pEngine->SampleRate,
448                            Delay);                                               Delay);
449          }          }
450    
451      #if ENABLE_FILTER  
452          #if FORCE_FILTER_USAGE          #if CONFIG_FORCE_FILTER
453          FilterLeft.Enabled = FilterRight.Enabled = true;          const bool bUseFilter = true;
454          #else // use filter only if instrument file told so          #else // use filter only if instrument file told so
455          FilterLeft.Enabled = FilterRight.Enabled = pDimRgn->VCFEnabled;          const bool bUseFilter = pDimRgn->VCFEnabled;
456          #endif // FORCE_FILTER_USAGE          #endif // CONFIG_FORCE_FILTER
457          if (pDimRgn->VCFEnabled) {          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
458              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL          if (bUseFilter) {
459              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;              #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
460                VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
461              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
462              switch (pDimRgn->VCFCutoffController) {              switch (pDimRgn->VCFCutoffController) {
463                  case ::gig::vcf_cutoff_ctrl_modwheel:                  case ::gig::vcf_cutoff_ctrl_modwheel:
# Line 428  namespace LinuxSampler { namespace gig { Line 493  namespace LinuxSampler { namespace gig {
493                      VCFCutoffCtrl.controller = 0;                      VCFCutoffCtrl.controller = 0;
494                      break;                      break;
495              }              }
496              #endif // OVERRIDE_FILTER_CUTOFF_CTRL              #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
497    
498              #ifdef OVERRIDE_FILTER_RES_CTRL              #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
499              VCFResonanceCtrl.controller = OVERRIDE_FILTER_RES_CTRL;              VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
500              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
501              switch (pDimRgn->VCFResonanceController) {              switch (pDimRgn->VCFResonanceController) {
502                  case ::gig::vcf_res_ctrl_genpurpose3:                  case ::gig::vcf_res_ctrl_genpurpose3:
# Line 450  namespace LinuxSampler { namespace gig { Line 515  namespace LinuxSampler { namespace gig {
515                  default:                  default:
516                      VCFResonanceCtrl.controller = 0;                      VCFResonanceCtrl.controller = 0;
517              }              }
518              #endif // OVERRIDE_FILTER_RES_CTRL              #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
519    
520              #ifndef OVERRIDE_FILTER_TYPE              #ifndef CONFIG_OVERRIDE_FILTER_TYPE
521              FilterLeft.SetType(pDimRgn->VCFType);              FilterLeft.SetType(pDimRgn->VCFType);
522              FilterRight.SetType(pDimRgn->VCFType);              FilterRight.SetType(pDimRgn->VCFType);
523              #else // override filter type              #else // override filter type
524              FilterLeft.SetType(OVERRIDE_FILTER_TYPE);              FilterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
525              FilterRight.SetType(OVERRIDE_FILTER_TYPE);              FilterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
526              #endif // OVERRIDE_FILTER_TYPE              #endif // CONFIG_OVERRIDE_FILTER_TYPE
527    
528              VCFCutoffCtrl.value    = pEngine->ControllerTable[VCFCutoffCtrl.controller];              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
529              VCFResonanceCtrl.value = pEngine->ControllerTable[VCFResonanceCtrl.controller];              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
530    
531              // calculate cutoff frequency              // calculate cutoff frequency
532              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = (!VCFCutoffCtrl.controller)
533                  ? exp((float) (127 - pNoteOnEvent->Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX                  ? exp((float) (127 - itNoteOnEvent->Param.Note.Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX
534                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX;
535    
536              // calculate resonance              // calculate resonance
537              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0
538              if (pDimRgn->VCFKeyboardTracking) {              if (pDimRgn->VCFKeyboardTracking) {
539                  resonance += (float) (pNoteOnEvent->Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;                  resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
540              }              }
541              Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)              Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)
542    
543              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;              VCFCutoffCtrl.fvalue    = cutoff - CONFIG_FILTER_CUTOFF_MIN;
544              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
545    
             FilterLeft.SetParameters(cutoff,  resonance, SampleRate);  
             FilterRight.SetParameters(cutoff, resonance, SampleRate);  
   
546              FilterUpdateCounter = -1;              FilterUpdateCounter = -1;
547          }          }
548          else {          else {
549              VCFCutoffCtrl.controller    = 0;              VCFCutoffCtrl.controller    = 0;
550              VCFResonanceCtrl.controller = 0;              VCFResonanceCtrl.controller = 0;
551          }          }
     #endif // ENABLE_FILTER  
   
         // ************************************************  
         // TODO: ARTICULATION DATA HANDLING IS MISSING HERE  
         // ************************************************  
552    
553          return 0; // success          return 0; // success
554      }      }
# Line 509  namespace LinuxSampler { namespace gig { Line 566  namespace LinuxSampler { namespace gig {
566       */       */
567      void Voice::Render(uint Samples) {      void Voice::Render(uint Samples) {
568    
569            // select default values for synthesis mode bits
570            SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, (PitchBase * PitchBend) != 1.0f);
571            SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, true);
572            SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
573    
574          // Reset the synthesis parameter matrix          // Reset the synthesis parameter matrix
575          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume);  
576            pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume);
577          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
     #if ENABLE_FILTER  
578          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
579          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
     #endif // ENABLE_FILTER  
   
580    
581          // Apply events to the synthesis parameter matrix          // Apply events to the synthesis parameter matrix
582          ProcessEvents(Samples);          ProcessEvents(Samples);
583    
   
584          // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment          // Let all modulators write their parameter changes to the synthesis parameter matrix for the current audio fragment
585          pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);          pEG1->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);
586      #if ENABLE_FILTER          pEG2->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
587          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);          if (pEG3->Process(Samples)) { // if pitch EG is active
588      #endif // ENABLE_FILTER              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
589          pEG3->Process(Samples);              SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
590          pLFO1->Process(Samples);          }
591      #if ENABLE_FILTER          if (bLFO1Enabled) pLFO1->Process(Samples);
592          pLFO2->Process(Samples);          if (bLFO2Enabled) pLFO2->Process(Samples);
593      #endif // ENABLE_FILTER          if (bLFO3Enabled) {
594          pLFO3->Process(Samples);              if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active
595                    SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
596                    SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
597                }
598            }
599    
600            if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
601                CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
602    
603          switch (this->PlaybackState) {          switch (this->PlaybackState) {
604    
605                case playback_state_init:
606                    this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
607                    // no break - continue with playback_state_ram
608    
609              case playback_state_ram: {              case playback_state_ram: {
610                      if (RAMLoop) InterpolateAndLoop(Samples, (sample_t*) pSample->GetCache().pStart, Delay);                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
611                      else         Interpolate(Samples, (sample_t*) pSample->GetCache().pStart, Delay);  
612                        // render current fragment
613                        Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
614    
615                      if (DiskVoice) {                      if (DiskVoice) {
616                          // check if we reached the allowed limit of the sample RAM cache                          // check if we reached the allowed limit of the sample RAM cache
617                          if (Pos > MaxRAMPos) {                          if (Pos > MaxRAMPos) {
# Line 559  namespace LinuxSampler { namespace gig { Line 631  namespace LinuxSampler { namespace gig {
631                          DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);                          DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
632                          if (!DiskStreamRef.pStream) {                          if (!DiskStreamRef.pStream) {
633                              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;
634                              Kill();                              KillImmediately();
635                              return;                              return;
636                          }                          }
637                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (RTMath::DoubleToInt(Pos) - MaxRAMPos));                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
638                          Pos -= RTMath::DoubleToInt(Pos);                          Pos -= int(Pos);
639                            RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
640                      }                      }
641    
642                        const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
643    
644                      // 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)
645                      if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) {                      if (DiskStreamRef.State == Stream::state_end) {
646                          DiskStreamRef.pStream->WriteSilence((MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels);                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
647                          this->PlaybackState = playback_state_end;                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
648                                // remember how many sample words there are before any silence has been added
649                                if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
650                                DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
651                            }
652                      }                      }
653    
654                      sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from                      sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
655                      Interpolate(Samples, ptr, Delay);  
656                      DiskStreamRef.pStream->IncrementReadPos(RTMath::DoubleToInt(Pos) * pSample->Channels);                      // render current audio fragment
657                      Pos -= RTMath::DoubleToInt(Pos);                      Synthesize(Samples, ptr, Delay);
658    
659                        const int iPos = (int) Pos;
660                        const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
661                        DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
662                        Pos -= iPos; // just keep fractional part of Pos
663    
664                        // change state of voice to 'end' if we really reached the end of the sample data
665                        if (RealSampleWordsLeftToRead >= 0) {
666                            RealSampleWordsLeftToRead -= readSampleWords;
667                            if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
668                        }
669                  }                  }
670                  break;                  break;
671    
672              case playback_state_end:              case playback_state_end:
673                  Kill(); // free voice                  std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
674                  break;                  break;
675          }          }
676    
   
     #if ENABLE_FILTER  
677          // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)          // Reset synthesis event lists (except VCO, as VCO events apply channel wide currently)
678          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vca]->clear();
679          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->clear();
680      #endif // ENABLE_FILTER          pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->clear();
681    
682          // Reset delay          // Reset delay
683          Delay = 0;          Delay = 0;
684    
685          pTriggerEvent = NULL;          itTriggerEvent = Pool<Event>::Iterator();
686    
687          // If release stage finished, let the voice be killed          // If sample stream or release stage finished, kill the voice
688          if (pEG1->GetStage() == EGADSR::stage_end) this->PlaybackState = playback_state_end;          if (PlaybackState == playback_state_end || pEG1->GetStage() == EGADSR::stage_end) KillImmediately();
689      }      }
690    
691      /**      /**
# Line 608  namespace LinuxSampler { namespace gig { Line 696  namespace LinuxSampler { namespace gig {
696          pLFO1->Reset();          pLFO1->Reset();
697          pLFO2->Reset();          pLFO2->Reset();
698          pLFO3->Reset();          pLFO3->Reset();
699            FilterLeft.Reset();
700            FilterRight.Reset();
701          DiskStreamRef.pStream = NULL;          DiskStreamRef.pStream = NULL;
702          DiskStreamRef.hStream = 0;          DiskStreamRef.hStream = 0;
703          DiskStreamRef.State   = Stream::state_unused;          DiskStreamRef.State   = Stream::state_unused;
704          DiskStreamRef.OrderID = 0;          DiskStreamRef.OrderID = 0;
705          Active = false;          PlaybackState = playback_state_end;
706            itTriggerEvent = Pool<Event>::Iterator();
707            itKillEvent    = Pool<Event>::Iterator();
708      }      }
709    
710      /**      /**
# Line 625  namespace LinuxSampler { namespace gig { Line 717  namespace LinuxSampler { namespace gig {
717      void Voice::ProcessEvents(uint Samples) {      void Voice::ProcessEvents(uint Samples) {
718    
719          // dispatch control change events          // dispatch control change events
720          Event* pCCEvent = pEngine->pCCEvents->first();          RTList<Event>::Iterator itCCEvent = pEngineChannel->pCCEvents->first();
721          if (Delay) { // skip events that happened before this voice was triggered          if (Delay) { // skip events that happened before this voice was triggered
722              while (pCCEvent && pCCEvent->FragmentPos() <= Delay) pCCEvent = pEngine->pCCEvents->next();              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
723          }          }
724          while (pCCEvent) {          while (itCCEvent) {
725              if (pCCEvent->Controller) { // if valid MIDI controller              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
726                  #if ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
727                  if (pCCEvent->Controller == VCFCutoffCtrl.controller) {                      *pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
728                      pEngine->pSynthesisEvents[Event::destination_vcfc]->alloc_assign(*pCCEvent);                  }
729                    if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
730                        *pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
731                  }                  }
732                  if (pCCEvent->Controller == VCFResonanceCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
733                      pEngine->pSynthesisEvents[Event::destination_vcfr]->alloc_assign(*pCCEvent);                      pLFO1->SendEvent(itCCEvent);
734                  }                  }
735                  #endif // ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO2->ExtController) {
736                  if (pCCEvent->Controller == pLFO1->ExtController) {                      pLFO2->SendEvent(itCCEvent);
                     pLFO1->SendEvent(pCCEvent);  
737                  }                  }
738                  #if ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO3->ExtController) {
739                  if (pCCEvent->Controller == pLFO2->ExtController) {                      pLFO3->SendEvent(itCCEvent);
                     pLFO2->SendEvent(pCCEvent);  
740                  }                  }
741                  #endif // ENABLE_FILTER                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
742                  if (pCCEvent->Controller == pLFO3->ExtController) {                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
743                      pLFO3->SendEvent(pCCEvent);                      *pEngineChannel->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
744                  }                  }
745              }              }
746    
747              pCCEvent = pEngine->pCCEvents->next();              ++itCCEvent;
748          }          }
749    
750    
751          // process pitch events          // process pitch events
752          {          {
753              RTEList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];              RTList<Event>* pVCOEventList = pEngineChannel->pSynthesisEvents[Event::destination_vco];
754              Event* pVCOEvent = pVCOEventList->first();              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
755              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
756                  while (pVCOEvent && pVCOEvent->FragmentPos() <= Delay) pVCOEvent = pVCOEventList->next();                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
757              }              }
758              // apply old pitchbend value until first pitch event occurs              // apply old pitchbend value until first pitch event occurs
759              if (this->PitchBend != 1.0) {              if (this->PitchBend != 1.0) {
760                  uint end = (pVCOEvent) ? pVCOEvent->FragmentPos() : Samples;                  uint end = (itVCOEvent) ? itVCOEvent->FragmentPos() : Samples;
761                  for (uint i = Delay; i < end; i++) {                  for (uint i = Delay; i < end; i++) {
762                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
763                  }                  }
764              }              }
765              float pitch;              float pitch;
766              while (pVCOEvent) {              while (itVCOEvent) {
767                  Event* pNextVCOEvent = pVCOEventList->next();                  RTList<Event>::Iterator itNextVCOEvent = itVCOEvent;
768                    ++itNextVCOEvent;
769    
770                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
771                  uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples;                  uint end = (itNextVCOEvent) ? itNextVCOEvent->FragmentPos() : Samples;
772    
773                  pitch = RTMath::CentsToFreqRatio(((double) pVCOEvent->Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents                  pitch = RTMath::CentsToFreqRatio(((double) itVCOEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
774    
775                  // apply pitch value to the pitch parameter sequence                  // apply pitch value to the pitch parameter sequence
776                  for (uint i = pVCOEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCOEvent->FragmentPos(); i < end; i++) {
777                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
778                  }                  }
779    
780                  pVCOEvent = pNextVCOEvent;                  itVCOEvent = itNextVCOEvent;
781                }
782                if (!pVCOEventList->isEmpty()) {
783                    this->PitchBend = pitch;
784                    SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
785                    SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
786              }              }
             if (pVCOEventList->last()) this->PitchBend = pitch;  
787          }          }
788    
789            // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)
790            {
791                RTList<Event>* pVCAEventList = pEngineChannel->pSynthesisEvents[Event::destination_vca];
792                RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
793                if (Delay) { // skip events that happened before this voice was triggered
794                    while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
795                }
796                float crossfadevolume;
797                while (itVCAEvent) {
798                    RTList<Event>::Iterator itNextVCAEvent = itVCAEvent;
799                    ++itNextVCAEvent;
800    
801                    // calculate the influence length of this event (in sample points)
802                    uint end = (itNextVCAEvent) ? itNextVCAEvent->FragmentPos() : Samples;
803    
804                    crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
805    
806                    float effective_volume = crossfadevolume * this->Volume * pEngineChannel->GlobalVolume;
807    
808                    // apply volume value to the volume parameter sequence
809                    for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
810                        pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;
811                    }
812    
813                    itVCAEvent = itNextVCAEvent;
814                }
815                if (!pVCAEventList->isEmpty()) this->CrossfadeVolume = crossfadevolume;
816            }
817    
     #if ENABLE_FILTER  
818          // process filter cutoff events          // process filter cutoff events
819          {          {
820              RTEList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];              RTList<Event>* pCutoffEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfc];
821              Event* pCutoffEvent = pCutoffEventList->first();              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
822              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
823                  while (pCutoffEvent && pCutoffEvent->FragmentPos() <= Delay) pCutoffEvent = pCutoffEventList->next();                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
824              }              }
825              float cutoff;              float cutoff;
826              while (pCutoffEvent) {              while (itCutoffEvent) {
827                  Event* pNextCutoffEvent = pCutoffEventList->next();                  RTList<Event>::Iterator itNextCutoffEvent = itCutoffEvent;
828                    ++itNextCutoffEvent;
829    
830                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
831                  uint end = (pNextCutoffEvent) ? pNextCutoffEvent->FragmentPos() : Samples;                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
832    
833                  cutoff = exp((float) pCutoffEvent->Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;                  cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX - CONFIG_FILTER_CUTOFF_MIN;
834    
835                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
836                  for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) {                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
837                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
838                  }                  }
839    
840                  pCutoffEvent = pNextCutoffEvent;                  itCutoffEvent = itNextCutoffEvent;
841              }              }
842              if (pCutoffEventList->last()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time              if (!pCutoffEventList->isEmpty()) VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of parameter matrix next time
843          }          }
844    
845          // process filter resonance events          // process filter resonance events
846          {          {
847              RTEList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];              RTList<Event>* pResonanceEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfr];
848              Event* pResonanceEvent = pResonanceEventList->first();              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
849              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
850                  while (pResonanceEvent && pResonanceEvent->FragmentPos() <= Delay) pResonanceEvent = pResonanceEventList->next();                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
851              }              }
852              while (pResonanceEvent) {              while (itResonanceEvent) {
853                  Event* pNextResonanceEvent = pResonanceEventList->next();                  RTList<Event>::Iterator itNextResonanceEvent = itResonanceEvent;
854                    ++itNextResonanceEvent;
855    
856                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
857                  uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples;                  uint end = (itNextResonanceEvent) ? itNextResonanceEvent->FragmentPos() : Samples;
858    
859                  // convert absolute controller value to differential                  // convert absolute controller value to differential
860                  int ctrldelta = pResonanceEvent->Value - VCFResonanceCtrl.value;                  int ctrldelta = itResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;
861                  VCFResonanceCtrl.value = pResonanceEvent->Value;                  VCFResonanceCtrl.value = itResonanceEvent->Param.CC.Value;
862    
863                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
864    
865                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
866                  for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) {                  for (uint i = itResonanceEvent->FragmentPos(); i < end; i++) {
867                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
868                  }                  }
869    
870                  pResonanceEvent = pNextResonanceEvent;                  itResonanceEvent = itNextResonanceEvent;
871              }              }
872              if (pResonanceEventList->last()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Value * 0.00787f; // needed for initialization of parameter matrix next time              if (!pResonanceEventList->isEmpty()) VCFResonanceCtrl.fvalue = pResonanceEventList->last()->Param.CC.Value * 0.00787f; // needed for initialization of parameter matrix next time
873          }          }
     #endif // ENABLE_FILTER  
874      }      }
875    
876      /**      /**
877       *  Interpolates the input audio data (no loop).       * Calculate all necessary, final biquad filter parameters.
878       *       *
879       *  @param Samples - number of sample points to be rendered in this audio       * @param Samples - number of samples to be rendered in this audio fragment cycle
      *                   fragment cycle  
      *  @param pSrc    - pointer to input sample data  
      *  @param Skip    - number of sample points to skip in output buffer  
880       */       */
881      void Voice::Interpolate(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::CalculateBiquadParameters(uint Samples) {
882          int i = Skip;          biquad_param_t bqbase;
883            biquad_param_t bqmain;
884          // FIXME: assuming either mono or stereo          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
885          if (this->pSample->Channels == 2) { // Stereo Sample          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
886              while (i < Samples) {          FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
887                  InterpolateOneStep_Stereo(pSrc, i,          FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
888                                            pEngine->pSynthesisParameters[Event::destination_vca][i],          pEngine->pBasicFilterParameters[0] = bqbase;
889                                            pEngine->pSynthesisParameters[Event::destination_vco][i],          pEngine->pMainFilterParameters[0]  = bqmain;
890                                            pEngine->pSynthesisParameters[Event::destination_vcfc][i],  
891                                            pEngine->pSynthesisParameters[Event::destination_vcfr][i]);          float* bq;
892              }          for (int i = 1; i < Samples; i++) {
893          }              // recalculate biquad parameters if cutoff or resonance differ from previous sample point
894          else { // Mono Sample              if (!(i & FILTER_UPDATE_MASK)) {
895              while (i < Samples) {                  if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
896                  InterpolateOneStep_Mono(pSrc, i,                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff)
897                                          pEngine->pSynthesisParameters[Event::destination_vca][i],                  {
898                                          pEngine->pSynthesisParameters[Event::destination_vco][i],                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
899                                          pEngine->pSynthesisParameters[Event::destination_vcfc][i],                      prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
900                                          pEngine->pSynthesisParameters[Event::destination_vcfr][i]);                      FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
901                        FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
902                    }
903              }              }
904    
905                //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
906                bq    = (float*) &pEngine->pBasicFilterParameters[i];
907                bq[0] = bqbase.b0;
908                bq[1] = bqbase.b1;
909                bq[2] = bqbase.b2;
910                bq[3] = bqbase.a1;
911                bq[4] = bqbase.a2;
912    
913                // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
914                bq    = (float*) &pEngine->pMainFilterParameters[i];
915                bq[0] = bqmain.b0;
916                bq[1] = bqmain.b1;
917                bq[2] = bqmain.b2;
918                bq[3] = bqmain.a1;
919                bq[4] = bqmain.a2;
920          }          }
921      }      }
922    
923      /**      /**
924       *  Interpolates the input audio data, this method honors looping.       *  Synthesizes the current audio fragment for this voice.
925       *       *
926       *  @param Samples - number of sample points to be rendered in this audio       *  @param Samples - number of sample points to be rendered in this audio
927       *                   fragment cycle       *                   fragment cycle
928       *  @param pSrc    - pointer to input sample data       *  @param pSrc    - pointer to input sample data
929       *  @param Skip    - number of sample points to skip in output buffer       *  @param Skip    - number of sample points to skip in output buffer
930       */       */
931      void Voice::InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
932          int i = Skip;          RunSynthesisFunction(SynthesisMode, *this, Samples, pSrc, Skip);
   
         // FIXME: assuming either mono or stereo  
         if (pSample->Channels == 2) { // Stereo Sample  
             if (pSample->LoopPlayCount) {  
                 // render loop (loop count limited)  
                 while (i < Samples && LoopCyclesLeft) {  
                     InterpolateOneStep_Stereo(pSrc, i,  
                                               pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                               pEngine->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);;  
                     }  
                 }  
             }  
         }  
933      }      }
934    
935      /**      /**
936       *  Immediately kill the voice.       *  Immediately kill the voice. This method should not be used to kill
937         *  a normal, active voice, because it doesn't take care of things like
938         *  fading down the volume level to avoid clicks and regular processing
939         *  until the kill event actually occured!
940         *
941         *  @see Kill()
942       */       */
943      void Voice::Kill() {      void Voice::KillImmediately() {
944          if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {          if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
945              pDiskThread->OrderDeletionOfStream(&DiskStreamRef);              pDiskThread->OrderDeletionOfStream(&DiskStreamRef);
946          }          }
947          Reset();          Reset();
948      }      }
949    
950        /**
951         *  Kill the voice in regular sense. Let the voice render audio until
952         *  the kill event actually occured and then fade down the volume level
953         *  very quickly and let the voice die finally. Unlike a normal release
954         *  of a voice, a kill process cannot be cancalled and is therefore
955         *  usually used for voice stealing and key group conflicts.
956         *
957         *  @param itKillEvent - event which caused the voice to be killed
958         */
959        void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
960            #if CONFIG_DEVMODE
961            if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
962            if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
963            #endif // CONFIG_DEVMODE
964    
965            if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
966            this->itKillEvent = itKillEvent;
967        }
968    
969  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.64  
changed lines
  Added in v.687

  ViewVC Help
Powered by ViewVC