/[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 80 by schoenebeck, Sun May 23 19:16:33 2004 UTC revision 411 by schoenebeck, Sat Feb 26 02:01:14 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());      const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());
# Line 47  namespace LinuxSampler { namespace gig { Line 48  namespace LinuxSampler { namespace gig {
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 57  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 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 71  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 111  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 pInstrument         - points to the loaded instrument which provides sample wave(s) and articulation data
124         *  @param iLayer              - layer number this voice refers to (only if this is a layered sound of course)
125         *  @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)
126         *  @param VoiceStealing       - wether the voice is allowed to steal voices for further subvoices
127         *  @returns 0 on success, a value < 0 if the voice wasn't triggered
128         *           (either due to an error or e.g. because no region is
129         *           defined for the given key)
130       */       */
131      int Voice::Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument) {      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) {
132            this->pEngineChannel = pEngineChannel;
133          if (!pInstrument) {          if (!pInstrument) {
134             dmsg(1,("voice::trigger: !pInstrument\n"));             dmsg(1,("voice::trigger: !pInstrument\n"));
135             exit(EXIT_FAILURE);             exit(EXIT_FAILURE);
136          }          }
137            if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // FIXME: should be removed before the final release (purpose: just a sanity check for debugging)
138                dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
139            }
140    
141          Active          = true;          Type            = type_normal;
142          MIDIKey         = pNoteOnEvent->Key;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
143          pRegion         = pInstrument->GetRegion(MIDIKey);          pRegion         = pInstrument->GetRegion(MIDIKey);
144          PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed          PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
145          Pos             = 0;          Delay           = itNoteOnEvent->FragmentPos();
146          Delay           = pNoteOnEvent->FragmentPos();          itTriggerEvent  = itNoteOnEvent;
147          pTriggerEvent   = pNoteOnEvent;          itKillEvent     = Pool<Event>::Iterator();
148            itChildVoice    = Pool<Voice>::Iterator();
149    
150          if (!pRegion) {          if (!pRegion) {
151              std::cerr << "Audio Thread: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;              dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey));
             Kill();  
152              return -1;              return -1;
153          }          }
154    
155          //TODO: current MIDI controller values are not taken into account yet          KeyGroup = pRegion->KeyGroup;
156          ::gig::DimensionRegion* pDimRgn = NULL;  
157          for (int i = pRegion->Dimensions - 1; i >= 0; i--) { // Check if instrument has a velocity split          // get current dimension values to select the right dimension region
158              if (pRegion->pDimensionDefinitions[i].dimension == ::gig::dimension_velocity) {          //FIXME: controller values for selecting the dimension region here are currently not sample accurate
159                  uint DimValues[5] = {0,0,0,0,0};          uint DimValues[8] = { 0 };
160                      DimValues[i] = pNoteOnEvent->Velocity;          for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
161                  pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);              switch (pRegion->pDimensionDefinitions[i].dimension) {
162                  break;                  case ::gig::dimension_samplechannel:
163                        DimValues[i] = 0; //TODO: we currently ignore this dimension
164                        break;
165                    case ::gig::dimension_layer:
166                        DimValues[i] = iLayer;
167                        // if this is the 1st layer then spawn further voices for all the other layers
168                        if (iLayer == 0)
169                            for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++)
170                                itChildVoice = pEngine->LaunchVoice(pEngineChannel, itNoteOnEvent, iNewLayer, ReleaseTriggerVoice, VoiceStealing);
171                        break;
172                    case ::gig::dimension_velocity:
173                        DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
174                        break;
175                    case ::gig::dimension_channelaftertouch:
176                        DimValues[i] = 0; //TODO: we currently ignore this dimension
177                        break;
178                    case ::gig::dimension_releasetrigger:
179                        Type = (ReleaseTriggerVoice) ? type_release_trigger : (!iLayer) ? type_release_trigger_required : type_normal;
180                        DimValues[i] = (uint) ReleaseTriggerVoice;
181                        break;
182                    case ::gig::dimension_keyboard:
183                        DimValues[i] = (uint) pEngineChannel->CurrentKeyDimension;
184                        break;
185                    case ::gig::dimension_modwheel:
186                        DimValues[i] = pEngineChannel->ControllerTable[1];
187                        break;
188                    case ::gig::dimension_breath:
189                        DimValues[i] = pEngineChannel->ControllerTable[2];
190                        break;
191                    case ::gig::dimension_foot:
192                        DimValues[i] = pEngineChannel->ControllerTable[4];
193                        break;
194                    case ::gig::dimension_portamentotime:
195                        DimValues[i] = pEngineChannel->ControllerTable[5];
196                        break;
197                    case ::gig::dimension_effect1:
198                        DimValues[i] = pEngineChannel->ControllerTable[12];
199                        break;
200                    case ::gig::dimension_effect2:
201                        DimValues[i] = pEngineChannel->ControllerTable[13];
202                        break;
203                    case ::gig::dimension_genpurpose1:
204                        DimValues[i] = pEngineChannel->ControllerTable[16];
205                        break;
206                    case ::gig::dimension_genpurpose2:
207                        DimValues[i] = pEngineChannel->ControllerTable[17];
208                        break;
209                    case ::gig::dimension_genpurpose3:
210                        DimValues[i] = pEngineChannel->ControllerTable[18];
211                        break;
212                    case ::gig::dimension_genpurpose4:
213                        DimValues[i] = pEngineChannel->ControllerTable[19];
214                        break;
215                    case ::gig::dimension_sustainpedal:
216                        DimValues[i] = pEngineChannel->ControllerTable[64];
217                        break;
218                    case ::gig::dimension_portamento:
219                        DimValues[i] = pEngineChannel->ControllerTable[65];
220                        break;
221                    case ::gig::dimension_sostenutopedal:
222                        DimValues[i] = pEngineChannel->ControllerTable[66];
223                        break;
224                    case ::gig::dimension_softpedal:
225                        DimValues[i] = pEngineChannel->ControllerTable[67];
226                        break;
227                    case ::gig::dimension_genpurpose5:
228                        DimValues[i] = pEngineChannel->ControllerTable[80];
229                        break;
230                    case ::gig::dimension_genpurpose6:
231                        DimValues[i] = pEngineChannel->ControllerTable[81];
232                        break;
233                    case ::gig::dimension_genpurpose7:
234                        DimValues[i] = pEngineChannel->ControllerTable[82];
235                        break;
236                    case ::gig::dimension_genpurpose8:
237                        DimValues[i] = pEngineChannel->ControllerTable[83];
238                        break;
239                    case ::gig::dimension_effect1depth:
240                        DimValues[i] = pEngineChannel->ControllerTable[91];
241                        break;
242                    case ::gig::dimension_effect2depth:
243                        DimValues[i] = pEngineChannel->ControllerTable[92];
244                        break;
245                    case ::gig::dimension_effect3depth:
246                        DimValues[i] = pEngineChannel->ControllerTable[93];
247                        break;
248                    case ::gig::dimension_effect4depth:
249                        DimValues[i] = pEngineChannel->ControllerTable[94];
250                        break;
251                    case ::gig::dimension_effect5depth:
252                        DimValues[i] = pEngineChannel->ControllerTable[95];
253                        break;
254                    case ::gig::dimension_none:
255                        std::cerr << "gig::Voice::Trigger() Error: dimension=none\n" << std::flush;
256                        break;
257                    default:
258                        std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;
259              }              }
260          }          }
261          if (!pDimRgn) { // if there was no velocity split          pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
             pDimRgn = pRegion->GetDimensionRegionByValue(0,0,0,0,0);  
         }  
