Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. //------------------------------------------------------------------------------------------------------------------------------------------
  2. // Get the phase parameters for the given envelope, phase and current envelope level
  3. //------------------------------------------------------------------------------------------------------------------------------------------
  4. static EnvPhaseParams getEnvPhaseParams(const AdsrEnvelope env, const EnvPhase phase, const int16_t envLevel) noexcept {
  5.     // Envelope level shouldn't be negative, but just in case...
  6.     const int32_t absEnvLevel = std::abs((int32_t) envLevel);
  7.  
  8.     // Gather basic info for the envelope phase
  9.     int32_t     targetLevel;
  10.     int32_t     stepUnscaled;
  11.     uint32_t    stepScale;
  12.     bool        bExponential;
  13.  
  14.     switch (phase) {
  15.         // Attack phase: ramps up to the maximum volume always
  16.         case EnvPhase::Attack: {
  17.             targetLevel = MAX_ENV_LEVEL;
  18.             stepScale = env.attackShift;
  19.             stepUnscaled = 7 - (int32_t) env.attackStep;
  20.             bExponential = env.bAttackExp;
  21.         }   break;
  22.  
  23.         // Decay phase: ramps down to the sustain level and always exponentially
  24.         case EnvPhase::Decay: {
  25.             targetLevel = std::min<int32_t>(((int32_t) env.sustainLevel + 1) * 2048, MAX_ENV_LEVEL);
  26.             stepScale = env.decayShift;
  27.             stepUnscaled = -8;
  28.             bExponential = true;
  29.         }   break;
  30.  
  31.         // Sustain phase: has no target level (-1, lasts forever) and can ramp up or down
  32.         case EnvPhase::Sustain: {
  33.             targetLevel = -1;
  34.             stepScale = env.sustainShift;
  35.             stepUnscaled = (env.bSustainDec) ? (int32_t) env.sustainStep - 8 : 7 - (int32_t) env.sustainStep;
  36.             bExponential = env.bSustainExp;
  37.         }   break;
  38.  
  39.         // Release, off or unknown phase: fade out to zero
  40.         case EnvPhase::Release:
  41.         case EnvPhase::Off:
  42.         default: {
  43.             targetLevel = MIN_ENV_LEVEL;
  44.             stepScale = env.releaseShift;
  45.             stepUnscaled = -8;
  46.             bExponential = env.bReleaseExp;
  47.         }   break;
  48.     }
  49.  
  50.     // Scale the step accordingly and decide how many cycles an envelope step takes
  51.     const int32_t stepScaleMultiplier = 1 << std::max<int32_t>(0, 11 - stepScale);
  52.  
  53.     EnvPhaseParams params;
  54.     params.targetLevel = targetLevel;
  55.     params.stepCycles = 1 << std::max<int32_t>(0, stepScale - 11);
  56.     params.step = stepUnscaled * stepScaleMultiplier;
  57.  
  58.     if (bExponential) {
  59.         // Adjustments based on the current envelope level when the envelope mode is 'exponential'.
  60.         // Slower fade-outs as the envelope level decreases & 4x slower fade-ins when envelope level surpasses '0x6000'.
  61.         if ((stepUnscaled > 0) && (absEnvLevel > 0x6000)) {
  62.             params.stepCycles *= 4;
  63.         }
  64.         else if (stepUnscaled < 0) {
  65.             params.step = (int32_t)(((int64_t) params.step * absEnvLevel) >> 15);
  66.         }
  67.     }
  68.  
  69.     return params;
  70. }
  71.  
  72. //------------------------------------------------------------------------------------------------------------------------------------------
  73. // Step the ADSR envelope for the given voice
  74. //------------------------------------------------------------------------------------------------------------------------------------------
  75. static void stepVoiceEnvelope(Voice& voice) noexcept {
  76.     // Don't process the envelope if we must wait a few more cycles
  77.     if (voice.envWaitCycles > 0) {
  78.         voice.envWaitCycles--;
  79.  
  80.         if (voice.envWaitCycles > 0)
  81.             return;
  82.     }
  83.  
  84.     // Step the envelope in it's current phase and compute the new envelope level
  85.     const EnvPhaseParams envParams = getEnvPhaseParams(voice.env, voice.envPhase, voice.envLevel);
  86.     int32_t newEnvLevel = std::clamp<int32_t>(voice.envLevel + envParams.step, MIN_ENV_LEVEL, MAX_ENV_LEVEL);
  87.  
  88.     // Do state transitions when ramping up or down, unless we're in the 'sustain' phase (targetLevel < 0)
  89.     bool bReachedTargetLevel = false;
  90.  
  91.     if (envParams.targetLevel >= 0) {
  92.         if (envParams.step > 0) {
  93.             bReachedTargetLevel = (newEnvLevel >= envParams.targetLevel);
  94.         } else if (envParams.step < 0) {
  95.             bReachedTargetLevel = (newEnvLevel <= envParams.targetLevel);
  96.         }
  97.     }
  98.  
  99.     if (bReachedTargetLevel) {
  100.         newEnvLevel = envParams.targetLevel;
  101.         voice.envPhase = getNextEnvPhase(voice.envPhase);
  102.         voice.envWaitCycles = 0;
  103.     } else {
  104.         voice.envWaitCycles = envParams.stepCycles;
  105.     }
  106.  
  107.     voice.envLevel = (int16_t) newEnvLevel;
  108. }