/[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 31 by schoenebeck, Sun Jan 18 20:31:31 2004 UTC revision 32 by schoenebeck, Tue Feb 3 13:21:19 2004 UTC
# Line 30  EG_VCA::EG_VCA() { Line 30  EG_VCA::EG_VCA() {
30  /**  /**
31   * Will be called by the voice for every audio fragment to let the EG   * Will be called by the voice for every audio fragment to let the EG
32   * queue it's modulation changes for the current audio fragment.   * queue it's modulation changes for the current audio fragment.
33     *
34     * @param Samples - total number of sample points to be rendered in this
35     *                  audio fragment cycle by the audio engine
36   */   */
37  void EG_VCA::Process(uint Samples) {  void EG_VCA::Process(uint Samples) {
38      if (Stage == stage_sustain) return; // nothing to do      if (Stage == stage_sustain && !ReleaseSignalReceived) return; // nothing to do
39    
40      for (int to_process_total = Samples; to_process_total;) {      int iSample = TriggerDelay;
41          int iSample = 0;      while (iSample < Samples) {
42          switch (Stage) {          switch (Stage) {
43              case stage_attack: {              case stage_attack: {
44                  int to_process    = Min(to_process_total, AttackStepsLeft);                  int to_process    = Min(Samples - iSample, AttackStepsLeft);
45                  int process_end   = iSample + to_process;                  int process_end   = iSample + to_process;
46                  AttackStepsLeft  -= to_process;                  AttackStepsLeft  -= to_process;
47                  to_process_total -= to_process;                  while (iSample < process_end) {
                 for (; iSample < process_end; iSample++) {  
48                      Level += AttackCoeff;                      Level += AttackCoeff;
49                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample] *= Level;                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample++] *= Level;
                 }  
                 if (!AttackStepsLeft) {  
                     Stage = (ReleaseSignalReceived) ? stage_release : stage_sustain;  
50                  }                  }
51                    TriggerDelay = 0;
52                    if (!AttackStepsLeft) Stage = (ReleaseSignalReceived) ? stage_release : stage_sustain;
53                  break;                  break;
54              }              }
55              case stage_sustain: {              case stage_sustain: {
56                  return;                  if (!ReleaseSignalReceived) return; // nothing to do
57                    Stage = stage_release;
58                    break;
59              }              }
60              case stage_release: {              case stage_release: {
61                  int process_end = iSample + to_process_total;                  iSample = ReleaseDelay;
62                  for (; iSample < process_end; iSample++) {                  while (iSample < Samples) {
63                      Level -= Level * ReleaseCoeff;                      Level -= Level * ReleaseCoeff;
64                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample] *= Level;                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample++] *= Level;
65                  }                  }
66                  if (Level <= EG_ENVELOPE_LIMIT) Stage = stage_end;                  if (Level <= EG_ENVELOPE_LIMIT) Stage = stage_end;
67                    ReleaseDelay = 0;
68                  return;                  return;
69              }              }
70              case stage_end: {              case stage_end: {
71                  int process_end = iSample + to_process_total;                  while (iSample < Samples) {
72                  for (; iSample < process_end; iSample++) {                      ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample++] *= Level;
                     ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample] *= Level;  
73                  }                  }
74                  return;                  return;
75              }              }
# Line 80  void EG_VCA::Process(uint Samples) { Line 83  void EG_VCA::Process(uint Samples) {
83   * @param PreAttack   - Preattack value for the envelope (0 - 1000 permille)   * @param PreAttack   - Preattack value for the envelope (0 - 1000 permille)
84   * @param AttackTime  - Attack time for the envelope (0.000 - 60.000s)   * @param AttackTime  - Attack time for the envelope (0.000 - 60.000s)
85   * @param ReleaseTIme - Release time for the envelope (0.000 - 60.000s)   * @param ReleaseTIme - Release time for the envelope (0.000 - 60.000s)
86     * @param Delay       - number of sample points triggering should be delayed
87   */   */
88  void EG_VCA::Trigger(uint PreAttack, double AttackTime, double ReleaseTime) {  void EG_VCA::Trigger(uint PreAttack, double AttackTime, double ReleaseTime, uint Delay) {
89      ReleaseSignalReceived = false;      ReleaseSignalReceived = false;
90        TriggerDelay = Delay;
91      Stage = stage_attack;      Stage = stage_attack;
92    
93      // calculate attack stage parameters      // calculate attack stage parameters
94      AttackStepsLeft = (long) (AttackTime * ModulationSystem::GetSampleRate());      AttackStepsLeft = (long) (AttackTime * ModulationSystem::SampleRate());
95      if (AttackStepsLeft) {      if (AttackStepsLeft) {
96          Level       = PreAttack;          Level       = PreAttack;
97          AttackCoeff = (1.0 - PreAttack) / AttackStepsLeft;          AttackCoeff = (1.0 - PreAttack) / AttackStepsLeft;
# Line 98  void EG_VCA::Trigger(uint PreAttack, dou Line 103  void EG_VCA::Trigger(uint PreAttack, dou
103    
104      // calcuate release stage parameters      // calcuate release stage parameters
105      if (ReleaseTime < EG_MIN_RELEASE_TIME) ReleaseTime = EG_MIN_RELEASE_TIME;  // to avoid click sounds at the end of the sample playback      if (ReleaseTime < EG_MIN_RELEASE_TIME) ReleaseTime = EG_MIN_RELEASE_TIME;  // to avoid click sounds at the end of the sample playback
106      ReleaseStepsLeft = (long) (ReleaseTime * ModulationSystem::GetSampleRate());      ReleaseStepsLeft = (long) (ReleaseTime * ModulationSystem::SampleRate());
107      ReleaseCoeff     = 1.0 - exp(log(EG_ENVELOPE_LIMIT) / (double) ReleaseStepsLeft);      ReleaseCoeff     = 1.0 - exp(log(EG_ENVELOPE_LIMIT) / (double) ReleaseStepsLeft);
108    
109      dmsg(4,("AttackLength=%d, ReleaseLength=%d",AttackStepsLeft,ReleaseStepsLeft));      dmsg(4,("AttackLength=%d, ReleaseLength=%d",AttackStepsLeft,ReleaseStepsLeft));
# Line 106  void EG_VCA::Trigger(uint PreAttack, dou Line 111  void EG_VCA::Trigger(uint PreAttack, dou
111    
112  /**  /**
113   * Will be called by the voice when the key / voice was released.   * Will be called by the voice when the key / voice was released.
114     *
115     * @param Delay - number of sample points the release stage should be delayed
116   */   */
117  void EG_VCA::Release() {  void EG_VCA::Release(uint Delay) {
     // postpone release stage until sustain stage reached  
     if (Stage == stage_sustain) Stage = stage_release;  
118      ReleaseSignalReceived = true;      ReleaseSignalReceived = true;
119        ReleaseDelay          = Delay;
120  }  }

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

  ViewVC Help
Powered by ViewVC