262    
263          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          pSample = pDimRgn->pSample; // sample won't change until the voice is finished
264            if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent
265    
266            // select channel mode (mono or stereo)
267            SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
268    
269            // get starting crossfade volume level
270            switch (pDimRgn->AttenuationController.type) {
271                case ::gig::attenuation_ctrl_t::type_channelaftertouch:
272                    CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
273                    break;
274                case ::gig::attenuation_ctrl_t::type_velocity:
275                    CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
276                    break;
277                case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
278                    CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);
279                    break;
280                case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
281                default:
282                    CrossfadeVolume = 1.0f;
283            }
284    
285            PanLeft  = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) /  63.0f;
286            PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;
287    
288            Pos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
289    
290          // 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
291          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
292          DiskVoice          = cachedsamples < pSample->SamplesTotal;          DiskVoice          = cachedsamples < pSample->SamplesTotal;
293    
294          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
295              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 << 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)
296    
297              // 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
298              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
# Line 168  namespace LinuxSampler { namespace gig { Line 303  namespace LinuxSampler { namespace gig {
303    
304              if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {              if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {
305                  dmsg(1,("Disk stream order failed!\n"));                  dmsg(1,("Disk stream order failed!\n"));
306                  Kill();                  KillImmediately();
307                  return -1;                  return -1;
308              }              }
309              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 186  namespace LinuxSampler { namespace gig { Line 321  namespace LinuxSampler { namespace gig {
321    
322          // calculate initial pitch value          // calculate initial pitch value
323          {          {
324              double pitchbasecents = pDimRgn->FineTune * 10;              double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
325              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
326              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents);              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));
327              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
328          }          }
329    
330            Volume = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity) / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
331    
332          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)          Volume *= pDimRgn->SampleAttenuation;
   
