double GetStateLength(double inp, EnvelopeTimeScale scale)
 {
     if (scale == EnvelopeTimeScale.Long)
     {
         inp *= 10;
     }
     return((inp * 200) + 1);
 }
        public double Get(out double linear, double attack, double decay, double sustain, double release, double curvature, EnvelopeTimeScale timeScale, EnvelopeMode envMode)
        {
            if (CurrentState != State.InActive)
            {
                StateTime++;
            }
            switch (CurrentState)
            {
            case State.Attack:
            {
                double L = GetStateLength(attack, timeScale);
                double P = StateTime / L;

                Value += 1.0 / L;
                if (Value >= 1)
                {
                    Value        = 1.0;
                    DecayStart   = 1.0;
                    CurrentState = State.Decay;
                    StateTime    = 0;
                }
                linear = Value;
                return(Curved(Value, curvature));
            }

            case State.Decay:
            {
                double L = GetStateLength(decay, timeScale);
                double P = StateTime / L;

                Value -= 1.0 / L;
                if (Value <= sustain)
                {
                    Value = sustain;

                    if (envMode == EnvelopeMode.Trigger || envMode == EnvelopeMode.Loop)
                    {
                        ReleaseStart = Value;
                        CurrentState = State.Release;
                        StateTime    = 0;
                    }
                    else
                    {
                        CurrentState = State.Sustain;
                        StateTime    = 0;
                    }
                }
                linear = Value;
                return(sustain + Curved((Value - sustain) / (DecayStart - sustain), curvature) * (1 - sustain));
            }

            case State.Sustain:
            {
                StateTime = 0;
                linear    = sustain;
                return(sustain);
            }

            case State.Release:
            {
                double L = GetStateLength(release, timeScale);
                double P = StateTime / L;

                Value -= 1.0 / L;

                if (Value <= 0)
                {
                    Value = 0;

                    if (envMode == EnvelopeMode.Loop && Trigger)
                    {
                        CurrentState = State.Attack;
                        StateTime    = 0;
                    }
                    else
                    {
                        CurrentState = State.InActive;
                        StateTime    = 0;
                    }
                }
                linear = Value;
                return(Curved(Value / (1 - sustain), curvature) * sustain);
            }

            case State.InActive: linear = 0; return(0);
            }
            linear = 0;
            return(0);
        }