/[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 64 by schoenebeck, Thu May 6 20:06:20 2004 UTC revision 225 by schoenebeck, Sun Aug 22 14:46:47 2004 UTC
# Line 31  namespace LinuxSampler { namespace gig { Line 31  namespace LinuxSampler { namespace gig {
31    
32      const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());      const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());
33    
34        const int Voice::FILTER_UPDATE_MASK(CalculateFilterUpdateMask());
35    
36      float Voice::CalculateFilterCutoffCoeff() {      float Voice::CalculateFilterCutoffCoeff() {
37          return log(FILTER_CUTOFF_MIN / FILTER_CUTOFF_MAX);          return log(FILTER_CUTOFF_MIN / FILTER_CUTOFF_MAX);
38      }      }
39    
40        int Voice::CalculateFilterUpdateMask() {
41            if (FILTER_UPDATE_PERIOD <= 0) return 0;
42            int power_of_two;
43            for (power_of_two = 0; 1<<power_of_two < FILTER_UPDATE_PERIOD; power_of_two++);
44            return (1 << power_of_two) - 1;
45        }
46    
47      Voice::Voice() {      Voice::Voice() {
48          pEngine     = NULL;          pEngine     = NULL;
49          pDiskThread = NULL;          pDiskThread = NULL;
# Line 62  namespace LinuxSampler { namespace gig { Line 71  namespace LinuxSampler { namespace gig {
71          if (pVCOManipulator)  delete pVCOManipulator;          if (pVCOManipulator)  delete pVCOManipulator;
72      }      }
73    
     void Voice::SetOutput(AudioOutputDevice* pAudioOutputDevice) {  
         this->pOutputLeft        = pAudioOutputDevice->Channel(0)->Buffer();  
         this->pOutputRight       = pAudioOutputDevice->Channel(1)->Buffer();  
         this->MaxSamplesPerCycle = pAudioOutputDevice->MaxSamplesPerCycle();  
         this->SampleRate         = pAudioOutputDevice->SampleRate();  
     }  
   