333    
334          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
335          {          {
# Line 208  namespace LinuxSampler { namespace gig { Line 343  namespace LinuxSampler { namespace gig {
343                      eg1controllervalue = 0; // TODO: aftertouch not yet supported                      eg1controllervalue = 0; // TODO: aftertouch not yet supported
344                      break;                      break;
345                  case ::gig::eg1_ctrl_t::type_velocity:                  case ::gig::eg1_ctrl_t::type_velocity:
346                      eg1controllervalue = pNoteOnEvent->Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
347                      break;                      break;
348                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
349                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];                      eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
350                      break;                      break;
351              }              }
352              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
# Line 234  namespace LinuxSampler { namespace gig { Line 369  namespace LinuxSampler { namespace gig {
369          }          }
370    
371    
     #if ENABLE_FILTER  
372          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
373          {          {
374              // get current value of EG2 controller              // get current value of EG2 controller
# Line 247  namespace LinuxSampler { namespace gig { Line 381  namespace LinuxSampler { namespace gig {
381                      eg2controllervalue = 0; // TODO: aftertouch not yet supported                      eg2controllervalue = 0; // TODO: aftertouch not yet supported
382                      break;                      break;
383                  case ::gig::eg2_ctrl_t::type_velocity:                  case ::gig::eg2_ctrl_t::type_velocity:
384                      eg2controllervalue = pNoteOnEvent->Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
385                      break;                      break;
386                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
387                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];                      eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
388                      break;                      break;
389              }              }
390              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
# Line 271  namespace LinuxSampler { namespace gig { Line 405  namespace LinuxSampler { namespace gig {
405                            pDimRgn->EG2Release + eg2release,                            pDimRgn->EG2Release + eg2release,
406                            Delay);                            Delay);
407          }          }
     #endif // ENABLE_FILTER  
408    
409    
410          // setup EG 3 (VCO EG)          // setup EG 3 (VCO EG)
# Line 312  namespace LinuxSampler { namespace gig { Line 445  namespace LinuxSampler { namespace gig {
445              pLFO1->Trigger(pDimRgn->LFO1Frequency,              pLFO1->Trigger(pDimRgn->LFO1Frequency,
446                            lfo1_internal_depth,                            lfo1_internal_depth,
447                            pDimRgn->LFO1ControlDepth,                            pDimRgn->LFO1ControlDepth,
448                            pEngine->ControllerTable[pLFO1->ExtController],                            pEngineChannel->ControllerTable[pLFO1->ExtController],
449                            pDimRgn->LFO1FlipPhase,                            pDimRgn->LFO1FlipPhase,
450                            this->SampleRate,                            pEngine->SampleRate,
451                            Delay);                            Delay);
452          }          }
453    
454      #if ENABLE_FILTER  
455          // setup LFO 2 (VCF Cutoff LFO)          // setup LFO 2 (VCF Cutoff LFO)
456          {          {
457              uint16_t lfo2_internal_depth;              uint16_t lfo2_internal_depth;
# Line 350  namespace LinuxSampler { namespace gig { Line 483  namespace LinuxSampler { namespace gig {
483              pLFO2->Trigger(pDimRgn->LFO2Frequency,              pLFO2->Trigger(pDimRgn->LFO2Frequency,
484                            lfo2_internal_depth,                            lfo2_internal_depth,
485                            pDimRgn->LFO2ControlDepth,                            pDimRgn->LFO2ControlDepth,
486                            pEngine->ControllerTable[pLFO2->ExtController],                            pEngineChannel->ControllerTable[pLFO2->ExtController],
487                            pDimRgn->LFO2FlipPhase,                            pDimRgn->LFO2FlipPhase,
488                            this->SampleRate,                            pEngine->SampleRate,
489                            Delay);                            Delay);
490          }          }
491      #endif // ENABLE_FILTER  
492    
493          // setup LFO 3 (VCO LFO)          // setup LFO 3 (VCO LFO)
494          {          {
# Line 388  namespace LinuxSampler { namespace gig { Line 521  namespace LinuxSampler { namespace gig {
521              pLFO3->Trigger(pDimRgn->LFO3Frequency,              pLFO3->Trigger(pDimRgn->LFO3Frequency,
522                            lfo3_internal_depth,                            lfo3_internal_depth,
523                            pDimRgn->LFO3ControlDepth,                            pDimRgn->LFO3ControlDepth,
524                            pEngine->ControllerTable[pLFO3->ExtController],                            pEngineChannel->ControllerTable[pLFO3->ExtController],
525                            false,                            false,
526                            this->SampleRate,                            pEngine->SampleRate,
527                            Delay);                            Delay);
528          }          }
529    
530      #if ENABLE_FILTER  
531          #if FORCE_FILTER_USAGE          #if FORCE_FILTER_USAGE
532          FilterLeft.Enabled = FilterRight.Enabled = true;          const bool bUseFilter = true;
533          #else // use filter only if instrument file told so          #else // use filter only if instrument file told so
534          FilterLeft.Enabled = FilterRight.Enabled = pDimRgn->VCFEnabled;          const bool bUseFilter = pDimRgn->VCFEnabled;
535          #endif // FORCE_FILTER_USAGE          #endif // FORCE_FILTER_USAGE
536          if (pDimRgn->VCFEnabled) {          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
537            if (bUseFilter) {
538              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL
539              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;
540              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
# Line 470  namespace LinuxSampler { namespace gig { Line 604  namespace LinuxSampler { namespace gig {
604              FilterRight.SetType(OVERRIDE_FILTER_TYPE);              FilterRight.SetType(OVERRIDE_FILTER_TYPE);
605              #endif // OVERRIDE_FILTER_TYPE              #endif // OVERRIDE_FILTER_TYPE
606    
607              VCFCutoffCtrl.value    = pEngine->ControllerTable[VCFCutoffCtrl.controller];              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
608              VCFResonanceCtrl.value = pEngine->ControllerTable[VCFResonanceCtrl.controller];              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
609    
610              // calculate cutoff frequency              // calculate cutoff frequency
611              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = (!VCFCutoffCtrl.controller)
612                  ? exp((float) (127 - pNoteOnEvent->Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX                  ? exp((float) (127 - itNoteOnEvent->Param.Note.Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX
613                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;
614    
615              // calculate resonance              // calculate resonance
616              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0
617              if (pDimRgn->VCFKeyboardTracking) {              if (pDimRgn->VCFKeyboardTracking) {
618                  resonance += (float) (pNoteOnEvent->Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;                  resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
619              }              }
620              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)
621    
622              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;
623              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
624    
             FilterLeft.SetParameters(cutoff,  resonance, SampleRate);  
             FilterRight.SetParameters(cutoff, resonance, SampleRate);  
   
625              FilterUpdateCounter = -1;              FilterUpdateCounter = -1;
626          }          }
627          else {          else {
628              VCFCutoffCtrl.controller    = 0;              VCFCutoffCtrl.controller    = 0;
629              VCFResonanceCtrl.controller = 0;              VCFResonanceCtrl.controller = 0;
630          }          }
     #endif // ENABLE_FILTER  
   
         // ************************************************  
         // TODO: ARTICULATION DATA HANDLING IS MISSING HERE  
         // ************************************************  
631    
632          return 0; // success          return 0; // success
633      }      }
# Line 519  namespace LinuxSampler { namespace gig { Line 645  namespace LinuxSampler { namespace gig {
645       */       */
646      void Voice::Render(uint Samples) {      void Voice::Render(uint Samples) {
647    
648            // select default values for synthesis mode bits
649            SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, (PitchBase * PitchBend) != 1.0f);
650            SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, true);
651            SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
652    
653          // Reset the synthesis parameter matrix          // Reset the synthesis parameter matrix
654          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume);  
655            pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume);
656          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
     #if ENABLE_FILTER  
