24 mStart(s), mEnd(e), mDuration(d), mMode(mode), mCurrentValue(s), mCurrentFrame(0) {
50 nextBuffer(outputBuffer, outBufNum, 0, 0);
57 unsigned numFrames = outputBuffer.mNumFrames;
59 float scaleValue = 1, offsetValue = 0;
63 unsigned numFramesToCalc = (int)(mDuration * rate) - mCurrentFrame;
64 unsigned constantFrames;
68 if (numFramesToCalc <= 0) {
70 constantFrames = numFrames;
73 if (numFramesToCalc > numFrames)
74 numFramesToCalc = numFrames;
75 constantFrames = numFrames - numFramesToCalc;
77 float currentValue = mCurrentValue;
84 increment = (mEnd - mStart) / (mDuration * rate);
85 for (i = 0; i < numFramesToCalc; i++) {
87 *outPtr++ = (currentValue * scaleValue) + offsetValue;
88 currentValue += increment;
92 increment = pow(mEnd / mStart, 1/(mDuration * rate));
93 for (i = 0; i < numFramesToCalc; i++) {
95 *outPtr++ = (currentValue * scaleValue) + offsetValue;
96 currentValue *= increment;
102 for (i = 0; i < constantFrames; i++) {
104 *outPtr++ = (mEnd * scaleValue) + offsetValue;
106 if (mCurrentValue != mEnd) {
107 mCurrentFrame += numFrames;
108 mCurrentValue = currentValue;
118 float x4,
float y4,
float x5,
float y5,
float x6,
float y6)
131 for (
unsigned int i = 0; i <
size; i++)
137 float x4,
float y4,
float x5,
float y5,
float x6,
float y6)
150 for (
unsigned int i = 0; i <
size; i++)
173 Breakpoints::iterator idx;
183 for (i = 1; i <
mSize; ++i) {
207 for (
unsigned i = 0; i <
mSize; i++)
231 for (
unsigned i = 0; i <
mSize; ++i) {
235 for (
unsigned i = 0; i <
mSize; ++i) {
248 for (
unsigned i = 0; i <
mSize; ++i) {
251 if (seg->
end() > maxV) maxV = seg->
end();
253 float scale = s / maxV;
254 for (
unsigned i = 0; i <
mSize; ++i) {
265 fprintf(stderr,
"\tat 0 seconds \t\t");
267 for (
unsigned i = 1; i <
mSize; i++) {
268 fprintf(stderr,
"\tat %g seconds \t\t",
mValues[i-1]);
278 for (
unsigned i = 0; i <
mSize; ++i)
294 unsigned numFrames = outputBuffer.mNumFrames;
295 unsigned i, tempFrames;
304 if (mCurrentMark >= mDuration) {
305 x = mSegments[mSize - 1]->end();
306 for (i = 0; i < numFrames; i++) {
307 *outPtr++ = (x * scaleValue) + offsetValue;
315 for (i = 0; i < mSize; ++i) {
317 if (mCurrentMark < x) {
318 endMark = mCurrentMark + ((float)numFrames / rate);
320 mSegments[i]->nextBuffer(outputBuffer, outBufNum, scalePort, offsetPort);
321 mCurrentMark += ((float) (numFrames + 1) / rate);
327 logMsg(
"\t\tEnvelope crossing: current mark: %g point: %g @ %g ls: %g to %g in %g",
328 mCurrentMark, mValues[i], mSegments[i]->end(),
329 mSegments[i]->start(), mSegments[i]->end(), mSegments[i]->duration());
331 tempFrames = (unsigned) ((mValues[i] - mCurrentMark) * rate);
332 outputBuffer.mNumFrames = tempFrames;
334 mSegments[i]->nextBuffer(outputBuffer, outBufNum, scalePort, offsetPort);
337 mCurrentMark += ((float) (numFrames + 1) / rate);
338 outputBuffer.setBuffer(outBufNum, outputBuffer.buffer(outBufNum) + tempFrames);
339 outputBuffer.mNumFrames = numFrames - tempFrames;
341 this->nextBuffer(outputBuffer, outBufNum);
343 mCurrentMark += ((float) (numFrames + 1) / rate);
344 outputBuffer.setBuffer(outBufNum, outPtr);
345 outputBuffer.mNumFrames = numFrames;
346 if (i == (mSize - 1)) {
348 logMsg(
"Envelope finished");
350 mCurrentMark = mDuration;
356 logMsg(
kLogError,
"Envelope nextBuffer: it shouldn't get here %f", rate);
366 :
Envelope(mode, t, 0.0, 0.0, a, 1.0, a + d, s, t - r, s, t, 0.0) { };
371 :
Envelope(mode, t, i, 0.0, i + a, 1.0, i + a + d, s, t - r, s, t, 0.0) { };
376 :
Envelope(t, 0.0, 0.0, a, 1.0, a + d, s, t - r, s, t, 0.0) { };
381 :
Envelope(t, i, 0.0, i + a, 1.0, i + a + d, s, t - r, s, t, 0.0) { };
400 mSegmentMap[del] = mSegmentMap[mValues[0]];
401 mSegmentMap[del + mSegments[1]->duration()] = mSegmentMap[mValues[1]];
402 if (mValues[0] != del) {
403 mSegmentMap.erase(mValues[0]);
404 mSegmentMap.erase(mValues[1]);
406 this->calculateSegments();
410 mSegmentMap[mValues[0] + attack] = mSegmentMap[mValues[1]];
411 mSegmentMap[mValues[0] + attack + mSegments[2]->duration()] = mSegmentMap[mValues[2]];
412 if (mValues[1] != mValues[0] + attack) {
413 mSegmentMap.erase(mValues[1]);
414 mSegmentMap.erase(mValues[2]);
416 this->calculateSegments();
420 mSegmentMap[mValues[1] + decay] = mSegmentMap[mValues[2]];
421 if (mValues[2] != mValues[1] + decay)
422 mSegmentMap.erase(mValues[2]);
423 this->calculateSegments();
427 mSegments[2]->setEnd(sustain);
428 mSegments[3]->setEnd(sustain);
429 this->calculateSegments();
433 mSegmentMap[mDuration - trelease] = mSegmentMap[mValues[3]];
434 if (mValues[3] != mDuration - trelease)
435 mSegmentMap.erase(mValues[3]);
436 this->calculateSegments();
442 mCurrentMark = mValues[3];
450 :
Envelope(mode, t, 0.0, 0.0, a, 1.0, t - r, 1.0, t, 0.0) { };
455 :
Envelope(mode, t, i, 0.0, i + a, 1.0, t - r, 1.0, t, 0.0) { };
460 :
Envelope(t, 0.0, 0.0, a, 1.0, t - r, 1.0, t, 0.0) { };
464 AR::AR(
float t,
float i,
float a,
float r)
465 :
Envelope(t, i, 0.0, i + a, 1.0, t - r, 1.0, t, 0.0) { };
483 if (mValues[0] != del)
490 if (mValues[1] != mValues[0] + attack)
507 if (mValues[2] != a)
mSegmentMap.erase(mValues[1]);
508 if (mValues[3] != r)
mSegmentMap.erase(mValues[2]);
509 if (mValues[4] != d)
mSegmentMap.erase(mValues[3]);
526 :
Envelope(mode, t, 0.0, 0.0, t/2, a, t, 0.0) { }
531 :
Envelope(mode, t, i, 0.0, (t-i)/2, a, t, 0.0) { }
536 :
Envelope(t, 0.0, 0.0, t/2, a, t, 0.0) { }
541 :
Envelope(t, i, 0.0, (t-i)/2, a, t, 0.0) { }
549 :
Envelope(), mFrequency(frequency), mAmplitude(amplitude),
550 mStep(step), mOffset(offset), mWalk(false) {
570 float next = 0.0f, randVal;
596 unsigned numFrames = outputBuffer.mNumFrames;
597 unsigned endMark = mCurrentIndex + numFrames;
601 if (endMark < mSegmentLength) {
602 mSegment.nextBuffer(outputBuffer, outBufNum, scalePort, offsetPort);
603 mCurrentIndex += numFrames;
607 unsigned tempFrames = mSegmentLength - mCurrentIndex;
608 outputBuffer.mNumFrames = tempFrames;
609 mSegment.nextBuffer(outputBuffer, outBufNum, scalePort, offsetPort);
612 outputBuffer.setBuffer(outBufNum, outputBuffer.buffer(outBufNum) + tempFrames);
613 outputBuffer.mNumFrames = numFrames - tempFrames;
615 mSegment.nextBuffer(outputBuffer, outBufNum, scalePort, offsetPort);
617 mCurrentIndex = numFrames - tempFrames;
618 outputBuffer.setBuffer(outBufNum, outPtr);
619 outputBuffer.mNumFrames = numFrames;
sample * SampleBuffer
1-channel buffer data type, vector of (sample)
void dump()
reset internal time to restart envelope
float end()
Returns the target value of the line segment.
#define UPDATE_SCALABLE_CONTROLS
void logMsg(const char *format,...)
These are the public logging messages.
AR()
Various Constructors.
float mDuration
Total duration, typically in seconds.
virtual void dump()
Pretty-printer.
unsigned mCurrentFrame
cache
Triangle()
Various Constructors.
static unsigned mFrameRate
default sample rate (tested up to 96000)
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
virtual void trigger()
reset internal time to restart envelope
virtual void setDuration(float d)
set/scale durations
LineSegment mSegment
single line segment
#define CHECK_UPDATE_SCALABLE_CONTROLS
unsigned mFrameRate
trigger ignored here
void setAttack(float attack)
Illegal operation at run time.
RandEnvelope(float frequency=1, float amplitude=1, float offset=0, float step=0)
defaults are 1 Hz, +- 1.0 range
void setRelease(float release)
void nextSegment()
choose the values for the next line segment
virtual void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
The main FrameStream work method.
LineMode mMode
How am I to calculate the values from start to end values of the line.
void setAll(float d, float a, float r)
void initSegment()
set up the line segment
float duration()
Returns the total time it will take to get from start to end value.
void setStart(float tstart)
void createSegments()
Allocate memory for the segments.
float mCurrentValue
Internal book-keeping.
Scalable – mix-in class with scale and offset control inputs (may be constants or generators)...
A linearly interpolated segment – this has start and end values, and a duration (in seconds)...
void setDuration(unsigned tduration)
Overloaded to accept either float or unsigned.
virtual void scaleTimes(float s)
scale durations
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
next buffer interpolator
Breakpoints mSegmentMap
list of envelope breakpoints
bool mWalk
whether to produce random values or a random walk
void setAttack(float attack)
float mAmplitude
scale (+-)
void setDuration(float d)
Special accessors.
void reset()
reset counters
#define kLine
LineSegment flags for line interpolation.
float mStep
max step between values (+-)
void addBreakpoint(float startTime, float value)
unsigned mSegmentLength
line segment's length in frames
void calculateSegments()
Calculate the internal data.
#define LOAD_SCALABLE_CONTROLS
Load the scale/offset-related values at the start.
float fRandZ(void)
A variety of useful random-number functions.
virtual void reset()
reset internal time to restart envelope
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
scale durations
virtual bool isActive()
This answers whether I'm active (ptr < end)
float mFrequency
frequency for picking new values
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
float mDuration
Length of the line segment (IN SECONDS)
virtual void scaleValues(float s)
scale values so the max is s
void setSustain(float sustain)
void setDecay(float decay)
Port – used to represent constant, control-rate or signal inputs and outputs in named maps; holds a ...
float mLastVal
last line segment ending value (unscaled and unoffset)
LineSegment()
empty constructor
unsigned mCurrentIndex
current index in line segment
void setDuration(float d)
Special accessors.
void setMode(LineMode mode)
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.
void setRelease(float release)
LineSegment ** mSegments
array of line segments that for the envelope
float mCurrentMark
How far we have read.
virtual void dump()
pretty-print the receiver's input/controls map
void release(void)
Operations.
Base class of CSL exceptions (written upper-case). Has a string message.
#define DECLARE_SCALABLE_CONTROLS
Macros for all the Scalable UnitGenerators (note that these don't end with ";")