/[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 411 by schoenebeck, Sat Feb 26 02:01:14 2005 UTC revision 630 by persson, Sat Jun 11 14:51:49 2005 UTC
# Line 35  namespace LinuxSampler { namespace gig { Line 35  namespace LinuxSampler { namespace gig {
35      const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());      const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());
36    
37      float Voice::CalculateFilterCutoffCoeff() {      float Voice::CalculateFilterCutoffCoeff() {
38          return log(FILTER_CUTOFF_MIN / FILTER_CUTOFF_MAX);          return log(CONFIG_FILTER_CUTOFF_MIN / CONFIG_FILTER_CUTOFF_MAX);
39      }      }
40    
41      int Voice::CalculateFilterUpdateMask() {      int Voice::CalculateFilterUpdateMask() {
42          if (FILTER_UPDATE_PERIOD <= 0) return 0;          if (CONFIG_FILTER_UPDATE_STEPS <= 0) return 0;
43          int power_of_two;          int power_of_two;
44          for (power_of_two = 0; 1<<power_of_two < FILTER_UPDATE_PERIOD; power_of_two++);          for (power_of_two = 0; 1<<power_of_two < CONFIG_FILTER_UPDATE_STEPS; power_of_two++);
45          return (1 << power_of_two) - 1;          return (1 << power_of_two) - 1;
46      }      }
47    
# Line 61  namespace LinuxSampler { namespace gig { Line 61  namespace LinuxSampler { namespace gig {
61          KeyGroup = 0;          KeyGroup = 0;
62          SynthesisMode = 0; // set all mode bits to 0 first          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          #if CONFIG_ASM && ARCH_X86
65          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
66          #else          #else
67          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
# Line 117  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 pEngineChannel      - engine channel on which this voice was ordered       *  @param pEngineChannel       - engine channel on which this voice was ordered
121       *  @param itNoteOnEvent       - event that caused triggering of this voice       *  @param itNoteOnEvent        - event that caused triggering of this voice
122       *  @param PitchBend           - MIDI detune factor (-8192 ... +8191)       *  @param PitchBend            - MIDI detune factor (-8192 ... +8191)
123       *  @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
124       *  @param iLayer              - layer number this voice refers to (only if this is a layered sound of course)       *  @param iLayer               - layer number this voice refers to (only if this is a layered sound of course)
125       *  @param ReleaseTriggerVoice - if this new voice is a release trigger voice (optional, default = false)       *  @param ReleaseTriggerVoice  - if this new voice is a release trigger voice (optional, default = false)
126       *  @param VoiceStealing       - wether the voice is allowed to steal voices for further subvoices       *  @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       *  @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       *           (either due to an error or e.g. because no region is
129       *           defined for the given key)       *           defined for the given key)
130       */       */
131      int Voice::Trigger(EngineChannel* pEngineChannel, 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;          this->pEngineChannel = pEngineChannel;
133          if (!pInstrument) {          if (!pInstrument) {
134             dmsg(1,("voice::trigger: !pInstrument\n"));             dmsg(1,("voice::trigger: !pInstrument\n"));
135             exit(EXIT_FAILURE);             exit(EXIT_FAILURE);
136          }          }
137          if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // FIXME: should be removed before the final release (purpose: just a sanity check for debugging)          #if CONFIG_DEVMODE
138            if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
139              dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));              dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
140          }          }
141            #endif // CONFIG_DEVMODE
142    
143          Type            = type_normal;          Type            = type_normal;
144          MIDIKey         = itNoteOnEvent->Param.Note.Key;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
145          pRegion         = pInstrument->GetRegion(MIDIKey);          pRegion         = pInstrument->GetRegion(MIDIKey);
146          PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed          PlaybackState   = playback_state_init; // mark voice as triggered, but no audio rendered yet
147          Delay           = itNoteOnEvent->FragmentPos();          Delay           = itNoteOnEvent->FragmentPos();
148          itTriggerEvent  = itNoteOnEvent;          itTriggerEvent  = itNoteOnEvent;
149          itKillEvent     = Pool<Event>::Iterator();          itKillEvent     = Pool<Event>::Iterator();
         itChildVoice    = Pool<Voice>::Iterator();  
