void EnterStage(EnvelopStage newStage) { FCurrentStage = newStage; CurrentStage.Value = (int)FCurrentStage; FCurrentSampleIndex = 0; switch (FCurrentStage) { case EnvelopStage.Off: FNextStageSampleIndex = 0; FCurrentLevel = 0.0; FMultiplier = 1.0; break; case EnvelopStage.Attack: FNextStageSampleIndex = (int)(Math.Max(Attack.Value, 0.0f) * SampleRate); FCurrentLevel = CMinimumLevel; FMultiplier = CalcExpCoeff(FCurrentLevel, 1.0, FNextStageSampleIndex); break; case EnvelopStage.Decay: FNextStageSampleIndex = (int)(Decay.Value * SampleRate); FCurrentLevel = 1.0; FMultiplier = CalcExpCoeff(FCurrentLevel, Math.Max(Math.Max(Sustain.Value, 0.0f), CMinimumLevel), FNextStageSampleIndex); break; case EnvelopStage.Sustain: FCurrentLevel = Sustain.Value; FMultiplier = 1 + Slope.Value * 0.0001; FNextStageSampleIndex = 0; break; case EnvelopStage.Release: FNextStageSampleIndex = (int)(Math.Max(Release.Value, 0.0f) * SampleRate); // We could go from ATTACK/DECAY to RELEASE, // so we're not changing currentLevel here. FMultiplier = CalcExpCoeff(FCurrentLevel, CMinimumLevel, FNextStageSampleIndex); break; } }