You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.9 KiB
92 lines
2.9 KiB
#pragma once
|
|
#ifndef ADENV_H
|
|
#define ADENV_H
|
|
#include <stdint.h>
|
|
#ifdef __cplusplus
|
|
|
|
namespace daisysp
|
|
{
|
|
/** Distinct stages that the phase of the envelope can be located in.
|
|
@see AdEnv
|
|
*/
|
|
enum AdEnvSegment
|
|
{
|
|
/** located at phase location 0, and not currently running */
|
|
ADENV_SEG_IDLE,
|
|
/** First segment of envelope where phase moves from MIN value to MAX value */
|
|
ADENV_SEG_ATTACK,
|
|
/** Second segment of envelope where phase moves from MAX to MIN value */
|
|
ADENV_SEG_DECAY,
|
|
/** The final segment of the envelope (currently decay) */
|
|
ADENV_SEG_LAST,
|
|
};
|
|
|
|
/** Trigger-able envelope with adjustable min/max, and independent per-segment time control.
|
|
|
|
\author shensley
|
|
\todo - Add Cycling
|
|
\todo - Implement Curve (its only linear for now).
|
|
\todo - Maybe make this an ADsr_ that has AD/AR/Asr_ modes.
|
|
*/
|
|
class AdEnv
|
|
{
|
|
public:
|
|
AdEnv() {}
|
|
~AdEnv() {}
|
|
/** Initializes the ad envelope.
|
|
|
|
Defaults:
|
|
- current segment = idle
|
|
- curve = linear
|
|
- phase = 0
|
|
- min = 0
|
|
- max = 1
|
|
|
|
\param sample_rate sample rate of the audio engine being run
|
|
*/
|
|
void Init(float sample_rate);
|
|
|
|
/** Processes the current sample of the envelope. This should be called once
|
|
per sample period.
|
|
\return the current envelope value.
|
|
*/
|
|
float Process();
|
|
|
|
/** Starts or retriggers the envelope.*/
|
|
inline void Trigger() { trigger_ = 1; }
|
|
/** Sets the length of time (in seconds) for a specific segment. */
|
|
inline void SetTime(uint8_t seg, float time) { segment_time_[seg] = time; }
|
|
/** Sets the amount of curve applied. A positve value will create a log
|
|
curve. Input range: -100 to 100. (or more)
|
|
*/
|
|
inline void SetCurve(float scalar) { curve_scalar_ = scalar; }
|
|
/** Sets the minimum value of the envelope output.
|
|
Input range: -FLTmax_, to FLTmax_
|
|
*/
|
|
inline void SetMin(float min) { min_ = min; }
|
|
/** Sets the maximum value of the envelope output.
|
|
Input range: -FLTmax_, to FLTmax_
|
|
*/
|
|
inline void SetMax(float max) { max_ = max; }
|
|
/** Returns the current output value without processing the next sample */
|
|
inline float GetValue() const { return (output_ * (max_ - min_)) + min_; }
|
|
/** Returns the segment of the envelope that the phase is currently located
|
|
in.
|
|
*/
|
|
inline uint8_t GetCurrentSegment() { return current_segment_; }
|
|
/** Returns true if the envelope is currently in any stage apart from idle.
|
|
*/
|
|
inline bool IsRunning() const { return current_segment_ != ADENV_SEG_IDLE; }
|
|
|
|
private:
|
|
uint8_t current_segment_, prev_segment_;
|
|
float segment_time_[ADENV_SEG_LAST];
|
|
float sample_rate_, min_, max_, output_, curve_scalar_;
|
|
float c_inc_, curve_x_, retrig_val_;
|
|
uint32_t phase_;
|
|
uint8_t trigger_;
|
|
};
|
|
|
|
} // namespace daisysp
|
|
#endif
|
|
#endif
|
|
|