/[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 84 by schoenebeck, Sun May 23 20:17:31 2004 UTC revision 361 by schoenebeck, Wed Feb 9 01:22:18 2005 UTC
# Line 22  Line 22 
22    
23  #include "EGADSR.h"  #include "EGADSR.h"
24  #include "Manipulator.h"  #include "Manipulator.h"
25    #include "../../common/Features.h"
26    #include "Synthesizer.h"
27    
28  #include "Voice.h"  #include "Voice.h"
29    
30  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
31    
     // FIXME: no support for layers (nor crossfades) yet  
   
32      const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());      const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());
33    
34      const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());      const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());
# Line 47  namespace LinuxSampler { namespace gig { Line 47  namespace LinuxSampler { namespace gig {
47      Voice::Voice() {      Voice::Voice() {
48          pEngine     = NULL;          pEngine     = NULL;
49          pDiskThread = NULL;          pDiskThread = NULL;
50          Active = false;          PlaybackState = playback_state_end;
51          pEG1   = NULL;          pEG1   = NULL;
52          pEG2   = NULL;          pEG2   = NULL;
53          pEG3   = NULL;          pEG3   = NULL;
# Line 57  namespace LinuxSampler { namespace gig { Line 57  namespace LinuxSampler { namespace gig {
57          pLFO1  = NULL;          pLFO1  = NULL;
58          pLFO2  = NULL;          pLFO2  = NULL;
59          pLFO3  = NULL;          pLFO3  = NULL;
60            KeyGroup = 0;
61            SynthesisMode = 0; // set all mode bits to 0 first
62            // select synthesis implementation (currently either pure C++ or MMX+SSE(1))
63            #if ARCH_X86
64            SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
65            #else
66            SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
67            #endif
68            SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true);
69      }      }
70    
71      Voice::~Voice() {      Voice::~Voice() {
# Line 71  namespace LinuxSampler { namespace gig { Line 80  namespace LinuxSampler { namespace gig {
80          if (pVCOManipulator)  delete pVCOManipulator;          if (pVCOManipulator)  delete pVCOManipulator;
81      }      }
82    
     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();  
     }  
   
