CSL  6.0
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);
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
void dump()
reset internal time to restart envelope
Definition: Envelope.cpp:44
float end()
Returns the target value of the line segment.
Definition: Envelope.h:52
AR()
Various Constructors.
Definition: Envelope.h:202
float mDuration
Total duration, typically in seconds.
Definition: Envelope.h:118
virtual void dump()
Pretty-printer.
Definition: Envelope.cpp:263
unsigned mCurrentFrame
cache
Definition: Envelope.h:77
Triangle()
Various Constructors.
Definition: Envelope.h:230
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
virtual void trigger()
reset internal time to restart envelope
Definition: Envelope.cpp:284
void setOffset(float offset)
Definition: Envelope.h:256
virtual void setDuration(float d)
set/scale durations
Definition: Envelope.cpp:220
void setDuration(float tduration)
Definition: Envelope.h:59
LineSegment mSegment
single line segment
Definition: Envelope.h:278
void trigger()
reset internal time to restart envelope
Definition: Envelope.h:261
void setAttack(float attack)
Definition: Envelope.cpp:409
void setMode(LineMode tmode)
Sets the interpolation kind (linear or exponential)
Definition: Envelope.h:60
RandEnvelope(float frequency=1, float amplitude=1, float offset=0, float step=0)
defaults are 1 Hz, +- 1.0 range
Definition: Envelope.cpp:548
void setStep(float step)
Definition: Envelope.h:255
void setRelease(float release)
Definition: Envelope.cpp:432
void nextSegment()
choose the values for the next line segment
Definition: Envelope.cpp:569
void setAmplitude(float amplitude)
Definition: Envelope.h:253
virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
The main FrameStream work method.
Definition: Envelope.cpp:292
map< float, LineSegment * > Breakpoints
a map between a time and a line segment
Definition: Envelope.h:82
float mOffset
DC offset.
Definition: Envelope.h:274
LineMode mMode
How am I to calculate the values from start to end values of the line.
Definition: Envelope.h:75
void setAll(float d, float a, float r)
Definition: Envelope.cpp:502
void setEnd(float tend)
Definition: Envelope.h:56
void initSegment()
set up the line segment
Definition: Envelope.cpp:561
unsigned mSize
Definition: Envelope.h:123
float duration()
Returns the total time it will take to get from start to end value.
Definition: Envelope.h:53
void trigger()
Definition: Envelope.h:68
void setStart(float tstart)
Definition: Envelope.h:57
void createSegments()
Allocate memory for the segments.
Definition: Envelope.cpp:164
float mCurrentValue
Internal book-keeping.
Definition: Envelope.h:76
#define kExpon
Definition: Envelope.h:37
Scalable – mix-in class with scale and offset control inputs (may be constants or generators)...
Definition: CSL_Core.h:403
A linearly interpolated segment – this has start and end values, and a duration (in seconds)...
Definition: Envelope.h:45
void release(void)
Definition: Envelope.cpp:441
void setDuration(unsigned tduration)
Overloaded to accept either float or unsigned.
Definition: Envelope.h:58
void scaleTimes(float s)
set/scale durations
Definition: Envelope.h:264
virtual void scaleTimes(float s)
scale durations
Definition: Envelope.cpp:229
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
next buffer interpolator
Definition: Envelope.cpp:49
Breakpoints mSegmentMap
list of envelope breakpoints
Definition: Envelope.h:120
bool mWalk
whether to produce random values or a random walk
Definition: Envelope.h:277
void setAttack(float attack)
Definition: Envelope.cpp:488
static size_t size
Definition: fft_N.c:40
void dump()
reset internal time to restart envelope
Definition: Envelope.h:262
ADSR = 4-segment attack/decay/sustain/release envelope class.
Definition: Envelope.h:153
float mAmplitude
scale (+-)
Definition: Envelope.h:272
unsigned currentFrame()
Definition: Envelope.h:54
void setWalk(bool walk)
Accessors.
Definition: Envelope.h:252
~Triangle()
Minimal version - AR.
Definition: Envelope.h:240
void setDuration(float d)
print the receiver
Definition: Envelope.h:263
void setDelay(float del)
Definition: Envelope.cpp:481
void reset()
These are no-ops in Random envelopes.
Definition: Envelope.h:260
void setDuration(float d)
Special accessors.
Definition: Envelope.cpp:385
void reset()
reset counters
Definition: Envelope.cpp:39
int LineMode
Definition: Envelope.h:38
#define kLine
LineSegment flags for line interpolation.
Definition: Envelope.h:36
float mStep
max step between values (+-)
Definition: Envelope.h:273
void addBreakpoint(float startTime, float value)
Definition: Envelope.cpp:192
unsigned mSegmentLength
line segment's length in frames
Definition: Envelope.h:276
void calculateSegments()
Calculate the internal data.
Definition: Envelope.cpp:170
float mEnd
Ending value.
Definition: Envelope.h:73
void setDelay(float del)
Definition: Envelope.cpp:399
virtual void reset()
reset internal time to restart envelope
Definition: Envelope.cpp:276
RandEnvelope envelope class – makes random control signals using a single line segment.
Definition: Envelope.h:247
Triangle envelope class – equal attack/release times.
Definition: Envelope.h:227
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
scale durations
Definition: Envelope.cpp:594
virtual bool isActive()
This answers whether I'm active (ptr < end)
Definition: Envelope.h:258
virtual bool isActive()
This answers whether I'm active (ptr < end)
Definition: Envelope.cpp:211
float mFrequency
frequency for picking new values
Definition: Envelope.h:271
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
float mDuration
Length of the line segment (IN SECONDS)
Definition: Envelope.h:74
virtual sample value()
Definition: CSL_Core.h:285
virtual void scaleValues(float s)
scale values so the max is s
Definition: Envelope.cpp:246
void setSustain(float sustain)
Definition: Envelope.cpp:426
void setDecay(float decay)
Definition: Envelope.cpp:419
float start()
Accessors.
Definition: Envelope.h:51
float mStart
Start value.
Definition: Envelope.h:72
unsigned int privateNextBuffer(CPoint *breakpoint, LineSegment *segment, float *buffer, unsigned int numFrames)
Internal helper method for computing the next buffer.
void setFrequency(float frequency)
Definition: Envelope.h:254
Port – used to represent constant, control-rate or signal inputs and outputs in named maps; holds a ...
Definition: CSL_Core.h:312
AR = 3-segment attack/release envelope class.
Definition: Envelope.h:199
float mLastVal
last line segment ending value (unscaled and unoffset)
Definition: Envelope.h:270
LineSegment()
empty constructor
Definition: Envelope.cpp:19
virtual ~Envelope()
Definition: Envelope.cpp:155
forward declaration
Definition: CSL_Core.h:241
float * mValues
Definition: Envelope.h:122
unsigned mCurrentIndex
current index in line segment
Definition: Envelope.h:275
void setDuration(float d)
Special accessors.
Definition: Envelope.cpp:469
void setMode(LineMode mode)
Definition: Envelope.cpp:206
Envelope: a collection of LineSegments; may have an input (scale) and act like a processor, or have no input and act like a control UGen. I inherit Scalable setScale, setOffset for inputs.
Definition: Envelope.h:89
void setRelease(float release)
Definition: Envelope.cpp:495
LineSegment ** mSegments
array of line segments that for the envelope
Definition: Envelope.h:121
float mCurrentMark
How far we have read.
Definition: Envelope.h:119
void release(void)
Operations.
Definition: Envelope.cpp:516
Base class of CSL exceptions (written upper-case). Has a string message.