f@0
|
1 #pragma once
|
f@0
|
2
|
f@0
|
3 namespace collidoscope {
|
f@0
|
4
|
f@2
|
5
|
f@2
|
6 /*
|
f@2
|
7 * An ASR envelope with linear shape. It is modeled after the STK envelope classes.
|
f@2
|
8 * The tick() method advances the computation of the envelope one sample and returns the computed sample
|
f@2
|
9 * The class is templated for the type of the samples that each tick of the envelope produces.
|
f@2
|
10 *
|
f@2
|
11 * Client classes can set/get the current state of the envelope with the
|
f@2
|
12 * respective getter/setter methods
|
f@2
|
13 *
|
f@2
|
14 */
|
f@0
|
15 template <typename T>
|
f@0
|
16 class EnvASR
|
f@0
|
17 {
|
f@0
|
18 public:
|
f@0
|
19
|
f@3
|
20 /** Possible states of the envelope. Idle means the envelope ouputs 0 */
|
f@0
|
21 enum class State {
|
f@0
|
22 eAttack,
|
f@0
|
23 eSustain,
|
f@0
|
24 eRelease,
|
f@0
|
25 eIdle // before attack after release
|
f@0
|
26 };
|
f@0
|
27
|
f@0
|
28 EnvASR( T sustainLevel, T attackTime, T releaseTime, std::size_t sampleRate ) :
|
f@0
|
29 mSustainLevel( sustainLevel ),
|
f@0
|
30 mState( State::eIdle ),
|
f@0
|
31 mValue( 0 )
|
f@0
|
32
|
f@0
|
33 {
|
f@0
|
34 if ( attackTime <= 0 )
|
f@0
|
35 attackTime = T( 0.001 );
|
f@0
|
36
|
f@0
|
37 if ( releaseTime <= 0 )
|
f@0
|
38 releaseTime = T( 0.001 );
|
f@0
|
39
|
f@0
|
40 mAttackRate = T( 1.0 ) / (attackTime * sampleRate);
|
f@0
|
41 mReleaseRate = T( 1.0 ) / (releaseTime * sampleRate);
|
f@0
|
42 }
|
f@0
|
43
|
f@3
|
44 /** Produces one sample worth of envelope */
|
f@0
|
45 T tick()
|
f@0
|
46 {
|
f@0
|
47
|
f@0
|
48 switch ( mState )
|
f@0
|
49 {
|
f@0
|
50
|
f@0
|
51 case State::eIdle: {
|
f@0
|
52 mValue = 0;
|
f@0
|
53 };
|
f@0
|
54 break;
|
f@0
|
55
|
f@0
|
56 case State::eAttack: {
|
f@0
|
57 mValue += mAttackRate;
|
f@0
|
58 if ( mValue >= mSustainLevel ){
|
f@0
|
59 mValue = mSustainLevel;
|
f@0
|
60 mState = State::eSustain;
|
f@0
|
61 }
|
f@0
|
62 };
|
f@0
|
63 break;
|
f@0
|
64
|
f@0
|
65 case State::eRelease:
|
f@0
|
66 mValue -= mReleaseRate;
|
f@0
|
67 if ( mValue <= 0 ){
|
f@0
|
68 mValue = 0;
|
f@0
|
69 mState = State::eIdle;
|
f@0
|
70 }
|
f@0
|
71 break;
|
f@0
|
72 default:
|
f@0
|
73 break;
|
f@0
|
74 }
|
f@0
|
75
|
f@0
|
76 return mValue;
|
f@0
|
77
|
f@0
|
78 }
|
f@0
|
79
|
f@0
|
80 State getState() const
|
f@0
|
81 {
|
f@0
|
82 return mState;
|
f@0
|
83 }
|
f@0
|
84
|
f@0
|
85 void setState( State state )
|
f@0
|
86 {
|
f@0
|
87 mState = state;
|
f@0
|
88 }
|
f@0
|
89
|
f@0
|
90 private:
|
f@0
|
91 T mSustainLevel;
|
f@0
|
92 T mAttackRate;
|
f@0
|
93 T mReleaseRate;
|
f@0
|
94
|
f@0
|
95 // output
|
f@0
|
96 T mValue;
|
f@0
|
97
|
f@0
|
98 State mState;
|
f@0
|
99
|
f@0
|
100 };
|
f@0
|
101
|
f@0
|
102
|
f@2
|
103 }
|