Skip to content

Commit

Permalink
Plugins: Demand: Add Dconst UGen, with schelp
Browse files Browse the repository at this point in the history
  • Loading branch information
James Harkins committed Feb 3, 2015
1 parent f312c5f commit 84dcef8
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
45 changes: 45 additions & 0 deletions HelpSource/Classes/Dconst.schelp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
TITLE:: Dconst
summary:: Constrain a demand-rate stream to a given sum
categories:: UGens>Demand

DESCRIPTION::
A demand-rate analog to link::Classes/Pconst::. It outputs values from the child demand stream until the sum of those values reaches or exceeds a given total. The last value will be truncated so that the sum of Dconst's output values will match the total exactly.

CLASSMETHODS::

METHOD:: new

ARGUMENT:: sum
The sum to reach. This may be a number, demand UGen or any other UGen. When a Dconst instance resets, one value will be taken for the sum, and it can't be modulated until the next reset.

ARGUMENT:: in
A demand-rate stream, providing the output values.

ARGUMENT:: tolerance
Because of floating point rounding error, it isn't safe to stop only when the output's running sum is equal to the desired total. teletype::tolerance:: is how close the running sum can get to stop the output: code::abs(runningsum - sum) <= tolerance::.

returns:: A demand-rate stream.


EXAMPLES::

code::
// fast notes of random duration for 0.5 seconds
// then a single note for 0.5 seconds
(
a = {
var freq = Duty.kr(
Dseq([
Dconst(0.5, Dwhite(0.05, 0.08, inf)),
0.5
], inf),
0,
// workaround for the lack of Dexprand
Dwhite(0, 1, inf).linexp(0, 1, 200, 600)
);
VarSaw.ar(Lag.kr(freq, 0.02), 0, 0.3, 0.1).dup
}.play;
)

a.free;
::
6 changes: 6 additions & 0 deletions SCClassLibrary/Common/Audio/Demand.sc
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ Dstutter : DUGen {
}
}

Dconst : DUGen {
*new { arg sum, in, tolerance = 0.001;
^this.multiNew('demand', sum, in, tolerance);
}
}

Donce : DUGen {
*new { arg in;
^this.multiNew('demand', in)
Expand Down
73 changes: 73 additions & 0 deletions server/plugins/DemandUGens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,13 @@ struct Dreset : public Unit
float prev_reset;
};

struct Dconst : public Unit
{
float m_total;
float m_runningsum;
float m_tolerance;
};

extern "C"
{

Expand Down Expand Up @@ -279,6 +286,9 @@ void Dreset_next(Dreset *unit, int inNumSamples);
void Donce_Ctor(Donce *unit);
void Donce_next(Donce *unit, int inNumSamples);

void Dconst_Ctor(Dconst *unit);
void Dconst_next(Dconst *unit, int inNumSamples);

};


Expand Down Expand Up @@ -2062,6 +2072,68 @@ void Dstutter_Ctor(Dstutter *unit)

//////////////////////////////

void Dconst_next(Dconst *unit, int inNumSamples)
{
float total, tolerance;

if (inNumSamples) {
if(sc_isnan(unit->m_runningsum)) {
OUT0(0) = NAN;
return;
}

if (unit->m_total < 0.f) {

total = DEMANDINPUT_A(0, inNumSamples);
tolerance = DEMANDINPUT_A(2, inNumSamples);
if(sc_isnan(total) || sc_isnan(tolerance)) {
OUT0(0) = NAN;
return;
}
unit->m_total = total;
unit->m_tolerance = tolerance;

} {
total = unit->m_total;
tolerance = unit->m_tolerance;
}

float val = DEMANDINPUT_A(1, inNumSamples);

if(sc_isnan(val)) {
OUT0(0) = NAN;
return;
} else {
float runningsum = unit->m_runningsum + val;
if((runningsum > total) || (fabs(total - runningsum) <= tolerance)) {
OUT0(0) = total - unit->m_runningsum;
unit->m_runningsum = NAN; // stop next time
} else {
unit->m_runningsum = runningsum;
OUT0(0) = val;
}
}

} else {

unit->m_total = -1.f;
unit->m_runningsum = 0.f;
RESETINPUT(0);
RESETINPUT(1);
RESETINPUT(2);

}
}

void Dconst_Ctor(Dconst *unit)
{
SETCALC(Dconst_next);
Dconst_next(unit, 0);
OUT0(0) = 0.f;
}

//////////////////////////////



void Dpoll_next(Dpoll *unit, int inNumSamples)
Expand Down Expand Up @@ -2381,6 +2453,7 @@ PluginLoad(Demand)
DefineSimpleUnit(Dswitch1);
DefineSimpleUnit(Dswitch);
DefineSimpleUnit(Dstutter);
DefineSimpleUnit(Dconst);
DefineSimpleUnit(Donce);
DefineSimpleUnit(Dreset);
DefineDtorUnit(Dpoll);
Expand Down

0 comments on commit 84dcef8

Please sign in to comment.