Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
// revision: 9
package de.sciss.synth
package ugen
import UGenSource._
/** A UGen which outputs a value of 1 for a given duration when triggered.
*
* When a trigger occurs at the input, a value of 1 is output for the specified
* duration, otherwise zero is output. When a new trigger occurs while this ugens
* outputs 1, the hold-time is reset to the duration.
*
* ''Warning:'' The hold-time is subject to a bug that depends on the input
* signal. For example with `Trig1.ar(Impulse.ar(0), 4 * SampleDur.ir)` one
* actually gets a high signal for five sample frames instead of four.
*
* ===Examples===
*
* {{{
* // hold dust spikes
* play { Trig1.ar(Dust.ar(1), 0.2) * SinOsc.ar(800) * 0.2 }
* }}}
*
* @see [[de.sciss.synth.ugen.Trig$ Trig]]
*/
object Trig1 {
/** @param in the trigger. This can be any signal. A trigger happens
* when the signal changes from non-positive to positive.
* @param dur the duration for which the ugens holds the value of 1
* when triggered
*/
def kr(in: GE, dur: GE = 0.1f): Trig1 = new Trig1(control, in, dur)
/** @param in the trigger. This can be any signal. A trigger happens
* when the signal changes from non-positive to positive.
* @param dur the duration for which the ugens holds the value of 1
* when triggered
*/
def ar(in: GE, dur: GE = 0.1f): Trig1 = new Trig1(audio, in, dur)
}
/** A UGen which outputs a value of 1 for a given duration when triggered.
*
* When a trigger occurs at the input, a value of 1 is output for the specified
* duration, otherwise zero is output. When a new trigger occurs while this ugens
* outputs 1, the hold-time is reset to the duration.
*
* ''Warning:'' The hold-time is subject to a bug that depends on the input
* signal. For example with `Trig1.ar(Impulse.ar(0), 4 * SampleDur.ir)` one
* actually gets a high signal for five sample frames instead of four.
*
* @param in the trigger. This can be any signal. A trigger happens
* when the signal changes from non-positive to positive.
* @param dur the duration for which the ugens holds the value of 1
* when triggered
*
* @see [[de.sciss.synth.ugen.Trig$ Trig]]
*/
final case class Trig1(rate: Rate, in: GE, dur: GE = 0.1f) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand, dur.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = UGen.SingleOut(name, rate, _args)
}
/** A UGen which holds and outputs an input value for a given duration when
* triggered.
*
* When a trigger occurs at the input, the input value is sampled and output for
* the specified duration, otherwise zero is output. When a new trigger occurs
* while this ugens outputs 1, the hold-time is reset to the duration.
*
* ''Warning:'' The hold-time is subject to a bug that depends on the input
* signal. For example with `Trig1.ar(Impulse.ar(0), 4 * SampleDur.ir)` one
* actually gets a high signal for five sample frames instead of four.
*
* ===Examples===
*
* {{{
* // hold dust spikes
* play { Trig.ar(Dust.ar(1), 0.2) * SinOsc.ar(800) * 0.2 }
* }}}
*
* @see [[de.sciss.synth.ugen.Trig1$ Trig1]]
*/
object Trig {
/** @param in the trigger. This can be any signal. A trigger happens
* when the signal changes from non-positive to positive.
* @param dur the duration for which the ugens holds the value of the
* input signal when triggered
*/
def kr(in: GE, dur: GE = 0.1f): Trig = new Trig(control, in, dur)
/** @param in the trigger. This can be any signal. A trigger happens
* when the signal changes from non-positive to positive.
* @param dur the duration for which the ugens holds the value of the
* input signal when triggered
*/
def ar(in: GE, dur: GE = 0.1f): Trig = new Trig(audio, in, dur)
}
/** A UGen which holds and outputs an input value for a given duration when
* triggered.
*
* When a trigger occurs at the input, the input value is sampled and output for
* the specified duration, otherwise zero is output. When a new trigger occurs
* while this ugens outputs 1, the hold-time is reset to the duration.
*
* ''Warning:'' The hold-time is subject to a bug that depends on the input
* signal. For example with `Trig1.ar(Impulse.ar(0), 4 * SampleDur.ir)` one
* actually gets a high signal for five sample frames instead of four.
*
* @param in the trigger. This can be any signal. A trigger happens
* when the signal changes from non-positive to positive.
* @param dur the duration for which the ugens holds the value of the
* input signal when triggered
*
* @see [[de.sciss.synth.ugen.Trig1$ Trig1]]
*/
final case class Trig(rate: Rate, in: GE, dur: GE = 0.1f) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand, dur.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = UGen.SingleOut(name, rate, _args)
}
/** A UGen that sends a value from the server to all notified clients upon
* receiving triggers. The message sent is
* `osc.Message("/tr", <(Int) nodeID>, <(Int) trigID>, <(Float) value>)` .
*
* For sending an array of values, or using an arbitrary reply command, see
* `SendReply` .
*
* @note The argument order is different from its sclang counterpart.
*
* @see [[de.sciss.synth.ugen.SendReply$ SendReply]]
*/
object SendTrig {
/** @param trig the trigger signal causing the value to be read and
* sent. A trigger occurs when passing from non-positive to
* positive.
* @param value a changing signal or constant that will be polled at
* the time of trigger, and its value passed with the
* trigger message
* @param id an arbitrary integer that will be sent along with the
* `"/tr"` message. This is useful to distinguish between
* several SendTrig instances per SynthDef.
*/
def kr(trig: GE, value: GE = 0.0f, id: GE = 0): SendTrig = new SendTrig(control, trig, value, id)
/** @param trig the trigger signal causing the value to be read and
* sent. A trigger occurs when passing from non-positive to
* positive.
* @param value a changing signal or constant that will be polled at
* the time of trigger, and its value passed with the
* trigger message
* @param id an arbitrary integer that will be sent along with the
* `"/tr"` message. This is useful to distinguish between
* several SendTrig instances per SynthDef.
*/
def ar(trig: GE, value: GE = 0.0f, id: GE = 0): SendTrig = new SendTrig(audio, trig, value, id)
}
/** A UGen that sends a value from the server to all notified clients upon
* receiving triggers. The message sent is
* `osc.Message("/tr", <(Int) nodeID>, <(Int) trigID>, <(Float) value>)` .
*
* For sending an array of values, or using an arbitrary reply command, see
* `SendReply` .
*
* @note The argument order is different from its sclang counterpart.
*
* @param trig the trigger signal causing the value to be read and
* sent. A trigger occurs when passing from non-positive to
* positive.
* @param value a changing signal or constant that will be polled at
* the time of trigger, and its value passed with the
* trigger message
* @param id an arbitrary integer that will be sent along with the
* `"/tr"` message. This is useful to distinguish between
* several SendTrig instances per SynthDef.
*
* @see [[de.sciss.synth.ugen.SendReply$ SendReply]]
*/
final case class SendTrig(rate: MaybeRate, trig: GE, value: GE = 0.0f, id: GE = 0)
extends UGenSource.ZeroOut with HasSideEffect {
protected def makeUGens: Unit = unwrap(this, Vector(trig.expand, id.expand, value.expand))
protected def makeUGen(_args: Vec[UGenIn]): Unit = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRateT(_args, 0, _rate)
UGen.ZeroOut(name, _rate, _args1)
}
}
/** A UGen which sends an sequence of values from the server to all notified
* clients upon receiving triggers. The message sent is
* `osc.Message(<(String) msgName>, <(Int) nodeID>, <(Int) replyID>, <(Float) values>*)`
* .
*
* For sending a single value, `SendTrig` provides an alternative.
*
* @note The argument order is different from its sclang counterpart.
*
* @see [[de.sciss.synth.ugen.SendTrig$ SendTrig]]
*/
object SendReply {
/** @param trig a non-positive to positive transition triggers a message
* @param values a graph element comprising the signal channels to be
* polled
* @param msgName a string specifying the OSC message's name. by
* convention, this should start with a forward slash and
* contain only 7-bit ascii characters.
* @param id an integer identifier which is contained in the reply
* message. While you can distinguish different `SendReply`
* instances from the same Synth by choosing different OSC
* message names, depending on the application you may use
* the same message name but different ids (similar to
* `SendTrig` ).
*/
def kr(trig: GE, values: GE, msgName: String = "/reply", id: GE = 0): SendReply =
new SendReply(control, trig, values, msgName, id)
/** @param trig a non-positive to positive transition triggers a message
* @param values a graph element comprising the signal channels to be
* polled
* @param msgName a string specifying the OSC message's name. by
* convention, this should start with a forward slash and
* contain only 7-bit ascii characters.
* @param id an integer identifier which is contained in the reply
* message. While you can distinguish different `SendReply`
* instances from the same Synth by choosing different OSC
* message names, depending on the application you may use
* the same message name but different ids (similar to
* `SendTrig` ).
*/
def ar(trig: GE, values: GE, msgName: String = "/reply", id: GE = 0): SendReply =
new SendReply(audio, trig, values, msgName, id)
}
/** A UGen which sends an sequence of values from the server to all notified
* clients upon receiving triggers. The message sent is
* `osc.Message(<(String) msgName>, <(Int) nodeID>, <(Int) replyID>, <(Float) values>*)`
* .
*
* For sending a single value, `SendTrig` provides an alternative.
*
* @note The argument order is different from its sclang counterpart.
*
* @param trig a non-positive to positive transition triggers a message
* @param values a graph element comprising the signal channels to be
* polled
* @param msgName a string specifying the OSC message's name. by
* convention, this should start with a forward slash and
* contain only 7-bit ascii characters.
* @param id an integer identifier which is contained in the reply
* message. While you can distinguish different `SendReply`
* instances from the same Synth by choosing different OSC
* message names, depending on the application you may use
* the same message name but different ids (similar to
* `SendTrig` ).
*
* @see [[de.sciss.synth.ugen.SendTrig$ SendTrig]]
*/
final case class SendReply(rate: MaybeRate, trig: GE, values: GE, msgName: String = "/reply", id: GE = 0)
extends UGenSource.ZeroOut with HasSideEffect {
protected def makeUGens: Unit =
unwrap(this, Vector(trig.expand, id.expand).++(stringArg(msgName).++(values.expand.outputs)))
protected def makeUGen(_args: Vec[UGenIn]): Unit = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRateT(_args, 0, _rate)
UGen.ZeroOut(name, _rate, _args1)
}
}
/** A UGen for printing the current output value of its input to the console.
*
* @see [[de.sciss.synth.ugen.SendTrig$ SendTrig]]
*/
object Poll {
/** @param trig a non-positive to positive transition telling Poll to
* return a value
* @param in the signal you want to poll
* @param label a string or symbol to be printed with the polled value
* @param trigID if greater then 0, a `"/tr"` OSC message is sent back
* to the client (similar to `SendTrig` )
*/
def kr(trig: GE, in: GE, label: String = "poll", trigID: GE = -1): Poll =
new Poll(control, trig, in, label, trigID)
/** @param trig a non-positive to positive transition telling Poll to
* return a value
* @param in the signal you want to poll
* @param label a string or symbol to be printed with the polled value
* @param trigID if greater then 0, a `"/tr"` OSC message is sent back
* to the client (similar to `SendTrig` )
*/
def ar(trig: GE, in: GE, label: String = "poll", trigID: GE = -1): Poll =
new Poll(audio, trig, in, label, trigID)
}
/** A UGen for printing the current output value of its input to the console.
*
* @param trig a non-positive to positive transition telling Poll to
* return a value
* @param in the signal you want to poll
* @param label a string or symbol to be printed with the polled value
* @param trigID if greater then 0, a `"/tr"` OSC message is sent back
* to the client (similar to `SendTrig` )
*
* @see [[de.sciss.synth.ugen.SendTrig$ SendTrig]]
*/
final case class Poll(rate: MaybeRate, trig: GE, in: GE, label: String = "poll", trigID: GE = -1)
extends UGenSource.SingleOut with HasSideEffect {
protected def makeUGens: UGenInLike =
unwrap(this, Vector(trig.expand, in.expand, trigID.expand).++(stringArg(label)))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRateT(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1, hasSideEffect = true)
}
}
/** A UGen that toggles like a flip-flop between zero and one upon receiving a
* trigger. The flip-flop initially outputs zero and changes to one when the first
* trigger arrives.
*
* ===Examples===
*
* {{{
* // mouse-button toggle
* play {
* // make sure lag is zero, otherwise the output
* // never falls back exactly to zero!
* val tr = MouseButton.kr(lag = 0)
* val ff = ToggleFF.kr(tr)
* SinOsc.ar(ff.madd(400, 800)) * 0.1
* }
* }}}
*
* @see [[de.sciss.synth.ugen.SetResetFF$ SetResetFF]]
*/
object ToggleFF {
/** @param trig a signal to trigger the flip-flop. a trigger occurs
* when the signal changes from non-positive to positive.
*/
def kr(trig: GE): ToggleFF = new ToggleFF(control, trig)
/** @param trig a signal to trigger the flip-flop. a trigger occurs
* when the signal changes from non-positive to positive.
*/
def ar(trig: GE): ToggleFF = new ToggleFF(audio, trig)
}
/** A UGen that toggles like a flip-flop between zero and one upon receiving a
* trigger. The flip-flop initially outputs zero and changes to one when the first
* trigger arrives.
*
* @param trig a signal to trigger the flip-flop. a trigger occurs
* when the signal changes from non-positive to positive.
*
* @see [[de.sciss.synth.ugen.SetResetFF$ SetResetFF]]
*/
final case class ToggleFF(rate: MaybeRate, trig: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(trig.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRateT(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A flip-flop UGen with two inputs, one (set) triggering an output of 1.0, the
* other (reset) triggering an output of 0.0. Subsequent triggers happening within
* the same input slot have no effect. If both inputs receive a trigger at the same
* time, the ''reset'' input takes precedence.
*
* ===Examples===
*
* {{{
* // mouse-button toggle
* play {
* // make sure lag is zero, otherwise the output
* // never falls back exactly to zero!
* val set = MouseButton.kr(lag = 0)
* val reset = Impulse.kr(1)
* val ff = SetResetFF.kr(set, reset)
* SinOsc.ar(ff.madd(400, 800)) * 0.1
* }
* }}}
* {{{
* // limit trigger rate
* play {
* // with a combination of TDelay and SetResetFF
* // we can build a filter that lets triggers
* // pass at a maximum rate.
* val dur = 1.0 // minimum spacing between triggers
* val in = Dust.ar(10) // high frequency trigger
* val lim = SetResetFF.ar(in, TDelay.ar(in, dur))
* val time = Timer.ar(lim)
* time.poll(lim, "bang")
* ()
* }
* }}}
*
* @see [[de.sciss.synth.ugen.ToggleFF$ ToggleFF]]
*/
object SetResetFF {
/** @param trig trigger that sets output to 1. A trigger happens when
* the signal changes from non-positive to positive.
* @param reset trigger that sets output to 0. A trigger happens when
* the signal changes from non-positive to positive.
*/
def kr(trig: GE, reset: GE): SetResetFF = new SetResetFF(control, trig, reset)
/** @param trig trigger that sets output to 1. A trigger happens when
* the signal changes from non-positive to positive.
* @param reset trigger that sets output to 0. A trigger happens when
* the signal changes from non-positive to positive.
*/
def ar(trig: GE, reset: GE): SetResetFF = new SetResetFF(audio, trig, reset)
}
/** A flip-flop UGen with two inputs, one (set) triggering an output of 1.0, the
* other (reset) triggering an output of 0.0. Subsequent triggers happening within
* the same input slot have no effect. If both inputs receive a trigger at the same
* time, the ''reset'' input takes precedence.
*
* @param trig trigger that sets output to 1. A trigger happens when
* the signal changes from non-positive to positive.
* @param reset trigger that sets output to 0. A trigger happens when
* the signal changes from non-positive to positive.
*
* @see [[de.sciss.synth.ugen.ToggleFF$ ToggleFF]]
*/
final case class SetResetFF(rate: MaybeRate, trig: GE, reset: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(trig.expand, reset.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRateT(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A sample-and-hold UGen. When triggered, a new value is taken from the input and
* hold until the next trigger occurs.
*
* Before the first trigger is registered, this UGen outputs zero.
*
* @see [[de.sciss.synth.ugen.Gate$ Gate]]
* @see [[de.sciss.synth.ugen.Demand$ Demand]]
*/
object Latch {
/** @param in the input signal
* @param trig the trigger. The can be any signal. A trigger happens
* when the signal changes from non-positive to positive.
*/
def kr(in: GE, trig: GE = 1): Latch = new Latch(control, in, trig)
/** @param in the input signal
* @param trig the trigger. The can be any signal. A trigger happens
* when the signal changes from non-positive to positive.
*/
def ar(in: GE, trig: GE = 1): Latch = new Latch(audio, in, trig)
}
/** A sample-and-hold UGen. When triggered, a new value is taken from the input and
* hold until the next trigger occurs.
*
* Before the first trigger is registered, this UGen outputs zero.
*
* @param in the input signal
* @param trig the trigger. The can be any signal. A trigger happens
* when the signal changes from non-positive to positive.
*
* @see [[de.sciss.synth.ugen.Gate$ Gate]]
* @see [[de.sciss.synth.ugen.Demand$ Demand]]
*/
final case class Latch(rate: Rate, in: GE, trig: GE = 1) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand, trig.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = UGen.SingleOut(name, rate, _args)
}
/** A gate or hold UGen. It allows the input signal value to pass when the `gate`
* argument is positive, otherwise it holds last value.
*
* Before the first high gate value is registered, this UGen outputs zero.
*
* @see [[de.sciss.synth.ugen.Latch$ Latch]]
*/
object Gate {
/** @param in the input signal to gate
* @param gate the signal specifying whether to pass the input signal
* (when greater than zero) or whether to close the gate
* and hold the last value (when less than or equal to
* zero)
*/
def kr(in: GE, gate: GE): Gate = new Gate(control, in, gate)
/** @param in the input signal to gate
* @param gate the signal specifying whether to pass the input signal
* (when greater than zero) or whether to close the gate
* and hold the last value (when less than or equal to
* zero)
*/
def ar(in: GE, gate: GE): Gate = new Gate(audio, in, gate)
}
/** A gate or hold UGen. It allows the input signal value to pass when the `gate`
* argument is positive, otherwise it holds last value.
*
* Before the first high gate value is registered, this UGen outputs zero.
*
* @param in the input signal to gate
* @param gate the signal specifying whether to pass the input signal
* (when greater than zero) or whether to close the gate
* and hold the last value (when less than or equal to
* zero)
*
* @see [[de.sciss.synth.ugen.Latch$ Latch]]
*/
final case class Gate(rate: MaybeRate, in: GE, gate: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand, gate.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRate(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A Schmidt trigger UGen. Initially it outputs zero. When the input signal rises
* above `hi` , its output switches to 1.0, which is hold until the signal falls
* below `lo` , switching the output again to 0.0. The produces a kind of
* hysteresis behavior, preventing heavy oscillations in a noisy system which might
* occur with a single-threshold trigger.
*/
object Schmidt {
/** @param in input signal to be analyzed
* @param lo low threshold
* @param hi high threshold
*/
def kr(in: GE, lo: GE = 0.0f, hi: GE = 1.0f): Schmidt = new Schmidt(control, in, lo, hi)
/** @param in input signal to be analyzed
* @param lo low threshold
* @param hi high threshold
*/
def ar(in: GE, lo: GE = 0.0f, hi: GE = 1.0f): Schmidt = new Schmidt(audio, in, lo, hi)
}
/** A Schmidt trigger UGen. Initially it outputs zero. When the input signal rises
* above `hi` , its output switches to 1.0, which is hold until the signal falls
* below `lo` , switching the output again to 0.0. The produces a kind of
* hysteresis behavior, preventing heavy oscillations in a noisy system which might
* occur with a single-threshold trigger.
*
* @param in input signal to be analyzed
* @param lo low threshold
* @param hi high threshold
*/
final case class Schmidt(rate: MaybeRate, in: GE, lo: GE = 0.0f, hi: GE = 1.0f)
extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand, lo.expand, hi.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRate(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A UGen that decimates trigger by outputting one impulse each time a certain
* number of triggers at its input have been received.
*
* ===Examples===
*
* {{{
* // every two mouse-button clicks
* play {
* val in = MouseButton.kr(lag = 0)
* in.poll(in, "in")
* val out = PulseDivider.kr(in, 2, -1)
* out.poll(out, "out")
* ()
* }
* }}}
* {{{
* // rhythmic 1:4 pattern
* play {
* val p = Impulse.ar(8)
* val d = PulseDivider.ar(p, 4)
* val a = SinOsc.ar(1200) * Decay2.ar(p, 0.005, 0.1) * 0.3
* val b = SinOsc.ar( 600) * Decay2.ar(d, 0.005, 0.5) * 0.3
* Seq(a, b)
* }
* }}}
*
* @see [[de.sciss.synth.ugen.PulseCount$ PulseCount]]
* @see [[de.sciss.synth.ugen.Stepper$ Stepper]]
*/
object PulseDivider {
/** @param trig a trigger occurs when the signal changes from
* non-positive to positive.
* @param div decimation factor of the UGen. A value of 1 would cause
* an output trigger for each input trigger, whereas a
* value of 2 would cause an output trigger each time the
* internal counter has seen two input triggers.
* @param start value of the internal counter. For example, if `div` is
* `2` , then a `start` value of `0` (default) means that
* the first output trigger happens after two input
* triggers, a `start` value of `1` means that the first
* output trigger happens after just one input trigger.
* Negative values can increase the number of required
* input triggers for the first output trigger. For
* example, if `start` is `-1` , the first output trigger
* happens after three input triggers.
*/
def kr(trig: GE, div: GE = 2, start: GE = 0): PulseDivider =
new PulseDivider(control, trig, div, start)
/** @param trig a trigger occurs when the signal changes from
* non-positive to positive.
* @param div decimation factor of the UGen. A value of 1 would cause
* an output trigger for each input trigger, whereas a
* value of 2 would cause an output trigger each time the
* internal counter has seen two input triggers.
* @param start value of the internal counter. For example, if `div` is
* `2` , then a `start` value of `0` (default) means that
* the first output trigger happens after two input
* triggers, a `start` value of `1` means that the first
* output trigger happens after just one input trigger.
* Negative values can increase the number of required
* input triggers for the first output trigger. For
* example, if `start` is `-1` , the first output trigger
* happens after three input triggers.
*/
def ar(trig: GE, div: GE = 2, start: GE = 0): PulseDivider = new PulseDivider(audio, trig, div, start)
}
/** A UGen that decimates trigger by outputting one impulse each time a certain
* number of triggers at its input have been received.
*
* @param trig a trigger occurs when the signal changes from
* non-positive to positive.
* @param div decimation factor of the UGen. A value of 1 would cause
* an output trigger for each input trigger, whereas a
* value of 2 would cause an output trigger each time the
* internal counter has seen two input triggers.
* @param start value of the internal counter. For example, if `div` is
* `2` , then a `start` value of `0` (default) means that
* the first output trigger happens after two input
* triggers, a `start` value of `1` means that the first
* output trigger happens after just one input trigger.
* Negative values can increase the number of required
* input triggers for the first output trigger. For
* example, if `start` is `-1` , the first output trigger
* happens after three input triggers.
*
* @see [[de.sciss.synth.ugen.PulseCount$ PulseCount]]
* @see [[de.sciss.synth.ugen.Stepper$ Stepper]]
*/
final case class PulseDivider(rate: MaybeRate, trig: GE, div: GE = 2, start: GE = 0)
extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(trig.expand, div.expand, start.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRateT(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A UGen that counts the number of triggers observed.
*
* ===Examples===
*
* {{{
* // count mouse clicks, reset at 10
* play {
* val tr = MouseButton.kr(lag = 0)
* val reset = PulseDivider.kr(tr, 10)
* val c = PulseCount.kr(tr, reset)
* c.poll(tr + Impulse.kr(0), "count")
* ()
* }
* }}}
*
* @see [[de.sciss.synth.ugen.Stepper$ Stepper]]
*/
object PulseCount {
/** @param trig a trigger happens when the signal changes from
* non-positive to positive
* @param reset when triggered, resets the counter to zero. When both
* `trig` and `reset` are triggered at the same time, the
* `reset` takes precedence (output will be zero).
*/
def kr(trig: GE, reset: GE = 0): PulseCount = new PulseCount(control, trig, reset)
/** @param trig a trigger happens when the signal changes from
* non-positive to positive
* @param reset when triggered, resets the counter to zero. When both
* `trig` and `reset` are triggered at the same time, the
* `reset` takes precedence (output will be zero).
*/
def ar(trig: GE, reset: GE = 0): PulseCount = new PulseCount(audio, trig, reset)
}
/** A UGen that counts the number of triggers observed.
*
* @param trig a trigger happens when the signal changes from
* non-positive to positive
* @param reset when triggered, resets the counter to zero. When both
* `trig` and `reset` are triggered at the same time, the
* `reset` takes precedence (output will be zero).
*
* @see [[de.sciss.synth.ugen.Stepper$ Stepper]]
*/
final case class PulseCount(rate: MaybeRate, trig: GE, reset: GE = 0) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(trig.expand, reset.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRateT(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A pulse counting UGen. Each trigger increments a counter which is output as a
* signal. The counter wraps inside the interval from `lo` to `hi` (inclusive).
* That if you use a `lo` other than zero, you might want to adjust `resetVal` as
* well. `Stepper` always starts with the value in `resetVal` , no matter what `lo`
* is or whether the `reset` trigger is high or not.
*
* ===Examples===
*
* {{{
* // arpeggio
* play {
* val tr = Impulse.ar(10)
* val step = Stepper.ar(tr, lo = 4, hi = 16)
* val freq = step * 100
* SinOsc.ar(freq) * AmpComp.ar(freq) * 0.1
* }
* }}}
*
* @see [[de.sciss.synth.ugen.PulseCount$ PulseCount]]
*/
object Stepper {
/** @param trig The trigger signal which increments the counter. A
* trigger happens when the signal changes from
* non-positive to positive. Note that if the UGen is
* created with the trigger initially high, the counter
* will also be incremented immediately. Thus a
* `Stepper.kr(Impulse.kr(1))` will begin by outputting `1`
* . If you want to avoid this, you could their subtract
* `Impulse.kr(0)` from the trigger input, or set
* `resetVal` to `hi` . E.g.
* `Stepper.kr(Impulse.kr(1), lo = 0, hi = 4, resetVal = 4)`
* will produce the sequence 0, 1, 2, 4, 0, ...
* @param reset A trigger which resets the counter to `resetVal`
* immediately.
* @param lo The minimum value output. For a decremental `step`
* value, the counter jumps to `hi` if it were to fall
* below `lo` .
* @param hi The maximum value output. For an incremental `step`
* value, the counter jumps to `lo` if it were to rise
* beyond `hi` . Note that values greater than `0x7FFFFFBF`
* (the default) cause numeric overflow and the UGen to
* malfunction.
* @param step The amount by which the counter increases or decreases
* upon receiving triggers. Note that if you use a
* decremental counter, still `lo` must be the minimum and
* `hi` must be the maximum value output. If `lo` > `hi` ,
* the UGen behaves wrongly. In the case of decremental
* counter, set `resetVal` to `hi` . E.g. to count from 4
* down to 0, use
* `Stepper.kr(trig, lo = 0, hi = 4, step = -1, resetVal = 4)`
* , or, if you want to ignore an initial high trigger, you
* could do
* `Stepper.kr(Impulse.kr(1), lo = 0, hi = 4, step = -1, resetVal = 0)`
* -- so `resetVal` is `lo` but due to the initial trigger
* from `Impulse` the `Stepper` will in fact start
* outputting from `4` .
*/
def kr(trig: GE, reset: GE = 0, lo: GE = 0, hi: GE = 2147483583, step: GE = 1, resetVal: GE = 0): Stepper =
new Stepper(control, trig, reset, lo, hi, step, resetVal)
/** @param trig The trigger signal which increments the counter. A
* trigger happens when the signal changes from
* non-positive to positive. Note that if the UGen is
* created with the trigger initially high, the counter
* will also be incremented immediately. Thus a
* `Stepper.kr(Impulse.kr(1))` will begin by outputting `1`
* . If you want to avoid this, you could their subtract
* `Impulse.kr(0)` from the trigger input, or set
* `resetVal` to `hi` . E.g.
* `Stepper.kr(Impulse.kr(1), lo = 0, hi = 4, resetVal = 4)`
* will produce the sequence 0, 1, 2, 4, 0, ...
* @param reset A trigger which resets the counter to `resetVal`
* immediately.
* @param lo The minimum value output. For a decremental `step`
* value, the counter jumps to `hi` if it were to fall
* below `lo` .
* @param hi The maximum value output. For an incremental `step`
* value, the counter jumps to `lo` if it were to rise
* beyond `hi` . Note that values greater than `0x7FFFFFBF`
* (the default) cause numeric overflow and the UGen to
* malfunction.
* @param step The amount by which the counter increases or decreases
* upon receiving triggers. Note that if you use a
* decremental counter, still `lo` must be the minimum and
* `hi` must be the maximum value output. If `lo` > `hi` ,
* the UGen behaves wrongly. In the case of decremental
* counter, set `resetVal` to `hi` . E.g. to count from 4
* down to 0, use
* `Stepper.kr(trig, lo = 0, hi = 4, step = -1, resetVal = 4)`
* , or, if you want to ignore an initial high trigger, you
* could do
* `Stepper.kr(Impulse.kr(1), lo = 0, hi = 4, step = -1, resetVal = 0)`
* -- so `resetVal` is `lo` but due to the initial trigger
* from `Impulse` the `Stepper` will in fact start
* outputting from `4` .
*/
def ar(trig: GE, reset: GE = 0, lo: GE = 0, hi: GE = 2147483583, step: GE = 1, resetVal: GE = 0): Stepper =
new Stepper(audio, trig, reset, lo, hi, step, resetVal)
}
/** A pulse counting UGen. Each trigger increments a counter which is output as a
* signal. The counter wraps inside the interval from `lo` to `hi` (inclusive).
* That if you use a `lo` other than zero, you might want to adjust `resetVal` as
* well. `Stepper` always starts with the value in `resetVal` , no matter what `lo`
* is or whether the `reset` trigger is high or not.
*
* @param trig The trigger signal which increments the counter. A
* trigger happens when the signal changes from
* non-positive to positive. Note that if the UGen is
* created with the trigger initially high, the counter
* will also be incremented immediately. Thus a
* `Stepper.kr(Impulse.kr(1))` will begin by outputting `1`
* . If you want to avoid this, you could their subtract
* `Impulse.kr(0)` from the trigger input, or set
* `resetVal` to `hi` . E.g.
* `Stepper.kr(Impulse.kr(1), lo = 0, hi = 4, resetVal = 4)`
* will produce the sequence 0, 1, 2, 4, 0, ...
* @param reset A trigger which resets the counter to `resetVal`
* immediately.
* @param lo The minimum value output. For a decremental `step`
* value, the counter jumps to `hi` if it were to fall
* below `lo` .
* @param hi The maximum value output. For an incremental `step`
* value, the counter jumps to `lo` if it were to rise
* beyond `hi` . Note that values greater than `0x7FFFFFBF`
* (the default) cause numeric overflow and the UGen to
* malfunction.
* @param step The amount by which the counter increases or decreases
* upon receiving triggers. Note that if you use a
* decremental counter, still `lo` must be the minimum and
* `hi` must be the maximum value output. If `lo` > `hi` ,
* the UGen behaves wrongly. In the case of decremental
* counter, set `resetVal` to `hi` . E.g. to count from 4
* down to 0, use
* `Stepper.kr(trig, lo = 0, hi = 4, step = -1, resetVal = 4)`
* , or, if you want to ignore an initial high trigger, you
* could do
* `Stepper.kr(Impulse.kr(1), lo = 0, hi = 4, step = -1, resetVal = 0)`
* -- so `resetVal` is `lo` but due to the initial trigger
* from `Impulse` the `Stepper` will in fact start
* outputting from `4` .
*
* @see [[de.sciss.synth.ugen.PulseCount$ PulseCount]]
*/
final case class Stepper(rate: MaybeRate, trig: GE, reset: GE = 0, lo: GE = 0, hi: GE = 2147483583, step: GE = 1, resetVal: GE = 0)
extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike =
unwrap(this, Vector(trig.expand, reset.expand, lo.expand, hi.expand, step.expand, resetVal.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRateT(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A delay UGen for trigger signals. Other than a normal buffer delay, any new
* trigger arriving in the time between the previous trigger and the passing of the
* delay time is ignored.
*/
object TDelay {
/** @param trig The input trigger. A trigger is recognized when the
* signal passes from non-positive to positive. Note that,
* no matter what the amplitude of the input trigger is,
* the UGen will output a delayed trigger of amplitude 1.0.
* @param dur The delay time in seconds.
*/
def kr(trig: GE, dur: GE = 0.1f): TDelay = new TDelay(control, trig, dur)
/** @param trig The input trigger. A trigger is recognized when the
* signal passes from non-positive to positive. Note that,
* no matter what the amplitude of the input trigger is,
* the UGen will output a delayed trigger of amplitude 1.0.
* @param dur The delay time in seconds.
*/
def ar(trig: GE, dur: GE = 0.1f): TDelay = new TDelay(audio, trig, dur)
}
/** A delay UGen for trigger signals. Other than a normal buffer delay, any new
* trigger arriving in the time between the previous trigger and the passing of the
* delay time is ignored.
*
* @param trig The input trigger. A trigger is recognized when the
* signal passes from non-positive to positive. Note that,
* no matter what the amplitude of the input trigger is,
* the UGen will output a delayed trigger of amplitude 1.0.
* @param dur The delay time in seconds.
*/
final case class TDelay(rate: MaybeRate, trig: GE, dur: GE = 0.1f) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(trig.expand, dur.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRateT(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A pitch estimation UGen based on counting the zero-crossings of the input
* signal. This is a very crude pitch follower, but can be useful in some
* situations.
*
* ===Examples===
*
* {{{
* // reconstruct sine frequency
* play {
* val f1 = SinOsc.kr(0.2).madd(600, 700).roundTo(100)
* val a = SinOsc.ar(f1) * 0.1
* val f2 = ZeroCrossing.ar(a)
* f2.poll(10, "estimation")
* val b = SinOsc.ar(f2) * 0.1
* Seq(a, b)
* }
* }}}
*
* @see [[de.sciss.synth.ugen.Pitch$ Pitch]]
*/
object ZeroCrossing {
/** @param in signal to analyze
*/
def kr(in: GE): ZeroCrossing = new ZeroCrossing(control, in)
/** @param in signal to analyze
*/
def ar(in: GE): ZeroCrossing = new ZeroCrossing(audio, in)
}
/** A pitch estimation UGen based on counting the zero-crossings of the input
* signal. This is a very crude pitch follower, but can be useful in some
* situations.
*
* @param in signal to analyze
*
* @see [[de.sciss.synth.ugen.Pitch$ Pitch]]
*/
final case class ZeroCrossing(rate: MaybeRate, in: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRate(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A UGen that returns time since last triggered. The time returned is in seconds
* and is measured from the last received trigger. Note that currently it seems the
* initial memory is at -1 sample, so for `Impulse.ar(1)` the result (at 44.1 kHz)
* is 2.26757e-05, followed strangely by 1.00002, and then (as expected) 1.0.
*
* @see [[de.sciss.synth.ugen.Sweep$ Sweep]]
*/
object Timer {
/** @param trig the trigger to update the output signal. A trigger
* occurs when trig signal crosses from non-positive to
* positive.
*/
def kr(trig: GE): Timer = new Timer(control, trig)
/** @param trig the trigger to update the output signal. A trigger
* occurs when trig signal crosses from non-positive to
* positive.
*/
def ar(trig: GE): Timer = new Timer(audio, trig)
}
/** A UGen that returns time since last triggered. The time returned is in seconds
* and is measured from the last received trigger. Note that currently it seems the
* initial memory is at -1 sample, so for `Impulse.ar(1)` the result (at 44.1 kHz)
* is 2.26757e-05, followed strangely by 1.00002, and then (as expected) 1.0.
*
* @param trig the trigger to update the output signal. A trigger
* occurs when trig signal crosses from non-positive to
* positive.
*
* @see [[de.sciss.synth.ugen.Sweep$ Sweep]]
*/
final case class Timer(rate: MaybeRate, trig: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(trig.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRateT(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A UGen which starts a linear raise from zero each time it is triggered.
*
* When speed is one, one gets a continually-updating measurement of the time (in
* seconds) since the last trigger.
*
* @see [[de.sciss.synth.ugen.Ramp$ Ramp]]
* @see [[de.sciss.synth.ugen.Phasor$ Phasor]]
* @see [[de.sciss.synth.ugen.Line$ Line]]
*/
object Sweep {
/** @param trig the trigger that restarts the ramp, when passing from
* non-positive to positive
* @param speed the amount of increment of the output signal per
* second. In SCLang this argument is named `rate` , while
* ScalaCollider uses `speed` to avoid conflict with the
* UGen's calculation rate.
*/
def kr(trig: GE, speed: GE): Sweep = new Sweep(control, trig, speed)
/** @param trig the trigger that restarts the ramp, when passing from
* non-positive to positive
* @param speed the amount of increment of the output signal per
* second. In SCLang this argument is named `rate` , while
* ScalaCollider uses `speed` to avoid conflict with the
* UGen's calculation rate.
*/
def ar(trig: GE, speed: GE): Sweep = new Sweep(audio, trig, speed)
}
/** A UGen which starts a linear raise from zero each time it is triggered.
*
* When speed is one, one gets a continually-updating measurement of the time (in
* seconds) since the last trigger.
*
* @param trig the trigger that restarts the ramp, when passing from
* non-positive to positive
* @param speed the amount of increment of the output signal per
* second. In SCLang this argument is named `rate` , while
* ScalaCollider uses `speed` to avoid conflict with the
* UGen's calculation rate.
*
* @see [[de.sciss.synth.ugen.Ramp$ Ramp]]
* @see [[de.sciss.synth.ugen.Phasor$ Phasor]]
* @see [[de.sciss.synth.ugen.Line$ Line]]
*/
final case class Sweep(rate: Rate, trig: GE, speed: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(trig.expand, speed.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = UGen.SingleOut(name, rate, _args)
}
/** A linear repeating ramp UGen between start and end values. Using a trigger
* input, it can be reset to a specific position. Upon reaching the end of its
* ramp, `Phasor` will wrap back to its start value. '''Note''': Since `end` is
* defined as the wrap point, its value is never actually output.
*
* ===Examples===
*
* {{{
* // glissandi
* play {
* // mouse-x controls phasor speed
* val freq = MouseX.kr(0.2, 2, 1)
* // mouse button can be used to jump back
* val reset = MouseButton.kr(lag = 0)
* val p = Phasor.ar(reset, freq / SampleRate.ir)
* SinOsc.ar(p.linlin(0, 1, 600, 1000)) * 0.1
* }
* }}}
*
* @see [[de.sciss.synth.ugen.Ramp$ Ramp]]
* @see [[de.sciss.synth.ugen.Stepper$ Stepper]]
* @see [[de.sciss.synth.ugen.Line$ Line]]
* @see [[de.sciss.synth.ugen.LFSaw$ LFSaw]]
*/
object Phasor {
def kr: Phasor = kr()
/** @param trig trigger signal that causes the phasor to jump to the
* `resetVal` position
* @param speed amount of increment ''per sample frame''. I.e at a
* speed of 1, each sample output by the UGen will be 1
* greater than the preceding sample. To achieve a specific
* frequency `f` in Hertz, use a speed value of
* `f / SampleRate.ir` .
* @param lo start value of the ramp
* @param hi end value of the ramp (exclusive)
* @param resetVal value to jump to upon receiving a trigger in the `trig`
* input
*/
def kr(trig: GE = 0, speed: GE = 1.0f, lo: GE = 0.0f, hi: GE = 1.0f, resetVal: GE = 0.0f): Phasor =
new Phasor(control, trig, speed, lo, hi, resetVal)
def ar: Phasor = ar()
/** @param trig trigger signal that causes the phasor to jump to the
* `resetVal` position
* @param speed amount of increment ''per sample frame''. I.e at a
* speed of 1, each sample output by the UGen will be 1
* greater than the preceding sample. To achieve a specific
* frequency `f` in Hertz, use a speed value of
* `f / SampleRate.ir` .
* @param lo start value of the ramp
* @param hi end value of the ramp (exclusive)
* @param resetVal value to jump to upon receiving a trigger in the `trig`
* input
*/
def ar(trig: GE = 0, speed: GE = 1.0f, lo: GE = 0.0f, hi: GE = 1.0f, resetVal: GE = 0.0f): Phasor =
new Phasor(audio, trig, speed, lo, hi, resetVal)
}
/** A linear repeating ramp UGen between start and end values. Using a trigger
* input, it can be reset to a specific position. Upon reaching the end of its
* ramp, `Phasor` will wrap back to its start value. '''Note''': Since `end` is
* defined as the wrap point, its value is never actually output.
*
* @param trig trigger signal that causes the phasor to jump to the
* `resetVal` position
* @param speed amount of increment ''per sample frame''. I.e at a
* speed of 1, each sample output by the UGen will be 1
* greater than the preceding sample. To achieve a specific
* frequency `f` in Hertz, use a speed value of
* `f / SampleRate.ir` .
* @param lo start value of the ramp
* @param hi end value of the ramp (exclusive)
* @param resetVal value to jump to upon receiving a trigger in the `trig`
* input
*
* @see [[de.sciss.synth.ugen.Ramp$ Ramp]]
* @see [[de.sciss.synth.ugen.Stepper$ Stepper]]
* @see [[de.sciss.synth.ugen.Line$ Line]]
* @see [[de.sciss.synth.ugen.LFSaw$ LFSaw]]
*/
final case class Phasor(rate: Rate, trig: GE = 0, speed: GE = 1.0f, lo: GE = 0.0f, hi: GE = 1.0f, resetVal: GE = 0.0f)
extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike =
unwrap(this, Vector(trig.expand, speed.expand, lo.expand, hi.expand, resetVal.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = UGen.SingleOut(name, rate, _args)
}
/** A UGen to measure a signal's peak amplitude. Technically, this UGen works like
* `RunningMax` after the absolute value of the input signal is taken.
*
* The UGen keeps an internal state that reflects the maximum absolute input value
* observed. When a trigger occurs at the reset input, it first copies the current
* maximum value to its output and then (quasi-simultaneously) resets its internal
* state to the current absolute input value. This way, the peak value seen from
* the outside at trigger time is the correct peak value up to that moment. See the
* 'illustrate timing' example to understand this timing.
*
* ===Examples===
*
* {{{
* // illustrate timing
* play {
* val i = Impulse.ar(0)
* // first impulse after 100ms
* val t1 = DelayN.ar(i * 1.0 , 0.100, 0.100)
* // one sample later
* val t2 = Delay1.ar(t1) * 0.5
* // another sample later
* val t3 = Delay1.ar(t2)
* val p = Peak.ar(t1 + t2, t2)
* // at t1, peak has already seen t1
* p.poll(t1, "t1")
* // at t2, peak still reports 1.0, while internally resetting
* p.poll(t2, "t2")
* // at t3, we observe 0.5, therefore peak did reset at t2
* p.poll(t3, "t3")
* ()
* }
* }}}
*
* @see [[de.sciss.synth.ugen.RunningMin$ RunningMin]]
* @see [[de.sciss.synth.ugen.RunningMax$ RunningMax]]
* @see [[de.sciss.synth.ugen.RunningSum$ RunningSum]]
* @see [[de.sciss.synth.ugen.PeakFollower$ PeakFollower]]
* @see [[de.sciss.synth.ugen.Amplitude$ Amplitude]]
*/
object Peak {
/** @param in input signal to analyze
* @param trig resets the maximum observed value to the current
* absolute value of the input signal
*/
def kr(in: GE, trig: GE): Peak = new Peak(control, in, trig)
/** @param in input signal to analyze
* @param trig resets the maximum observed value to the current
* absolute value of the input signal
*/
def ar(in: GE, trig: GE): Peak = new Peak(audio, in, trig)
}
/** A UGen to measure a signal's peak amplitude. Technically, this UGen works like
* `RunningMax` after the absolute value of the input signal is taken.
*
* The UGen keeps an internal state that reflects the maximum absolute input value
* observed. When a trigger occurs at the reset input, it first copies the current
* maximum value to its output and then (quasi-simultaneously) resets its internal
* state to the current absolute input value. This way, the peak value seen from
* the outside at trigger time is the correct peak value up to that moment. See the
* 'illustrate timing' example to understand this timing.
*
* @param in input signal to analyze
* @param trig resets the maximum observed value to the current
* absolute value of the input signal
*
* @see [[de.sciss.synth.ugen.RunningMin$ RunningMin]]
* @see [[de.sciss.synth.ugen.RunningMax$ RunningMax]]
* @see [[de.sciss.synth.ugen.RunningSum$ RunningSum]]
* @see [[de.sciss.synth.ugen.PeakFollower$ PeakFollower]]
* @see [[de.sciss.synth.ugen.Amplitude$ Amplitude]]
*/
final case class Peak(rate: Rate, in: GE, trig: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand, trig.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _args1 = if (rate.==(audio)) matchRate(_args, 0, audio) else _args
UGen.SingleOut(name, rate, _args1)
}
}
/** A UGen to measure a signal's minimum value between triggers.
*
* The UGen keeps an internal state that reflects the minimum input value
* observed. When a trigger occurs at the reset input, it first copies the current
* minimum value to its output and then (quasi-simultaneously) resets its internal
* state to the current input value.
*
* ===Examples===
*
* {{{
* // illustrate timing
* play {
* val n = BrownNoise.ar
* val t = Impulse.ar(4)
* val r = RunningMin.ar(n, t)
* // value at the moment the reset
* // is triggered
* n.poll(t, "cur")
* // this is the minimum of the
* // recent two input samples
* // (the one during reset and
* // the current one), therefore
* // equal or slightly less than
* // the 'cur' value
* r.poll(Delay1.ar(t), "min")
* ()
* }
* }}}
*
* @see [[de.sciss.synth.ugen.RunningMax$ RunningMax]]
* @see [[de.sciss.synth.ugen.Peak$ Peak]]
* @see [[de.sciss.synth.ugen.RunningSum$ RunningSum]]
*/
object RunningMin {
/** @param in input signal to analyze
* @param trig resets the minimum observed value to the current value
* of the input signal
*/
def kr(in: GE, trig: GE): RunningMin = new RunningMin(control, in, trig)
/** @param in input signal to analyze
* @param trig resets the minimum observed value to the current value
* of the input signal
*/
def ar(in: GE, trig: GE): RunningMin = new RunningMin(audio, in, trig)
}
/** A UGen to measure a signal's minimum value between triggers.
*
* The UGen keeps an internal state that reflects the minimum input value
* observed. When a trigger occurs at the reset input, it first copies the current
* minimum value to its output and then (quasi-simultaneously) resets its internal
* state to the current input value.
*
* @param in input signal to analyze
* @param trig resets the minimum observed value to the current value
* of the input signal
*
* @see [[de.sciss.synth.ugen.RunningMax$ RunningMax]]
* @see [[de.sciss.synth.ugen.Peak$ Peak]]
* @see [[de.sciss.synth.ugen.RunningSum$ RunningSum]]
*/
final case class RunningMin(rate: Rate, in: GE, trig: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand, trig.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _args1 = if (rate.==(audio)) matchRate(_args, 0, audio) else _args
UGen.SingleOut(name, rate, _args1)
}
}
/** A UGen to measure a signal's maximum value between triggers.
*
* The UGen keeps an internal state that reflects the maximum input value
* observed. When a trigger occurs at the reset input, it first copies the current
* maximum value to its output and then (quasi-simultaneously) resets its internal
* state to the current input value.
*
* ===Examples===
*
* {{{
* // illustrate timing
* play {
* val n = BrownNoise.ar
* val t = Impulse.ar(4)
* val r = RunningMax.ar(n, t)
* // value at the moment the reset
* // is triggered
* n.poll(t, "cur")
* // this is the maximum of the
* // recent two input samples
* // (the one during reset and
* // the current one), therefore
* // equal or slightly greater than
* // the 'cur' value
* r.poll(Delay1.ar(t), "max")
* ()
* }
* }}}
*
* @see [[de.sciss.synth.ugen.RunningMin$ RunningMin]]
* @see [[de.sciss.synth.ugen.Peak$ Peak]]
* @see [[de.sciss.synth.ugen.RunningSum$ RunningSum]]
*/
object RunningMax {
/** @param in input signal to analyze
* @param trig resets the maximum observed value to the current value
* of the input signal
*/
def kr(in: GE, trig: GE): RunningMax = new RunningMax(control, in, trig)
/** @param in input signal to analyze
* @param trig resets the maximum observed value to the current value
* of the input signal
*/
def ar(in: GE, trig: GE): RunningMax = new RunningMax(audio, in, trig)
}
/** A UGen to measure a signal's maximum value between triggers.
*
* The UGen keeps an internal state that reflects the maximum input value
* observed. When a trigger occurs at the reset input, it first copies the current
* maximum value to its output and then (quasi-simultaneously) resets its internal
* state to the current input value.
*
* @param in input signal to analyze
* @param trig resets the maximum observed value to the current value
* of the input signal
*
* @see [[de.sciss.synth.ugen.RunningMin$ RunningMin]]
* @see [[de.sciss.synth.ugen.Peak$ Peak]]
* @see [[de.sciss.synth.ugen.RunningSum$ RunningSum]]
*/
final case class RunningMax(rate: Rate, in: GE, trig: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand, trig.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _args1 = if (rate.==(audio)) matchRate(_args, 0, audio) else _args
UGen.SingleOut(name, rate, _args1)
}
}
/** A UGen that continually reports the peak amplitude of the signal received at
* the input. If the absolute input level drops below the observed peak value, this
* value decreases by the factor given as `decay` parameter (but no more than the
* current absolute input level).
*
* ===Examples===
*
* {{{
* // mouse-controlled decay
* play {
* val in = Impulse.ar(2)
* val decay = MouseX.kr(0.995, 1.0001, 1).min(1.0)
* decay.poll(HPZ1.kr(decay).abs, "decay")
* val p = PeakFollower.ar(in, decay)
* val tr = Impulse.ar(20)
* val pm = RunningMax.ar(p, tr)
* pm.roundTo(0.001).poll(20, "peak")
* in
* }
* }}}
*
* @see [[de.sciss.synth.ugen.Peak$ Peak]]
* @see [[de.sciss.synth.ugen.Amplitude$ Amplitude]]
* @see [[de.sciss.synth.ugen.RunningSum$ RunningSum]]
* @see [[de.sciss.synth.ugen.LagUD$ LagUD]]
*/
object PeakFollower {
/** @param in input signal to trace
* @param decay feedback coefficient controlling the release rate. This
* should be less than one, otherwise the UGen may blow up.
*/
def kr(in: GE, decay: GE = 0.999f): PeakFollower = new PeakFollower(control, in, decay)
/** @param in input signal to trace
* @param decay feedback coefficient controlling the release rate. This
* should be less than one, otherwise the UGen may blow up.
*/
def ar(in: GE, decay: GE = 0.999f): PeakFollower = new PeakFollower(audio, in, decay)
}
/** A UGen that continually reports the peak amplitude of the signal received at
* the input. If the absolute input level drops below the observed peak value, this
* value decreases by the factor given as `decay` parameter (but no more than the
* current absolute input level).
*
* @param in input signal to trace
* @param decay feedback coefficient controlling the release rate. This
* should be less than one, otherwise the UGen may blow up.
*
* @see [[de.sciss.synth.ugen.Peak$ Peak]]
* @see [[de.sciss.synth.ugen.Amplitude$ Amplitude]]
* @see [[de.sciss.synth.ugen.RunningSum$ RunningSum]]
* @see [[de.sciss.synth.ugen.LagUD$ LagUD]]
*/
final case class PeakFollower(rate: MaybeRate, in: GE, decay: GE = 0.999f) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand, decay.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRate(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A UGen that switches between two input signal depending on which is changing
* more. Change is based on the absolute of the differentiation of the respective
* signals.
*
* ===Examples===
*
* {{{
* // mouse-x versus mouse-y
* play {
* val x = MouseX.kr(lag = 1)
* val y = MouseY.kr(lag = 1)
* val c = MostChange.kr(x, y)
* val isX = c sig_== x
* val isY = 1 - isX
* // if X change stronger, modulate pan position
* val p = LFTri.ar(c * 10 * isX)
* // if Y change stronger, modulate sine frequency
* val f = LFTri.ar(c * 10 * isY).linexp(-1, 1, 100, 4000)
* // report current state
* c.poll(5, "c")
* x.poll(isX, "now X")
* y.poll(isY, "now Y")
* Pan2.ar(SinOsc.ar(f) * 0.1, p)
* }
* }}}
*
* @see [[de.sciss.synth.ugen.LeastChange$ LeastChange]]
*/
object MostChange {
/** @param a first input signal to select from
* @param b second input signal to select from
*/
def kr(a: GE, b: GE): MostChange = new MostChange(control, a, b)
/** @param a first input signal to select from
* @param b second input signal to select from
*/
def ar(a: GE, b: GE): MostChange = new MostChange(audio, a, b)
}
/** A UGen that switches between two input signal depending on which is changing
* more. Change is based on the absolute of the differentiation of the respective
* signals.
*
* @param a first input signal to select from
* @param b second input signal to select from
*
* @see [[de.sciss.synth.ugen.LeastChange$ LeastChange]]
*/
final case class MostChange(rate: Rate, a: GE, b: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(a.expand, b.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = UGen.SingleOut(name, rate, _args)
}
/** A UGen that switches between two input signal depending on which is changing
* less. Change is based on the absolute of the differentiation of the respective
* signals.
*
* ===Examples===
*
* {{{
* // mouse-x versus mouse-y
* play {
* val x = MouseX.kr(lag = 1)
* val y = MouseY.kr(lag = 1)
* val c = LeastChange.kr(x, y)
* val isX = c sig_== x
* val isY = 1 - isX
* // if X change weaker, modulate pan position
* val p = LFTri.ar(c * 10 * isX)
* // if Y change weaker, modulate sine frequency
* val f = LFTri.ar(c * 10 * isY).linexp(-1, 1, 100, 4000)
* // report current state
* c.poll(5, "c")
* x.poll(isX, "now X")
* y.poll(isY, "now Y")
* Pan2.ar(SinOsc.ar(f) * 0.1, p)
* }
* }}}
*
* @see [[de.sciss.synth.ugen.MostChange$ MostChange]]
*/
object LeastChange {
/** @param a first input signal to select from
* @param b second input signal to select from
*/
def kr(a: GE, b: GE): LeastChange = new LeastChange(control, a, b)
/** @param a first input signal to select from
* @param b second input signal to select from
*/
def ar(a: GE, b: GE): LeastChange = new LeastChange(audio, a, b)
}
/** A UGen that switches between two input signal depending on which is changing
* less. Change is based on the absolute of the differentiation of the respective
* signals.
*
* @param a first input signal to select from
* @param b second input signal to select from
*
* @see [[de.sciss.synth.ugen.MostChange$ MostChange]]
*/
final case class LeastChange(rate: MaybeRate, a: GE, b: GE) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(a.expand, b.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = {
val _rate = rate.getOrElse(_args(0).rate)
val _args1 = matchRate(_args, 0, _rate)
UGen.SingleOut(name, _rate, _args1)
}
}
/** A sample-and-hold UGen that outputs the last value before the input changed
* more than a threshold. Change is based on the absolute of the differentiation of
* input signal.
*
* ===Examples===
*
* {{{
* // distortion
* play {
* val in = SinOsc.ar(262)
* val thresh = MouseX.kr(1.0e-3, 2.0, 1, lag = 1)
* thresh.poll(5, "thresh")
* LeakDC.ar(LastValue.ar(in, thresh)) * 0.1
* }
* }}}
*
* @see [[de.sciss.synth.ugen.Slew$ Slew]]
*/
object LastValue {
/** @param in input signal to analyze and filter
* @param thresh threshold below which the input sign
*/
def kr(in: GE, thresh: GE = 0.01f): LastValue = new LastValue(control, in, thresh)
/** @param in input signal to analyze and filter
* @param thresh threshold below which the input sign
*/
def ar(in: GE, thresh: GE = 0.01f): LastValue = new LastValue(audio, in, thresh)
}
/** A sample-and-hold UGen that outputs the last value before the input changed
* more than a threshold. Change is based on the absolute of the differentiation of
* input signal.
*
* @param in input signal to analyze and filter
* @param thresh threshold below which the input sign
*
* @see [[de.sciss.synth.ugen.Slew$ Slew]]
*/
final case class LastValue(rate: Rate, in: GE, thresh: GE = 0.01f) extends UGenSource.SingleOut {
protected def makeUGens: UGenInLike = unwrap(this, Vector(in.expand, thresh.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = UGen.SingleOut(name, rate, _args)
}
/** A UGen which monitors another UGen to see when it is finished. Some UGens, such
* as `PlayBuf` , `RecordBuf` , `Line` , `XLine` , `EnvGen` , `Linen` , `BufRd` ,
* `BufWr` , `DbufRd` , and the Buffer delay UGens set a 'done' flag when they are
* finished playing. This UGen echoes that flag as an explicit output signal when
* it is set to track a particular UGen. When the tracked UGen changes to done, the
* output signal changes from zero to one.
*
* @see [[de.sciss.synth.ugen.PlayBuf$ PlayBuf]]
* @see [[de.sciss.synth.ugen.Line$ Line]]
* @see [[de.sciss.synth.ugen.EnvGen$ EnvGen]]
*/
object Done {
/** @param src the UGen to track
*/
def kr(src: GE with HasDoneFlag): Done = new Done(src)
}
/** A UGen which monitors another UGen to see when it is finished. Some UGens, such
* as `PlayBuf` , `RecordBuf` , `Line` , `XLine` , `EnvGen` , `Linen` , `BufRd` ,
* `BufWr` , `DbufRd` , and the Buffer delay UGens set a 'done' flag when they are
* finished playing. This UGen echoes that flag as an explicit output signal when
* it is set to track a particular UGen. When the tracked UGen changes to done, the
* output signal changes from zero to one.
*
* @param src the UGen to track
*
* @see [[de.sciss.synth.ugen.PlayBuf$ PlayBuf]]
* @see [[de.sciss.synth.ugen.Line$ Line]]
* @see [[de.sciss.synth.ugen.EnvGen$ EnvGen]]
*/
final case class Done(src: GE with HasDoneFlag)
extends UGenSource.SingleOut with ControlRated with HasSideEffect {
protected def makeUGens: UGenInLike = unwrap(this, Vector(src.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike =
UGen.SingleOut(name, control, _args, hasSideEffect = true)
}
/** A UGen which pauses and resumes another node. Note that the UGen initially
* assumes the node is running, that is, if `gate` is initially 1, this will
* '''not''' resume a paused node. Instead, the gate must go to zero and back to
* one to resume the node. Additionally, this UGen will only cause action if the
* gate value changes, that is, if the node is paused or resumed otherwise, this
* UGen will not interfere with that action, unless the gate value is adjusted.
*
* @see [[de.sciss.synth.ugen.Free$ Free]]
* @see [[de.sciss.synth.ugen.PauseSelf$ PauseSelf]]
*/
object Pause {
/** @param gate when 0, node is paused, when 1, node is resumed
* @param node the id of the node to be paused or resumed
*/
def kr(gate: GE, node: GE): Pause = new Pause(gate, node)
}
/** A UGen which pauses and resumes another node. Note that the UGen initially
* assumes the node is running, that is, if `gate` is initially 1, this will
* '''not''' resume a paused node. Instead, the gate must go to zero and back to
* one to resume the node. Additionally, this UGen will only cause action if the
* gate value changes, that is, if the node is paused or resumed otherwise, this
* UGen will not interfere with that action, unless the gate value is adjusted.
*
* @param gate when 0, node is paused, when 1, node is resumed
* @param node the id of the node to be paused or resumed
*
* @see [[de.sciss.synth.ugen.Free$ Free]]
* @see [[de.sciss.synth.ugen.PauseSelf$ PauseSelf]]
*/
final case class Pause(gate: GE, node: GE)
extends UGenSource.SingleOut with ControlRated with HasSideEffect {
protected def makeUGens: UGenInLike = unwrap(this, Vector(gate.expand, node.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike =
UGen.SingleOut(name, control, _args, hasSideEffect = true)
}
/** A UGen that, when triggered, frees enclosing synth. It frees the enclosing
* synth when the input signal crosses from non-positive to positive.
*
* ''Note'' that if the trigger is initially high the UGen will not react. For
* example, `FreeSelf.kr("foo".kr)` will not work if the control is initially `1` .
* A work-around is to wrap the input in this case in a `Trig` object:
* `FreeSelf.kr(Trig.kr("foo".kr))` . This is most likely a bug.
*
* This UGen outputs its input signal for convenience.
*
* @see [[de.sciss.synth.ugen.Free$ Free]]
* @see [[de.sciss.synth.ugen.PauseSelf$ PauseSelf]]
*/
object FreeSelf {
/** @param trig the input signal which will trigger the action.
*/
def kr(trig: GE): FreeSelf = new FreeSelf(trig)
}
/** A UGen that, when triggered, frees enclosing synth. It frees the enclosing
* synth when the input signal crosses from non-positive to positive.
*
* ''Note'' that if the trigger is initially high the UGen will not react. For
* example, `FreeSelf.kr("foo".kr)` will not work if the control is initially `1` .
* A work-around is to wrap the input in this case in a `Trig` object:
* `FreeSelf.kr(Trig.kr("foo".kr))` . This is most likely a bug.
*
* This UGen outputs its input signal for convenience.
*
* @param trig the input signal which will trigger the action.
*
* @see [[de.sciss.synth.ugen.Free$ Free]]
* @see [[de.sciss.synth.ugen.PauseSelf$ PauseSelf]]
*/
final case class FreeSelf(trig: GE) extends UGenSource.SingleOut with ControlRated with HasSideEffect {
protected def makeUGens: UGenInLike = unwrap(this, Vector(trig.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike =
UGen.SingleOut(name, control, _args, hasSideEffect = true)
}
/** A UGen that, when triggered, pauses enclosing synth. It pauses the enclosing
* synth when the input signal crosses from non-positive to positive.
*
* ''Note'' that if the trigger is initially high the UGen will not react. For
* example, `PauseSelf.kr("foo".kr)` will not work if the control is initially `1`
* . A work-around is to wrap the input in this case in a `Trig` object:
* `PauseSelf.kr(Trig.kr("foo".kr))` . This is most likely a bug.
*
* This UGen outputs its input signal for convenience.
*
* @see [[de.sciss.synth.ugen.Pause$ Pause]]
* @see [[de.sciss.synth.ugen.FreeSelf$ FreeSelf]]
*/
object PauseSelf {
/** @param trig the input signal which will trigger the action.
*/
def kr(trig: GE): PauseSelf = new PauseSelf(trig)
}
/** A UGen that, when triggered, pauses enclosing synth. It pauses the enclosing
* synth when the input signal crosses from non-positive to positive.
*
* ''Note'' that if the trigger is initially high the UGen will not react. For
* example, `PauseSelf.kr("foo".kr)` will not work if the control is initially `1`
* . A work-around is to wrap the input in this case in a `Trig` object:
* `PauseSelf.kr(Trig.kr("foo".kr))` . This is most likely a bug.
*
* This UGen outputs its input signal for convenience.
*
* @param trig the input signal which will trigger the action.
*
* @see [[de.sciss.synth.ugen.Pause$ Pause]]
* @see [[de.sciss.synth.ugen.FreeSelf$ FreeSelf]]
*/
final case class PauseSelf(trig: GE) extends UGenSource.SingleOut with ControlRated with HasSideEffect {
protected def makeUGens: UGenInLike = unwrap(this, Vector(trig.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike =
UGen.SingleOut(name, control, _args, hasSideEffect = true)
}
/** A UGen that, when triggered, frees a given node.
*
* This UGen outputs its trig input signal for convenience.
*
* @see [[de.sciss.synth.ugen.Pause$ Pause]]
* @see [[de.sciss.synth.ugen.FreeSelf$ FreeSelf]]
*/
object Free {
/** @param trig the trigger to cause the action
* @param node the id of the target node to free upon receiving the
* trigger
*/
def kr(trig: GE, node: GE): Free = new Free(trig, node)
}
/** A UGen that, when triggered, frees a given node.
*
* This UGen outputs its trig input signal for convenience.
*
* @param trig the trigger to cause the action
* @param node the id of the target node to free upon receiving the
* trigger
*
* @see [[de.sciss.synth.ugen.Pause$ Pause]]
* @see [[de.sciss.synth.ugen.FreeSelf$ FreeSelf]]
*/
final case class Free(trig: GE, node: GE) extends UGenSource.SingleOut with ControlRated with HasSideEffect {
protected def makeUGens: UGenInLike = unwrap(this, Vector(trig.expand, node.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike =
UGen.SingleOut(name, control, _args, hasSideEffect = true)
}
/** A UGen that, when its input UGen is finished, frees enclosing synth. This is
* essentially a shortcut for `FreeSelf.kr(Done.kr(src))` , so instead of providing
* a trigger signal it reads directly the done flag of an appropriate ugen (such as
* `Line` or `PlayBuf` ).
*
* This UGen outputs its input signal for convenience.
*
* @see [[de.sciss.synth.ugen.Free$ Free]]
* @see [[de.sciss.synth.ugen.FreeSelf$ FreeSelf]]
* @see [[de.sciss.synth.ugen.PauseSelfWhenDone$ PauseSelfWhenDone]]
* @see [[de.sciss.synth.ugen.Done$ Done]]
*/
object FreeSelfWhenDone {
/** @param src the input UGen which when finished will trigger the
* action.
*/
def kr(src: GE with HasDoneFlag): FreeSelfWhenDone = new FreeSelfWhenDone(src)
}
/** A UGen that, when its input UGen is finished, frees enclosing synth. This is
* essentially a shortcut for `FreeSelf.kr(Done.kr(src))` , so instead of providing
* a trigger signal it reads directly the done flag of an appropriate ugen (such as
* `Line` or `PlayBuf` ).
*
* This UGen outputs its input signal for convenience.
*
* @param src the input UGen which when finished will trigger the
* action.
*
* @see [[de.sciss.synth.ugen.Free$ Free]]
* @see [[de.sciss.synth.ugen.FreeSelf$ FreeSelf]]
* @see [[de.sciss.synth.ugen.PauseSelfWhenDone$ PauseSelfWhenDone]]
* @see [[de.sciss.synth.ugen.Done$ Done]]
*/
final case class FreeSelfWhenDone(src: GE with HasDoneFlag)
extends UGenSource.SingleOut with ControlRated with HasSideEffect {
protected def makeUGens: UGenInLike = unwrap(this, Vector(src.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike =
UGen.SingleOut(name, control, _args, hasSideEffect = true)
}
/** A UGen that, when its input UGen is finished, pauses enclosing synth. This is
* essentially a shortcut for `PauseSelf.kr(Done.kr(src))` , so instead of
* providing a trigger signal it reads directly the done flag of an appropriate
* ugen (such as `Line` or `PlayBuf` ).
*
* This UGen outputs its input signal for convenience.
*
* @see [[de.sciss.synth.ugen.Pause$ Pause]]
* @see [[de.sciss.synth.ugen.PauseSelf$ PauseSelf]]
* @see [[de.sciss.synth.ugen.FreeSelfWhenDone$ FreeSelfWhenDone]]
* @see [[de.sciss.synth.ugen.Done$ Done]]
*/
object PauseSelfWhenDone {
/** @param src the input UGen which when finished will trigger the
* action.
*/
def kr(src: GE with HasDoneFlag): PauseSelfWhenDone = new PauseSelfWhenDone(src)
}
/** A UGen that, when its input UGen is finished, pauses enclosing synth. This is
* essentially a shortcut for `PauseSelf.kr(Done.kr(src))` , so instead of
* providing a trigger signal it reads directly the done flag of an appropriate
* ugen (such as `Line` or `PlayBuf` ).
*
* This UGen outputs its input signal for convenience.
*
* @param src the input UGen which when finished will trigger the
* action.
*
* @see [[de.sciss.synth.ugen.Pause$ Pause]]
* @see [[de.sciss.synth.ugen.PauseSelf$ PauseSelf]]
* @see [[de.sciss.synth.ugen.FreeSelfWhenDone$ FreeSelfWhenDone]]
* @see [[de.sciss.synth.ugen.Done$ Done]]
*/
final case class PauseSelfWhenDone(src: GE with HasDoneFlag)
extends UGenSource.SingleOut with ControlRated with HasSideEffect {
protected def makeUGens: UGenInLike = unwrap(this, Vector(src.expand))
protected def makeUGen(_args: Vec[UGenIn]): UGenInLike =
UGen.SingleOut(name, control, _args, hasSideEffect = true)
}