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

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

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

revision 36 by schoenebeck, Mon Feb 16 19:30:42 2004 UTC revision 37 by schoenebeck, Wed Mar 10 22:01:36 2004 UTC
# Line 41  EG_VCA::EG_VCA() { Line 41  EG_VCA::EG_VCA() {
41   * @param CurrentPitch  - current pitch value for playback   * @param CurrentPitch  - current pitch value for playback
42   */   */
43  void EG_VCA::Process(uint Samples, RTEList<ModulationSystem::Event>* pEvents, ModulationSystem::Event* pTriggerEvent, double SamplePos, double CurrentPitch) {  void EG_VCA::Process(uint Samples, RTEList<ModulationSystem::Event>* pEvents, ModulationSystem::Event* pTriggerEvent, double SamplePos, double CurrentPitch) {
44      ModulationSystem::Event* pReleaseTransitionEvent;      ModulationSystem::Event* pTransitionEvent;
45      if (pTriggerEvent) {      if (pTriggerEvent) {
46          pEvents->set_current(pTriggerEvent);          pEvents->set_current(pTriggerEvent);
47          pReleaseTransitionEvent = pEvents->next();          pTransitionEvent = pEvents->next();
48      }      }
49      else {      else {
50          pReleaseTransitionEvent = pEvents->first();          pTransitionEvent = pEvents->first();
51      }      }
52    
53      int iSample = TriggerDelay;      int iSample = TriggerDelay;
54      while (iSample < Samples) {      while (iSample < Samples) {
55          switch (Stage) {          switch (Stage) {
56              case stage_attack: {              case stage_attack: {
57                    TriggerDelay = 0;
58                  int to_process   = Min(Samples - iSample, AttackStepsLeft);                  int to_process   = Min(Samples - iSample, AttackStepsLeft);
59                  int process_end  = iSample + to_process;                  int process_end  = iSample + to_process;
60                  AttackStepsLeft -= to_process;                  AttackStepsLeft -= to_process;
61                  while (iSample < process_end) {                  while (iSample < process_end) {
62                      Level += AttackCoeff;                      Level += AttackCoeff;
63                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample++] *= Level;                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample++] *= Level;
64                  }                  }                                
                 TriggerDelay = 0;  
                 if (!AttackStepsLeft) Stage = (HoldAttack) ? stage_attack_hold : stage_decay1;  
65                  if (iSample == Samples) { // postpone last transition event for the next audio fragment                  if (iSample == Samples) { // postpone last transition event for the next audio fragment
66                      ModulationSystem::Event* pLastEvent = pEvents->last();                      ModulationSystem::Event* pLastEvent = pEvents->last();
67                      if (pLastEvent) ReleasePostponed = (pLastEvent->Type == ModulationSystem::event_type_release);                      if (pLastEvent) ReleasePostponed = (pLastEvent->Type == ModulationSystem::event_type_release);
68                  }                  }
69                    if (!AttackStepsLeft) Stage = (ReleasePostponed) ? stage_release : (HoldAttack) ? stage_attack_hold : stage_decay1;
70                  break;                  break;
71              }              }
72              case stage_attack_hold: {              case stage_attack_hold: {
# Line 75  void EG_VCA::Process(uint Samples, RTELi Line 75  void EG_VCA::Process(uint Samples, RTELi
75                      break;                      break;
76                  }                  }
77                  int holdstepsleft = (int) (LoopStart - SamplePos / CurrentPitch); // FIXME: just an approximation, inaccuracy grows with higher audio fragment size, sufficient for usual fragment sizes though                  int holdstepsleft = (int) (LoopStart - SamplePos / CurrentPitch); // FIXME: just an approximation, inaccuracy grows with higher audio fragment size, sufficient for usual fragment sizes though
78                  int to_process    = Min(Samples - iSample, holdstepsleft);                  int to_process    = Min(Samples - iSample, holdstepsleft);                                                                
79                  int process_end   = iSample + to_process;                  int process_end   = iSample + to_process;                
80                    if (pTransitionEvent && pTransitionEvent->FragmentPos() <= process_end) {
81                        process_end      = pTransitionEvent->FragmentPos();                    
82                        Stage            = (pTransitionEvent->Type == ModulationSystem::event_type_release) ? stage_release : (InfiniteSustain) ? stage_sustain : stage_decay2;
83                        pTransitionEvent = pEvents->next();
84                    }
85                    else if (to_process == holdstepsleft) Stage = stage_decay1;                
86                  while (iSample < process_end) {                  while (iSample < process_end) {
87                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample++] *= Level;                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample++] *= Level;
88                  }                  }                
                 if (to_process == holdstepsleft) Stage = stage_decay1;  
                 if (iSample == Samples) { // postpone last transition event for the next audio fragment  
                     ModulationSystem::Event* pLastEvent = pEvents->last();  
                     if (pLastEvent) ReleasePostponed = (pLastEvent->Type == ModulationSystem::event_type_release);  
                 }  
89                  break;                  break;
90              }              }
91              case stage_decay1: {              case stage_decay1: {
92                  int to_process   = Min(Samples - iSample, Decay1StepsLeft);                  int to_process   = Min(Samples - iSample, Decay1StepsLeft);
93                  int process_end  = iSample + to_process;                  int process_end  = iSample + to_process;
94                  Decay1StepsLeft -= to_process;                  if (pTransitionEvent && pTransitionEvent->FragmentPos() <= process_end) {
95                        process_end      = pTransitionEvent->FragmentPos();                    
96                        Stage            = (pTransitionEvent->Type == ModulationSystem::event_type_release) ? stage_release : (InfiniteSustain) ? stage_sustain : stage_decay2;
97                        pTransitionEvent = pEvents->next();
98                    }
99                    else {
100                        Decay1StepsLeft -= to_process;
101                        if (!Decay1StepsLeft) Stage = (InfiniteSustain) ? stage_sustain : stage_decay2;
102                    }
103                  while (iSample < process_end) {                  while (iSample < process_end) {
104                      Level += Decay1Coeff;                      Level += Decay1Coeff;
105                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample++] *= Level;                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample++] *= Level;
106                  }                  }                
                 if (iSample == Samples) { // postpone last transition event for the next audio fragment  
                     ModulationSystem::Event* pLastEvent = pEvents->last();  
                     if (pLastEvent) ReleasePostponed = (pLastEvent->Type == ModulationSystem::event_type_release);  
                 }  
                 if (!Decay1StepsLeft) {  
                     Stage = (ReleasePostponed) ? stage_release  
                                                : (InfiniteSustain) ? stage_sustain  
                                                                    : stage_decay2;  
                 }  