74      void Voice::SetEngine(Engine* pEngine) {      void Voice::SetEngine(Engine* pEngine) {
75          this->pEngine = pEngine;          this->pEngine = pEngine;
76    
# Line 148  namespace LinuxSampler { namespace gig { Line 150  namespace LinuxSampler { namespace gig {
150          DiskVoice          = cachedsamples < pSample->SamplesTotal;          DiskVoice          = cachedsamples < pSample->SamplesTotal;
151    
152          if (DiskVoice) { // voice to be streamed from disk          if (DiskVoice) { // voice to be streamed from disk
153              MaxRAMPos = cachedsamples - (MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)              MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)
154    
155              // 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
156              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {              if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
# Line 305  namespace LinuxSampler { namespace gig { Line 307  namespace LinuxSampler { namespace gig {
307                            pDimRgn->LFO1ControlDepth,                            pDimRgn->LFO1ControlDepth,
308                            pEngine->ControllerTable[pLFO1->ExtController],                            pEngine->ControllerTable[pLFO1->ExtController],
309                            pDimRgn->LFO1FlipPhase,                            pDimRgn->LFO1FlipPhase,
310                            this->SampleRate,                            pEngine->SampleRate,
311                            Delay);                            Delay);
312          }          }
313    
# Line 343  namespace LinuxSampler { namespace gig { Line 345  namespace LinuxSampler { namespace gig {
345                            pDimRgn->LFO2ControlDepth,                            pDimRgn->LFO2ControlDepth,
346                            pEngine->ControllerTable[pLFO2->ExtController],                            pEngine->ControllerTable[pLFO2->ExtController],
347                            pDimRgn->LFO2FlipPhase,                            pDimRgn->LFO2FlipPhase,
348                              pEngine->SampleRate,
349                            Delay);                            Delay);
350          }          }
351      #endif // ENABLE_FILTER      #endif // ENABLE_FILTER
# Line 380  namespace LinuxSampler { namespace gig { Line 383  namespace LinuxSampler { namespace gig {
383                            pDimRgn->LFO3ControlDepth,                            pDimRgn->LFO3ControlDepth,
384                            pEngine->ControllerTable[pLFO3->ExtController],                            pEngine->ControllerTable[pLFO3->ExtController],
385                            false,                            false,
386                            this->SampleRate,                            pEngine->SampleRate,
387                            Delay);                            Delay);
388          }          }
389    
# Line 478  namespace LinuxSampler { namespace gig { Line 481  namespace LinuxSampler { namespace gig {
481              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;              VCFCutoffCtrl.fvalue    = cutoff - FILTER_CUTOFF_MIN;
482              VCFResonanceCtrl.fvalue = resonance;              VCFResonanceCtrl.fvalue = resonance;
483    
484              FilterLeft.SetParameters(cutoff,  resonance, SampleRate);              FilterLeft.SetParameters(cutoff,  resonance, pEngine->SampleRate);
485              FilterRight.SetParameters(cutoff, resonance, SampleRate);              FilterRight.SetParameters(cutoff, resonance, pEngine->SampleRate);
486    
487              FilterUpdateCounter = -1;              FilterUpdateCounter = -1;
488          }          }
# Line 510  namespace LinuxSampler { namespace gig { Line 513  namespace LinuxSampler { namespace gig {
513      void Voice::Render(uint Samples) {      void Voice::Render(uint Samples) {
514    
515          // Reset the synthesis parameter matrix          // Reset the synthesis parameter matrix
516          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume);          pEngine->ResetSynthesisParameters(Event::destination_vca, this->Volume * pEngine->GlobalVolume);
517          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);          pEngine->ResetSynthesisParameters(Event::destination_vco, this->PitchBase);
518      #if ENABLE_FILTER      #if ENABLE_FILTER
519          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);          pEngine->ResetSynthesisParameters(Event::destination_vcfc, VCFCutoffCtrl.fvalue);
# Line 535  namespace LinuxSampler { namespace gig { Line 538  namespace LinuxSampler { namespace gig {
538          pLFO3->Process(Samples);          pLFO3->Process(Samples);
539    
540    
541        #if ENABLE_FILTER
542            CalculateBiquadParameters(Samples); // calculate the final biquad filter parameters
543        #endif // ENABLE_FILTER
544    
545    
546          switch (this->PlaybackState) {          switch (this->PlaybackState) {
547    
548              case playback_state_ram: {              case playback_state_ram: {
# Line 567  namespace LinuxSampler { namespace gig { Line 575  namespace LinuxSampler { namespace gig {
575                      }                      }
576    
577                      // 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)
578                      if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) {                      if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (pEngine->MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) {
579                          DiskStreamRef.pStream->WriteSilence((MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels);                          DiskStreamRef.pStream->WriteSilence((pEngine->MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels);
580                          this->PlaybackState = playback_state_end;                          this->PlaybackState = playback_state_end;
581                      }                      }
582    
# Line 748  namespace LinuxSampler { namespace gig { Line 756  namespace LinuxSampler { namespace gig {
756      #endif // ENABLE_FILTER      #endif // ENABLE_FILTER
757      }      }
758    
759        #if ENABLE_FILTER
760        /**
761         * Calculate all necessary, final biquad filter parameters.
762         *
763         * @param Samples - number of samples to be rendered in this audio fragment cycle
764         */
765        void Voice::CalculateBiquadParameters(uint Samples) {
766            if (!FilterLeft.Enabled) return;
767    
768            biquad_param_t bqbase;
769            biquad_param_t bqmain;
770            float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0];
771            float prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][0];
772            FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
773            pEngine->pBasicFilterParameters[0] = bqbase;
774            pEngine->pMainFilterParameters[0]  = bqmain;
775    
776            float* bq;
777            for (int i = 1; i < Samples; i++) {
778                // recalculate biquad parameters if cutoff or resonance differ from previous sample point
779                if (!(i & FILTER_UPDATE_MASK)) if (pEngine->pSynthesisParameters[Event::destination_vcfr][i] != prev_res ||
780                                                   pEngine->pSynthesisParameters[Event::destination_vcfc][i] != prev_cutoff) {
781                    prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i];
782                    prev_res    = pEngine->pSynthesisParameters[Event::destination_vcfr][i];
783                    FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate);
784                }
785    
786                //same as 'pEngine->pBasicFilterParameters[i] = bqbase;'
787                bq    = (float*) &pEngine->pBasicFilterParameters[i];
788                bq[0] = bqbase.a1;
789                bq[1] = bqbase.a2;
790                bq[2] = bqbase.b0;
791                bq[3] = bqbase.b1;
792                bq[4] = bqbase.b2;
793    
794                // same as 'pEngine->pMainFilterParameters[i] = bqmain;'
795                bq    = (float*) &pEngine->pMainFilterParameters[i];
796                bq[0] = bqmain.a1;
797                bq[1] = bqmain.a2;
798                bq[2] = bqmain.b0;
799                bq[3] = bqmain.b1;
800                bq[4] = bqmain.b2;
801            }
802        }
803        #endif // ENABLE_FILTER
804    
805      /**      /**
806       *  Interpolates the input audio data (no loop).       *  Interpolates the input audio data (no loop).
807       *       *
# Line 765  namespace LinuxSampler { namespace gig { Line 819  namespace LinuxSampler { namespace gig {
819                  InterpolateOneStep_Stereo(pSrc, i,                  InterpolateOneStep_Stereo(pSrc, i,
820                                            pEngine->pSynthesisParameters[Event::destination_vca][i],                                            pEngine->pSynthesisParameters[Event::destination_vca][i],
821                                            pEngine->pSynthesisParameters[Event::destination_vco][i],                                            pEngine->pSynthesisParameters[Event::destination_vco][i],
822                                            pEngine->pSynthesisParameters[Event::destination_vcfc][i],                                            pEngine->pBasicFilterParameters[i],
823                                            pEngine->pSynthesisParameters[Event::destination_vcfr][i]);                                            pEngine->pMainFilterParameters[i]);
824              }              }
825          }          }
826          else { // Mono Sample          else { // Mono Sample
# Line 774  namespace LinuxSampler { namespace gig { Line 828  namespace LinuxSampler { namespace gig {
828                  InterpolateOneStep_Mono(pSrc, i,                  InterpolateOneStep_Mono(pSrc, i,
829                                          pEngine->pSynthesisParameters[Event::destination_vca][i],                                          pEngine->pSynthesisParameters[Event::destination_vca][i],
830                                          pEngine->pSynthesisParameters[Event::destination_vco][i],                                          pEngine->pSynthesisParameters[Event::destination_vco][i],
831                                          pEngine->pSynthesisParameters[Event::destination_vcfc][i],                                          pEngine->pBasicFilterParameters[i],
832                                          pEngine->pSynthesisParameters[Event::destination_vcfr][i]);                                          pEngine->pMainFilterParameters[i]);
833              }              }
834          }          }
835      }      }
# Line 799  namespace LinuxSampler { namespace gig { Line 853  namespace LinuxSampler { namespace gig {
853                      InterpolateOneStep_Stereo(pSrc, i,                      InterpolateOneStep_Stereo(pSrc, i,
854                                                pEngine->pSynthesisParameters[Event::destination_vca][i],                                                pEngine->pSynthesisParameters[Event::destination_vca][i],
855                                                pEngine->pSynthesisParameters[Event::destination_vco][i],                                                pEngine->pSynthesisParameters[Event::destination_vco][i],
856                                                pEngine->pSynthesisParameters[Event::destination_vcfc][i],                                                pEngine->pBasicFilterParameters[i],
857                                                pEngine->pSynthesisParameters[Event::destination_vcfr][i]);                                                pEngine->pMainFilterParameters[i]);
858                      if (Pos > pSample->LoopEnd) {                      if (Pos > pSample->LoopEnd) {
859                          Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;                          Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;
860                          LoopCyclesLeft--;                          LoopCyclesLeft--;
# Line 811  namespace LinuxSampler { namespace gig { Line 865  namespace LinuxSampler { namespace gig {
865                      InterpolateOneStep_Stereo(pSrc, i,                      InterpolateOneStep_Stereo(pSrc, i,
866                                                pEngine->pSynthesisParameters[Event::destination_vca][i],                                                pEngine->pSynthesisParameters[Event::destination_vca][i],
867                                                pEngine->pSynthesisParameters[Event::destination_vco][i],                                                pEngine->pSynthesisParameters[Event::destination_vco][i],
868                                                pEngine->pSynthesisParameters[Event::destination_vcfc][i],                                                pEngine->pBasicFilterParameters[i],
869                                                pEngine->pSynthesisParameters[Event::destination_vcfr][i]);                                                pEngine->pMainFilterParameters[i]);
870                  }                  }
871              }              }
872              else { // render loop (endless loop)              else { // render loop (endless loop)
# Line 820  namespace LinuxSampler { namespace gig { Line 874  namespace LinuxSampler { namespace gig {
874                      InterpolateOneStep_Stereo(pSrc, i,                      InterpolateOneStep_Stereo(pSrc, i,
875                                                pEngine->pSynthesisParameters[Event::destination_vca][i],                                                pEngine->pSynthesisParameters[Event::destination_vca][i],
876                                                pEngine->pSynthesisParameters[Event::destination_vco][i],                                                pEngine->pSynthesisParameters[Event::destination_vco][i],
877                                                pEngine->pSynthesisParameters[Event::destination_vcfc][i],                                                pEngine->pBasicFilterParameters[i],
878                                                pEngine->pSynthesisParameters[Event::destination_vcfr][i]);                                                pEngine->pMainFilterParameters[i]);
879                      if (Pos > pSample->LoopEnd) {                      if (Pos > pSample->LoopEnd) {
880                          Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);                          Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);
881                      }                      }
# Line 835  namespace LinuxSampler { namespace gig { Line 889  namespace LinuxSampler { namespace gig {
889                      InterpolateOneStep_Mono(pSrc, i,                      InterpolateOneStep_Mono(pSrc, i,
890                                              pEngine->pSynthesisParameters[Event::destination_vca][i],                                              pEngine->pSynthesisParameters[Event::destination_vca][i],
891                                              pEngine->pSynthesisParameters[Event::destination_vco][i],                                              pEngine->pSynthesisParameters[Event::destination_vco][i],
892                                              pEngine->pSynthesisParameters[Event::destination_vcfc][i],                                              pEngine->pBasicFilterParameters[i],
893                                              pEngine->pSynthesisParameters[Event::destination_vcfr][i]);                                              pEngine->pMainFilterParameters[i]);
894                      if (Pos > pSample->LoopEnd) {                      if (Pos > pSample->LoopEnd) {
895                          Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;                          Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;
896                          LoopCyclesLeft--;                          LoopCyclesLeft--;
# Line 847  namespace LinuxSampler { namespace gig { Line 901  namespace LinuxSampler { namespace gig {
901                      InterpolateOneStep_Mono(pSrc, i,                      InterpolateOneStep_Mono(pSrc, i,
902                                              pEngine->pSynthesisParameters[Event::destination_vca][i],                                              pEngine->pSynthesisParameters[Event::destination_vca][i],
903                                              pEngine->pSynthesisParameters[Event::destination_vco][i],                                              pEngine->pSynthesisParameters[Event::destination_vco][i],
904                                              pEngine->pSynthesisParameters[Event::destination_vcfc][i],                                              pEngine->pBasicFilterParameters[i],
905                                              pEngine->pSynthesisParameters[Event::destination_vcfr][i]);                                              pEngine->pMainFilterParameters[i]);
906                  }                  }
907              }              }
908              else { // render loop (endless loop)              else { // render loop (endless loop)
# Line 856  namespace LinuxSampler { namespace gig { Line 910  namespace LinuxSampler { namespace gig {
910                      InterpolateOneStep_Mono(pSrc, i,                      InterpolateOneStep_Mono(pSrc, i,
911                                              pEngine->pSynthesisParameters[Event::destination_vca][i],                                              pEngine->pSynthesisParameters[Event::destination_vca][i],
912                                              pEngine->pSynthesisParameters[Event::destination_vco][i],                                              pEngine->pSynthesisParameters[Event::destination_vco][i],
913                                              pEngine->pSynthesisParameters[Event::destination_vcfc][i],                                              pEngine->pBasicFilterParameters[i],
914                                              pEngine->pSynthesisParameters[Event::destination_vcfr][i]);                                              pEngine->pMainFilterParameters[i]);
915                      if (Pos > pSample->LoopEnd) {                      if (Pos > pSample->LoopEnd) {
916                          Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;                          Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);;
917                      }                      }

Legend:
Removed from v.64  
changed lines
  Added in v.225

  ViewVC Help
Powered by ViewVC