657          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
658          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
     #endif // ENABLE_FILTER  
   
659    
660          // Apply events to the synthesis parameter matrix          // Apply events to the synthesis parameter matrix
661          ProcessEvents(Samples);          ProcessEvents(Samples);
662    
   
663          // 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
664          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);
665      #if ENABLE_FILTER          pEG2->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
666          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);          if (pEG3->Process(Samples)) { // if pitch EG is active
667      #endif // ENABLE_FILTER              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
668          pEG3->Process(Samples);              SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
669            }
670          pLFO1->Process(Samples);          pLFO1->Process(Samples);
     #if ENABLE_FILTER  
671          pLFO2->Process(Samples);          pLFO2->Process(Samples);
672      #endif // ENABLE_FILTER          if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active
673          pLFO3->Process(Samples);              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
674                SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
675            }
     #if ENABLE_FILTER  
         CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters  
     #endif // ENABLE_FILTER  
676    
677            if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
678                    CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
679    
680          switch (this->PlaybackState) {          switch (this->PlaybackState) {
681    
682              case playback_state_ram: {              case playback_state_ram: {
683                      if (RAMLoop) InterpolateAndLoop(Samples, (sample_t*) pSample->GetCache().pStart, Delay);                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
684                      else         Interpolate(Samples, (sample_t*) pSample->GetCache().pStart, Delay);  
685                        // render current fragment
686                        Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
687    
688                      if (DiskVoice) {                      if (DiskVoice) {
689                          // check if we reached the allowed limit of the sample RAM cache                          // check if we reached the allowed limit of the sample RAM cache
690                          if (Pos > MaxRAMPos) {                          if (Pos > MaxRAMPos) {
# Line 574  namespace LinuxSampler { namespace gig { Line 704  namespace LinuxSampler { namespace gig {
704                          DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);                          DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
705                          if (!DiskStreamRef.pStream) {                          if (!DiskStreamRef.pStream) {
706                              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;
707                              Kill();                              KillImmediately();
708                              return;                              return;
709                          }                          }
710                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (RTMath::DoubleToInt(Pos) - MaxRAMPos));                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
711                          Pos -= RTMath::DoubleToInt(Pos);                          Pos -= int(Pos);
712                            RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
713                      }                      }
714    
715                        const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
716    
717                      // 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)
718                      if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) {                      if (DiskStreamRef.State == Stream::state_end) {
719                          DiskStreamRef.pStream->WriteSilence((MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels);                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
720                          this->PlaybackState = playback_state_end;                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
721                                // remember how many sample words there are before any silence has been added
722                                if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
723                                DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
724                            }
725                      }                      }
726    
727                      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
728                      Interpolate(Samples, ptr, Delay);  
729                      DiskStreamRef.pStream->IncrementReadPos(RTMath::DoubleToInt(Pos) * pSample->Channels);                      // render current audio fragment
730                      Pos -= RTMath::DoubleToInt(Pos);                      Synthesize(Samples, ptr, Delay);
731    
732                        const int iPos = (int) Pos;
733                        const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
734                        DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
735                        Pos -= iPos; // just keep fractional part of Pos
736    
737                        // change state of voice to 'end' if we really reached the end of the sample data
738                        if (RealSampleWordsLeftToRead >= 0) {
739                            RealSampleWordsLeftToRead -= readSampleWords;
740                            if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
741                        }
742                  }                  }
743                  break;                  break;
744    
745              case playback_state_end:              case playback_state_end:
746                  Kill(); // free voice                  std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
747                  break;                  break;
748          }          }
749    
   
     #if ENABLE_FILTER  
