TITLE:: Dunique
summary:: Return the same unique series of values for several demand streams
categories:: UGens>Demand
related:: Classes/Demand, Classes/Drand, Classes/Dser, Classes/Duty, Classes/Dxrand, Classes/TDuty

DESCRIPTION::
A demand UGen represents a single series of states. When used by more than one demand stream, it will output only every nth value for each. Wrapping a demand UGen in a Dunique will guarantee that that all streams receive the same value.

code::
// without any measures, a demand ugen's values will be distributed between several series:
{ var x = Dseq([0, 1, 2, 3, 4, 5], inf); { Demand.ar(Impulse.ar(1/rrand(0.001, 0.0015)), 0, x) } ! 3 }.plot;

// using a Dunique, each series iterates through the same values
{ var x = Dunique(Dseq([0, 1, 2, 3, 4, 5], inf)); { Demand.ar(Impulse.ar(1/rrand(0.001, 0.0015)), 0, x) } ! 3 }.plot;

// random values will also be identical
{ var x = Dunique(Drand([0, 1, 2, 3, 4, 5], inf)); { Demand.ar(Impulse.ar(1/rrand(0.001, 0.0015)), 0, x) } ! 3 }.plot;
::

CLASSMETHODS::

METHOD:: new
Return a new instance.

ARGUMENT:: source
The demand ugen that is to be reused in several others.

ARGUMENT:: maxBufferSize
Maximum size for the value buffer when protected is false. Values will loop after maxBufferSize has been exceeded.

ARGUMENT:: protected
There are limitations to this ugen: If one copy is called much faster than the slowest, the buffer can overrun. Trying to protect from such a buffer overrun, one has to rely on counting up to infinity. Using 32bit float, only 16777216 events can be correctly played back. When protected is true, these two limitations are caught by ending the series (default: true). Set this parameter to false (or zero) in order to ignore this (e.g. by adjusting buffer size appropriately).
code::
// to demonstrate, make the buffer deliberately small:
{ var x = Dunique(Drand([0, 1, 2, 3, 4, 5], inf), 20); { Duty.ar(0.5e-4 + 0.001.rand, 0, x, doneAction: Done.freeSelf) } ! 3}.plot;
::
