/[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 324 by senkov, Sat Dec 18 18:54:46 2004 UTC revision 354 by schoenebeck, Sat Jan 29 15:17:59 2005 UTC
# Line 58  namespace LinuxSampler { namespace gig { Line 58  namespace LinuxSampler { namespace gig {
58          pLFO2  = NULL;          pLFO2  = NULL;
59          pLFO3  = NULL;          pLFO3  = NULL;
60          KeyGroup = 0;          KeyGroup = 0;
61            SynthesisMode = 0; //Set all mode bits to 0 first
62    
63          // select synthesis implementation (currently either pure C++ or MMX+SSE(1))          // select synthesis implementation (currently either pure C++ or MMX+SSE(1))
64          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());          SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
65            SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true);
66      }      }
67    
68      Voice::~Voice() {      Voice::~Voice() {
# Line 114  namespace LinuxSampler { namespace gig { Line 116  namespace LinuxSampler { namespace gig {
116       *  @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)
117       *  @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)
118       *  @param VoiceStealing       - wether the voice is allowed to steal voices for further subvoices       *  @param VoiceStealing       - wether the voice is allowed to steal voices for further subvoices
119       *  @returns 0 on success, a value < 0 if something failed       *  @returns 0 on success, a value < 0 if the voice wasn't triggered
120         *           (either due to an error or e.g. because no region is
121         *           defined for the given key)
122       */       */
123      int Voice::Trigger(Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) {      int Voice::Trigger(Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) {
124          if (!pInstrument) {          if (!pInstrument) {
# Line 135  namespace LinuxSampler { namespace gig { Line 139  namespace LinuxSampler { namespace gig {
139          itChildVoice    = Pool<Voice>::Iterator();          itChildVoice    = Pool<Voice>::Iterator();
140    
141          if (!pRegion) {          if (!pRegion) {
142              std::cerr << "gig::Voice: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;              dmsg(4, ("gig::Voice: No Region defined for MIDI key %d\n", MIDIKey));
             KillImmediately();  
143              return -1;              return -1;
144          }          }
145    
# Line 144  namespace LinuxSampler { namespace gig { Line 147  namespace LinuxSampler { namespace gig {
147    
148          // get current dimension values to select the right dimension region          // get current dimension values to select the right dimension region
149          //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
150          uint DimValues[5] = {0,0,0,0,0};          uint DimValues[8] = { 0 };
151          for (int i = pRegion->Dimensions - 1; i >= 0; i--) {          for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
152              switch (pRegion->pDimensionDefinitions[i].dimension) {              switch (pRegion->pDimensionDefinitions[i].dimension) {
153                  case ::gig::dimension_samplechannel:                  case ::gig::dimension_samplechannel:
# Line 168  namespace LinuxSampler { namespace gig { Line 171  namespace LinuxSampler { namespace gig {
171                      DimValues[i] = (uint) ReleaseTriggerVoice;                      DimValues[i] = (uint) ReleaseTriggerVoice;
172                      break;                      break;
173                  case ::gig::dimension_keyboard:                  case ::gig::dimension_keyboard:
174                      DimValues[i] = (uint) itNoteOnEvent->Param.Note.Key;                      DimValues[i] = (uint) pEngine->CurrentKeyDimension;
175                      break;                      break;
176                  case ::gig::dimension_modwheel:                  case ::gig::dimension_modwheel:
177                      DimValues[i] = pEngine->ControllerTable[1];                      DimValues[i] = pEngine->ControllerTable[1];
# Line 246  namespace LinuxSampler { namespace gig { Line 249  namespace LinuxSampler { namespace gig {
249                      std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;                      std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush;
250              }              }
251          }          }
252          pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);          pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
253    
254          pSample = pDimRgn->pSample; // sample won't change until the voice is finished          pSample = pDimRgn->pSample; // sample won't change until the voice is finished
255            if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent
256    
257          // select channel mode (mono or stereo)          // select channel mode (mono or stereo)
258          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);          SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
# Line 308  namespace LinuxSampler { namespace gig { Line 312  namespace LinuxSampler { namespace gig {
312    
313          // calculate initial pitch value          // calculate initial pitch value
314          {          {
315              double pitchbasecents = pDimRgn->FineTune * 10 + (int) pEngine->ScaleTuning[MIDIKey % 12];              double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
316              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;              if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
317              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));              this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate()));
318              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents              this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
# Line 693  namespace LinuxSampler { namespace gig { Line 697  namespace LinuxSampler { namespace gig {
697                          }                          }
698                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));                          DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos));
699                          Pos -= int(Pos);                          Pos -= int(Pos);
700                            RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
701                      }                      }
702    
703                      const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();                      const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
# Line 701  namespace LinuxSampler { namespace gig { Line 706  namespace LinuxSampler { namespace gig {
706                      if (DiskStreamRef.State == Stream::state_end) {                      if (DiskStreamRef.State == Stream::state_end) {
707                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm                          const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
708                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {                          if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
709                                // remember how many sample words there are before any silence has been added
710                                if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
711                              DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);                              DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
712                          }                          }
713                      }                      }
# Line 716  namespace LinuxSampler { namespace gig { Line 723  namespace LinuxSampler { namespace gig {
723                      Pos -= iPos; // just keep fractional part of Pos                      Pos -= iPos; // just keep fractional part of Pos
724    
725                      // change state of voice to 'end' if we really reached the end of the sample data                      // change state of voice to 'end' if we really reached the end of the sample data
726                      if (DiskStreamRef.State == Stream::state_end && readSampleWords >= sampleWordsLeftToRead) this->PlaybackState = playback_state_end;                      if (RealSampleWordsLeftToRead >= 0) {
727                            RealSampleWordsLeftToRead -= readSampleWords;
728                            if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
729                        }
730                  }                  }
731                  break;                  break;
732    
# Line 979  namespace LinuxSampler { namespace gig { Line 989  namespace LinuxSampler { namespace gig {
989       *  @param pSrc    - pointer to input sample data       *  @param pSrc    - pointer to input sample data
990       *  @param Skip    - number of sample points to skip in output buffer       *  @param Skip    - number of sample points to skip in output buffer
991       */       */
992      void Voice::Synthesize(uint Samples, sample_t* pSrc, int Skip) {      void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
993          UpdateSynthesisMode();          RunSynthesisFunction(SynthesisMode, *this, Samples, pSrc, Skip);
         SynthesizeFragment_Fn* f = (SynthesizeFragment_Fn*) SynthesizeFragmentFnPtr;  
         f(*this, Samples, pSrc, Skip);  
     }  
   
     /**  
      *  Determine the respective synthesis function for the given synthesis  
      *  mode.  
      */  
     void Voice::UpdateSynthesisMode() {  
         SynthesizeFragmentFnPtr = GetSynthesisFunction(SynthesisMode);  
994      }      }
995    
996      /**      /**

Legend:
Removed from v.324  
changed lines
  Added in v.354

  ViewVC Help
Powered by ViewVC