750          // 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)
751            pEngine->pSynthesisEvents[Event::destination_vca]->clear();
752          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();
753          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();
     #endif // ENABLE_FILTER  
754    
755          // Reset delay          // Reset delay
756          Delay = 0;          Delay = 0;
757    
758          pTriggerEvent = NULL;          itTriggerEvent = Pool<Event>::Iterator();
759    
760          // If release stage finished, let the voice be killed          // If sample stream or release stage finished, kill the voice
761          if (pEG1->GetStage() == EGADSR::stage_end) this->PlaybackState = playback_state_end;          if (PlaybackState == playback_state_end || pEG1->GetStage() == EGADSR::stage_end) KillImmediately();
762      }      }
763    
764      /**      /**
# Line 623  namespace LinuxSampler { namespace gig { Line 769  namespace LinuxSampler { namespace gig {
769          pLFO1->Reset();          pLFO1->Reset();
770          pLFO2->Reset();          pLFO2->Reset();
771          pLFO3->Reset();          pLFO3->Reset();
772            FilterLeft.Reset();
773            FilterRight.Reset();
774          DiskStreamRef.pStream = NULL;          DiskStreamRef.pStream = NULL;
775          DiskStreamRef.hStream = 0;          DiskStreamRef.hStream = 0;
776          DiskStreamRef.State   = Stream::state_unused;          DiskStreamRef.State   = Stream::state_unused;
777          DiskStreamRef.OrderID = 0;          DiskStreamRef.OrderID = 0;
778          Active = false;          PlaybackState = playback_state_end;
779            itTriggerEvent = Pool<Event>::Iterator();
780            itKillEvent    = Pool<Event>::Iterator();
781      }      }
782    
783      /**      /**
# Line 640  namespace LinuxSampler { namespace gig { Line 790  namespace LinuxSampler { namespace gig {
790      void Voice::ProcessEvents(uint Samples) {      void Voice::ProcessEvents(uint Samples) {
791    
792          // dispatch control change events          // dispatch control change events
793          Event* pCCEvent = pEngine->pCCEvents->first();          RTList<Event>::Iterator itCCEvent = pEngine->pCCEvents->first();
794          if (Delay) { // skip events that happened before this voice was triggered          if (Delay) { // skip events that happened before this voice was triggered
795              while (pCCEvent && pCCEvent->FragmentPos() <= Delay) pCCEvent = pEngine->pCCEvents->next();              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
796          }          }
797          while (pCCEvent) {          while (itCCEvent) {
798              if (pCCEvent->Controller) { // if valid MIDI controller              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
799                  #if ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
800                  if (pCCEvent->Controller == VCFCutoffCtrl.controller) {                      *pEngine->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
801                      pEngine->pSynthesisEvents[Event::destination_vcfc]->alloc_assign(*pCCEvent);                  }
802                    if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
803                        *pEngine->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
804                  }                  }
805                  if (pCCEvent->Controller == VCFResonanceCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
806                      pEngine->pSynthesisEvents[Event::destination_vcfr]->alloc_assign(*pCCEvent);                      pLFO1->SendEvent(itCCEvent);
807                  }                  }
808                  #endif // ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO2->ExtController) {
809                  if (pCCEvent->Controller == pLFO1->ExtController) {                      pLFO2->SendEvent(itCCEvent);
                     pLFO1->SendEvent(pCCEvent);  
810                  }                  }
811                  #if ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO3->ExtController) {
812                  if (pCCEvent->Controller == pLFO2->ExtController) {                      pLFO3->SendEvent(itCCEvent);
                     pLFO2->SendEvent(pCCEvent);  
813                  }                  }
814                  #endif // ENABLE_FILTER                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
815                  if (pCCEvent->Controller == pLFO3->ExtController) {                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
816                      pLFO3->SendEvent(pCCEvent);                      *pEngine->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
817                  }                  }
818              }              }
819    
820              pCCEvent = pEngine->pCCEvents->next();              ++itCCEvent;
821          }          }
822    
823    
824          // process pitch events          // process pitch events
825          {          {
826              RTEList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];              RTList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];
827              Event* pVCOEvent = pVCOEventList->first();              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
828              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
829                  while (pVCOEvent && pVCOEvent->FragmentPos() <= Delay) pVCOEvent = pVCOEventList->next();                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
830              }              }
831              // apply old pitchbend value until first pitch event occurs              // apply old pitchbend value until first pitch event occurs
832              if (this->PitchBend != 1.0) {              if (this->PitchBend != 1.0) {
833                  uint end = (pVCOEvent) ? pVCOEvent->FragmentPos() : Samples;                  uint end = (itVCOEvent) ? itVCOEvent->FragmentPos() : Samples;
834                  for (uint i = Delay; i < end; i++) {                  for (uint i = Delay; i < end; i++) {
835                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
836                  }                  }
837              }              }
838              float pitch;              float pitch;
839              while (pVCOEvent) {              while (itVCOEvent) {
840                  Event* pNextVCOEvent = pVCOEventList->next();                  RTList<Event>::Iterator itNextVCOEvent = itVCOEvent;
841                    ++itNextVCOEvent;
842    
843                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
844                  uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples;                  uint end = (itNextVCOEvent) ? itNextVCOEvent->FragmentPos() : Samples;
845    
846                  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
847    
848                  // apply pitch value to the pitch parameter sequence                  // apply pitch value to the pitch parameter sequence
849                  for (uint i = pVCOEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCOEvent->FragmentPos(); i < end; i++) {
850                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
851                  }                  }
852    
853                  pVCOEvent = pNextVCOEvent;                  itVCOEvent = itNextVCOEvent;
854                }
855                if (!pVCOEventList->isEmpty()) {
856                    this->PitchBend = pitch;
857                    SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
858                    SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
859              }              }
             if (pVCOEventList->last()) this->PitchBend = pitch;  
860          }          }
861    
862            // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)
863            {
864                RTList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];
865                RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
866                if (Delay) { // skip events that happened before this voice was triggered
867                    while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
868                }
869                float crossfadevolume;
870                while (itVCAEvent) {
871                    RTList<Event>::Iterator itNextVCAEvent = itVCAEvent;
872                    ++itNextVCAEvent;
873    
874                    // calculate the influence length of this event (in sample points)
875                    uint end = (itNextVCAEvent) ? itNextVCAEvent->FragmentPos() : Samples;
876    
877                    crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
878    
879                    float effective_volume = crossfadevolume * this->Volume * pEngineChannel->GlobalVolume;
880    
881                    // apply volume value to the volume parameter sequence
882                    for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
883                        pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;
884                    }
885    
886                    itVCAEvent = itNextVCAEvent;
887                }
888                if (!pVCAEventList->isEmpty()) this->CrossfadeVolume = crossfadevolume;
889            }
890    
     #if ENABLE_FILTER  
891          // process filter cutoff events          // process filter cutoff events
892          {          {
893              RTEList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];              RTList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];
894              Event* pCutoffEvent = pCutoffEventList->first();              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
895              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
896                  while (pCutoffEvent && pCutoffEvent->FragmentPos() <= Delay) pCutoffEvent = pCutoffEventList->next();                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
897              }              }
898              float cutoff;              float cutoff;
899              while (pCutoffEvent) {              while (itCutoffEvent) {
900                  Event* pNextCutoffEvent = pCutoffEventList->next();                  RTList<Event>::Iterator itNextCutoffEvent = itCutoffEvent;
901                    ++itNextCutoffEvent;
902    
903                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
904                  uint end = (pNextCutoffEvent) ? pNextCutoffEvent->FragmentPos() : Samples;                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
905    
906                  cutoff = exp((float) pCutoffEvent->Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;                  cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;
907    
908                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
909                  for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) {                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
910                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
911                  }                  }
912    
913                  pCutoffEvent = pNextCutoffEvent;                  itCutoffEvent = itNextCutoffEvent;
914              }              }
915              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
916          }          }
917    
918          // process filter resonance events          // process filter resonance events
919          {          {
920              RTEList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];              RTList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];
921              Event* pResonanceEvent = pResonanceEventList->first();              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
922              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
923                  while (pResonanceEvent && pResonanceEvent->FragmentPos() <= Delay) pResonanceEvent = pResonanceEventList->next();                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
924              }              }
925              while (pResonanceEvent) {              while (itResonanceEvent) {
926                  Event* pNextResonanceEvent = pResonanceEventList->next();                  RTList<Event>::Iterator itNextResonanceEvent = itResonanceEvent;
927                    ++itNextResonanceEvent;
928    
929                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
930                  uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples;                  uint end = (itNextResonanceEvent) ? itNextResonanceEvent->FragmentPos() : Samples;
931    
932                  // convert absolute controller value to differential                  // convert absolute controller value to differential
933                  int ctrldelta = pResonanceEvent->Value - VCFResonanceCtrl.value;                  int ctrldelta = itResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;
934                  VCFResonanceCtrl.value = pResonanceEvent->Value;                  VCFResonanceCtrl.value = itResonanceEvent->Param.CC.Value;
935    
936                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
937    
938                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
939                  for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) {                  for (uint i = itResonanceEvent->FragmentPos(); i < end; i++) {
940                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
941                  }                  }
942    
943                  pResonanceEvent = pNextResonanceEvent;                  itResonanceEvent = itNextResonanceEvent;
944              }              }
945              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
946          }          }
     #endif // ENABLE_FILTER  
947      }      }
948    
     #if ENABLE_FILTER  
949      /**      /**
950       * Calculate all necessary, final biquad filter parameters.       * Calculate all necessary, final biquad filter parameters.
951       *       *
952       * @param Samples - number of samples to be rendered in this audio fragment cycle       * @param Samples - number of samples to be rendered in this audio fragment cycle
953       */       */
954      void Voice::CalculateBiquadParameters(uint Samples) {      void Voice::CalculateBiquadParameters(uint Samples) {
         if (!FilterLeft.Enabled) return;  
   
955          biquad_param_t bqbase;          biquad_param_t bqbase;
956          biquad_param_t bqmain;          biquad_param_t bqmain;
957          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
958          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
959          FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, SampleRate);          FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
960            FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
961          pEngine->pBasicFilterParameters[0] = bqbase;          pEngine->pBasicFilterParameters[0] = bqbase;
962          pEngine->pMainFilterParameters[0]  = bqmain;          pEngine->pMainFilterParameters[0]  = bqmain;
963    
964          float* bq;          float* bq;
965          for (int i = 1; i < Samples; i++) {          for (int i = 1; i < Samples; i++) {
966              // recalculate biquad parameters if cutoff or resonance differ from previous sample point              // recalculate biquad parameters if cutoff or resonance differ from previous sample point
967              if (!(i & FILTER_UPDATE_MASK)) if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||              if (!(i & FILTER_UPDATE_MASK)) {
968                                                 pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff) {                  if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
969                  prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff)
970                  prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];                  {
971                  FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, SampleRate);                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
972                        prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
973                        FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
974                        FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
975                    }
976              }              }
             pEngine->pBasicFilterParameters[i] = bqbase;  
