f@5
|
1 /*
|
f@5
|
2
|
f@5
|
3 Copyright (C) 2016 Queen Mary University of London
|
f@16
|
4 Author: Fiore Martin, based on CCRMA STK ADSR.h (https://ccrma.stanford.edu/software/stk/classstk_1_1ADSR.html)
|
f@5
|
5
|
f@5
|
6 This file is part of Collidoscope.
|
f@5
|
7
|
f@5
|
8 Collidoscope is free software: you can redistribute it and/or modify
|
f@5
|
9 it under the terms of the GNU General Public License as published by
|
f@5
|
10 the Free Software Foundation, either version 3 of the License, or
|
f@5
|
11 (at your option) any later version.
|
f@5
|
12
|
f@5
|
13 This program is distributed in the hope that it will be useful,
|
f@5
|
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
f@5
|
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
f@5
|
16 GNU General Public License for more details.
|
f@5
|
17
|
f@5
|
18 You should have received a copy of the GNU General Public License
|
f@5
|
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
f@16
|
20
|
f@16
|
21 This file incorporates work covered by the following copyright and permission notice:
|
f@16
|
22
|
f@16
|
23 The Synthesis ToolKit in C++ (STK)
|
f@16
|
24
|
f@16
|
25 Copyright (c) 1995--2016 Perry R. Cook and Gary P. Scavone
|
f@16
|
26
|
f@16
|
27 Permission is hereby granted, free of charge, to any person obtaining
|
f@16
|
28 a copy of this software and associated documentation files (the
|
f@16
|
29 "Software"), to deal in the Software without restriction, including
|
f@16
|
30 without limitation the rights to use, copy, modify, merge, publish,
|
f@16
|
31 distribute, sublicense, and/or sell copies of the Software, and to
|
f@16
|
32 permit persons to whom the Software is furnished to do so, subject to
|
f@16
|
33 the following conditions:
|
f@16
|
34
|
f@16
|
35 The above copyright notice and this permission notice shall be
|
f@16
|
36 included in all copies or substantial portions of the Software.
|
f@16
|
37
|
f@16
|
38 Any person wishing to distribute modifications to the Software is
|
f@16
|
39 asked to send the modifications to the original developer so that they
|
f@16
|
40 can be incorporated into the canonical version. This is, however, not
|
f@16
|
41 a binding provision of this license.
|
f@16
|
42
|
f@16
|
43 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
f@16
|
44 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
f@16
|
45 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
f@16
|
46 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
f@16
|
47 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
f@16
|
48 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
f@16
|
49 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
f@16
|
50
|
f@5
|
51 */
|
f@5
|
52
|
f@0
|
53 #pragma once
|
f@0
|
54
|
f@0
|
55 namespace collidoscope {
|
f@0
|
56
|
f@2
|
57
|
f@2
|
58 /*
|
f@2
|
59 * An ASR envelope with linear shape. It is modeled after the STK envelope classes.
|
f@2
|
60 * The tick() method advances the computation of the envelope one sample and returns the computed sample
|
f@2
|
61 * The class is templated for the type of the samples that each tick of the envelope produces.
|
f@2
|
62 *
|
f@2
|
63 * Client classes can set/get the current state of the envelope with the
|
f@2
|
64 * respective getter/setter methods
|
f@2
|
65 *
|
f@2
|
66 */
|
f@0
|
67 template <typename T>
|
f@0
|
68 class EnvASR
|
f@0
|
69 {
|
f@0
|
70 public:
|
f@0
|
71
|
f@3
|
72 /** Possible states of the envelope. Idle means the envelope ouputs 0 */
|
f@0
|
73 enum class State {
|
f@0
|
74 eAttack,
|
f@0
|
75 eSustain,
|
f@0
|
76 eRelease,
|
f@0
|
77 eIdle // before attack after release
|
f@0
|
78 };
|
f@0
|
79
|
f@0
|
80 EnvASR( T sustainLevel, T attackTime, T releaseTime, std::size_t sampleRate ) :
|
f@0
|
81 mSustainLevel( sustainLevel ),
|
f@0
|
82 mState( State::eIdle ),
|
f@0
|
83 mValue( 0 )
|
f@0
|
84
|
f@0
|
85 {
|
f@0
|
86 if ( attackTime <= 0 )
|
f@0
|
87 attackTime = T( 0.001 );
|
f@0
|
88
|
f@0
|
89 if ( releaseTime <= 0 )
|
f@0
|
90 releaseTime = T( 0.001 );
|
f@0
|
91
|
f@0
|
92 mAttackRate = T( 1.0 ) / (attackTime * sampleRate);
|
f@0
|
93 mReleaseRate = T( 1.0 ) / (releaseTime * sampleRate);
|
f@0
|
94 }
|
f@0
|
95
|
f@3
|
96 /** Produces one sample worth of envelope */
|
f@0
|
97 T tick()
|
f@0
|
98 {
|
f@0
|
99
|
f@0
|
100 switch ( mState )
|
f@0
|
101 {
|
f@0
|
102
|
f@0
|
103 case State::eIdle: {
|
f@0
|
104 mValue = 0;
|
f@0
|
105 };
|
f@0
|
106 break;
|
f@0
|
107
|
f@0
|
108 case State::eAttack: {
|
f@0
|
109 mValue += mAttackRate;
|
f@0
|
110 if ( mValue >= mSustainLevel ){
|
f@0
|
111 mValue = mSustainLevel;
|
f@0
|
112 mState = State::eSustain;
|
f@0
|
113 }
|
f@0
|
114 };
|
f@0
|
115 break;
|
f@0
|
116
|
f@0
|
117 case State::eRelease:
|
f@0
|
118 mValue -= mReleaseRate;
|
f@0
|
119 if ( mValue <= 0 ){
|
f@0
|
120 mValue = 0;
|
f@0
|
121 mState = State::eIdle;
|
f@0
|
122 }
|
f@0
|
123 break;
|
f@0
|
124 default:
|
f@0
|
125 break;
|
f@0
|
126 }
|
f@0
|
127
|
f@0
|
128 return mValue;
|
f@0
|
129
|
f@0
|
130 }
|
f@0
|
131
|
f@0
|
132 State getState() const
|
f@0
|
133 {
|
f@0
|
134 return mState;
|
f@0
|
135 }
|
f@0
|
136
|
f@0
|
137 void setState( State state )
|
f@0
|
138 {
|
f@0
|
139 mState = state;
|
f@0
|
140 }
|
f@0
|
141
|
f@0
|
142 private:
|
f@0
|
143 T mSustainLevel;
|
f@0
|
144 T mAttackRate;
|
f@0
|
145 T mReleaseRate;
|
f@0
|
146
|
f@0
|
147 // output
|
f@0
|
148 T mValue;
|
f@0
|
149
|
f@0
|
150 State mState;
|
f@0
|
151
|
f@0
|
152 };
|
f@0
|
153
|
f@0
|
154
|
f@2
|
155 }
|