/[svn]/linuxsampler/trunk/src/voice.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/voice.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 32 by schoenebeck, Tue Feb 3 13:21:19 2004 UTC revision 33 by schoenebeck, Mon Feb 16 19:30:42 2004 UTC
# Line 38  Voice::~Voice() { Line 38  Voice::~Voice() {
38   *  Initializes and triggers the voice, a disk stream will be launched if   *  Initializes and triggers the voice, a disk stream will be launched if
39   *  needed.   *  needed.
40   *   *
41   *  @param MIDIKey     - MIDI key number of the triggered key   *  @param pNoteOnEvent - event that caused triggering of this voice
42   *  @param Velocity    - MIDI velocity value of the triggered key   *  @param Pitch        - MIDI detune factor (-8192 ... +8191)
43   *  @param Pitch       - MIDI detune factor (-8192 ... +8191)   *  @param pInstrument  - points to the loaded instrument which provides sample wave(s) and articulation data
44   *  @param pInstrument - points to the loaded instrument which provides sample wave(s) and articulation data   *  @returns            0 on success, a value < 0 if something failed
  *  @param Delay       - number of sample points triggering should be delayed  
  *  @returns           0 on success, a value < 0 if something failed  
45   */   */
46  int Voice::Trigger(int MIDIKey, uint8_t Velocity, int Pitch, gig::Instrument* pInstrument, uint Delay) {  int Voice::Trigger(ModulationSystem::Event* pNoteOnEvent, int Pitch, gig::Instrument* pInstrument) {
47      Active                = true;      Active          = true;
48      this->MIDIKey         = MIDIKey;      MIDIKey         = pNoteOnEvent->Key;
49      pRegion               = pInstrument->GetRegion(MIDIKey);      pRegion         = pInstrument->GetRegion(MIDIKey);
50      PlaybackState         = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed      PlaybackState   = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
51      Pos                   = 0;      Pos             = 0;
52      ReleaseVelocity       = 127; // default release velocity value      ReleaseVelocity = 127; // default release velocity value
53      this->Delay           = Delay;      Delay           = pNoteOnEvent->FragmentPos();
54      ReleaseSignalReceived = false;      pTriggerEvent   = pNoteOnEvent;
55    
56      if (!pRegion) {      if (!pRegion) {
57          std::cerr << "Audio Thread: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;          std::cerr << "Audio Thread: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush;
# Line 66  int Voice::Trigger(int MIDIKey, uint8_t Line 64  int Voice::Trigger(int MIDIKey, uint8_t
64      for (int i = pRegion->Dimensions - 1; i >= 0; i--) { // Check if instrument has a velocity split      for (int i = pRegion->Dimensions - 1; i >= 0; i--) { // Check if instrument has a velocity split
65          if (pRegion->pDimensionDefinitions[i].dimension == gig::dimension_velocity) {          if (pRegion->pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
66              uint DimValues[5] = {0,0,0,0,0};              uint DimValues[5] = {0,0,0,0,0};
67                   DimValues[i] = Velocity;                   DimValues[i] = pNoteOnEvent->Velocity;
68              pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);              pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]);
69              break;              break;
70          }          }
# Line 113  int Voice::Trigger(int MIDIKey, uint8_t Line 111  int Voice::Trigger(int MIDIKey, uint8_t
111      this->Pitch = ((double) Pitch / 8192.0) / 12.0 + (pDimRgn->PitchTrack) ? pow(2, ((double) (MIDIKey - (int) pDimRgn->UnityNote) + (double) pDimRgn->FineTune / 100.0) / 12.0)      this->Pitch = ((double) Pitch / 8192.0) / 12.0 + (pDimRgn->PitchTrack) ? pow(2, ((double) (MIDIKey - (int) pDimRgn->UnityNote) + (double) pDimRgn->FineTune / 100.0) / 12.0)
112                                                                             : pow(2, ((double) pDimRgn->FineTune / 100.0) / 12.0);                                                                             : pow(2, ((double) pDimRgn->FineTune / 100.0) / 12.0);
113    
114      Volume = pDimRgn->GetVelocityAttenuation(Velocity);      Volume = pDimRgn->GetVelocityAttenuation(pNoteOnEvent->Velocity);
115    
116      EG1.Trigger(pDimRgn->EG1PreAttack, pDimRgn->EG1Attack, pDimRgn->EG1Release, Delay);      EG1.Trigger(pDimRgn->EG1PreAttack,
117                    pDimRgn->EG1Attack,
118                    pDimRgn->EG1Hold,
119                    pSample->LoopStart,
120                    pDimRgn->EG1Decay1,
121                    pDimRgn->EG1Decay2,
122                    pDimRgn->EG1InfiniteSustain,
123                    pDimRgn->EG1Sustain,
124                    pDimRgn->EG1Release,
125                    Delay);
126    
127      // ************************************************      // ************************************************
128      // TODO: ARTICULATION DATA HANDLING IS MISSING HERE      // TODO: ARTICULATION DATA HANDLING IS MISSING HERE
# Line 147  void Voice::Render(uint Samples) { Line 154  void Voice::Render(uint Samples) {
154    
155    
156      // Let all modulators throw their parameter changes for the current audio fragment      // Let all modulators throw their parameter changes for the current audio fragment
157      EG1.Process(Samples);      EG1.Process(Samples, pEngine->pMIDIKeyInfo[MIDIKey].pEvents, pTriggerEvent, this->Pos, this->Pitch);
158    
159    
160      switch (this->PlaybackState) {      switch (this->PlaybackState) {
# Line 203  void Voice::Render(uint Samples) { Line 210  void Voice::Render(uint Samples) {
210      // Reset delay      // Reset delay
211      Delay = 0;      Delay = 0;
212    
213        pTriggerEvent = NULL;
214    
215      // If release stage finished, let the voice be killed      // If release stage finished, let the voice be killed
216      if (EG1.GetStage() == EG_VCA::stage_end) this->PlaybackState = playback_state_end;      if (EG1.GetStage() == EG_VCA::stage_end) this->PlaybackState = playback_state_end;
# Line 357  void Voice::Kill() { Line 365  void Voice::Kill() {
365      DiskStreamRef.OrderID = 0;      DiskStreamRef.OrderID = 0;
366      Active = false;      Active = false;
367  }  }
   
 /**  
  *  Release the voice in an appropriate time range, the voice will go through  
  *  it's release stage before it will be killed.  
  *  
  *  @param Delay - number of sample points releasing should be delayed (for jitter correction)  
  */  
 void Voice::Release(uint Delay) {  
    if (!ReleaseSignalReceived) {  
        EG1.Release(Delay);  
        ReleaseSignalReceived = true;  
    }  
 }  

Legend:
Removed from v.32  
changed lines
  Added in v.33

  ViewVC Help
Powered by ViewVC