83      void Voice::SetEngine(Engine* pEngine) {      void Voice::SetEngine(Engine* pEngine) {
84          this->pEngine = pEngine;          this->pEngine = pEngine;
85    
# Line 111  namespace LinuxSampler { namespace gig { Line 113  namespace LinuxSampler { namespace gig {
113       *  Initializes and triggers the voice, a disk stream will be launched if       *  Initializes and triggers the voice, a disk stream will be launched if
114       *  needed.       *  needed.
115       *       *
116       *  @param pNoteOnEvent - event that caused triggering of this voice       *  @param itNoteOnEvent       - event that caused triggering of this voice
117       *  @param PitchBend    - MIDI detune factor (-8192 ... +8191)       *  @param PitchBend           - MIDI detune factor (-8192 ... +8191)
118       *  @param pInstrument  - points to the loaded instrument which provides sample wave(s) and articulation data       *  @param pInstrument         - points to the loaded instrument which provides sample wave(s) and articulation data
119       *  @returns            0 on success, a value < 0 if something failed       *  @param iLayer              - layer number this voice refers to (only if this is a layered sound of course)
120         *  @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)
121         *  @param VoiceStealing       - wether the voice is allowed to steal voices for further subvoices
122         *  @returns 0 on success, a value < 0 if the voice wasn't triggered
123         *           (either due to an error or e.g. because no region is
124         *           defined for the given key)
125       */       */
126      int Voice::Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument) {      int Voice::Trigger(Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) {
127          if (!pInstrument) {          if (!pInstrument) {
128             dmsg(1,("voice::trigger: !pInstrument\n"));             dmsg(1,("voice::trigger: !pInstrument\n"));
129             exit(EXIT_FAILURE);             exit(EXIT_FAILURE);
130          }          }
131            if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // FIXME: should be removed before the final release (purpose: just a sanity check for debugging)
132                dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
133            }
134    
135          Active          = true;          Type            = type_normal;
136          MIDIKey         = pNoteOnEvent->Key;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
137          pRegion         = pInstrument->GetRegion(MIDIKey);          pRegion         = pInstrument->GetRegion(MIDIKey);
138          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
139          Pos             = 0;          Delay           = itNoteOnEvent->FragmentPos();
140          Delay           = pNoteOnEvent->FragmentPos();          itTriggerEvent  = itNoteOnEvent;
141          pTriggerEvent   = pNoteOnEvent;          itKillEvent     = Pool<Event>::Iterator();
142            itChildVoice    = Pool<Voice>::Iterator();
143    
144          if (!pRegion) {          if (!pRegion) {
145              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();  
146              return -1;              return -1;
147          }          }
148    
149          //TODO: current MIDI controller values are not taken into account yet          KeyGroup = pRegion->KeyGroup;
150          ::gig::DimensionRegion* pDimRgn = NULL;  
151          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
152              if (pRegion->pDimensionDefinitions[i].dimension == ::gig::dimension_velocity) {          //FIXME: controller values for selecting the dimension region here are currently not sample accurate
153                  uint DimValues[5] = {0,0,0,0,0};          uint DimValues[8] = { 0 };
154                      DimValues[i] = pNoteOnEvent->Velocity;          for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
155                  pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);              switch (pRegion->pDimensionDefinitions[i].dimension) {
156                  break;                  case ::gig::dimension_samplechannel:
157                        DimValues[i] = 0; //TODO: we currently ignore this dimension
158                        break;
159                    case ::gig::dimension_layer:
160                        DimValues[i] = iLayer;
161                        // if this is the 1st layer then spawn further voices for all the other layers
162                        if (iLayer == 0)
163                            for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++)
164                                itChildVoice = pEngine->LaunchVoice(itNoteOnEvent, iNewLayer, ReleaseTriggerVoice, VoiceStealing);
165                        break;
166                    case ::gig::dimension_velocity:
167                        DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
168                        break;
169                    case ::gig::dimension_channelaftertouch:
170                        DimValues[i] = 0; //TODO: we currently ignore this dimension
171                        break;
172                    case ::gig::dimension_releasetrigger:
173                        Type = (ReleaseTriggerVoice) ? type_release_trigger : (!iLayer) ? type_release_trigger_required : type_normal;
174                        DimValues[i] = (uint) ReleaseTriggerVoice;
175                        break;
176                    case ::gig::dimension_keyboard:
177                        DimValues[i] = (uint) pEngine->CurrentKeyDimension;
178                        break;
179                    case ::gig::dimension_modwheel:
180                        DimValues[i] = pEngine->ControllerTable[1];
181                        break;
182                    case ::gig::dimension_breath:
183                        DimValues[i] = pEngine->ControllerTable[2];
184                        break;
185                    case ::gig::dimension_foot:
186                        DimValues[i] = pEngine->ControllerTable[4];
187                        break;
188                    case ::gig::dimension_portamentotime:
189                        DimValues[i] = pEngine->ControllerTable[5];
190                        break;
191                    case ::gig::dimension_effect1:
192                        DimValues[i] = pEngine->ControllerTable[12];
193                        break;
194                    case ::gig::dimension_effect2:
195                        DimValues[i] = pEngine->ControllerTable[13];
196                        break;
197                    case ::gig::dimension_genpurpose1:
198                        DimValues[i] = pEngine->ControllerTable[16];
199                        break;
200                    case ::gig::dimension_genpurpose2:
201                        DimValues[i] = pEngine->ControllerTable[17];
202                        break;
203                    case ::gig::dimension_genpurpose3:
204                        DimValues[i] = pEngine->ControllerTable[18];
205                        break;
206                    case ::gig::dimension_genpurpose4:
207                        DimValues[i] = pEngine->ControllerTable[19];
208                        break;
209                    case ::gig::dimension_sustainpedal:
210                        DimValues[i] = pEngine->ControllerTable[64];
211                        break;
212                    case ::gig::dimension_portamento:
213                        DimValues[i] = pEngine->ControllerTable[65];
214                        break;
215                    case ::gig::dimension_sostenutopedal:
216                        DimValues[i] = pEngine->ControllerTable[66];
217                        break;
218                    case ::gig::dimension_softpedal:
219                        DimValues[i] = pEngine->ControllerTable[67];
220                        break;
221                    case ::gig::dimension_genpurpose5:
222                        DimValues[i] = pEngine->ControllerTable[80];
223                        break;
224                    case ::gig::dimension_genpurpose6:
225                        DimValues[i] = pEngine->ControllerTable[81];
226                        break;
227                    case ::gig::dimension_genpurpose7:
228                        DimValues[i] = pEngine->ControllerTable[82];
229                        break;
230                    case ::gig::dimension_genpurpose8:
231                        DimValues[i] = pEngine->ControllerTable[83];
232                        break;
233                    case ::gig::dimension_effect1depth:
234                        DimValues[i] = pEngine->ControllerTable[91];
235                        break;
236                    case ::gig::dimension_effect2depth:
237                        DimValues[i] = pEngine->ControllerTable[92];
238                        break;
239                    case ::gig::dimension_effect3depth:
240                        DimValues[i] = pEngine->ControllerTable[93];
241                        break;
242                    case ::gig::dimension_effect4depth:
243                        DimValues[i] = pEngine->ControllerTable[94];
244                        break;
245                    case ::gig::dimension_effect5depth:
246                        DimValues[i] = pEngine->ControllerTable[95];
247                        break;
248                    case ::gig::dimension_none:
249                        std::cerr << "gig::Voice::Trigger() Error: dimension=none\n" << std::flush;
250                        break;
251                    default:
252                        std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;
253              }              }
254          }          }
255          if (!pDimRgn) { // if there was no velocity split          pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
             pDimRgn = pRegion->GetDimensionRegionByValue(0,0,0,0,0);  
         }  
