Skip to content

File adsr.h

File List > Control > adsr.h

Go to the documentation of this file

Source Code

/*
Copyright (c) 2020 Electrosmith, Corp, Paul Batchelor

Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/

#pragma once
#ifndef DSY_ADSR_H
#define DSY_ADSR_H

#include <stdint.h>
#ifdef __cplusplus

namespace daisysp
{
enum
{
    ADSR_SEG_IDLE    = 0,
    ADSR_SEG_ATTACK  = 1,
    ADSR_SEG_DECAY   = 2,
    ADSR_SEG_RELEASE = 4
};


class Adsr
{
  public:
    Adsr() {}
    ~Adsr() {}
    void Init(float sample_rate, int blockSize = 1);
    void Retrigger(bool hard);
    float Process(bool gate);
    void SetTime(int seg, float time);
    void SetAttackTime(float timeInS, float shape = 0.0f);
    void SetDecayTime(float timeInS);
    void SetReleaseTime(float timeInS);

  private:
    void SetTimeConstant(float timeInS, float& time, float& coeff);

  public:
    inline void SetSustainLevel(float sus_level)
    {
        sus_level = (sus_level <= 0.f) ? -0.01f // forces envelope into idle
                                       : (sus_level > 1.f) ? 1.f : sus_level;
        sus_level_ = sus_level;
    }
    inline uint8_t GetCurrentSegment() { return mode_; }
    inline bool IsRunning() const { return mode_ != ADSR_SEG_IDLE; }

  private:
    float   sus_level_{0.f};
    float   x_{0.f};
    float   attackShape_{-1.f};
    float   attackTarget_{0.0f};
    float   attackTime_{-1.0f};
    float   decayTime_{-1.0f};
    float   releaseTime_{-1.0f};
    float   attackD0_{0.f};
    float   decayD0_{0.f};
    float   releaseD0_{0.f};
    int     sample_rate_;
    uint8_t mode_{ADSR_SEG_IDLE};
    bool    gate_{false};
};
} // namespace daisysp
#endif
#endif