CSL
5.2
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
Envelope.h
Go to the documentation of this file.
1
///
2
/// Envelope.h -- The basic (concrete) CSL breakpoint envelope classes.
3
/// See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4
///
5
///
6
/// These are UnitGenerators that represent arbitrarily long breakpoint functions and do linear
7
/// interpolation between their breakpoints. There are several kinds of
8
/// constructors, e.g., using breakpoint objects or x/y value pairs, and one
9
/// can scale the values or times of an existing envelope.
10
///
11
/// Classes:
12
/// LineSegment: A linearly interpolated segment with start and end values, and a duration (in seconds).
13
/// Envelope: a collection of LineSegments; may have an input and act like an effect,
14
/// or have no input and act like a control UnitGenerator
15
/// Specific kinds of envelope (AR, ADSR, Triangle) and RandomEnvelope
16
///
17
18
#ifndef CSL_Envelope_H
19
#define CSL_Envelope_H
20
21
#include "
CSL_Core.h
"
22
#include "
CPoint.h
"
23
24
namespace
csl {
25
26
///
27
/// LineSegment flags for line interpolation.
28
///
29
30
#ifdef CSL_ENUMS
31
typedef
enum
{
32
kLine
,
///< linear interpolation between start and end values.
33
kExpon
,
///< linear interpolation between start and end values.
34
}
LineMode
;
35
#else
36
#define kLine 1
37
#define kExpon 2
38
typedef
int
LineMode
;
39
#endif
40
41
///
42
/// A linearly interpolated segment -- this has start and end values, and a duration (in seconds).
43
///
44
45
class
LineSegment
:
public
UnitGenerator
{
46
public
:
47
LineSegment
();
///< empty constructor
48
LineSegment
(
float
d,
float
s,
float
e,
LineMode
mode =
kLine
);
///< Declare dur in sec, start, stop values
49
50
/// Accessors
51
float
start
() {
return
mStart
; }
///< Returns the initial value of the line segment.
52
float
end
() {
return
mEnd
; }
///< Returns the target value of the line segment.
53
float
duration
() {
return
mDuration
; }
///< Returns the total time it will take to get from start to end value.
54
unsigned
currentFrame
() {
return
mCurrentFrame
; };
55
56
void
setEnd
(
float
tend) {
mEnd
= tend; }
57
void
setStart
(
float
tstart) {
mStart
= tstart;
mCurrentValue
=
mStart
; }
58
void
setDuration
(
unsigned
tduration) {
mDuration
= (float) tduration; }
///< Overloaded to accept either float or unsigned.
59
void
setDuration
(
float
tduration) {
mDuration
= tduration; }
60
void
setMode
(
LineMode
tmode) {
mMode
= tmode; }
///< Sets the interpolation kind (linear or exponential)
61
62
/// next buffer interpolator
63
void
nextBuffer
(
Buffer
&outputBuffer,
unsigned
outBufNum)
throw
(
CException
);
64
/// handy version given Scalable port pointers
65
virtual
void
nextBuffer
(
Buffer
&outputBuffer,
unsigned
outBufNum,
Port
* scalePort,
Port
* offsetPort)
throw
(
CException
);
66
67
void
reset
();
///< reset counters
68
void
trigger
() { this->
reset
(); };
///< reset internal time to restart envelope
69
void
dump
();
///< Prints to screen the start and end values and the duration of the line.
70
71
protected
:
72
float
mStart
;
///< Start value
73
float
mEnd
;
///< Ending value
74
float
mDuration
;
///< Length of the line segment (IN SECONDS)
75
LineMode
mMode
;
///< How am I to calculate the values from start to end values of the line.
76
float
mCurrentValue
;
///< Internal book-keeping
77
unsigned
mCurrentFrame
;
///< cache
78
};
79
80
/// a map between a time and a line segment
81
82
typedef
map<float, LineSegment *>
Breakpoints
;
83
84
///
85
/// Envelope: a collection of LineSegments; may have an input (scale) and act like a processor,
86
/// or have no input and act like a control UGen. I inherit Scalable setScale, setOffset for inputs
87
///
88
89
class
Envelope
:
public
UnitGenerator
,
public
Scalable
{
90
public
:
91
Envelope
() :
UnitGenerator
(),
Scalable
(1, 0),
mDuration
(0),
mSegments
(0),
mValues
(0) { };
92
Envelope
(
LineMode
mode,
float
t,
float
x1,
float
y1,
float
x2 = 0,
float
y2 = 1.0,
float
x3 = 0,
float
y3 = 1.0,
93
float
x4 = 0,
float
y4 = 1.0,
float
x5 = 0,
float
y5 = 1.0,
float
x6 = 0,
float
y6 = 1.0);
94
Envelope
(
LineMode
mode,
float
t,
unsigned
int
size,
float
x[],
float
y[]);
95
Envelope
(
float
t,
float
x1,
float
y1,
float
x2 = 0,
float
y2 = 1.0,
float
x3 = 0,
float
y3 = 1.0,
96
float
x4 = 0,
float
y4 = 1.0,
float
x5 = 0,
float
y5 = 1.0,
float
x6 = 0,
float
y6 = 1.0);
97
Envelope
(
float
t,
unsigned
int
size,
float
x[],
float
y[]);
98
99
virtual
~Envelope
();
100
/// This answers whether I'm active (ptr < end)
101
virtual
bool
isActive
();
102
103
void
addBreakpoint
(
float
startTime,
float
value
);
104
105
void
setMode
(
LineMode
mode);
106
// void setInterpolationAtSegment(LineMode mode, unsigned idx); ///< allows to specify interpolation other than linear for a segment.
107
virtual
void
setDuration
(
float
d);
///< set/scale durations
108
virtual
void
scaleTimes
(
float
s);
///< scale durations
109
virtual
void
scaleValues
(
float
s);
///< scale values so the max is s
110
111
virtual
void
reset
();
///< reset internal time to restart envelope
112
virtual
void
trigger
();
///< reset internal time to restart envelope
113
virtual
void
dump
();
114
/// The main FrameStream work method
115
virtual
void
nextBuffer
(
Buffer
&outputBuffer,
unsigned
outBufNum)
throw
(
CException
);
116
117
protected
:
118
float
mDuration
;
///< Total duration, typically in seconds
119
float
mCurrentMark
;
///< How far we have read
120
Breakpoints
mSegmentMap
;
///< list of envelope breakpoints
121
LineSegment
**
mSegments
;
///< array of line segments that for the envelope
122
float
*
mValues
;
123
unsigned
mSize
;
124
/// Internal helper method for computing the next buffer
125
unsigned
int
privateNextBuffer
(
CPoint
*breakpoint,
LineSegment
*segment,
float
*buffer,
unsigned
int
numFrames);
126
void
createSegments
();
///< Allocate memory for the segments.
127
void
calculateSegments
();
///< Calculate the internal data
128
};
129
130
/// ADSR = 4-segment attack/decay/sustain/release envelope class.
131
132
/**
133
Most of this is inherited from Envelope.
134
This design is an extended ADSR envelope with an initial constant segment and offset
135
(default = 0@0; this can be used to make an attack delay as on ARP ADSRs), attack time and
136
max. val (default = 1.0), decay time, sustain level, and release time and final value (default = 0.0).
137
All times are assumed to be given in seconds.
138
Note that there are many variations on the constructor.
139
The 5 line segments used internally look something like the following
140
141
| / .
142
| / \ .
143
| / \--------------- .
144
| / \ .
145
|---/ \ .
146
| \----- .
147
--------------------------------------------------------------------
148
149
Note that, internally, the breakpoints are kept with cumulative times, whereas the
150
line segments only have start/stop Y values and durations (i.e., no absolute time reference).
151
*/
152
153
class
ADSR
:
public
Envelope
{
154
155
public
:
156
ADSR
() :
Envelope
() { };
157
/// Minimal version - ADSR
158
ADSR
(
LineMode
mode,
float
t,
float
a,
float
d,
float
s,
float
r);
159
/// with initial delay - IADSR
160
ADSR
(
LineMode
mode,
float
t,
float
i,
float
a,
float
d,
float
s,
float
r);
161
/// Minimal version - ADSR
162
ADSR
(
float
t,
float
a,
float
d,
float
s,
float
r);
163
/// with initial delay - IADSR
164
ADSR
(
float
t,
float
i,
float
a,
float
d,
float
s,
float
r);
165
~ADSR
() { };
166
/// Special accessors
167
void
setDuration
(
float
d);
///< set duration = scale steady-state part of env
168
void
setDelay
(
float
del);
169
void
setAttack
(
float
attack);
170
void
setDecay
(
float
decay);
171
void
setSustain
(
float
sustain);
172
void
setRelease
(
float
release
);
173
174
void
release
(
void
);
/// trigger the release segment
175
};
176
177
/// AR = 3-segment attack/release envelope class.
178
179
/**
180
Most of this is inherited from Envelope.
181
This design is an extended AR envelope with an initial constant segment and offset
182
(default = 0@0; this can be used to make an attack delay as on ARP ARs), attack time and
183
max. val (default = 1.0), and release time and final value (default = 0.0).
184
All times are assumed to be given in seconds.
185
Note that there are many variations on the constructor.
186
The line segments used internally look something like the following
187
188
|
189
| /---------------
190
| / \
191
|---/ \
192
| \-----
193
------------------------------------
194
195
Note that, internally, the breakpoints are kept with cumulative times, whereas the
196
line segments only have start/stop Y values and durations (i.e., no absolute time reference).
197
*/
198
199
class
AR
:
public
Envelope
{
200
201
public
:
/// Various Constructors
202
AR
() :
Envelope
() { };
203
/// Minimal version - AR
204
AR
(
LineMode
mode,
float
t,
float
a,
float
r);
205
/// with initial delay - IAR
206
AR
(
LineMode
mode,
float
t,
float
i,
float
a,
float
r);
207
/// Minimal version - AR
208
AR
(
float
t,
float
a,
float
r);
209
/// with initial delay - IAR
210
AR
(
float
t,
float
i,
float
a,
float
r);
211
212
~AR
() { };
213
/// Special accessors
214
void
setDuration
(
float
d);
///< set duration = scale steady-state part of env
215
void
setDelay
(
float
del);
216
void
setAttack
(
float
attack);
217
void
setRelease
(
float
release
);
218
void
setAll
(
float
d,
float
a,
float
r);
219
/// Operations
220
void
release
(
void
);
///< trigger the release segment
221
};
222
223
///
224
/// Triangle envelope class -- equal attack/release times
225
///
226
227
class
Triangle
:
public
Envelope
{
228
229
public
:
/// Various Constructors
230
Triangle
() :
Envelope
() { };
231
/// Simple constructor
232
Triangle
(
LineMode
mode,
float
duration,
float
amplitude);
233
/// Versions with initial delay segments
234
Triangle
(
LineMode
mode,
float
duration,
float
initialDelay,
float
amplitude);
235
/// Simple constructor
236
Triangle
(
float
duration,
float
amplitude = 1.0f);
237
/// Versions with initial delay segments
238
Triangle
(
float
duration,
float
initialDelay,
float
amplitude);
239
/// Minimal version - AR
240
~Triangle
() { };
241
};
242
243
///
244
/// RandEnvelope envelope class -- makes random control signals using a single line segment
245
///
246
247
class
RandEnvelope
:
public
Envelope
{
248
public
:
/// defaults are 1 Hz, +- 1.0 range
249
RandEnvelope
(
float
frequency = 1,
float
amplitude = 1,
float
offset = 0,
float
step = 0);
250
~RandEnvelope
() { };
251
/// Accessors
252
void
setWalk
(
bool
walk) {
mWalk
= walk; };
253
void
setAmplitude
(
float
amplitude) {
mAmplitude
= amplitude; };
254
void
setFrequency
(
float
frequency) {
mFrequency
= frequency; };
255
void
setStep
(
float
step) {
mStep
= step; };
256
void
setOffset
(
float
offset) {
mOffset
= offset; };
257
258
virtual
bool
isActive
() {
return
false
; };
259
/// These are no-ops in Random envelopes
260
void
reset
() { };
///< reset internal time to restart envelope
261
void
trigger
() { };
///< reset internal time to restart envelope
262
void
dump
() { };
///< print the receiver
263
void
setDuration
(
float
d) { };
///< set/scale durations
264
void
scaleTimes
(
float
s) { };
///< scale durations
265
266
/// The main UGen work method
267
void
nextBuffer
(
Buffer
&outputBuffer,
unsigned
outBufNum)
throw
(
CException
);
268
269
protected
:
270
float
mLastVal
;
///< last line segment ending value (unscaled and unoffset)
271
float
mFrequency
;
///< frequency for picking new values
272
float
mAmplitude
;
///< scale (+-)
273
float
mStep
;
///< max step between values (+-)
274
float
mOffset
;
///< DC offset
275
unsigned
mCurrentIndex
;
///< current index in line segment
276
unsigned
mSegmentLength
;
///< line segment's length in frames
277
bool
mWalk
;
///< whether to produce random values or a random walk
278
LineSegment
mSegment
;
///< single line segment
279
280
void
initSegment
();
///< set up the line segment
281
void
nextSegment
();
///< choose the values for the next line segment
282
283
};
284
285
}
286
287
#endif
CSL
Sources
Envelope.h
Generated on Thu Nov 15 2012 22:01:10 for CSL by
1.8.1.1