256    
257          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          pSample = pDimRgn->pSample; // sample won't change until the voice is finished
258            if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent
259    
260            // select channel mode (mono or stereo)
261            SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
262    
263            // get starting crossfade volume level
264            switch (pDimRgn->AttenuationController.type) {
265                case ::gig::attenuation_ctrl_t::type_channelaftertouch:
266                    CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
267                    break;
268                case ::gig::attenuation_ctrl_t::type_velocity:
269                    CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
270                    break;
271                case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
272                    CrossfadeVolume = CrossfadeAttenuation(pEngine->ControllerTable[pDimRgn->AttenuationController.controller_number]);
273                    break;
274                case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
275                default:
276                    CrossfadeVolume = 1.0f;
277            }
278    
279            PanLeft  = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) /  63.0f;
280            PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;
281    
282            Pos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
283    
284          // 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
285          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;          long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
286          DiskVoice          = cachedsamples < pSample->SamplesTotal;          DiskVoice          = cachedsamples < pSample->SamplesTotal;
287    
288          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
289              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)
290    
291              // 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
292              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
# Line 168  namespace LinuxSampler { namespace gig { Line 297  namespace LinuxSampler { namespace gig {
297    
298              if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {              if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {
299                  dmsg(1,("Disk stream order failed!\n"));                  dmsg(1,("Disk stream order failed!\n"));
300                  Kill();                  KillImmediately();
301                  return -1;                  return -1;
302              }              }
303              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 315  namespace LinuxSampler { namespace gig {
315    
316          // calculate initial pitch value          // calculate initial pitch value
317          {          {
318              double pitchbasecents = pDimRgn->FineTune * 10;              double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
319              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
320              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents);              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));
321              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
322          }          }
323    
324            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)
         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)  
   
325    
326          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
327          {          {
# Line 208  namespace LinuxSampler { namespace gig { Line 335  namespace LinuxSampler { namespace gig {
335                      eg1controllervalue = 0; // TODO: aftertouch not yet supported                      eg1controllervalue = 0; // TODO: aftertouch not yet supported
336                      break;                      break;
337                  case ::gig::eg1_ctrl_t::type_velocity:                  case ::gig::eg1_ctrl_t::type_velocity:
338                      eg1controllervalue = pNoteOnEvent->Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
339                      break;                      break;
340                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
341                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];
# Line 234  namespace LinuxSampler { namespace gig { Line 361  namespace LinuxSampler { namespace gig {
361          }          }
362    
363    
     #if ENABLE_FILTER  
364          // setup EG 2 (VCF Cutoff EG)          // setup EG 2 (VCF Cutoff EG)
365          {          {
366              // get current value of EG2 controller              // get current value of EG2 controller
# Line 247  namespace LinuxSampler { namespace gig { Line 373  namespace LinuxSampler { namespace gig {
373                      eg2controllervalue = 0; // TODO: aftertouch not yet supported                      eg2controllervalue = 0; // TODO: aftertouch not yet supported
374                      break;                      break;
375                  case ::gig::eg2_ctrl_t::type_velocity:                  case ::gig::eg2_ctrl_t::type_velocity:
376                      eg2controllervalue = pNoteOnEvent->Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
377                      break;                      break;
378                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
379                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];
# Line 271  namespace LinuxSampler { namespace gig { Line 397  namespace LinuxSampler { namespace gig {
397                            pDimRgn->EG2Release + eg2release,                            pDimRgn->EG2Release + eg2release,
398                            Delay);                            Delay);
399          }          }
     #endif // ENABLE_FILTER  