977    
978              //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'              //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
979              bq    = (float*) &pEngine->pBasicFilterParameters[i];              bq    = (float*) &pEngine->pBasicFilterParameters[i];
980              bq[0] = bqbase.a1;              bq[0] = bqbase.b0;
981              bq[1] = bqbase.a2;              bq[1] = bqbase.b1;
982              bq[2] = bqbase.b0;              bq[2] = bqbase.b2;
983              bq[3] = bqbase.b1;              bq[3] = bqbase.a1;
984              bq[4] = bqbase.b2;              bq[4] = bqbase.a2;
985    
986              // same as 'pEngine->pMainFilterParameters[i] = bqmain;'              // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
987              bq    = (float*) &pEngine->pMainFilterParameters[i];              bq    = (float*) &pEngine->pMainFilterParameters[i];
988              bq[0] = bqmain.a1;              bq[0] = bqmain.b0;
989              bq[1] = bqmain.a2;              bq[1] = bqmain.b1;
990              bq[2] = bqmain.b0;              bq[2] = bqmain.b2;
991              bq[3] = bqmain.b1;              bq[3] = bqmain.a1;
992              bq[4] = bqmain.b2;              bq[4] = bqmain.a2;
993          }          }
994      }      }
     #endif // ENABLE_FILTER  
