/[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 460 by schoenebeck, Mon Mar 14 22:35:44 2005 UTC revision 669 by schoenebeck, Tue Jun 21 13:33:19 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 pDimRgn        - points to the dimension region 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 VoiceType      - type of this voice
125       *  @param ReleaseTriggerVoice  - if this new voice is a release trigger voice (optional, default = false)       *  @param iKeyGroup      - a value > 0 defines a key group in which this voice is member of
      *  @param VoiceStealingAllowed - wether the voice is allowed to steal voices for further subvoices  
126       *  @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
127       *           (either due to an error or e.g. because no region is       *           (either due to an error or e.g. because no region is
128       *           defined for the given key)       *           defined for the given key)
129       */       */
130      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealingAllowed) {      int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) {
131          this->pEngineChannel = pEngineChannel;          this->pEngineChannel = pEngineChannel;
132          if (!pInstrument) {          this->pDimRgn        = pDimRgn;
133             dmsg(1,("voice::trigger: !pInstrument\n"));  
134             exit(EXIT_FAILURE);          #if CONFIG_DEVMODE
135          }          if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
         if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // FIXME: should be removed before the final release (purpose: just a sanity check for debugging)  
136              dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));              dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
137          }          }
138            #endif // CONFIG_DEVMODE
139    
140          Type            = type_normal;          Type            = VoiceType;
141          MIDIKey         = itNoteOnEvent->Param.Note.Key;          MIDIKey         = itNoteOnEvent->Param.Note.Key;
142          pRegion         = pInstrument->GetRegion(MIDIKey);          PlaybackState   = playback_state_init; // mark voice as triggered, but no audio rendered yet
         PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed  
143          Delay           = itNoteOnEvent->FragmentPos();          Delay           = itNoteOnEvent->FragmentPos();
144          itTriggerEvent  = itNoteOnEvent;          itTriggerEvent  = itNoteOnEvent;
145          itKillEvent     = Pool<Event>::Iterator();          itKillEvent     = Pool<Event>::Iterator();
146            KeyGroup        = iKeyGroup;
147            pSample         = pDimRgn->pSample; // sample won't change until the voice is finished
148    
149          if (!pRegion) {          // calculate volume
150              dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey));          const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
             return -1;  
         }  
151    
152          // only mark the first voice of a layered voice (group) to be in a          Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
         // key group, so the layered voices won't kill each other  
         KeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;  