400    
401    
402          // setup EG 3 (VCO EG)          // setup EG 3 (VCO EG)
# Line 314  namespace LinuxSampler { namespace gig { Line 439  namespace LinuxSampler { namespace gig {
439                            pDimRgn->LFO1ControlDepth,                            pDimRgn->LFO1ControlDepth,
440                            pEngine->ControllerTable[pLFO1->ExtController],                            pEngine->ControllerTable[pLFO1->ExtController],
441                            pDimRgn->LFO1FlipPhase,                            pDimRgn->LFO1FlipPhase,
442                            this->SampleRate,                            pEngine->SampleRate,
443                            Delay);                            Delay);
444          }          }
445    
446      #if ENABLE_FILTER  
447          // setup LFO 2 (VCF Cutoff LFO)          // setup LFO 2 (VCF Cutoff LFO)
448          {          {
449              uint16_t lfo2_internal_depth;              uint16_t lfo2_internal_depth;
# Line 352  namespace LinuxSampler { namespace gig { Line 477  namespace LinuxSampler { namespace gig {
477                            pDimRgn->LFO2ControlDepth,                            pDimRgn->LFO2ControlDepth,
478                            pEngine->ControllerTable[pLFO2->ExtController],                            pEngine->ControllerTable[pLFO2->ExtController],
479                            pDimRgn->LFO2FlipPhase,                            pDimRgn->LFO2FlipPhase,
480                            this->SampleRate,                            pEngine->SampleRate,
481                            Delay);                            Delay);
482          }          }
483      #endif // ENABLE_FILTER  
484    
485          // setup LFO 3 (VCO LFO)          // setup LFO 3 (VCO LFO)
486          {          {
# Line 390  namespace LinuxSampler { namespace gig { Line 515  namespace LinuxSampler { namespace gig {
515                            pDimRgn->LFO3ControlDepth,                            pDimRgn->LFO3ControlDepth,
516                            pEngine->ControllerTable[pLFO3->ExtController],                            pEngine->ControllerTable[pLFO3->ExtController],
517                            false,                            false,
518                            this->SampleRate,                            pEngine->SampleRate,
519                            Delay);                            Delay);
520          }          }
521    
522      #if ENABLE_FILTER  
523          #if FORCE_FILTER_USAGE          #if FORCE_FILTER_USAGE
524          FilterLeft.Enabled = FilterRight.Enabled = true;          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, true);
525          #else // use filter only if instrument file told so          #else // use filter only if instrument file told so
526          FilterLeft.Enabled = FilterRight.Enabled = pDimRgn->VCFEnabled;          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, pDimRgn->VCFEnabled);
527          #endif // FORCE_FILTER_USAGE          #endif // FORCE_FILTER_USAGE
528          if (pDimRgn->VCFEnabled) {          if (pDimRgn->VCFEnabled) {
529              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL
# Line 475  namespace LinuxSampler { namespace gig { Line 600  namespace LinuxSampler { namespace gig {
600    
601              // calculate cutoff frequency              // calculate cutoff frequency
602              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = (!VCFCutoffCtrl.controller)
603                  ? 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
604                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;
605    
606              // calculate resonance              // calculate resonance
607              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0
608              if (pDimRgn->VCFKeyboardTracking) {              if (pDimRgn->VCFKeyboardTracking) {
609                  resonance += (float) (pNoteOnEvent->Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;                  resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
610              }              }
611              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)
612    
613              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;
614              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
615    
             FilterLeft.SetParameters(cutoff,  resonance, SampleRate);  
             FilterRight.SetParameters(cutoff, resonance, SampleRate);  
   
616              FilterUpdateCounter = -1;              FilterUpdateCounter = -1;
617          }          }
618          else {          else {
619              VCFCutoffCtrl.controller    = 0;              VCFCutoffCtrl.controller    = 0;
620              VCFResonanceCtrl.controller = 0;              VCFResonanceCtrl.controller = 0;
621          }          }
     #endif // ENABLE_FILTER  
   
         // ************************************************  
         // TODO: ARTICULATION DATA HANDLING IS MISSING HERE  
         // ************************************************  
622    
623          return 0; // success          return 0; // success
624      }      }
# Line 519  namespace LinuxSampler { namespace gig { Line 636  namespace LinuxSampler { namespace gig {
636       */       */
637      void Voice::Render(uint Samples) {      void Voice::Render(uint Samples) {
638    
639            // select default values for synthesis mode bits
640            SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, (PitchBase * PitchBend) != 1.0f);
641            SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, true);
642            SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
643    
644          // Reset the synthesis parameter matrix          // Reset the synthesis parameter matrix
645          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume);  
646            pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngine->GlobalVolume);
647          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
     #if ENABLE_FILTER  
648          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
649          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
     #endif // ENABLE_FILTER  
   
650    
651          // Apply events to the synthesis parameter matrix          // Apply events to the synthesis parameter matrix
652          ProcessEvents(Samples);          ProcessEvents(Samples);
653    
   