107                  break;                  break;
108              }              }
109              case stage_decay2: {              case stage_decay2: {
110                  int process_end;                  int process_end;
111                  if (pReleaseTransitionEvent && pReleaseTransitionEvent->Type == ModulationSystem::event_type_release) {                  if (pTransitionEvent && pTransitionEvent->Type == ModulationSystem::event_type_release) {
112                      process_end             = pReleaseTransitionEvent->FragmentPos();                      process_end      = pTransitionEvent->FragmentPos();
113                      pReleaseTransitionEvent = pEvents->next();                      pTransitionEvent = pEvents->next();
114                      Stage                   = stage_release; // switch to release stage soon                      Stage            = stage_release; // switch to release stage soon
115                  }                  }
116                  else process_end = Samples;                  else process_end = Samples;
117                  while (iSample < process_end) {                  while (iSample < process_end) {
# Line 123  void EG_VCA::Process(uint Samples, RTELi Line 123  void EG_VCA::Process(uint Samples, RTELi
123              }              }
124              case stage_sustain: {              case stage_sustain: {
125                  int process_end;                  int process_end;
126                  if (pReleaseTransitionEvent && pReleaseTransitionEvent->Type == ModulationSystem::event_type_release) {                  if (pTransitionEvent && pTransitionEvent->Type == ModulationSystem::event_type_release) {
127                      process_end             = pReleaseTransitionEvent->FragmentPos();                      process_end      = pTransitionEvent->FragmentPos();
128                      pReleaseTransitionEvent = pEvents->next();                      pTransitionEvent = pEvents->next();
129                      Stage                   = stage_release; // switch to release stage soon                      Stage            = stage_release; // switch to release stage soon
130                  }                  }
131                  else process_end = Samples;                  else process_end = Samples;
132                  while (iSample < process_end) {                  while (iSample < process_end) {
# Line 136  void EG_VCA::Process(uint Samples, RTELi Line 136  void EG_VCA::Process(uint Samples, RTELi
136              }              }
137              case stage_release: {              case stage_release: {
138                  int process_end;                  int process_end;
139                  if (pReleaseTransitionEvent && pReleaseTransitionEvent->Type == ModulationSystem::event_type_cancel_release) {                  if (pTransitionEvent && pTransitionEvent->Type == ModulationSystem::event_type_cancel_release) {
140                      process_end             = pReleaseTransitionEvent->FragmentPos();                      process_end      = pTransitionEvent->FragmentPos();
141                      pReleaseTransitionEvent = pEvents->next();                      pTransitionEvent = pEvents->next();
142                      Stage                   = (InfiniteSustain) ? stage_sustain : stage_decay2; // switch back to sustain / decay2 stage soon                      Stage            = (InfiniteSustain) ? stage_sustain : stage_decay2; // switch back to sustain / decay2 stage soon
143                  }                  }
144                  else process_end = Samples;                  else process_end = Samples;
145                  while (iSample < process_end) {                  while (iSample < process_end) {

Legend:
Removed from v.36  
changed lines
  Added in v.37

  ViewVC Help
Powered by ViewVC