150    
151          if (!pRegion) {          if (!pRegion) {
152              dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey));              dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey));
153              return -1;              return -1;
154          }          }
155    
156          KeyGroup = pRegion->KeyGroup;          // only mark the first voice of a layered voice (group) to be in a
157            // key group, so the layered voices won't kill each other
158            KeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;
159    
160          // get current dimension values to select the right dimension region          // get current dimension values to select the right dimension region
161          //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
# Line 164  namespace LinuxSampler { namespace gig { Line 167  namespace LinuxSampler { namespace gig {
167                      break;                      break;
168                  case ::gig::dimension_layer:                  case ::gig::dimension_layer:
169                      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(pEngineChannel, itNoteOnEvent, iNewLayer, ReleaseTriggerVoice, VoiceStealing);  
170                      break;                      break;
171                  case ::gig::dimension_velocity:                  case ::gig::dimension_velocity:
172                      DimValues[i] = itNoteOnEvent->Param.Note.Velocity;                      DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
# Line 182  namespace LinuxSampler { namespace gig { Line 181  namespace LinuxSampler { namespace gig {
181                  case ::gig::dimension_keyboard:                  case ::gig::dimension_keyboard:
182                      DimValues[i] = (uint) pEngineChannel->CurrentKeyDimension;                      DimValues[i] = (uint) pEngineChannel->CurrentKeyDimension;
183                      break;                      break;
184                    case ::gig::dimension_roundrobin:
185                        DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on
186                        break;
187                    case ::gig::dimension_random:
188                        pEngine->RandomSeed = pEngine->RandomSeed * 1103515245 + 12345; // classic pseudo random number generator
189                        DimValues[i] = (uint) pEngine->RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random
190                        break;
191                  case ::gig::dimension_modwheel:                  case ::gig::dimension_modwheel:
192                      DimValues[i] = pEngineChannel->ControllerTable[1];                      DimValues[i] = pEngineChannel->ControllerTable[1];
193                      break;                      break;
# Line 263  namespace LinuxSampler { namespace gig { Line 269  namespace LinuxSampler { namespace gig {
269          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          pSample = pDimRgn->pSample; // sample won't change until the voice is finished
270          if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent          if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent
271    
272            // calculate volume
273            const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
274    
275            Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
276    
277            Volume *= pDimRgn->SampleAttenuation;
278    
279            // the volume of release triggered samples depends on note length
280            if (ReleaseTriggerVoice) {
281                float noteLength = float(pEngine->FrameTime + Delay -
282                                         pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
283                float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
284                if (attenuation <= 0) return -1;
285                Volume *= attenuation;
286            }
287    
288          // select channel mode (mono or stereo)          // select channel mode (mono or stereo)
289          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
290    
# Line 292  namespace LinuxSampler { namespace gig { Line 314  namespace LinuxSampler { namespace gig {
314          DiskVoice          = cachedsamples < pSample->SamplesTotal;          DiskVoice          = cachedsamples < pSample->SamplesTotal;
315    
316          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
317              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)              MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)
318    
319              // 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
320              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
# Line 327  namespace LinuxSampler { namespace gig { Line 349  namespace LinuxSampler { namespace gig {
349              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
350          }          }
351    
352          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)          // the length of the decay and release curves are dependent on the velocity
353            const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
         Volume *= pDimRgn->SampleAttenuation;  