654          // 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
655          pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);          pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);
656      #if ENABLE_FILTER          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
657          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);          if (pEG3->Process(Samples)) { // if pitch EG is active
658      #endif // ENABLE_FILTER              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
659          pEG3->Process(Samples);              SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
660            }
661          pLFO1->Process(Samples);          pLFO1->Process(Samples);
     #if ENABLE_FILTER  
662          pLFO2->Process(Samples);          pLFO2->Process(Samples);
663      #endif // ENABLE_FILTER          if (pLFO3->Process(Samples)) { // if pitch LFO modulation is active
664          pLFO3->Process(Samples);              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
665                SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
666            }
     #if ENABLE_FILTER  
         CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters  
     #endif // ENABLE_FILTER  
667    
668            if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
669                    CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
670    
671          switch (this->PlaybackState) {          switch (this->PlaybackState) {
672    
673              case playback_state_ram: {              case playback_state_ram: {
674                      if (RAMLoop) InterpolateAndLoop(Samples, (sample_t*) pSample->GetCache().pStart, Delay);                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
675                      else         Interpolate(Samples, (sample_t*) pSample->GetCache().pStart, Delay);  
676                        // render current fragment
677                        Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
678    
679                      if (DiskVoice) {                      if (DiskVoice) {
680                          // check if we reached the allowed limit of the sample RAM cache                          // check if we reached the allowed limit of the sample RAM cache
681                          if (Pos > MaxRAMPos) {                          if (Pos > MaxRAMPos) {
# Line 574  namespace LinuxSampler { namespace gig { Line 695  namespace LinuxSampler { namespace gig {
695                          DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);                          DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
696                          if (!DiskStreamRef.pStream) {                          if (!DiskStreamRef.pStream) {
697                              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;
698                              Kill();                              KillImmediately();
699                              return;                              return;
700                          }                          }
701                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (RTMath::DoubleToInt(Pos) - MaxRAMPos));                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
702                          Pos -= RTMath::DoubleToInt(Pos);                          Pos -= int(Pos);
703                            RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
704                      }                      }
705    
706                        const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
707    
708                      // 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)
709                      if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) {                      if (DiskStreamRef.State == Stream::state_end) {
710                          DiskStreamRef.pStream->WriteSilence((MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels);                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
711                          this->PlaybackState = playback_state_end;                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
712                                // remember how many sample words there are before any silence has been added
713                                if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
714                                DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
715                            }
716                      }                      }
717    
718                      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
719                      Interpolate(Samples, ptr, Delay);  
720                      DiskStreamRef.pStream->IncrementReadPos(RTMath::DoubleToInt(Pos) * pSample->Channels);                      // render current audio fragment
721                      Pos -= RTMath::DoubleToInt(Pos);                      Synthesize(Samples, ptr, Delay);
722    
723                        const int iPos = (int) Pos;
724                        const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
725                        DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
726                        Pos -= iPos; // just keep fractional part of Pos
727    
728                        // change state of voice to 'end' if we really reached the end of the sample data
729                        if (RealSampleWordsLeftToRead >= 0) {
730                            RealSampleWordsLeftToRead -= readSampleWords;
731                            if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
732                        }
733                  }                  }
734                  break;                  break;
735    
736              case playback_state_end:              case playback_state_end:
737                  Kill(); // free voice                  std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
738                  break;                  break;
739          }          }
740    
   
     #if ENABLE_FILTER  
741          // 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)
742            pEngine->pSynthesisEvents[Event::destination_vca]->clear();
743          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();
744          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();
     #endif // ENABLE_FILTER  
