/[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 325 by senkov, Tue Dec 21 04:54:37 2004 UTC revision 460 by schoenebeck, Mon Mar 14 22:35:44 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 58  namespace LinuxSampler { namespace gig { Line 59  namespace LinuxSampler { namespace gig {
59          pLFO2  = NULL;          pLFO2  = NULL;
60          pLFO3  = NULL;          pLFO3  = NULL;
61          KeyGroup = 0;          KeyGroup = 0;
62            SynthesisMode = 0; // set all mode bits to 0 first
63          // select synthesis implementation (currently either pure C++ or MMX+SSE(1))          // 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());          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);          SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true);
70    
71            FilterLeft.Reset();
72            FilterRight.Reset();
73      }      }
74    
75      Voice::~Voice() {      Voice::~Voice() {
# Line 109  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 itNoteOnEvent       - 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       *  @param iLayer              - layer number this voice refers to (only if this is a layered sound of course)       *  @param pInstrument          - points to the loaded instrument which provides sample wave(s) and articulation data
124       *  @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)       *  @param iLayer               - layer number this voice refers to (only if this is a layered sound of course)
125       *  @param VoiceStealing       - wether the voice is allowed to steal voices for further subvoices       *  @param ReleaseTriggerVoice  - if this new voice is a release trigger voice (optional, default = false)
126       *  @returns 0 on success, a value < 0 if something failed       *  @param VoiceStealingAllowed - 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(Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) {      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealingAllowed) {
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);
# Line 133  namespace LinuxSampler { namespace gig { Line 145  namespace LinuxSampler { namespace gig {
145          Delay           = itNoteOnEvent->FragmentPos();          Delay           = itNoteOnEvent->FragmentPos();
146          itTriggerEvent  = itNoteOnEvent;          itTriggerEvent  = itNoteOnEvent;
147          itKillEvent     = Pool<Event>::Iterator();          itKillEvent     = Pool<Event>::Iterator();
         itChildVoice    = Pool<Voice>::Iterator();  
148    
149          if (!pRegion) {          if (!pRegion) {
150              std::cerr << "gig::Voice: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;              dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey));
             KillImmediately();  
151              return -1;              return -1;
152          }          }
153    
154          KeyGroup = pRegion->KeyGroup;          // only mark the first voice of a layered voice (group) to be in a
155            // key group, so the layered voices won't kill each other
156            KeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;
157    
158          // get current dimension values to select the right dimension region          // get current dimension values to select the right dimension region
159          //FIXME: controller values for selecting the dimension region here are currently not sample accurate          //FIXME: controller values for selecting the dimension region here are currently not sample accurate
160          uint DimValues[5] = {0,0,0,0,0};          uint DimValues[8] = { 0 };
161          for (int i = pRegion->Dimensions - 1; i >= 0; i--) {          for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
162              switch (pRegion->pDimensionDefinitions[i].dimension) {              switch (pRegion->pDimensionDefinitions[i].dimension) {
163                  case ::gig::dimension_samplechannel:                  case ::gig::dimension_samplechannel:
# Line 153  namespace LinuxSampler { namespace gig { Line 165  namespace LinuxSampler { namespace gig {
165                      break;                      break;
166                  case ::gig::dimension_layer:                  case ::gig::dimension_layer:
167                      DimValues[i] = iLayer;                      DimValues[i] = iLayer;
                     // if this is the 1st layer then spawn further voices for all the other layers  
                     if (iLayer == 0)  
                         for (int iNewLayer = 1; iNewLayer < pRegion->pDimensionDefinitions[i].zones; iNewLayer++)  
                             itChildVoice = pEngine->LaunchVoice(itNoteOnEvent, iNewLayer, ReleaseTriggerVoice, VoiceStealing);  
168                      break;                      break;
169                  case ::gig::dimension_velocity:                  case ::gig::dimension_velocity:
170                      DimValues[i] = itNoteOnEvent->Param.Note.Velocity;                      DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
# Line 169  namespace LinuxSampler { namespace gig { Line 177  namespace LinuxSampler { namespace gig {
177                      DimValues[i] = (uint) ReleaseTriggerVoice;                      DimValues[i] = (uint) ReleaseTriggerVoice;
178                      break;                      break;
179                  case ::gig::dimension_keyboard:                  case ::gig::dimension_keyboard:
180                      DimValues[i] = (uint) itNoteOnEvent->Param.Note.Key;                      DimValues[i] = (uint) pEngineChannel->CurrentKeyDimension;
181                        break;
182                    case ::gig::dimension_roundrobin:
183                        DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on
184                        break;
185                    case ::gig::dimension_random:
186                        pEngine->RandomSeed = pEngine->RandomSeed * 1103515245 + 12345; // classic pseudo random number generator
187                        DimValues[i] = (uint) pEngine->RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random
188                      break;                      break;
189                  case ::gig::dimension_modwheel:                  case ::gig::dimension_modwheel:
190                      DimValues[i] = pEngine->ControllerTable[1];                      DimValues[i] = pEngineChannel->ControllerTable[1];
191                      break;                      break;
192                  case ::gig::dimension_breath:                  case ::gig::dimension_breath:
193                      DimValues[i] = pEngine->ControllerTable[2];                      DimValues[i] = pEngineChannel->ControllerTable[2];
194                      break;                      break;
195                  case ::gig::dimension_foot:                  case ::gig::dimension_foot:
196                      DimValues[i] = pEngine->ControllerTable[4];                      DimValues[i] = pEngineChannel->ControllerTable[4];
197                      break;                      break;
198                  case ::gig::dimension_portamentotime:                  case ::gig::dimension_portamentotime:
199                      DimValues[i] = pEngine->ControllerTable[5];                      DimValues[i] = pEngineChannel->ControllerTable[5];
200                      break;                      break;
201                  case ::gig::dimension_effect1:                  case ::gig::dimension_effect1:
202                      DimValues[i] = pEngine->ControllerTable[12];                      DimValues[i] = pEngineChannel->ControllerTable[12];
203                      break;                      break;
204                  case ::gig::dimension_effect2:                  case ::gig::dimension_effect2:
205                      DimValues[i] = pEngine->ControllerTable[13];                      DimValues[i] = pEngineChannel->ControllerTable[13];
206                      break;                      break;
207                  case ::gig::dimension_genpurpose1:                  case ::gig::dimension_genpurpose1:
208                      DimValues[i] = pEngine->ControllerTable[16];                      DimValues[i] = pEngineChannel->ControllerTable[16];
209                      break;                      break;
210                  case ::gig::dimension_genpurpose2:                  case ::gig::dimension_genpurpose2:
211                      DimValues[i] = pEngine->ControllerTable[17];                      DimValues[i] = pEngineChannel->ControllerTable[17];
212                      break;                      break;
213                  case ::gig::dimension_genpurpose3:                  case ::gig::dimension_genpurpose3:
214                      DimValues[i] = pEngine->ControllerTable[18];                      DimValues[i] = pEngineChannel->ControllerTable[18];
215                      break;                      break;
216                  case ::gig::dimension_genpurpose4:                  case ::gig::dimension_genpurpose4:
217                      DimValues[i] = pEngine->ControllerTable[19];                      DimValues[i] = pEngineChannel->ControllerTable[19];
218                      break;                      break;
219                  case ::gig::dimension_sustainpedal:                  case ::gig::dimension_sustainpedal:
220                      DimValues[i] = pEngine->ControllerTable[64];                      DimValues[i] = pEngineChannel->ControllerTable[64];
221                      break;                      break;
222                  case ::gig::dimension_portamento:                  case ::gig::dimension_portamento:
223                      DimValues[i] = pEngine->ControllerTable[65];                      DimValues[i] = pEngineChannel->ControllerTable[65];
224                      break;                      break;
225                  case ::gig::dimension_sostenutopedal:                  case ::gig::dimension_sostenutopedal:
226                      DimValues[i] = pEngine->ControllerTable[66];                      DimValues[i] = pEngineChannel->ControllerTable[66];
227                      break;                      break;
228                  case ::gig::dimension_softpedal:                  case ::gig::dimension_softpedal:
229                      DimValues[i] = pEngine->ControllerTable[67];                      DimValues[i] = pEngineChannel->ControllerTable[67];
230                      break;                      break;
231                  case ::gig::dimension_genpurpose5:                  case ::gig::dimension_genpurpose5:
232                      DimValues[i] = pEngine->ControllerTable[80];                      DimValues[i] = pEngineChannel->ControllerTable[80];
233                      break;                      break;
234                  case ::gig::dimension_genpurpose6:                  case ::gig::dimension_genpurpose6:
235                      DimValues[i] = pEngine->ControllerTable[81];                      DimValues[i] = pEngineChannel->ControllerTable[81];
236                      break;                      break;
237                  case ::gig::dimension_genpurpose7:                  case ::gig::dimension_genpurpose7:
238                      DimValues[i] = pEngine->ControllerTable[82];                      DimValues[i] = pEngineChannel->ControllerTable[82];
239                      break;                      break;
240                  case ::gig::dimension_genpurpose8:                  case ::gig::dimension_genpurpose8:
241                      DimValues[i] = pEngine->ControllerTable[83];                      DimValues[i] = pEngineChannel->ControllerTable[83];
242                      break;                      break;
243                  case ::gig::dimension_effect1depth:                  case ::gig::dimension_effect1depth:
244                      DimValues[i] = pEngine->ControllerTable[91];                      DimValues[i] = pEngineChannel->ControllerTable[91];
245                      break;                      break;
246                  case ::gig::dimension_effect2depth:                  case ::gig::dimension_effect2depth:
247                      DimValues[i] = pEngine->ControllerTable[92];                      DimValues[i] = pEngineChannel->ControllerTable[92];
248                      break;                      break;
249                  case ::gig::dimension_effect3depth:                  case ::gig::dimension_effect3depth:
250                      DimValues[i] = pEngine->ControllerTable[93];                      DimValues[i] = pEngineChannel->ControllerTable[93];
251                      break;                      break;
252                  case ::gig::dimension_effect4depth:                  case ::gig::dimension_effect4depth:
253                      DimValues[i] = pEngine->ControllerTable[94];                      DimValues[i] = pEngineChannel->ControllerTable[94];
254                      break;                      break;
255                  case ::gig::dimension_effect5depth:                  case ::gig::dimension_effect5depth:
256                      DimValues[i] = pEngine->ControllerTable[95];                      DimValues[i] = pEngineChannel->ControllerTable[95];
257                      break;                      break;
258                  case ::gig::dimension_none:                  case ::gig::dimension_none:
259                      std::cerr << "gig::Voice::Trigger() Error: dimension=none\n" << std::flush;                      std::cerr << "gig::Voice::Trigger() Error: dimension=none\n" << std::flush;
# Line 247  namespace LinuxSampler { namespace gig { Line 262  namespace LinuxSampler { namespace gig {
262                      std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;                      std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;
263              }              }
264          }          }
265          pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);          pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
266    
267          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          pSample = pDimRgn->pSample; // sample won't change until the voice is finished
268            if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent
269    
270          // select channel mode (mono or stereo)          // select channel mode (mono or stereo)
271          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
# Line 263  namespace LinuxSampler { namespace gig { Line 279  namespace LinuxSampler { namespace gig {
279                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);                  CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
280                  break;                  break;
281              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate              case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
282                  CrossfadeVolume = CrossfadeAttenuation(pEngine->ControllerTable[pDimRgn->AttenuationController.controller_number]);                  CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);
283                  break;                  break;
284              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined              case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
285              default:              default:
# Line 309  namespace LinuxSampler { namespace gig { Line 325  namespace LinuxSampler { namespace gig {
325    
326          // calculate initial pitch value          // calculate initial pitch value
327          {          {
328              double pitchbasecents = pDimRgn->FineTune * 10 + (int) pEngine->ScaleTuning[MIDIKey % 12];              double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
329              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
330              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));
331              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
# Line 317  namespace LinuxSampler { namespace gig { Line 333  namespace LinuxSampler { namespace gig {
333    
334          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(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)
335    
336            Volume *= pDimRgn->SampleAttenuation;
337    
338          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
339          {          {
340              // get current value of EG1 controller              // get current value of EG1 controller
# Line 332  namespace LinuxSampler { namespace gig { Line 350  namespace LinuxSampler { namespace gig {
350                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;                      eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
351                      break;                      break;
352                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
353                      eg1controllervalue = pEngine->ControllerTable[pDimRgn->EG1Controller.controller_number];                      eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
354                      break;                      break;
355              }              }
356              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;              if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
# Line 351  namespace LinuxSampler { namespace gig { Line 369  namespace LinuxSampler { namespace gig {
369                            pDimRgn->EG1InfiniteSustain,                            pDimRgn->EG1InfiniteSustain,
370                            pDimRgn->EG1Sustain,                            pDimRgn->EG1Sustain,
371                            pDimRgn->EG1Release + eg1release,                            pDimRgn->EG1Release + eg1release,
372                            Delay);                            // the SSE synthesis implementation requires
373                              // the vca start to be 16 byte aligned
374                              SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ?
375                              Delay & 0xfffffffc : Delay);
376          }          }
377    
378    
# Line 370  namespace LinuxSampler { namespace gig { Line 391  namespace LinuxSampler { namespace gig {
391                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;                      eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
392                      break;                      break;
393                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller                  case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
394                      eg2controllervalue = pEngine->ControllerTable[pDimRgn->EG2Controller.controller_number];                      eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
395                      break;                      break;
396              }              }
397              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;              if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
# Line 431  namespace LinuxSampler { namespace gig { Line 452  namespace LinuxSampler { namespace gig {
452              pLFO1->Trigger(pDimRgn->LFO1Frequency,              pLFO1->Trigger(pDimRgn->LFO1Frequency,
453                            lfo1_internal_depth,                            lfo1_internal_depth,
454                            pDimRgn->LFO1ControlDepth,                            pDimRgn->LFO1ControlDepth,
455                            pEngine->ControllerTable[pLFO1->ExtController],                            pEngineChannel->ControllerTable[pLFO1->ExtController],
456                            pDimRgn->LFO1FlipPhase,                            pDimRgn->LFO1FlipPhase,
457                            pEngine->SampleRate,                            pEngine->SampleRate,
458                            Delay);                            Delay);
# Line 469  namespace LinuxSampler { namespace gig { Line 490  namespace LinuxSampler { namespace gig {
490              pLFO2->Trigger(pDimRgn->LFO2Frequency,              pLFO2->Trigger(pDimRgn->LFO2Frequency,
491                            lfo2_internal_depth,                            lfo2_internal_depth,
492                            pDimRgn->LFO2ControlDepth,                            pDimRgn->LFO2ControlDepth,
493                            pEngine->ControllerTable[pLFO2->ExtController],                            pEngineChannel->ControllerTable[pLFO2->ExtController],
494                            pDimRgn->LFO2FlipPhase,                            pDimRgn->LFO2FlipPhase,
495                            pEngine->SampleRate,                            pEngine->SampleRate,
496                            Delay);                            Delay);
# Line 507  namespace LinuxSampler { namespace gig { Line 528  namespace LinuxSampler { namespace gig {
528              pLFO3->Trigger(pDimRgn->LFO3Frequency,              pLFO3->Trigger(pDimRgn->LFO3Frequency,
529                            lfo3_internal_depth,                            lfo3_internal_depth,
530                            pDimRgn->LFO3ControlDepth,                            pDimRgn->LFO3ControlDepth,
531                            pEngine->ControllerTable[pLFO3->ExtController],                            pEngineChannel->ControllerTable[pLFO3->ExtController],
532                            false,                            false,
533                            pEngine->SampleRate,                            pEngine->SampleRate,
534                            Delay);                            Delay);
# Line 515  namespace LinuxSampler { namespace gig { Line 536  namespace LinuxSampler { namespace gig {
536    
537    
538          #if FORCE_FILTER_USAGE          #if FORCE_FILTER_USAGE
539          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, true);          const bool bUseFilter = true;
540          #else // use filter only if instrument file told so          #else // use filter only if instrument file told so
541          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, pDimRgn->VCFEnabled);          const bool bUseFilter = pDimRgn->VCFEnabled;
542          #endif // FORCE_FILTER_USAGE          #endif // FORCE_FILTER_USAGE
543          if (pDimRgn->VCFEnabled) {          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
544            if (bUseFilter) {
545              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL
546              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;
547              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
# Line 589  namespace LinuxSampler { namespace gig { Line 611  namespace LinuxSampler { namespace gig {
611              FilterRight.SetType(OVERRIDE_FILTER_TYPE);              FilterRight.SetType(OVERRIDE_FILTER_TYPE);
612              #endif // OVERRIDE_FILTER_TYPE              #endif // OVERRIDE_FILTER_TYPE
613    
614              VCFCutoffCtrl.value    = pEngine->ControllerTable[VCFCutoffCtrl.controller];              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
615              VCFResonanceCtrl.value = pEngine->ControllerTable[VCFResonanceCtrl.controller];              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
616    
617              // calculate cutoff frequency              // calculate cutoff frequency
618              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = (!VCFCutoffCtrl.controller)
# Line 637  namespace LinuxSampler { namespace gig { Line 659  namespace LinuxSampler { namespace gig {
659    
660          // Reset the synthesis parameter matrix          // Reset the synthesis parameter matrix
661    
662          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngine->GlobalVolume);          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume);
663          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
664          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
665          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfr, VCFResonanceCtrl.fvalue);
# Line 646  namespace LinuxSampler { namespace gig { Line 668  namespace LinuxSampler { namespace gig {
668          ProcessEvents(Samples);          ProcessEvents(Samples);
669    
670          // 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
671          pEG1->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);          pEG1->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend, itKillEvent);
672          pEG2->Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);          pEG2->Process(Samples, pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents, itTriggerEvent, this->Pos, this->PitchBase * this->PitchBend);
673          if (pEG3->Process(Samples)) { // if pitch EG is active          if (pEG3->Process(Samples)) { // if pitch EG is active
674              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);              SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, true);
675              SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);              SYNTHESIS_MODE_SET_CONSTPITCH(SynthesisMode, false);
# Line 660  namespace LinuxSampler { namespace gig { Line 682  namespace LinuxSampler { namespace gig {
682          }          }
683    
684          if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))          if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
685                  CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters              CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
686    
687          switch (this->PlaybackState) {          switch (this->PlaybackState) {
688    
# Line 694  namespace LinuxSampler { namespace gig { Line 716  namespace LinuxSampler { namespace gig {
716                          }                          }
717                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
718                          Pos -= int(Pos);                          Pos -= int(Pos);
719                            RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
720                      }                      }
721    
722                      const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();                      const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
# Line 702  namespace LinuxSampler { namespace gig { Line 725  namespace LinuxSampler { namespace gig {
725                      if (DiskStreamRef.State == Stream::state_end) {                      if (DiskStreamRef.State == Stream::state_end) {
726                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
727                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
728                                // remember how many sample words there are before any silence has been added
729                                if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
730                              DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);                              DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
731                          }                          }
732                      }                      }
# Line 717  namespace LinuxSampler { namespace gig { Line 742  namespace LinuxSampler { namespace gig {
742                      Pos -= iPos; // just keep fractional part of Pos                      Pos -= iPos; // just keep fractional part of Pos
743    
744                      // change state of voice to 'end' if we really reached the end of the sample data                      // change state of voice to 'end' if we really reached the end of the sample data
745                      if (DiskStreamRef.State == Stream::state_end && readSampleWords >= sampleWordsLeftToRead) this->PlaybackState = playback_state_end;                      if (RealSampleWordsLeftToRead >= 0) {
746                            RealSampleWordsLeftToRead -= readSampleWords;
747                            if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
748                        }
749                  }                  }
750                  break;                  break;
751    
# Line 727  namespace LinuxSampler { namespace gig { Line 755  namespace LinuxSampler { namespace gig {
755          }          }
756    
757          // 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)
758          pEngine->pSynthesisEvents[Event::destination_vca]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vca]->clear();
759          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->clear();
760          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->clear();
761    
762          // Reset delay          // Reset delay
763          Delay = 0;          Delay = 0;
# Line 769  namespace LinuxSampler { namespace gig { Line 797  namespace LinuxSampler { namespace gig {
797      void Voice::ProcessEvents(uint Samples) {      void Voice::ProcessEvents(uint Samples) {
798    
799          // dispatch control change events          // dispatch control change events
800          RTList<Event>::Iterator itCCEvent = pEngine->pCCEvents->first();          RTList<Event>::Iterator itCCEvent = pEngineChannel->pCCEvents->first();
801          if (Delay) { // skip events that happened before this voice was triggered          if (Delay) { // skip events that happened before this voice was triggered
802              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
803          }          }
804          while (itCCEvent) {          while (itCCEvent) {
805              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
806                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
807                      *pEngine->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;                      *pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
808                  }                  }
809                  if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
810                      *pEngine->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;                      *pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
811                  }                  }
812                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
813                      pLFO1->SendEvent(itCCEvent);                      pLFO1->SendEvent(itCCEvent);
# Line 792  namespace LinuxSampler { namespace gig { Line 820  namespace LinuxSampler { namespace gig {
820                  }                  }
821                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
822                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
823                      *pEngine->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;                      *pEngineChannel->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
824                  }                  }
825              }              }
826    
# Line 802  namespace LinuxSampler { namespace gig { Line 830  namespace LinuxSampler { namespace gig {
830    
831          // process pitch events          // process pitch events
832          {          {
833              RTList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];              RTList<Event>* pVCOEventList = pEngineChannel->pSynthesisEvents[Event::destination_vco];
834              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
835              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
836                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
# Line 840  namespace LinuxSampler { namespace gig { Line 868  namespace LinuxSampler { namespace gig {
868    
869          // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)          // process volume / attenuation events (TODO: we only handle and _expect_ crossfade events here ATM !)
870          {          {
871              RTList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];              RTList<Event>* pVCAEventList = pEngineChannel->pSynthesisEvents[Event::destination_vca];
872              RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();              RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
873              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
874                  while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;                  while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
# Line 855  namespace LinuxSampler { namespace gig { Line 883  namespace LinuxSampler { namespace gig {
883    
884                  crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);                  crossfadevolume = CrossfadeAttenuation(itVCAEvent->Param.CC.Value);
885    
886                  float effective_volume = crossfadevolume * this->Volume * pEngine->GlobalVolume;                  float effective_volume = crossfadevolume * this->Volume * pEngineChannel->GlobalVolume;
887    
888                  // apply volume value to the volume parameter sequence                  // apply volume value to the volume parameter sequence
889                  for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {                  for (uint i = itVCAEvent->FragmentPos(); i < end; i++) {
# Line 869  namespace LinuxSampler { namespace gig { Line 897  namespace LinuxSampler { namespace gig {
897    
898          // process filter cutoff events          // process filter cutoff events
899          {          {
900              RTList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];              RTList<Event>* pCutoffEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfc];
901              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
902              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
903                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
# Line 896  namespace LinuxSampler { namespace gig { Line 924  namespace LinuxSampler { namespace gig {
924    
925          // process filter resonance events          // process filter resonance events
926          {          {
927              RTList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];              RTList<Event>* pResonanceEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfr];
928              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
929              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
930                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
# Line 935  namespace LinuxSampler { namespace gig { Line 963  namespace LinuxSampler { namespace gig {
963          biquad_param_t bqmain;          biquad_param_t bqmain;
964          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
965          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
966          FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);          FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
967          FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);          FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
968          pEngine->pBasicFilterParameters[0] = bqbase;          pEngine->pBasicFilterParameters[0] = bqbase;
969          pEngine->pMainFilterParameters[0]  = bqmain;          pEngine->pMainFilterParameters[0]  = bqmain;
970    
# Line 949  namespace LinuxSampler { namespace gig { Line 977  namespace LinuxSampler { namespace gig {
977                  {                  {
978                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
979                      prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];                      prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
980                      FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);                      FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
981                      FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);                      FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
982                  }                  }
983              }              }
984    

Legend:
Removed from v.325  
changed lines
  Added in v.460

  ViewVC Help
Powered by ViewVC