153    
154          // get current dimension values to select the right dimension region          Volume *= pDimRgn->SampleAttenuation;
         //FIXME: controller values for selecting the dimension region here are currently not sample accurate  
         uint DimValues[8] = { 0 };  
         for (int i = pRegion->Dimensions - 1; i >= 0; i--) {  
             switch (pRegion->pDimensionDefinitions[i].dimension) {  
                 case ::gig::dimension_samplechannel:  
                     DimValues[i] = 0; //TODO: we currently ignore this dimension  
                     break;  
                 case ::gig::dimension_layer:  
                     DimValues[i] = iLayer;  
                     break;  
                 case ::gig::dimension_velocity:  
                     DimValues[i] = itNoteOnEvent->Param.Note.Velocity;  
                     break;  
                 case ::gig::dimension_channelaftertouch:  
                     DimValues[i] = 0; //TODO: we currently ignore this dimension  
                     break;  
                 case ::gig::dimension_releasetrigger:  
                     Type = (ReleaseTriggerVoice) ? type_release_trigger : (!iLayer) ? type_release_trigger_required : type_normal;  
                     DimValues[i] = (uint) ReleaseTriggerVoice;  
                     break;  
                 case ::gig::dimension_keyboard:  
                     DimValues[i] = (uint) pEngineChannel->CurrentKeyDimension;  
                     break;  
                 case ::gig::dimension_roundrobin:  
                     DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on  
                     break;  
                 case ::gig::dimension_random:  
                     pEngine->RandomSeed = pEngine->RandomSeed * 1103515245 + 12345; // classic pseudo random number generator  
                     DimValues[i] = (uint) pEngine->RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random  
                     break;  
                 case ::gig::dimension_modwheel:  
                     DimValues[i] = pEngineChannel->ControllerTable[1];  
                     break;  
                 case ::gig::dimension_breath:  
                     DimValues[i] = pEngineChannel->ControllerTable[2];  
                     break;  
                 case ::gig::dimension_foot:  
                     DimValues[i] = pEngineChannel->ControllerTable[4];  
                     break;  
                 case ::gig::dimension_portamentotime:  
                     DimValues[i] = pEngineChannel->ControllerTable[5];  
                     break;  
                 case ::gig::dimension_effect1:  
                     DimValues[i] = pEngineChannel->ControllerTable[12];  
                     break;  
                 case ::gig::dimension_effect2:  
                     DimValues[i] = pEngineChannel->ControllerTable[13];  
                     break;  
                 case ::gig::dimension_genpurpose1:  
                     DimValues[i] = pEngineChannel->ControllerTable[16];  
                     break;  
                 case ::gig::dimension_genpurpose2:  
                     DimValues[i] = pEngineChannel->ControllerTable[17];  
                     break;  
                 case ::gig::dimension_genpurpose3:  
                     DimValues[i] = pEngineChannel->ControllerTable[18];  
                     break;  
                 case ::gig::dimension_genpurpose4:  
                     DimValues[i] = pEngineChannel->ControllerTable[19];  
                     break;  
                 case ::gig::dimension_sustainpedal:  
                     DimValues[i] = pEngineChannel->ControllerTable[64];  
                     break;  
                 case ::gig::dimension_portamento:  
                     DimValues[i] = pEngineChannel->ControllerTable[65];  
                     break;  
                 case ::gig::dimension_sostenutopedal:  
                     DimValues[i] = pEngineChannel->ControllerTable[66];  
                     break;  
                 case ::gig::dimension_softpedal:  
                     DimValues[i] = pEngineChannel->ControllerTable[67];  
                     break;  
                 case ::gig::dimension_genpurpose5:  
                     DimValues[i] = pEngineChannel->ControllerTable[80];  
                     break;  
                 case ::gig::dimension_genpurpose6:  
                     DimValues[i] = pEngineChannel->ControllerTable[81];  
                     break;  
                 case ::gig::dimension_genpurpose7:  
                     DimValues[i] = pEngineChannel->ControllerTable[82];  
                     break;  
                 case ::gig::dimension_genpurpose8:  
                     DimValues[i] = pEngineChannel->ControllerTable[83];  
                     break;  
                 case ::gig::dimension_effect1depth:  
                     DimValues[i] = pEngineChannel->ControllerTable[91];  
                     break;  
                 case ::gig::dimension_effect2depth:  
                     DimValues[i] = pEngineChannel->ControllerTable[92];  
                     break;  
                 case ::gig::dimension_effect3depth:  
                     DimValues[i] = pEngineChannel->ControllerTable[93];  
                     break;  
                 case ::gig::dimension_effect4depth:  
                     DimValues[i] = pEngineChannel->ControllerTable[94];  
                     break;  
                 case ::gig::dimension_effect5depth:  
                     DimValues[i] = pEngineChannel->ControllerTable[95];  
                     break;  
                 case ::gig::dimension_none:  
                     std::cerr << "gig::Voice::Trigger() Error: dimension=none\n" << std::flush;  
                     break;  
                 default:  
                     std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;  
             }  
         }  
         pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);  
155    
156          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          // the volume of release triggered samples depends on note length
157          if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent          if (Type == type_release_trigger) {
158                float noteLength = float(pEngine->FrameTime + Delay -
159                                         pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
160                float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
161                if (attenuation <= 0) return -1;
162                Volume *= attenuation;
163            }
164    
165          // select channel mode (mono or stereo)          // select channel mode (mono or stereo)
166          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
# Line 296  namespace LinuxSampler { namespace gig { Line 191  namespace LinuxSampler { namespace gig {
191          DiskVoice          = cachedsamples < pSample->SamplesTotal;          DiskVoice          = cachedsamples < pSample->SamplesTotal;
192    
193          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
194              MaxRAMPos = cachedsamples - (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)
195    
196              // check if there's a loop defined which completely fits into the cached (RAM) part of the sample              // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
197              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
# Line 331  namespace LinuxSampler { namespace gig { Line 226  namespace LinuxSampler { namespace gig {
226              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
227          }          }
228    
229          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
230            const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
         Volume *= pDimRgn->SampleAttenuation;  