354    
355          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
356          {          {
# Line 360  namespace LinuxSampler { namespace gig { Line 381  namespace LinuxSampler { namespace gig {
381                            pDimRgn->EG1Attack + eg1attack,                            pDimRgn->EG1Attack + eg1attack,
382                            pDimRgn->EG1Hold,                            pDimRgn->EG1Hold,
383                            pSample->LoopStart,                            pSample->LoopStart,
384                            pDimRgn->EG1Decay1 + eg1decay,                            (pDimRgn->EG1Decay1 + eg1decay) * velrelease,
385                            pDimRgn->EG1Decay2 + eg1decay,                            (pDimRgn->EG1Decay2 + eg1decay) * velrelease,
386                            pDimRgn->EG1InfiniteSustain,                            pDimRgn->EG1InfiniteSustain,
387                            pDimRgn->EG1Sustain,                            pDimRgn->EG1Sustain,
388                            pDimRgn->EG1Release + eg1release,                            (pDimRgn->EG1Release + eg1release) * velrelease,
389                            Delay);                            // the SSE synthesis implementation requires
390                              // the vca start to be 16 byte aligned
391                              SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ?
392                              Delay & 0xfffffffc : Delay,
393                              velocityAttenuation);
394          }          }
395    
396    
# Line 398  namespace LinuxSampler { namespace gig { Line 423  namespace LinuxSampler { namespace gig {
423                            pDimRgn->EG2Attack + eg2attack,                            pDimRgn->EG2Attack + eg2attack,
424                            false,                            false,
425                            pSample->LoopStart,                            pSample->LoopStart,
426                            pDimRgn->EG2Decay1 + eg2decay,                            (pDimRgn->EG2Decay1 + eg2decay) * velrelease,
427                            pDimRgn->EG2Decay2 + eg2decay,                            (pDimRgn->EG2Decay2 + eg2decay) * velrelease,
428                            pDimRgn->EG2InfiniteSustain,                            pDimRgn->EG2InfiniteSustain,
429                            pDimRgn->EG2Sustain,                            pDimRgn->EG2Sustain,
430                            pDimRgn->EG2Release + eg2release,                            (pDimRgn->EG2Release + eg2release) * velrelease,
431                            Delay);                            Delay,
432                              velocityAttenuation);
433          }          }
434    
435    
# Line 528  namespace LinuxSampler { namespace gig { Line 554  namespace LinuxSampler { namespace gig {
554          }          }
555    
556    
557          #if FORCE_FILTER_USAGE          #if CONFIG_FORCE_FILTER
558          const bool bUseFilter = true;          const bool bUseFilter = true;
559          #else // use filter only if instrument file told so          #else // use filter only if instrument file told so
560          const bool bUseFilter = pDimRgn->VCFEnabled;          const bool bUseFilter = pDimRgn->VCFEnabled;
561          #endif // FORCE_FILTER_USAGE          #endif // CONFIG_FORCE_FILTER
562          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
563          if (bUseFilter) {          if (bUseFilter) {
564              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL              #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
565              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;              VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
566              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
567              switch (pDimRgn->VCFCutoffController) {              switch (pDimRgn->VCFCutoffController) {
568                  case ::gig::vcf_cutoff_ctrl_modwheel:                  case ::gig::vcf_cutoff_ctrl_modwheel:
# Line 572  namespace LinuxSampler { namespace gig { Line 598  namespace LinuxSampler { namespace gig {
598                      VCFCutoffCtrl.controller = 0;                      VCFCutoffCtrl.controller = 0;
599                      break;                      break;
600              }              }
601              #endif // OVERRIDE_FILTER_CUTOFF_CTRL              #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
602    
603              #ifdef OVERRIDE_FILTER_RES_CTRL              #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
604              VCFResonanceCtrl.controller = OVERRIDE_FILTER_RES_CTRL;              VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
605              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
606              switch (pDimRgn->VCFResonanceController) {              switch (pDimRgn->VCFResonanceController) {
607                  case ::gig::vcf_res_ctrl_genpurpose3:                  case ::gig::vcf_res_ctrl_genpurpose3:
# Line 594  namespace LinuxSampler { namespace gig { Line 620  namespace LinuxSampler { namespace gig {
620                  default:                  default:
621                      VCFResonanceCtrl.controller = 0;                      VCFResonanceCtrl.controller = 0;
622              }              }
623              #endif // OVERRIDE_FILTER_RES_CTRL              #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
624    
625              #ifndef OVERRIDE_FILTER_TYPE              #ifndef CONFIG_OVERRIDE_FILTER_TYPE
626              FilterLeft.SetType(pDimRgn->VCFType);              FilterLeft.SetType(pDimRgn->VCFType);
627              FilterRight.SetType(pDimRgn->VCFType);              FilterRight.SetType(pDimRgn->VCFType);
628              #else // override filter type              #else // override filter type
629              FilterLeft.SetType(OVERRIDE_FILTER_TYPE);              FilterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
630              FilterRight.SetType(OVERRIDE_FILTER_TYPE);              FilterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
631              #endif // OVERRIDE_FILTER_TYPE              #endif // CONFIG_OVERRIDE_FILTER_TYPE
632    
633              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
634              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
635    
636              // calculate cutoff frequency              // calculate cutoff frequency
637              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = (!VCFCutoffCtrl.controller)
638                  ? exp((float) (127 - itNoteOnEvent->Param.Note.Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX                  ? exp((float) (127 - itNoteOnEvent->Param.Note.Velocity) * (float) pDimRgn->VCFVelocityScale * 6.2E-5f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX
639                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX;                  : exp((float) VCFCutoffCtrl.value * 0.00787402f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX;
640    
641              // calculate resonance              // calculate resonance
642              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0
# Line 619  namespace LinuxSampler { namespace gig { Line 645  namespace LinuxSampler { namespace gig {
645              }              }
646              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)
647    
648              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;              VCFCutoffCtrl.fvalue    = cutoff - CONFIG_FILTER_CUTOFF_MIN;
649              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
650    
651              FilterUpdateCounter = -1;              FilterUpdateCounter = -1;
# Line 675  namespace LinuxSampler { namespace gig { Line 701  namespace LinuxSampler { namespace gig {
701          }          }
702    
703          if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))          if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode))
704                  CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters              CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
705    
706          switch (this->PlaybackState) {          switch (this->PlaybackState) {
707    
708                case playback_state_init:
709                    this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
710                    // no break - continue with playback_state_ram
711    
712              case playback_state_ram: {              case playback_state_ram: {
713                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
714    
# Line 716  namespace LinuxSampler { namespace gig { Line 746  namespace LinuxSampler { namespace gig {
746    
747                      // 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)
748                      if (DiskStreamRef.State == Stream::state_end) {                      if (DiskStreamRef.State == Stream::state_end) {
749                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
750                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
751                              // remember how many sample words there are before any silence has been added                              // remember how many sample words there are before any silence has been added
752                              if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;                              if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
# Line 748  namespace LinuxSampler { namespace gig { Line 778  namespace LinuxSampler { namespace gig {
778          }          }
779    
780          // 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)
781          pEngine->pSynthesisEvents[Event::destination_vca]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vca]->clear();
782          pEngine->pSynthesisEvents[Event::destination_vcfc]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->clear();
783          pEngine->pSynthesisEvents[Event::destination_vcfr]->clear();          pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->clear();
784    
785          // Reset delay          // Reset delay
786          Delay = 0;          Delay = 0;
# Line 790  namespace LinuxSampler { namespace gig { Line 820  namespace LinuxSampler { namespace gig {
820      void Voice::ProcessEvents(uint Samples) {      void Voice::ProcessEvents(uint Samples) {
821    
822          // dispatch control change events          // dispatch control change events
823          RTList<Event>::Iterator itCCEvent = pEngine->pCCEvents->first();          RTList<Event>::Iterator itCCEvent = pEngineChannel->pCCEvents->first();
824          if (Delay) { // skip events that happened before this voice was triggered          if (Delay) { // skip events that happened before this voice was triggered
825              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;              while (itCCEvent && itCCEvent->FragmentPos() <= Delay) ++itCCEvent;
826          }          }
827          while (itCCEvent) {          while (itCCEvent) {
828              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller              if (itCCEvent->Param.CC.Controller) { // if valid MIDI controller
829                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
830                      *pEngine->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;                      *pEngineChannel->pSynthesisEvents[Event::destination_vcfc]->allocAppend() = *itCCEvent;
831                  }                  }
832                  if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {                  if (itCCEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
833                      *pEngine->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;                      *pEngineChannel->pSynthesisEvents[Event::destination_vcfr]->allocAppend() = *itCCEvent;
834                  }                  }
835                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {                  if (itCCEvent->Param.CC.Controller == pLFO1->ExtController) {
836                      pLFO1->SendEvent(itCCEvent);                      pLFO1->SendEvent(itCCEvent);
# Line 813  namespace LinuxSampler { namespace gig { Line 843  namespace LinuxSampler { namespace gig {
843                  }                  }
844                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&                  if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
845                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event                      itCCEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) { // if crossfade event
846                      *pEngine->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;                      *pEngineChannel->pSynthesisEvents[Event::destination_vca]->allocAppend() = *itCCEvent;
847                  }                  }
848              }              }
849    
# Line 823  namespace LinuxSampler { namespace gig { Line 853  namespace LinuxSampler { namespace gig {
853    
854          // process pitch events          // process pitch events
855          {          {
856              RTList<Event>* pVCOEventList = pEngine->pSynthesisEvents[Event::destination_vco];              RTList<Event>* pVCOEventList = pEngineChannel->pSynthesisEvents[Event::destination_vco];
857              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();              RTList<Event>::Iterator itVCOEvent = pVCOEventList->first();
858              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
859                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;                  while (itVCOEvent && itVCOEvent->FragmentPos() <= Delay) ++itVCOEvent;
# Line 861  namespace LinuxSampler { namespace gig { Line 891  namespace LinuxSampler { namespace gig {
891    
892          // 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 !)
893          {          {
894              RTList<Event>* pVCAEventList = pEngine->pSynthesisEvents[Event::destination_vca];              RTList<Event>* pVCAEventList = pEngineChannel->pSynthesisEvents[Event::destination_vca];
895              RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();              RTList<Event>::Iterator itVCAEvent = pVCAEventList->first();
896              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
897                  while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;                  while (itVCAEvent && itVCAEvent->FragmentPos() <= Delay) ++itVCAEvent;
# Line 890  namespace LinuxSampler { namespace gig { Line 920  namespace LinuxSampler { namespace gig {
920    
921          // process filter cutoff events          // process filter cutoff events
922          {          {
923              RTList<Event>* pCutoffEventList = pEngine->pSynthesisEvents[Event::destination_vcfc];              RTList<Event>* pCutoffEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfc];
924              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();              RTList<Event>::Iterator itCutoffEvent = pCutoffEventList->first();
925              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
926                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;                  while (itCutoffEvent && itCutoffEvent->FragmentPos() <= Delay) ++itCutoffEvent;
# Line 903  namespace LinuxSampler { namespace gig { Line 933  namespace LinuxSampler { namespace gig {
933                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
934                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
935    
936                  cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * FILTER_CUTOFF_MAX - FILTER_CUTOFF_MIN;                  cutoff = exp((float) itCutoffEvent->Param.CC.Value * 0.00787402f * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MAX - CONFIG_FILTER_CUTOFF_MIN;
937    
938                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
939                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
# Line 917  namespace LinuxSampler { namespace gig { Line 947  namespace LinuxSampler { namespace gig {
947    
948          // process filter resonance events          // process filter resonance events
949          {          {
950              RTList<Event>* pResonanceEventList = pEngine->pSynthesisEvents[Event::destination_vcfr];              RTList<Event>* pResonanceEventList = pEngineChannel->pSynthesisEvents[Event::destination_vcfr];
951              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();              RTList<Event>::Iterator itResonanceEvent = pResonanceEventList->first();
952              if (Delay) { // skip events that happened before this voice was triggered              if (Delay) { // skip events that happened before this voice was triggered
953                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;                  while (itResonanceEvent && itResonanceEvent->FragmentPos() <= Delay) ++itResonanceEvent;
# Line 956  namespace LinuxSampler { namespace gig { Line 986  namespace LinuxSampler { namespace gig {
986          biquad_param_t bqmain;          biquad_param_t bqmain;
987          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
988          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
989          FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);          FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
990          FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);          FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
991          pEngine->pBasicFilterParameters[0] = bqbase;          pEngine->pBasicFilterParameters[0] = bqbase;
992          pEngine->pMainFilterParameters[0]  = bqmain;          pEngine->pMainFilterParameters[0]  = bqmain;
993    
# Line 970  namespace LinuxSampler { namespace gig { Line 1000  namespace LinuxSampler { namespace gig {
1000                  {                  {
1001                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
1002                      prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];                      prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
1003                      FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);                      FilterLeft.SetParameters( &bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
1004                      FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);                      FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff + CONFIG_FILTER_CUTOFF_MIN, prev_res, pEngine->SampleRate);
1005                  }                  }
1006              }              }
1007    
# Line 1030  namespace LinuxSampler { namespace gig { Line 1060  namespace LinuxSampler { namespace gig {
1060       *  @param itKillEvent - event which caused the voice to be killed       *  @param itKillEvent - event which caused the voice to be killed
1061       */       */
1062      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
1063          //FIXME: just two sanity checks for debugging, can be removed          #if CONFIG_DEVMODE
1064          if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));          if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
1065          if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));          if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
1066            #endif // CONFIG_DEVMODE
1067    
1068          if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;          if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
1069          this->itKillEvent = itKillEvent;          this->itKillEvent = itKillEvent;

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

  ViewVC Help
Powered by ViewVC