745    
746          // Reset delay          // Reset delay
747          Delay = 0;          Delay = 0;
748    
749          pTriggerEvent = NULL;          itTriggerEvent = Pool<Event>::Iterator();
750    
751          // If release stage finished, let the voice be killed          // If sample stream or release stage finished, kill the voice
752          if (pEG1->GetStage() == EGADSR::stage_end) this->PlaybackState = playback_state_end;          if (PlaybackState == playback_state_end || pEG1->GetStage() == EGADSR::stage_end) KillImmediately();
753      }      }
754    
755      /**      /**
# Line 623  namespace LinuxSampler { namespace gig { Line 760  namespace LinuxSampler { namespace gig {
760          pLFO1->Reset();          pLFO1->Reset();
761          pLFO2->Reset();          pLFO2->Reset();
762          pLFO3->Reset();          pLFO3->Reset();
763            FilterLeft.Reset();
764            FilterRight.Reset();
765          DiskStreamRef.pStream = NULL;          DiskStreamRef.pStream = NULL;
766          DiskStreamRef.hStream = 0;          DiskStreamRef.hStream = 0;
767          DiskStreamRef.State   = Stream::state_unused;          DiskStreamRef.State   = Stream::state_unused;
768          DiskStreamRef.OrderID = 0;          DiskStreamRef.OrderID = 0;
769          Active = false;          PlaybackState = playback_state_end;
770            itTriggerEvent = Pool<Event>::Iterator();
771            itKillEvent    = Pool<Event>::Iterator();
772      }      }
773    
774      /**      /**
# Line 640  namespace LinuxSampler { namespace gig { Line 781  namespace LinuxSampler { namespace gig {
781      void Voice::ProcessEvents(uint Samples) {      void Voice::ProcessEvents(uint Samples) {
782    
783          // dispatch control change events          // dispatch control change events
784          Event* pCCEvent = pEngine->pCCEvents->first();          RTList<Event>::Iterator itCCEvent = pEngine->pCCEvents->first();
785          if (Delay) { // skip events that happened before this voice was triggered          if (Delay) { // skip events that happened before this voice was triggered
786              while (pCCEvent && pCCEvent->FragmentPos() <= Delay) pCCEvent = pEngine->pCCEvents->next();              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
787          }          }
788          while (pCCEvent) {          while (itCCEvent) {
789              if (pCCEvent->Controller) { // if valid MIDI controller              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
790                  #if ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
791                  if (pCCEvent->Controller == VCFCutoffCtrl.controller) {                      *pEngine->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
792                      pEngine->pSynthesisEvents[Event::destination_vcfc]->alloc_assign(*pCCEvent);                  }
793                    if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
794                        *pEngine->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
795                  }                  }
796                  if (pCCEvent->Controller == VCFResonanceCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
797                      pEngine->pSynthesisEvents[Event::destination_vcfr]->alloc_assign(*pCCEvent);                      pLFO1->SendEvent(itCCEvent);
798                  }                  }
799                  #endif // ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO2->ExtController) {
800                  if (pCCEvent->Controller == pLFO1->ExtController) {                      pLFO2->SendEvent(itCCEvent);
                     pLFO1->SendEvent(pCCEvent);  
801                  }                  }
802                  #if ENABLE_FILTER                  if (itCCEvent->Param.CC.Controller == pLFO3->ExtController) {
803                  if (pCCEvent->Controller == pLFO2->ExtController) {                      pLFO3->SendEvent(itCCEvent);
                     pLFO2->SendEvent(pCCEvent);  
804                  }                  }
805                  #endif // ENABLE_FILTER                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
806                  if (pCCEvent->Controller == pLFO3->ExtController) {                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
807                      pLFO3->SendEvent(pCCEvent);                      *pEngine->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
808                  }                  }
809              }              }
810    
811              pCCEvent = pEngine->pCCEvents->next();              ++itCCEvent;
812          }          }
813    
814    
815          // process pitch events          // process pitch events
816          {          {
817              RTEList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];              RTList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];
818              Event* pVCOEvent = pVCOEventList->first();              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
819              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
820                  while (pVCOEvent && pVCOEvent->FragmentPos() <= Delay) pVCOEvent = pVCOEventList->next();                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
821              }              }
822              // apply old pitchbend value until first pitch event occurs              // apply old pitchbend value until first pitch event occurs
823              if (this->PitchBend != 1.0) {              if (this->PitchBend != 1.0) {
824                  uint end = (pVCOEvent) ? pVCOEvent->FragmentPos() : Samples;                  uint end = (itVCOEvent) ? itVCOEvent->FragmentPos() : Samples;
825                  for (uint i = Delay; i < end; i++) {                  for (uint i = Delay; i < end; i++) {
826                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= this->PitchBend;
827                  }                  }
828              }              }
829              float pitch;              float pitch;
830              while (pVCOEvent) {              while (itVCOEvent) {
831                  Event* pNextVCOEvent = pVCOEventList->next();                  RTList<Event>::Iterator itNextVCOEvent = itVCOEvent;
832                    ++itNextVCOEvent;
833    
834                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
835                  uint end = (pNextVCOEvent) ? pNextVCOEvent->FragmentPos() : Samples;                  uint end = (itNextVCOEvent) ? itNextVCOEvent->FragmentPos() : Samples;
836    
837                  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
838    
839                  // apply pitch value to the pitch parameter sequence                  // apply pitch value to the pitch parameter sequence
840                  for (uint i = pVCOEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCOEvent->FragmentPos(); i < end; i++) {
841                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;                      pEngine->pSynthesisParameters[Event::destination_vco][i] *= pitch;
842                  }                  }
843    
844                  pVCOEvent = pNextVCOEvent;                  itVCOEvent = itNextVCOEvent;
845                }
846                if (!pVCOEventList->isEmpty()) {
847                    this->PitchBend = pitch;
848                    SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
849                    SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
850              }              }
             if (pVCOEventList->last()) this->PitchBend = pitch;  
851          }          }
852    
853            // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)
854            {
855                RTList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];
856                RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
857                if (Delay) { // skip events that happened before this voice was triggered
858                    while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
859                }
860                float crossfadevolume;
861                while (itVCAEvent) {
862                    RTList<Event>::Iterator itNextVCAEvent = itVCAEvent;
863                    ++itNextVCAEvent;
864    
865                    // calculate the influence length of this event (in sample points)
866                    uint end = (itNextVCAEvent) ? itNextVCAEvent->FragmentPos() : Samples;
867    
868                    crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
869    
870                    float effective_volume = crossfadevolume * this->Volume * pEngine->GlobalVolume;
871    
872                    // apply volume value to the volume parameter sequence
873                    for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
874                        pEngine->pSynthesisParameters[Event::destination_vca][i] = effective_volume;
875                    }
876    
877                    itVCAEvent = itNextVCAEvent;
878                }
879                if (!pVCAEventList->isEmpty()) this->CrossfadeVolume = crossfadevolume;
880            }
881    
     #if ENABLE_FILTER  
882          // process filter cutoff events          // process filter cutoff events
883          {          {
884              RTEList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];              RTList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];
885              Event* pCutoffEvent = pCutoffEventList->first();              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
886              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
887                  while (pCutoffEvent && pCutoffEvent->FragmentPos() <= Delay) pCutoffEvent = pCutoffEventList->next();                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
888              }              }
889              float cutoff;              float cutoff;
890              while (pCutoffEvent) {              while (itCutoffEvent) {
891                  Event* pNextCutoffEvent = pCutoffEventList->next();                  RTList<Event>::Iterator itNextCutoffEvent = itCutoffEvent;
892                    ++itNextCutoffEvent;
893    
894                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
895                  uint end = (pNextCutoffEvent) ? pNextCutoffEvent->FragmentPos() : Samples;                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
896    
897                  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;
898    
899                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
900                  for (uint i = pCutoffEvent->FragmentPos(); i < end; i++) {                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
901                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] = cutoff;
902                  }                  }
903    
904                  pCutoffEvent = pNextCutoffEvent;                  itCutoffEvent = itNextCutoffEvent;
905              }              }
906              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
907          }          }
908    
909          // process filter resonance events          // process filter resonance events
910          {          {
911              RTEList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];              RTList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];
912              Event* pResonanceEvent = pResonanceEventList->first();              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
913              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
914                  while (pResonanceEvent && pResonanceEvent->FragmentPos() <= Delay) pResonanceEvent = pResonanceEventList->next();                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
915              }              }
916              while (pResonanceEvent) {              while (itResonanceEvent) {
917                  Event* pNextResonanceEvent = pResonanceEventList->next();                  RTList<Event>::Iterator itNextResonanceEvent = itResonanceEvent;
918                    ++itNextResonanceEvent;
919    
920                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
921                  uint end = (pNextResonanceEvent) ? pNextResonanceEvent->FragmentPos() : Samples;                  uint end = (itNextResonanceEvent) ? itNextResonanceEvent->FragmentPos() : Samples;
922    
923                  // convert absolute controller value to differential                  // convert absolute controller value to differential
924                  int ctrldelta = pResonanceEvent->Value - VCFResonanceCtrl.value;                  int ctrldelta = itResonanceEvent->Param.CC.Value - VCFResonanceCtrl.value;
925                  VCFResonanceCtrl.value = pResonanceEvent->Value;                  VCFResonanceCtrl.value = itResonanceEvent->Param.CC.Value;
926    
927                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0                  float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
928    
929                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
930                  for (uint i = pResonanceEvent->FragmentPos(); i < end; i++) {                  for (uint i = itResonanceEvent->FragmentPos(); i < end; i++) {
931                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;                      pEngine->pSynthesisParameters[Event::destination_vcfr][i] += resonancedelta;
932                  }                  }
933    
934                  pResonanceEvent = pNextResonanceEvent;                  itResonanceEvent = itNextResonanceEvent;
935              }              }
936              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
937          }          }
     #endif // ENABLE_FILTER  
938      }      }
939    
     #if ENABLE_FILTER  
940      /**      /**
941       * Calculate all necessary, final biquad filter parameters.       * Calculate all necessary, final biquad filter parameters.
942       *       *
943       * @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
944       */       */
945      void Voice::CalculateBiquadParameters(uint Samples) {      void Voice::CalculateBiquadParameters(uint Samples) {
         if (!FilterLeft.Enabled) return;  
   
946          biquad_param_t bqbase;          biquad_param_t bqbase;
947          biquad_param_t bqmain;          biquad_param_t bqmain;
948          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
949          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
950          FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, SampleRate);          FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
951            FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
952          pEngine->pBasicFilterParameters[0] = bqbase;          pEngine->pBasicFilterParameters[0] = bqbase;
953          pEngine->pMainFilterParameters[0]  = bqmain;          pEngine->pMainFilterParameters[0]  = bqmain;
954    
955          float* bq;          float* bq;
956          for (int i = 1; i < Samples; i++) {          for (int i = 1; i < Samples; i++) {
957              // recalculate biquad parameters if cutoff or resonance differ from previous sample point              // recalculate biquad parameters if cutoff or resonance differ from previous sample point
958              if (!(i & FILTER_UPDATE_MASK)) if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||              if (!(i & FILTER_UPDATE_MASK)) {
959                                                 pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff) {                  if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
960                  prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];                      pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff)
961                  prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];                  {
962                  FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, SampleRate);                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
963                        prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
964                        FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
965                        FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
966                    }
967              }              }
968    
969              //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'              //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
970              bq    = (float*) &pEngine->pBasicFilterParameters[i];              bq    = (float*) &pEngine->pBasicFilterParameters[i];
971              bq[0] = bqbase.a1;              bq[0] = bqbase.b0;
972              bq[1] = bqbase.a2;              bq[1] = bqbase.b1;
973              bq[2] = bqbase.b0;              bq[2] = bqbase.b2;
974              bq[3] = bqbase.b1;              bq[3] = bqbase.a1;
975              bq[4] = bqbase.b2;              bq[4] = bqbase.a2;
976    
977              // same as 'pEngine->pMainFilterParameters[i] = bqmain;'              // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
978              bq    = (float*) &pEngine->pMainFilterParameters[i];              bq    = (float*) &pEngine->pMainFilterParameters[i];
979              bq[0] = bqmain.a1;              bq[0] = bqmain.b0;
980              bq[1] = bqmain.a2;              bq[1] = bqmain.b1;
981              bq[2] = bqmain.b0;              bq[2] = bqmain.b2;
982              bq[3] = bqmain.b1;              bq[3] = bqmain.a1;
983              bq[4] = bqmain.b2;              bq[4] = bqmain.a2;
984          }          }
985      }      }
     #endif // ENABLE_FILTER  