231    
232          // setup EG 1 (VCA EG)          // setup EG 1 (VCA EG)
233          {          {
# Line 364  namespace LinuxSampler { namespace gig { Line 258  namespace LinuxSampler { namespace gig {
258                            pDimRgn->EG1Attack + eg1attack,                            pDimRgn->EG1Attack + eg1attack,
259                            pDimRgn->EG1Hold,                            pDimRgn->EG1Hold,
260                            pSample->LoopStart,                            pSample->LoopStart,
261                            pDimRgn->EG1Decay1 + eg1decay,                            (pDimRgn->EG1Decay1 + eg1decay) * velrelease,
262                            pDimRgn->EG1Decay2 + eg1decay,                            (pDimRgn->EG1Decay2 + eg1decay) * velrelease,
263                            pDimRgn->EG1InfiniteSustain,                            pDimRgn->EG1InfiniteSustain,
264                            pDimRgn->EG1Sustain,                            pDimRgn->EG1Sustain,
265                            pDimRgn->EG1Release + eg1release,                            (pDimRgn->EG1Release + eg1release) * velrelease,
266                            // the SSE synthesis implementation requires                            // the SSE synthesis implementation requires
267                            // the vca start to be 16 byte aligned                            // the vca start to be 16 byte aligned
268                            SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ?                            SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ?
269                            Delay & 0xfffffffc : Delay);                            Delay & 0xfffffffc : Delay,
270                              velocityAttenuation);
271          }          }
272    
273    
# Line 405  namespace LinuxSampler { namespace gig { Line 300  namespace LinuxSampler { namespace gig {
300                            pDimRgn->EG2Attack + eg2attack,                            pDimRgn->EG2Attack + eg2attack,
301                            false,                            false,
302                            pSample->LoopStart,                            pSample->LoopStart,
303                            pDimRgn->EG2Decay1 + eg2decay,                            (pDimRgn->EG2Decay1 + eg2decay) * velrelease,
304                            pDimRgn->EG2Decay2 + eg2decay,                            (pDimRgn->EG2Decay2 + eg2decay) * velrelease,
305                            pDimRgn->EG2InfiniteSustain,                            pDimRgn->EG2InfiniteSustain,
306                            pDimRgn->EG2Sustain,                            pDimRgn->EG2Sustain,
307                            pDimRgn->EG2Release + eg2release,                            (pDimRgn->EG2Release + eg2release) * velrelease,
308                            Delay);                            Delay,
309                              velocityAttenuation);
310          }          }
311    
312    
# Line 535  namespace LinuxSampler { namespace gig { Line 431  namespace LinuxSampler { namespace gig {
431          }          }
432    
433    
434          #if FORCE_FILTER_USAGE          #if CONFIG_FORCE_FILTER
435          const bool bUseFilter = true;          const bool bUseFilter = true;
436          #else // use filter only if instrument file told so          #else // use filter only if instrument file told so
437          const bool bUseFilter = pDimRgn->VCFEnabled;          const bool bUseFilter = pDimRgn->VCFEnabled;
438          #endif // FORCE_FILTER_USAGE          #endif // CONFIG_FORCE_FILTER
439          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);          SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
440          if (bUseFilter) {          if (bUseFilter) {
441              #ifdef OVERRIDE_FILTER_CUTOFF_CTRL              #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
442              VCFCutoffCtrl.controller = OVERRIDE_FILTER_CUTOFF_CTRL;              VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
443              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
444              switch (pDimRgn->VCFCutoffController) {              switch (pDimRgn->VCFCutoffController) {
445                  case ::gig::vcf_cutoff_ctrl_modwheel:                  case ::gig::vcf_cutoff_ctrl_modwheel:
# Line 579  namespace LinuxSampler { namespace gig { Line 475  namespace LinuxSampler { namespace gig {
475                      VCFCutoffCtrl.controller = 0;                      VCFCutoffCtrl.controller = 0;
476                      break;                      break;
477              }              }
478              #endif // OVERRIDE_FILTER_CUTOFF_CTRL              #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
479    
480              #ifdef OVERRIDE_FILTER_RES_CTRL              #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
481              VCFResonanceCtrl.controller = OVERRIDE_FILTER_RES_CTRL;              VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
482              #else // use the one defined in the instrument file              #else // use the one defined in the instrument file
483              switch (pDimRgn->VCFResonanceController) {              switch (pDimRgn->VCFResonanceController) {
484                  case ::gig::vcf_res_ctrl_genpurpose3:                  case ::gig::vcf_res_ctrl_genpurpose3:
# Line 601  namespace LinuxSampler { namespace gig { Line 497  namespace LinuxSampler { namespace gig {
497                  default:                  default:
498                      VCFResonanceCtrl.controller = 0;                      VCFResonanceCtrl.controller = 0;
499              }              }
500              #endif // OVERRIDE_FILTER_RES_CTRL              #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
501    
502              #ifndef OVERRIDE_FILTER_TYPE              #ifndef CONFIG_OVERRIDE_FILTER_TYPE
503              FilterLeft.SetType(pDimRgn->VCFType);              FilterLeft.SetType(pDimRgn->VCFType);
504              FilterRight.SetType(pDimRgn->VCFType);              FilterRight.SetType(pDimRgn->VCFType);
505              #else // override filter type              #else // override filter type
506              FilterLeft.SetType(OVERRIDE_FILTER_TYPE);              FilterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
507              FilterRight.SetType(OVERRIDE_FILTER_TYPE);              FilterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
508              #endif // OVERRIDE_FILTER_TYPE              #endif // CONFIG_OVERRIDE_FILTER_TYPE
509    
510              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];              VCFCutoffCtrl.value    = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
511              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];              VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
512    
513              // calculate cutoff frequency              // calculate cutoff frequency
514              float cutoff = (!VCFCutoffCtrl.controller)              float cutoff = (!VCFCutoffCtrl.controller)
515                  ? 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
516                  : 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;
517    
518              // calculate resonance              // calculate resonance
519              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0              float resonance = (float) VCFResonanceCtrl.value * 0.00787f;   // 0.0..1.0
# Line 626  namespace LinuxSampler { namespace gig { Line 522  namespace LinuxSampler { namespace gig {
522              }              }
523              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)
524    
525              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;              VCFCutoffCtrl.fvalue    = cutoff - CONFIG_FILTER_CUTOFF_MIN;
526              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
527    
528              FilterUpdateCounter = -1;              FilterUpdateCounter = -1;
# Line 686  namespace LinuxSampler { namespace gig { Line 582  namespace LinuxSampler { namespace gig {
582    
583          switch (this->PlaybackState) {          switch (this->PlaybackState) {
584    
585                case playback_state_init:
586                    this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
587                    // no break - continue with playback_state_ram
588    
589              case playback_state_ram: {              case playback_state_ram: {
590                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping                      if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
591    
# Line 723  namespace LinuxSampler { namespace gig { Line 623  namespace LinuxSampler { namespace gig {
623    
624                      // 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)
625                      if (DiskStreamRef.State == Stream::state_end) {                      if (DiskStreamRef.State == Stream::state_end) {
626                          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
627                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
628                              // 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
629                              if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;                              if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
# Line 910  namespace LinuxSampler { namespace gig { Line 810  namespace LinuxSampler { namespace gig {
810                  // calculate the influence length of this event (in sample points)                  // calculate the influence length of this event (in sample points)
811                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;                  uint end = (itNextCutoffEvent) ? itNextCutoffEvent->FragmentPos() : Samples;
812    
813                  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;
814    
815                  // apply cutoff frequency to the cutoff parameter sequence                  // apply cutoff frequency to the cutoff parameter sequence
816                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {                  for (uint i = itCutoffEvent->FragmentPos(); i < end; i++) {
# Line 963  namespace LinuxSampler { namespace gig { Line 863  namespace LinuxSampler { namespace gig {
863          biquad_param_t bqmain;          biquad_param_t bqmain;
864          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];          float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
865          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];          float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
866          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);
867          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);
868          pEngine->pBasicFilterParameters[0] = bqbase;          pEngine->pBasicFilterParameters[0] = bqbase;
869          pEngine->pMainFilterParameters[0]  = bqmain;          pEngine->pMainFilterParameters[0]  = bqmain;
870    
# Line 977  namespace LinuxSampler { namespace gig { Line 877  namespace LinuxSampler { namespace gig {
877                  {                  {
878                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];                      prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
879                      prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];                      prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
880                      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);
881                      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);
882                  }                  }
883              }              }
884    
# Line 1037  namespace LinuxSampler { namespace gig { Line 937  namespace LinuxSampler { namespace gig {
937       *  @param itKillEvent - event which caused the voice to be killed       *  @param itKillEvent - event which caused the voice to be killed
938       */       */
939      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {      void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
940          //FIXME: just two sanity checks for debugging, can be removed          #if CONFIG_DEVMODE
941          if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));          if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
942          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"));
943            #endif // CONFIG_DEVMODE
944    
945          if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;          if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
946          this->itKillEvent = itKillEvent;          this->itKillEvent = itKillEvent;

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

  ViewVC Help
Powered by ViewVC