995    
996      /**      /**
997       *  Interpolates the input audio data (no loop).       *  Synthesizes the current audio fragment for this voice.
998       *       *
999       *  @param Samples - number of sample points to be rendered in this audio       *  @param Samples - number of sample points to be rendered in this audio
1000       *                   fragment cycle       *                   fragment cycle
1001       *  @param pSrc    - pointer to input sample data       *  @param pSrc    - pointer to input sample data
1002       *  @param Skip    - number of sample points to skip in output buffer       *  @param Skip    - number of sample points to skip in output buffer
1003       */       */
1004      void Voice::Interpolate(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
1005          int i = Skip;          RunSynthesisFunction(SynthesisMode, *this, Samples, pSrc, Skip);
   
         // FIXME: assuming either mono or stereo  
         if (this->pSample->Channels == 2) { // Stereo Sample  
             while (i < Samples) {  
                 InterpolateOneStep_Stereo(pSrc, i,  
                                           pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                           pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                           pEngine->pBasicFilterParameters[i],  
                                           pEngine->pMainFilterParameters[i]);  
             }  
         }  
         else { // Mono Sample  
             while (i < Samples) {  
                 InterpolateOneStep_Mono(pSrc, i,  
                                         pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                         pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                         pEngine->pBasicFilterParameters[i],  
                                         pEngine->pMainFilterParameters[i]);  
             }  
         }  
1006      }      }
1007    
1008      /**      /**
1009       *  Interpolates the input audio data, this method honors looping.       *  Immediately kill the voice. This method should not be used to kill
1010         *  a normal, active voice, because it doesn't take care of things like
1011         *  fading down the volume level to avoid clicks and regular processing
1012         *  until the kill event actually occured!
1013       *       *
1014       *  @param Samples - number of sample points to be rendered in this audio       *  @see Kill()
      *                   fragment cycle  
      *  @param pSrc    - pointer to input sample data  
      *  @param Skip    - number of sample points to skip in output buffer  
1015       */       */
1016      void Voice::InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::KillImmediately() {
1017          int i = Skip;          if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
1018                pDiskThread->OrderDeletionOfStream(&DiskStreamRef);
         // FIXME: assuming either mono or stereo  
         if (pSample->Channels == 2) { // Stereo Sample  
             if (pSample->LoopPlayCount) {  
                 // render loop (loop count limited)  
                 while (i < Samples && LoopCyclesLeft) {  
                     InterpolateOneStep_Stereo(pSrc, i,  
                                               pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                               pEngine->pBasicFilterParameters[i],  
                                               pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;  
                         LoopCyclesLeft--;  
                     }  
                 }  
                 // render on without loop  
                 while (i < Samples) {  
                     InterpolateOneStep_Stereo(pSrc, i,  
                                               pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                               pEngine->pBasicFilterParameters[i],  
                                               pEngine->pMainFilterParameters[i]);  
                 }  
             }  
             else { // render loop (endless loop)  
                 while (i < Samples) {  
                     InterpolateOneStep_Stereo(pSrc, i,  
                                               pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                               pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                               pEngine->pBasicFilterParameters[i],  
                                               pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);  
                     }  
                 }  
             }  
         }  
         else { // Mono Sample  
             if (pSample->LoopPlayCount) {  
                 // render loop (loop count limited)  
                 while (i < Samples && LoopCyclesLeft) {  
                     InterpolateOneStep_Mono(pSrc, i,  
                                             pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                             pEngine->pBasicFilterParameters[i],  
                                             pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;  
                         LoopCyclesLeft--;  
                     }  
                 }  
                 // render on without loop  
                 while (i < Samples) {  
                     InterpolateOneStep_Mono(pSrc, i,  
                                             pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                             pEngine->pBasicFilterParameters[i],  
                                             pEngine->pMainFilterParameters[i]);  
                 }  
             }  
             else { // render loop (endless loop)  
                 while (i < Samples) {  
                     InterpolateOneStep_Mono(pSrc, i,  
                                             pEngine->pSynthesisParameters[Event::destination_vca][i],  
                                             pEngine->pSynthesisParameters[Event::destination_vco][i],  
                                             pEngine->pBasicFilterParameters[i],  
                                             pEngine->pMainFilterParameters[i]);  
                     if (Pos > pSample->LoopEnd) {  
                         Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;  
                     }  
                 }  
             }  
1019          }          }
1020            Reset();
1021      }      }
1022    
1023      /**      /**
1024       *  Immediately kill the voice.       *  Kill the voice in regular sense. Let the voice render audio until
1025         *  the kill event actually occured and then fade down the volume level
1026         *  very quickly and let the voice die finally. Unlike a normal release
1027         *  of a voice, a kill process cannot be cancalled and is therefore
1028         *  usually used for voice stealing and key group conflicts.
1029         *
1030         *  @param itKillEvent - event which caused the voice to be killed
1031       */       */
1032      void Voice::Kill() {      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1033          if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {          //FIXME: just two sanity checks for debugging, can be removed
1034              pDiskThread->OrderDeletionOfStream(&DiskStreamRef);          if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
1035          }          if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
1036          Reset();  
1037            if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1038            this->itKillEvent = itKillEvent;
1039      }      }
1040    
1041  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.80  
changed lines
  Added in v.411

  ViewVC Help
Powered by ViewVC