986    
987      /**      /**
988       *  Interpolates the input audio data (no loop).       *  Synthesizes the current audio fragment for this voice.
989       *       *
990       *  @param Samples - number of sample points to be rendered in this audio       *  @param Samples - number of sample points to be rendered in this audio
991       *                   fragment cycle       *                   fragment cycle
992       *  @param pSrc    - pointer to input sample data       *  @param pSrc    - pointer to input sample data
993       *  @param Skip    - number of sample points to skip in output buffer       *  @param Skip    - number of sample points to skip in output buffer
994       */       */
995      void Voice::Interpolate(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
996          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]);  
             }  
         }  
997      }      }
998    
999      /**      /**
1000       *  Interpolates the input audio data, this method honors looping.       *  Immediately kill the voice. This method should not be used to kill
1001         *  a normal, active voice, because it doesn't take care of things like
1002         *  fading down the volume level to avoid clicks and regular processing
1003         *  until the kill event actually occured!
1004       *       *
1005       *  @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  
1006       */       */
1007      void Voice::InterpolateAndLoop(uint Samples, sample_t* pSrc, uint Skip) {      void Voice::KillImmediately() {
1008          int i = Skip;          if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
1009                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);;  
                     }  
                 }  
             }  
1010          }          }
1011            Reset();
1012      }      }
1013    
1014      /**      /**
1015       *  Immediately kill the voice.       *  Kill the voice in regular sense. Let the voice render audio until
1016         *  the kill event actually occured and then fade down the volume level
1017         *  very quickly and let the voice die finally. Unlike a normal release
1018         *  of a voice, a kill process cannot be cancalled and is therefore
1019         *  usually used for voice stealing and key group conflicts.
1020         *
1021         *  @param itKillEvent - event which caused the voice to be killed
1022       */       */
1023      void Voice::Kill() {      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1024          if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {          //FIXME: just two sanity checks for debugging, can be removed
1025              pDiskThread->OrderDeletionOfStream(&DiskStreamRef);          if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
1026          }          if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
1027          Reset();  
1028            if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1029            this->itKillEvent = itKillEvent;
1030      }      }
1031    
1032  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.84  
changed lines
  Added in v.361

  ViewVC Help
Powered by ViewVC