Capytalk Reference

Download as pdf or txt
Download as pdf or txt
You are on page 1of 327

Capytalk Reference

*
Categories: arithmetic, scaling, range, logic

!Multiplicand * !Multiplier
Range (-infinity, infinity)

Multiplication.

You can use multiplication to change the range of a fader, an expression, or a Sound pasted into a parameter field.
Since the default range of EventExpressions is [0,1] and the default range of Sounds is [-1,1], changing the range is
easy; simply multiply by the desired maximum value.

You can also use * as a logical AND operator. In CapyTalk, TRUE is represented by 1 and FALSE by 0. So to test
whether two conditions are BOTH true, multiply them; if either one is false (0), then the result will be false (0).

Examples:

!Multiplicand * !Multiplier

2*3

!Range01 * 100

1 s random * !Jitter

(!BPM bpm s random abs * 4) of: #(4 8 16 32)

(!KeyNumber ge: 60) * (!KeyNumber lt: 72)

!sw01 * !sw02

1
**
Categories: arithmetic, exponentiation, exponential

!Base ** !Power
Range (-infinity, infinity)

Exponentiation: raise the !Base to a !Power. Multiply the !Base by itself !Power times.

Examples:

!Base ** !Power

2 ** 3

!aNumber ** !Power

1 repeatingRamp ** !Power * !Scale + !Offset

2
+
Categories: arithmetic, addition, logic

!Addend1 + !Addend2
Range (-infinity, infinity)

Addition.

Arithmetic addition or logical OR.

Examples:

!Addend1 + !Addend2

3+5

(!KeyNumber + !Interval) nn

{1 to: 8 collect: [:i | !Tonic + (!Step suffix2: i)]}

((1 repeatingTriangle: 2 s) * (!Max - !Min)) + !Min

(!Sw01 + !Sw02) asLogicValue

(!Sw01 + !Sw02) asLogicValue * (1 - (!Sw01 * !Sw02))

3
,
Categories: delimiters, separators, programming

!Expr1, !Expr2
Range NA

Terminates a single expression in a sequence of CapyTalk expressions.

Use the comma (,) to separate CapyTalk expressions so that they are evaluated one after another in sequence.

Examples:

!Expr1, !Expr2
---
| expr prevVal prevState |
expr := EventVariable new.
prevVal := EventVariable new.
prevState := EventVariable new.

expr := 1 repeatingFullRamp.

expr,
(!Sw01
true: (prevState
true: nil
false: (
prevState <+ 1,
(prevVal <+ (expr))))
false: (prevState <+ 0)),
prevVal

4
-
Categories: arithmetic, subtraction, logic

!Minuend - !Subtrahend
Range (-infinity, infinity)

Subtraction gives you the difference between two event values.

To use the difference as a logical NOT, subtract the logic expression from 1. To invert a sequence of pitches, subtract
them from (2 * the center pitch).

Examples:

!Minuend - !Subtrahend

3-5

1 - !aBoolean

{1 to: 8 collect: [:i | 2 * !centerPch - (!Pch suffix2: i)]}

1 - (!Sw01 + !Sw02) asLogicValue

5
/
Categories: arithmetic, division, quotient, ratio

!Dividend / !Divisor
Range (-infinity, infinity)

Divides the !Dividend by the !Divisor. Division is the inverse of multiplication so it tells you what you would have to
multiply !Divisor by to get the !Dividend. If a / b = c, then a = c * b.

Also expresses the ratio of the !Numerator to the !Demoninator. You can use / to compute the ratio between a desired
value and a given value.

Examples:

!Dividend / !Divisor

3.0 / 6.0

!Numerator / !Denominator

!Beats / !BeatsPerBar

1 s random / !Divisor

default * (!BPM / (’SwS - 062 Tidal.aif’ bpmForBeats: 8))

(!LoopStart * 8) rounded / 8

6
//
Categories: arithmetic, division, quotient, truncatingDivide

!Dividend // !Divisor
Range (-infinity, infinity)

Divide and truncate (toward negative infinity). The result is an integer.

If, instead, you want the remainder of !Dividend divided by !Divisor, use double-slashes in the opposite direction: \\

Examples:

!Dividend // !Divisor

9 // 4

-9 // 4

!Beats // !BeatsPerBar

7
/\
Category: logic

!Value1 /\ !Value2
Range (0, 1)

Logical AND.

Use this to test whether two conditions are BOTH true; if both are true, the result will be 1 (true), if either one is false,
the result will be 0 (false). In Capytalk, TRUE is represented by positive values and FALSE by zero or negative
values.

Examples:

!Value1 /\ !Value2

1 /\ 1

1 /\ 0

!KeyDown /\ (!KeyPitch gt: 60)

(!KeyNumber ge: 60) /\ (!KeyNumber lt: 72)

!sw01 /\ !sw02

8
<+
Categories: assignment, variables, programming

anEventVariable <+ anEventExpression


Range NA

Evaluates anEventExpression, stores the result in anEventVariable, and pops the result off the stack.

The <+ assignment operator is the one you should use in most situations. If there is a situation where you want the
result of the last EventVariable assignment to also be the value returned by a sequence of expressions, you can
choose to use the <~ assignment operator instead; this style assignment operator (<~) leaves the result of
anEventExpression on the top of the stack so the value of the assignment expression is also the value of the
comma-separated sequence of expressions. However, you can almost always get the same result by simply listing
the EventVariable as the last item in the sequence; this puts the value of the EventVariable at the top of the stack,
making it the the value of the entire sequence of expressions.

Examples:

anEventVariable <+ anEventExpression


---
| index |

index := EventVariable new initialValue: 0.

(index <+ (!Incr true: (index + 1) false: index)),


(index <~ (!Decr true: (index - 1) false: index))
---
| index |

index := EventVariable new initialValue: 0.

(index <+ (!Incr true: (index + 1) false: index)),


(index <+ (!Decr true: (index - 1) false: index)),
index

9
<~
Categories: assignment, variables, programming

anEventVariable <~ anEventExpression


Range NA

Evaluate anEventExpression, store the result in anEventVariable, and leave the result on the stack.

The result of a Capytalk expression is the value found at the top of the stack. So if you want the result of a sequence
of expressions to be the value of the last calculation, use <~ to perform the last calculation, assign it to an
EventVariable and leave the result on the stack so it will be returned as the final result of the sequence of
expressions. If you instead use the <+ assignment operator, the result of the last calculation will be stored in the
EventVariable but it will no longer be on the top of the stack, so if you want to return the value of the last calculation,
either use the <~ assignment operator, or use the <+ assignment operator followed by a comma, followed by the
name of the EventVariable; this will put the contents of the EventVariable on the top of the stack so it will be returned
as the value of the sequence of expressions.

Examples:

anEventVariable <~ anEventExpression


---
| index |

index := EventVariable new initialValue: 0.

(index <+ (!Incr true: (index + 1) false: index)),


(index <~ (!Decr true: (index - 1) false: index))
---
| prev |

prev := EventVariable new.

(prev <~ ((1 s tick sampleAndHold: ((prev + (!Random abs * 7) + 1) truncated)) mod: 9))

10
><
Category: logic

!Value1 >< !Value2


Range (0, 1)

Logical EXCLUSIVE OR.

Use this to test whether either of the conditions is true, but not both of them. In Capytalk, TRUE is represented by
positive values and FALSE by zero or negative values.

Examples:

!Value1 >< !Value2

1 >< 1

1 >< 0

!KeyDown >< (!KeyPitch gt: 60)

(!KeyNumber ge: 60) >< (!KeyNumber lt: 72)

!sw01 >< !sw02

11
@<
Categories: assignment, variables, arrays, programming

anArrayEventVariable @< anEventExpression


Range NA

Access an entry in an array EventVariable.

Read the nth entry in an array variable with anArray @< !n. Set the nth to !aValue using (anArray @< !n) <+ !aValue.
Use 0-based indexing (the first entry in the array is at location 0, not at location 1).

Examples:

anArrayEventVariable @< anEventExpression


---
| anArray |

anArray := EventVariable new size: 4.

(!Store true: ((anArray @< !WritePtr rounded) <+ !Value) false: (nil)),
(anArray @< !ReadPtr rounded)
---
| anArray writeIndex readIndex |

anArray := EventVariable new size: 8.


writeIndex := EventVariable new.
readIndex := EventVariable new.

(!KeyDown switchedOn
true: ( ((anArray @< writeIndex) <+ !KeyNumber),
(writeIndex <+ ((writeIndex + 1) mod: 8)))
false: (nil)),

(readIndex <+ ((1 bpm: !BPM) nextIndexMod: 8)),


(anArray @< readIndex)

12
abs
Category: arithmetic

!PositiveOrNegativeNumber abs
Range [0, infinity)

Absolute value of !PositiveOrNegativeNumber. The value is the (positive) magnitude of !PositiveOrNegativeNumber.

Whether the receiver of the abs message is positive or negative, the result of abs is a positive number. For example,
if you are generating random numbers in the range of (-1,1) but you want only positive numbers, you can take the
absolute value by sending the abs message. to the random number generating expression.

Examples:

!PositiveOrNegativeNumber abs

!Direction abs

((1 s random abs * 5) of: #(60 62 64 66 69 72)) nn

1 s random abs

1 repeatingFullRamp abs

13
accumulate
Category: interface expressions

!Increment accumulate
Range (-Infinity,+Infinity)

The value of this expression increases or decreases by !Increment once per millisecond. (For a version of this
expression that can turn the accumulation on or off, see accumulateWhile:. To reset the accumulation to a given initial
value, see accumulateWhile:initialValue:reset:. To accumulate incrementally, in response to a trigger, see
accumulateIf: and accumulateIf:initialValue:reset:)

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is a lever that you can push to the right or to the left and, when you let go, the lever springs back to the center
position. You could use a PitchBend lever to set the direction and speed of a change, and use accumulate to create a
smooth change in that direction and at that speed. Other examples of controllers that could be used with accumulate
are the spring-centering knob on a SpaceNavigator or the orientation controls from an accelerometer, for example,
!WiiAccelX or !WiiYaw.

Examples:

!Increment accumulate

(!Size * !Direction) accumulate

(!Rate * !Direction) accumulate

((!WiiRoll * 0.001) accumulate) * 2 - 1

14
accumulate01
Category: interface expressions

!Increment accumulate01
Range [0,1]

The value of this expression increases or decreases by !Increment once per millisecond. (For a version of this
expression that can turn the accumulation on or off, see accumulate01While:. To reset the accumulation to a given
initial value, see accumulate01While:initialValue:reset:. To accumulate incrementally, in response to a trigger, see
accumulate01If: and accumulate01If:initialValue:reset: For a version that does not clip to [0,1], see accumulate.)

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is a lever that you can push to the right or to the left and, when you let go, the lever springs back to the center
position. You could use a PitchBend lever to set the direction and speed of a change, and use accumulate to create a
smooth change in that direction and at that speed. Other examples of controllers that could be used with accumulate
are the spring-centering knob on a SpaceNavigator or the orientation controls from an accelerometer, for example,
!WiiAccelX or !WiiYaw

Examples:

!Increment accumulate01

(!Size * !Direction) accumulate01

(!Rate * !Direction) accumulate01

((!WiiRoll * 0.001) accumulate01) * 2 - 1

15
accumulate01If:
Category: interface expressions

!IncrementSize accumulate01If: !aBooleanTrigger


Range [0,1]

The value of this expression increases or decreases by !IncrementSize when !aBooleanTrigger becomes true. It
cannot be incremented or decremented again until !aBooleanTrigger first returns to 0 and then becomes nonzero
(true) again. Its initial value is 0.5. (See also accumulate01While: and accumulate01. To accumulate incrementally
with the option to reset to a specified initial value, see accumulate01If:initialValue:reset. For a version that does not
clip to [0,1], see accumulate01If:.)

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is a lever that you can push to the right or to the left and, when you let go, the lever springs back to the center
position. You could use a PitchBend lever to set the direction and speed of a change, and use accumulate to create a
smooth change in that direction and at that speed. Other examples of controllers that could be used with accumulate
are the spring-centering knob on a SpaceNavigator or the orientation controls from an accelerometer, for example,
!WiiAccelX or !WiiYaw.

Examples:

!IncrementSize accumulate01If: !aBooleanTrigger

(!Size * !Direction) accumulate01If: !Trigger

({1/12} * !WiiRoll sign accumulate01If: (!WiiAccel abs gt: 0.2)) * 2 - 1 * 12

16
accumulate01If: initialValue: reset:
Category: interface expressions

!IncrementSize accumulate01If: !aBooleanTrigger initialValue: !ResetValue reset: !Reset


Range [0,1]

The value of this expression increases or decreases by !IncrementSize each time !aBooleanTrigger becomes true. It
cannot be incremented or decremented again until !aBooleanTrigger first returns to 0 and then becomes nonzero
(true) again. Jumps to the !ResetValue when !Reset becomes true. (See also accumulate01While: and accumulate01.
To accumulate incrementally without a reset, see accumulate01If:. For a version that does not clip to [0,1], see
accumulate01If:initialValue:reset:.)

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is a lever that you can push to the right or to the left and, when you let go, the lever springs back to the center
position. You could use a PitchBend lever to set the direction and speed of a change, and use accumulate to create a
smooth change in that direction and at that speed. Other examples of controllers that could be used with accumulate
are the spring-centering knob on a SpaceNavigator or the orientation controls from an accelerometer, for example,
!WiiAccelX or !WiiYaw

Examples:

!IncrementSize accumulate01If: !aBooleanTrigger initialValue: !ResetValue reset: !Reset

(!Size * !Direction) accumulate01If: !Trigger initialValue: !ResetValue doNotTrigger reset: !Reset

({1/12} * !WiiRoll sign accumulate01If: (!WiiAccel abs gt: 0.2) initialValue: 0 reset: !Reset) * 2 - 1 * 12

17
accumulate01While:
Category: interface expressions

!Increment accumulate01While: !aBoolean


Range [0,1]

The value of this expression increases or decreases by !Increment once per millisecond, as long as !aBoolean
remains true. Its initial value is 0.5. (For a version of this expression that can be reset to a given initial value, see
accumulate01While:initialValue:reset:. To accumulate incrementally, in response to a trigger, see accumulate01If:
and accumulate01If:initialValue:reset:. For a version that does not clip to [0,1], see accumulateWhile:.)

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is a lever that you can push to the right or to the left and, when you let go, the lever springs back to the center
position. You could use a PitchBend lever to set the direction and speed of a change, and use accumulate to create a
smooth change in that direction and at that speed. Other examples of controllers that could be used with accumulate
are the spring-centering knob on a SpaceNavigator or the orientation controls from an accelerometer, for example,
!WiiAccelX or !WiiYaw

Examples:

!Increment accumulate01While: !aBoolean

(!Size * !Direction) accumulate01While: !Accumulate

((!WiiRoll * 0.001) accumulate01While: (!WiiRoll abs gt: 0.015)) * 2 - 1

18
accumulate01While: initialValue: reset:
Category: interface expressions

!Increment accumulate01While: !aBoolean01 initialValue: !ResetToValue reset: !Reset


Range [0,1]

The value of this expression increases or decreases by !Increment once per millisecond, as long as !aBoolean
remains true. Return to the initial value when !Reset becomes true. (See also accumulateWhile: and accumulate. To
accumulate incrementally, in response to a trigger, see accumulateIf: and accumulateIf:initialValue:reset:. For a
version that does not clip to [0,1], see accumulateWhile:initialValue:reset:.)

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is a lever that you can push to the right or to the left and, when you let go, the lever springs back to the center
position. You could use a PitchBend lever to set the direction and speed of a change, and use accumulate to create a
smooth change in that direction and at that speed. Other examples of controllers that could be used with accumulate
are the spring-centering knob on a SpaceNavigator or the orientation controls from an accelerometer, for example,
!WiiAccelX or !WiiYaw

Examples:

!Increment accumulate01While: !aBoolean01 initialValue: !ResetToValue reset: !Reset

(!Size * !Direction) accumulate01While: !Accumulate initialValue: !ResetToValue doNotTrigger reset: !Reset

((!WiiRoll * 0.001) accumulate01While: (!WiiRoll abs gt: 0.015) initialValue: 0.5 reset: !Reset) * 2 - 1

19
accumulateIf:
Category: interface expressions

!IncrementSize accumulateIf: !aBooleanTrigger


Range (-Infinity,+Infinity)

The value of this expression increases or decreases by !IncrementSize when !aBooleanTrigger becomes true. It
cannot be incremented or decremented again until !aBooleanTrigger first returns to 0 and then becomes nonzero
(true) again. Its initial value is 0.5. (See also accumulateWhile: and accumulate. To accumulate incrementally with the
option to reset to a specified initial value, see accumulateIf:initialValue:reset.)

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is a lever that you can push to the right or to the left and, when you let go, the lever springs back to the center
position. You could use a PitchBend lever to set the direction and speed of a change, and use accumulate to create a
smooth change in that direction and at that speed. Other examples of controllers that could be used with accumulate
are the spring-centering knob on a SpaceNavigator or the orientation controls from an accelerometer, for example,
!WiiAccelX or !WiiYaw

Examples:

!IncrementSize accumulateIf: !aBooleanTrigger

(!Size * !Direction) accumulateIf: !Trigger

({1/12} * !WiiRoll sign accumulateIf: (!WiiAccel abs gt: 0.2)) * 2 - 1 * 12

20
accumulateIf: initialValue: reset:
Category: interface expressions

!IncrementSize accumulateIf: !aBooleanTrigger initialValue: !ResetToValue reset: !Reset


Range (-Infinity,+Infinity)

The value of this expression increases or decreases by !IncrementSize each time !aBooleanTrigger becomes true. It
cannot be incremented or decremented again until !aBooleanTrigger first returns to 0 and then becomes nonzero
(true) again. Jumps to the !ResetValue when !Reset becomes true (1). (See also accumulateWhile: and accumulate.
To accumulate incrementally without a reset, see accumulateIf:.)

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is a lever that you can push to the right or to the left and, when you let go, the lever springs back to the center
position. You could use a PitchBend lever to set the direction and speed of a change, and use accumulate to create a
smooth change in that direction and at that speed. Other examples of controllers that could be used with accumulate
are the spring-centering knob on a SpaceNavigator or the orientation controls from an accelerometer, for example,
!WiiAccelX or !WiiYaw

Examples:

!IncrementSize accumulateIf: !aBooleanTrigger initialValue: !ResetToValue reset: !Reset

(!Size * !Direction) accumulateIf: !Trigger initialValue: !ResetToValue doNotTrigger reset: !Reset

({1/12} * !WiiRoll sign accumulateIf: (!WiiAccel abs gt: 0.2) initialValue: 0 reset: !Reset) * 2 - 1 * 12

21
accumulateWhile:
Category: interface expressions

!Increment accumulateWhile: !aBoolean


Range (-Infinity,+Infinity)

The value of this expression increases or decreases by !Increment once per millisecond, as long as !aBoolean
remains true. Its initial value is 0.5. (For a version of this expression that can be reset to a given initial value, see
accumulateWhile:initialValue:reset:. To accumulate incrementally, in response to a trigger, see accumulateIf: and
accumulateIf:initialValue:reset:)

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is a lever that you can push to the right or to the left and, when you let go, the lever springs back to the center
position. You could use a PitchBend lever to set the direction and speed of a change, and use accumulate to create a
smooth change in that direction and at that speed. Other examples of controllers that could be used with accumulate
are the spring-centering knob on a SpaceNavigator or the orientation controls from an accelerometer, for example,
!WiiAccelX or !WiiYaw

Examples:

!Increment accumulateWhile: !aBoolean

(!Size * !Direction) accumulateWhile: !Accumulate

((!WiiRoll * 0.001) accumulateWhile: (!WiiRoll abs gt: 0.015)) * 2 - 1

22
accumulateWhile: initialValue: reset:
Category: interface expressions

!Increment accumulateWhile: !aBoolean01 initialValue: !ResetToThisValue reset: !Reset


Range (-Infinity,+Infinity)

The value of this expression increases or decreases by !Increment once per millisecond, as long as !aBoolean
remains true. Jump to the initial value when !Reset becomes true. (See also accumulateWhile: and accumulate. To
accumulate incrementally, in response to a trigger, see accumulateIf: and accumulateIf:initialValue:reset:)

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is a lever that you can push to the right or to the left and, when you let go, the lever springs back to the center
position. You could use a PitchBend lever to set the direction and speed of a change, and use accumulate to create a
smooth change in that direction and at that speed. Other examples of controllers that could be used with accumulate
are the spring-centering knob on a SpaceNavigator or the orientation controls from an accelerometer, for example,
!WiiAccelX or !WiiYaw

Examples:

!Increment accumulateWhile: !aBoolean01 initialValue: !ResetToThisValue reset: !Reset

(!Size * !Direction) accumulateWhile: !Accumulate initialValue: !ResetValue doNotTrigger reset: !Reset

((!WiiRoll * 0.001) accumulateWhile: (!WiiRoll abs gt: 0.015) initialValue: 0.5 reset: !Reset) * 2 - 1

23
accumulateWithHalfLife:
Categories: interface expressions, controllers

!changePerSecond accumulateWithHalfLife: !timeToChangeHalfway


Range (-Infinity,+Infinity)

Once a millisecond, the value of this expression increases or decreases by !changePerSecond. When
!changePerSecond is 0, !timeToChangeHalfway is the amount of time it takes to get halfway to a value of zero.

With the accumulate messages you can specify the rate of change and the direction in which a parameter should
change, rather than specifying the end value. The accumulate messages can be useful when dealing with controllers
that supply an increment size and direction, rather than a specific value. For example, the typical PitchBend controller
is often a lever that you can push to the right or to the left by varying amounts, and it springs back to the center
position when you let go of it. You could send accumulateWithHalfLife: to !PitchBend to specify how quickly to
increase or decrease a value. Other examples of controllers that could be used with accumulates are the
spring-centering knob on a SpaceNavigator or the orientation signal from an accelerometer, for example, !WiiAccelX
or !WiiYaw. This version of the accumulate message is lossy it gradually tries to return to 0 over time, so when your
controller outputs zero and stops changing, the value of the accumulateWithHalfLife: expression will eventually return
to zero.

Examples:

!changePerSecond accumulateWithHalfLife: !timeToChangeHalfway

(!Size * !Direction) accumulateWithHalfLife: !LeakRate inverse

(!WiiRoll * 0.001) accumulateWithHalfLife: !Tc s

24
alignGateWith:
Categories: triggers & gates, trigger modifiers

!Gate alignGateWith: !GateGenerator


Range (0,1)

When !Gate becomes true, this expression waits until !GateGenerator becomes true before switching on. When !Gate
becomes false, it waits until !GateGenerator becomes true before switching off.

If !Gate turns on and off within one cycle of !GateGenerator, it will stay permanently on or off (no switching). For
consistent results, !GateGenerator should be at least twice the rate of !Gate. Useful for aligning a gate, pedal, or
key-press with a regular beat, by delaying the onset of the gate until the next time !GateGenerator switches on.

Examples:

!Gate alignGateWith: !GateGenerator

!KeyDown alignGateWith: (1 bpm: !BPM)

!KeyDown alignGateWith: (1 bpm: !BPM)

(1 bpm: !BPM_2) alignGateWith: (1 bpm: !BPM_1)

25
alignWith:
Categories: triggers & gates, trigger modifiers

!Trigger alignWith: !TriggerGenerator


Range [0,1]

When !Trigger becomes true, this expression waits until !TriggerGenerator becomes true before emitting a trigger.

Useful for aligning a trigger with a regular beat, by delaying your trigger until the next beat.

Examples:

!Trigger alignWith: !TriggerGenerator

!Trigger alignWith: (1 bpm: !BPM)

!Trigger alignWith: (1 bpm: (’SwS - 062 Tidal.aif’ bpmForBeats: 8))

(0.25 s random gt: 0) alignWith: (1 bpm: !BPM)

26
arcCosh
Categories: arithmetic, trigonometric

!anEventExpression arcCosh
Range [0, infinity)

The inverse hyperbolic cosine of !anEventExpression. NB: The result is valid ONLY when !anEventExpression >= 1.

You can use arcCosh to create interesting control shapes. For example, (1 + (1 repeatingRamp)) arcCosh * 0.759
looks like a distorted logarithmic curve, so if you want a controller that increases rapidly for small values, but looks
almost linear for larger values, arcCosh may be your inverse hyperbolic function of choice.

arcCosh is short for hyperbolic cosine: the cosine of an imaginary number. In other words, cosh (x) = cos (i * x),
where i is the square root of -1. You can also think of the cosh and sinh as the counterparts to cos and sin but
referring to the angles of a hyperbola instead of a unit circle. When you put the prefix ’arc’ in front of the function, it
means the area swept out by the angle (instead of the angle itself); the arcCosh is also called the inverse hyperbolic
cosine. For example, if cosh(x) = z, then arcCosh(z) = x.

Examples:

!anEventExpression arcCosh

1 arcCosh

2 arcCosh inverse

(1 + (1 repeatingRamp)) arcCosh

2 + (1 repeatingFullRamp) arcCosh

27
arcSinh
Categories: arithmetic, trigonometric

!anEventExpression arcSinh
Range [0, infinity)

The inverse hyperbolic sine of !anEventExpression.

You can use arcSinh to create interesting control shapes or nonlinear input controls. For example, (1 repeatingRamp)
arcSinh * 1.1346 is almost a straight line but is very slightly bowed in the center, so if you want a controller that is
almost linear but increases slightly more rapidly for both its smallests and largest values, arcSinh may be your inverse
hyperbolic function of choice.

The hyperbolic sine is the sine of an imaginary number. In other words, i * sinh (x) = sin (i * x), where i is the square
root of -1. You can also think of the cosh and sinh as the counterparts to cos and sin but referring to the angles of a
hyperbola instead of a unit circle. When you put the prefix ’arc’ in front of the function, it means the area swept out by
the angle instead of the angle; the arcSinh is also called the inverse hyperbolic sine. For example, if sinh(x) = z, then
arcSinh(z) = x.

Examples:

!anEventExpression arcSinh

1 arcSinh

0 arcSinh

(1 repeatingRamp) arcSinh * 1.1346

(1 repeatingFullRamp) arcSinh * 1.1346

28
asLeftPan
Categories: arithmetic, panning, spatializing

!anEventExpression asLeftPan
Range [0, 1]

Use this conjunction with asRightPan to obtain a constant-energy pan function. If you scale the amplitude of the left
channel by !anEventExpression asLeftPan and the amplitude of the right channel by !anEventExpression asRightPan,
you will hear a constant-energy pan that sounds smoother than a linear panning function.

Assume that !anEventExpression is a pan control (0,1) where 0 is hard left, 1 is hard right and 0.5 is directly ahead.
For a smooth perceptual pan, we want the sum of the left and right channels to equal a constant ENERGY. Energy is
proportional to the amplitude squared (not the amplitude). asLeftPan returns an amplitude scale which, when
summed with !anEventExpression asRightPan equals 1 (unity gain) for all values !anEventExpression.

Examples:

!anEventExpression asLeftPan

(1 repeatingTriangle: !Speed inverse s) asLeftPan

!Pan asLeftPan

!PenX asLeftPan

29
asLogicValue
Categories: Boolean, true, false, logic

!EventExpr asLogicValue
Range (0, 1)

The value is 0 if the !EventExpr is less than or equal to 0; the value is 1 if the !EventExpr is greater than 0.

If you have an expression that can return values larger than 1 or smaller than 0, and you would like to use it in a logic
test or logical expression, you can constrain it to be either 0 or 1 by sending it the message, asLogicValue. For
example: you can multiply two expressions to take the AND of the two expressions, add them to take the OR, subtract
the expression from 1 for logical negation or NOT.

Examples:

!EventExpr asLogicValue

!Button asLogicValue

1 s random asLogicValue

!A asLogicValue * !B asLogicValue

(!A asLogicValue + !B asLogicValue) * (1 - (!A asLogicValue * !B asLogicValue))

30
asRightPan
Categories: arithmetic, panning, spatializing

!anEventExpression asRightPan
Range [0, 1]

Use this conjunction with asLeftPan to obtain a constant-energy pan function. If you scale the amplitude of the left
channel by !anEventExpression asLeftPan and the amplitude of the right channel by !anEventExpression asRightPan,
you will hear a constant-energy pan that sounds smoother than a linear panning function.

Assume that !anEventExpression is a pan control (0,1) where 0 is hard left, 1 is hard right and 0.5 is directly ahead.
For a smooth perceptual pan, we want the sum of the left and right channels to equal a constant ENERGY. Energy is
proportional to the amplitude squared (not the amplitude). asRightPan returns an amplitude scale which, when
summed with !anEventExpression asLeftPan equals 1 (unity gain) for all values !anEventExpression.

Examples:

!anEventExpression asRightPan

(1 repeatingTriangle: !Speed inverse s) asRightPan

!Pan asRightPan

!PenX asRightPan

31
asToggle
Categories: triggers & gates, trigger modifiers

!aTrigger asToggle
Range [0,1]

Changes a trigger into a gate. This expression changes its state each time !aTrigger changes from 0 to a non-zero
value.

A toggle is like a light switch; when you switch it on, it stays on until you switch it off. You can use it to alternate
between two states (0 and 1) on successive triggers.

Examples:

!aTrigger asToggle

1 s tick asToggle

!OnOffSwitch asToggle smooth: 1 s

100 hz * (1 + (!OnOffSwitch asToggle smooth: 1 s))

32
barBPM: beats:
Category: triggers & gates

!OnOff barBPM: !BeatsPerMinute beats: !BeatsPerBar


Range (-1,1)

Given the !BeatsPerMinute and !BeatsPerBar, this expression generates one gate per bar. A change to the
!BeatsPerMinute will not take effect until the start of the next bar.

This is a shortcut for !On barBPM: !BPM beats: !Beats dutyCycle: 0.5

Examples:

!OnOff barBPM: !BeatsPerMinute beats: !BeatsPerBar

!On barBPM: !BPM beats: !Beats dutyCycle: 0.5

(1 barBPM: !BPM beats: 8) nextRandom abs

(!On barBPM: !BPM beats: !Beats) initialSampleAndHold: !aValue

(1 bpm: !BPM updateEvery: 8) euclideanForBeats: 8 pulses: 5 offset: ((1 barBPM: !BPM beats: 8) nextRandom
abs * 8) rounded

33
barBPM: beats: dutyCycle:
Category: triggers & gates

!OnOff barBPM: !BeatsPerMinute beats: !BeatsPerBar dutyCycle: !DutyCycle


Range (-1,1)

Given the !BeatsPerMinute and !BeatsPerBar, this expression generates one gate per bar. A change to the
!BeatsPerMinute does not take effect until the start of the next bar.

Examples:

!OnOff barBPM: !BeatsPerMinute beats: !BeatsPerBar dutyCycle: !DutyCycle

!On barBPM: !BPM beats: !Beats dutyCycle: !DutyCycle

(!On barBPM: !BPM beats: !Beats dutyCycle: 0.5) sampleAndHold: !aValue

34
bpm
Categories: units, bpm

!aFrequency hz bpm
Range [0, Infinity]

Just as hz is a unit of frequency and s is a unit of duration, bpm is a unit of tempo. You can use bpm to convert from
cycles-per-second to beats-per-minute (or vice versa). If you send bpm to a duration-in-seconds, it tells you the
beats-per-minute for which your duration-in-seconds would equal the duration of one beat. To convert a value from
one kind of unit to another, cascade the unit messages. For example, !BPM bpm s would tell you the duration of one
beat at the current tempo.

The bpm: message (bpm with a colon after it), takes a unitless argument, so before using a value in bpm units in a
bpm: message, first remove the units.

Examples:

!aFrequency hz bpm

1 hz bpm

1 s bpm

120 bpm s

4 a hz bpm hz s hz nn

!BPM bpm s

!BPM bpm hz

1 bpm: !BeatDur s bpm removeUnits

!BPM bpm s * !DutyCycle

!Tap durationBetweenTriggers s bpm removeUnits

35
bpm:
Category: triggers & gates

!On bpm: !GatesPerMinute


Range (-1,1)

This expression generates a gate at a periodic rate specified as beats-per-minute (BPM). The form of the expression
is:

<aToggle> bpm: <gatesPerMinute>

The first value, <aToggle> is like a switch that turns the metronome on or off. To leave the metronome switched on,
you can use a constant value of 1 for <aToggle>. You could permanently turn off the metronome gate generation
using a 0 instead (not very interesting). More interesting would be to use an EventValue such as !Gate or !OnOff for
the on/off switch or toggling. That way, you can start the metronome by pressing the !On toggle in the VCS. And turn
it off by pressing !On a second time. To control the rate, specify the number of gates that should be emitted each
minute. For example 1 bpm: 60 would generate 60 beats per minute (one beat each second). To specify a
changeable rate, use an EventValue, such as !BPM rather than a fixed number, for example 1 bpm: !BPM.

The duty cycle of each gate is 0.5, meaning that it stays on for half the time between gates; for other duty cycles, use
bpm:dutyCycle:. To specify the duration between gates in terms of seconds rather than beats per minute, see the
message, tick. Both bpm: and tick generate gates that can do voice stealing. At the beginning of each gate, the value
of the bpm: generated gate goes to -1 for 5 milliseconds before it jumps up to 1; this is to signal the currently playing
envelope to quickly return to 0 before beginning a new attack. To defeat the voice stealing, take the absolute value of
the bpm: gates by sending the abs message.

Examples:

!On bpm: !GatesPerMinute

1 bpm: !BPM

1 bpm: !Delay s bpm removeUnits

!On bpm: 1 s

(!OnOff bpm: !BPM) abs

(1 bpm: !BPM) nextChaotic: !k seed: 0.01 reset: !Reset

36
bpm: dutyCycle:
Category: triggers & gates

!OnOff bpm: !GatesPerMinute dutyCycle: !DutyCycle


Range [-1,1]

While switched on, bpm:dutyCycle: generates a metronome with a variable duty cycle. While !OnOff is greater than
zero, bpm: generates a periodic sequence of gates at a rate of !GatesPerMinute. Each gate stays on for a fraction of
the duration between gates; this fraction can vary from 0 to 1 and is set by !DutyCycle.

At the beginning of each gate, the value of bpm:dutyCycle: goes to -1 for 5 milliseconds before it jumps up to 1; this is
to allow the currently playing envelope to quickly ramp down to 0 before beginning a new attack. To defeat the voice
stealing, take the absolute value of the bpm:dutyCycle: expression, for example: (1 bpm: !BPM dutyCycle: !Duty) abs.

Examples:

!OnOff bpm: !GatesPerMinute dutyCycle: !DutyCycle

1 bpm: !BPM dutyCycle: 0.9

1 bpm: !Delay s bpm removeUnits dutyCycle: !OnDuration

(!OnOff bpm: !BPM dutyCycle: 0.9) abs

37
bpm: updateEvery:
Category: triggers & gates

!On bpm: !BPM updateEvery: !BeatsPerBar


Range (-1,1)

This is like bpm: except that a change to the tempo does not take effect until the start of the next bar (based on the
value of !BeatsPerBar, which itself can be updated only once per bar).

A shortcut for !On bpm: !BPM updateEvery: !BeatsPerBar dutyCycle: 0.5

Examples:

!On bpm: !BPM updateEvery: !BeatsPerBar

!On bpm: !BPM updateEvery: 8

(1 bpm: !BPM updateEvery: 8) euclideanForBeats: 8 pulses: 5 offset: ((1 barBPM: !BPM beats: 8) nextRandom
abs * 8) rounded

38
bpm: updateEvery: dutyCycle:
Category: triggers & gates

!On bpm: !BPM updateEvery: !BeatsPerBar dutyCycle: !DutyCycle


Range (-1,1)

This is like bpm: except that a change to the tempo does not take effect until the start of the next bar (based on the
value of !BeatsPerBar, which itself can be updated only once per bar).

Examples:

!On bpm: !BPM updateEvery: !BeatsPerBar dutyCycle: !DutyCycle

39
brownianGate:
Categories: random, triggers & gates

1 brownianGate: !StartDur s
Range (-1,1)

Same as 1 brownianGate: !StartDur s deviation: (!StartDur s * 0.01) minDur: 6 ms maxDur: !StartDur s * 2 dutyCycle:
0.5.

For more control, see brownianGate:deviation:minDur:maxDur:dutyCycle:

Examples:

1 brownianGate: !StartDur s

(1 brownianGate: !FirstDur s) seed: 0.3276

1 brownianGate: (!FirstDur s * ?VoiceNumber)

((0.9 - !Reset) brownianGate: !FirstDur s) seed: 0.7628

40
brownianGate: deviation: minDur: maxDur: dutyCycle:
Categories: random, triggers & gates

!On brownianGate: !FirstDuration s deviation: !DeviationInSeconds s minDur: !MinDur maxDur: !MaxDur


dutyCycle: !DutyCycle
Range (0,1)

Generates a gate at time intervals computed as the previous duration plus or minus a uniform random deviation (of
maximum size !DeviationInSeconds). Each randomly generated gate does voice-stealing and stays on for a
proportion of the time between gates as specified by !DutyCycle. !On turns the generation of gates on or off. To reset
to the current value of !FirstDuration, set the value of !On to a negative number. To limit the minimum and maximum
durations allowed between gates, use !MinDur and !MaxDur.

The minimum time interval between gates is 6 ms (to allow for voice-stealing). The maximum time interval is
!FirstDuration * 2. The duration of each generated gate is a randomly generated value computed as a random walk
(alternatively called brownian motion). At the beginning of each gate, the value is -1 for 5 milliseconds to allow for
voice stealing.

This expression generates gates that can gradually diverge from a regular, periodic pattern. If the deviation (the
second argument) is 0, you will hear a gate once every !initialDur seconds (the first argument). If the deviation
argument is a small number, you will hear the gate pattern become less and less like the original pattern over time.
This is because the duration between gates is equal to the previous duration plus a uniform random number scaled
by the deviation argument. To reset to the original duration interval between gates, re-gate the expression (by
bringing the receiver (!On) to a non positive number and then restoring it to a positive number again).

For more details on brownian motion, random walks and Weiner processes see:
http://en.wikipedia.org/wiki/Random_walk
http://mathworld.wolfram.com/WienerProcess.html

Examples:

!On brownianGate: !FirstDuration s deviation: !DeviationInSeconds s minDur: !MinDur maxDur: !MaxDur


dutyCycle: !DutyCycle

1 brownianGate: 0.2 s deviation: !Jitter s minDur: !Min s maxDur: !Max s dutyCycle: !DutyCycle

1 brownianGate: 0.2 s deviation: !Jitter s minDur: 0.2 s maxDur: 2 s dutyCycle: !Legato

(0.9 - !Reset) brownianGate: 1 s deviation: !Deviation s minDur: !MinDur s maxDur: !MaxDur s dutyCycle:
!DutyCycle

(!Sw01 brownianGate: !BPM bpm s deviation: (!BPM bpm s * !DevFraction) minDur: !BPM bpm s * 0.5 maxDur:
!BPM bpm s * 1.5 dutyCycle: 0.1) seed: (?VoiceNumber / ?NumberVoices)

((1 brownianGate: 0.2 s deviation: !Jitter s minDur: !Min s maxDur: !Max s dutyCycle: !DutyCycle) seededWith:
?VoiceNumber / ?NumberVoices) triggerEvery: ?NumberVoices offset: ?VoiceNumber - 1

1 brownianGate: !BPM bpm s deviation: (!BPM bpm s * !DevFraction) minDur: !BPM bpm s * 0.5 maxDur: !BPM
bpm s * 1.5 dutyCycle: 0.5

41
brownianTrigger:
Categories: random, triggers & gates

!Gate brownianTrigger: !FirstDuration s


Range (0,1)

Like brownianTrigger:deviation: but with the deviation set to 1% of the !FirstDuration.

The minimum time interval between triggers is 2 ms. The maximum time interval is !FirstDuration * 2. The duration of
each generated trigger is 1 ms. Triggers are positive 1 only (no voice stealing). For more details see
brownianTriggerStart:deviation:minDur:maxDur:

Examples:

!Gate brownianTrigger: !FirstDuration s

1 brownianTrigger: 0.2 s

1 brownianTrigger: 1 s

!sw01 brownianTrigger: !BPM bpm s

!KeyDown brownianTrigger: !BPM bpm s

!Sw01 brownianTrigger: !BPM bpm s

((1 brownianTrigger: 1 s) nextNormal * 0.02 s) seed: 0.23

42
brownianTriggerStart: deviation:
Categories: random, triggers & gates

!Gate brownianTriggerStart: !FirstDuration s deviation: !DeviationScale


Range (0,1)

Generates a trigger at time intervals computed as the previous duration plus or minus a uniform random deviation
scaled by !DeviationScale. !Gate turns the generation of triggers on or off. When !Gate changes from false (<= 0) to
true (>0), the time interval is reset to the current value of !FirstDuration.

This expression is a shortcut for brownianTriggerStart:deviation:minDur:maxDur: that uses 2 ms as the minDur and 2
* startDur as the maxDur

Examples:

!Gate brownianTriggerStart: !FirstDuration s deviation: !DeviationScale

1 brownianTriggerStart: 0.2 s deviation: !Jitter

1 brownianTriggerStart: 1 s deviation: 0.25

!sw01 brownianTriggerStart: !BPM bpm s deviation: !Jitter

!KeyDown brownianTriggerStart: 1 s deviation: !KeyVelocity

!Sw01 brownianTriggerStart: !BPM bpm s deviation: (!BPM bpm s * !DevFraction)

((1 brownianTriggerStart: 1 s deviation: !Jitter) nextNormal * 0.02 s) seed: 0.28

43
brownianTriggerStart: deviation: minDur: maxDur:
Categories: random, triggers & gates

!Gate brownianTriggerStart: !FirstDuration s deviation: !DeviationScale minDur: !MinDur maxDur: !MaxDur


Range (0,1)

Generates a trigger at time intervals computed as the previous duration plus or minus a uniform random deviation
scaled by !DeviationScale. !Gate turns the generation of triggers on or off. When !Gate changes from false (<= 0) to
true (>0), the time interval is reset to the current value of !FirstDuration. To limit the minimum and maximum durations
allowed between triggers, use !MinDur and !MaxDur.

The minimum time interval between triggers is 2 ms. The maximum time interval is !FirstDuration * 2. The duration of
each generated trigger is 1 ms. Triggers are positive 1 only (no voice stealing).

This expression generates triggers that can gradually diverge from a regular, periodic pattern. If the deviation (the
second argument) is 0, you will hear a trigger once every !initialDur seconds (the first argument). If the deviation
argument is a small number, you will hear the trigger pattern become less and less like the original pattern over time.
This is because the duration between triggers is equal to the previous duration plus a uniform random number scaled
by the deviation argument. To reset to the original duration interval between triggers, re-gate the expression (by
bringing the receiver to a non positive number and then restoring it to a positive number again).

For more details on brownian motion, random walks and Weiner processes see:
http://en.wikipedia.org/wiki/Random_walk
http://mathworld.wolfram.com/WienerProcess.html

Examples:

!Gate brownianTriggerStart: !FirstDuration s deviation: !DeviationScale minDur: !MinDur maxDur: !MaxDur

1 brownianTriggerStart: 0.2 s deviation: !Jitter minDur: !Min s maxDur: !Max s

1 brownianTriggerStart: 0.2 s deviation: !Jitter minDur: 0.2 s maxDur: 2 s

(!Sw01 brownianTriggerStart: !BPM bpm s deviation: (!BPM bpm s * !DevFraction) minDur: !BPM bpm s * 0.5
maxDur: !BPM bpm s * 1.5) seed: (?VoiceNumber / ?NumberVoices)

(((1 brownianTriggerStart: 0.2 s deviation: !Jitter minDur: !Min s maxDur: !Max s) seed: ?VoiceNumber /
?NumberVoices) countTriggersMod: ?NumberVoices) eq: ?VoiceNumber

!Sw01 brownianTriggerStart: !BPM bpm s deviation: (!BPM bpm s * !DevFraction) minDur: !BPM bpm s * 0.5
maxDur: !BPM bpm s * 1.5

44
cancelUniqueMemoryWriterRecordingNames
Category: memory writers

[aSound] cancelUniqueMemoryWriterRecordingNames
Range n/a

Cancel unique memory writer renaming for Sounds within the receiver.

This is equivalent to placing Sounds within the receiver into a CancelUniqueMemoryWriterRecordingNames Sound.
This is only needed if the receiver is an expression that contains a Sound.

Examples:

[aSound] cancelUniqueMemoryWriterRecordingNames

45
ceiling
Categories: arithmetic, integer, rounding

!FractionalNumber ceiling
Range (-infinity, infinity)

The ceiling of a number is the next larger integer. It differs from rounding in that it always goes up to the next higher
integer.

When you take the ceiling, you drop the fractional part of the number by moving toward positive infinity to the next
integer. This is the opposite of floor.

Examples:

!FractionalNumber ceiling

3.1 ceiling

-3.9 ceiling

(1 s random abs * 3) ceiling

!Fader ceiling

46
chaoticGate7:
Categories: random, triggers & gates

!On chaoticGate7: !FirstDuration s


Range (-1,1)

Shortcut for a 7-cycle of the logistic map: !On chaoticGate: !FirstDuration s kFactor: 0.70164 minDur: startDur * 0.5
maxDur: startDur * 2 dutyCycle: 0.5.

See chaoticGate:kFactor:minDur:maxDur:dutyCycle:

Examples:

!On chaoticGate7: !FirstDuration s

(0.9 - !Reset) chaoticGate7: !Seed

47
chaoticGate:
Categories: random, triggers & gates

!On chaoticGate: !FirstDuration s


Range (-1,1)

Shortcut for an chaotic (or very long quasicycle) region of logistic map: !On chaoticGate: !FirstDuration s kFactor: 1.0
minDur: startDur * 0.5 maxDur: startDur * 2 dutyCycle: 0.5.

See chaoticGate:kFactor:minDur:maxDur:dutyCycle:

Examples:

!On chaoticGate: !FirstDuration s

(0.9 - !Reset) chaoticGate: !Seed

48
chaoticGate: kFactor:
Categories: random, triggers & gates

!On chaoticGate: !FirstDuration s kFactor: !KFactor


Range (-1,1)

Shortcut for !On chaoticGate: !FirstDuration s kFactor: !KFactor minDur: 0.125 s maxDur: 0.25 s dutyCycle: 0.5.

See chaoticGate:kFactor:minDur:maxDur:dutyCycle:

Examples:

!On chaoticGate: !FirstDuration s kFactor: !KFactor

(0.9 - !Reset) chaoticGate: !Seed kFactor: !K

49
chaoticGate: kFactor: minDur: maxDur: dutyCycle:
Categories: random, triggers & gates

!On chaoticGate: !FirstDuration s kFactor: !KFactor minDur: !MinDur s maxDur: !MaxDur s dutyCycle: !DutyCycle
Range (-1,1)

Generates a gate at time intervals where each time interval is a function of the previous duration: nextDuration := r *
previousDuration * (1 - previousDuration), otherwise known as the logistic map. Instead of R, we use kFactor = (r - 3)
/ 4 which covers the interesting range (3, 4) of the traditional R. Each randomly generated gate does voice-stealing
and stays on for a proportion of the time between gates as specified by !DutyCycle. !On turns the generation of gates
on or off. To reset to the current value of !FirstDuration, set the value of !On to a negative number. To limit the
minimum and maximum durations allowed between gates, use !MinDur and !MaxDur.

The minimum time interval between gates is the larger of !MinDur and 6 ms (to allow for voice-stealing). At the
beginning of each generated gate, the value is -1 for 5 milliseconds to allow for voice stealing. This expression can
generate gates in cyclic patterns, quasi-cyclic patterns, or chaotic non-repeating patterns, depending on the value of
!KFactor.

For more details on logistic map see:


http://en.wikipedia.org/wiki/Logistic_map
http://mathworld.wolfram.com/LogisticMap.html

Examples:

!On chaoticGate: !FirstDuration s kFactor: !KFactor minDur: !MinDur s maxDur: !MaxDur s dutyCycle: !DutyCycle

(0.9 - !Reset) chaoticGate: !StartDur kFactor: !K minDur: !MinDur maxDur: !MaxDur dutyCycle: !DutyCycle

50
chaoticGateIntermittent3:
Categories: random, triggers & gates

!On chaoticGateIntermittent3: !FirstDuration s


Range (-1,1)

Shortcut for an intermittent region of logistic map: !On chaoticGate: !FirstDuration s kFactor: 0.828 minDur: startDur *
0.5 maxDur: startDur * 2 dutyCycle: 0.5.

See chaoticGate:kFactor:minDur:maxDur:dutyCycle:

Examples:

!On chaoticGateIntermittent3: !FirstDuration s

(0.9 - !Reset) chaoticGateIntermittent3: !Seed

51
chaoticGateIntermittent6:
Categories: random, triggers & gates

!On chaoticGateIntermittent6: !FirstDuration s


Range (-1,1)

Shortcut for an intermittent region of logistic map: !On chaoticGate: !FirstDuration s kFactor: 0.6262 minDur: startDur
* 0.5 maxDur: startDur * 2 dutyCycle: 0.5.

See chaoticGate:kFactor:minDur:maxDur:dutyCycle:

Examples:

!On chaoticGateIntermittent6: !FirstDuration s

(0.9 - !Reset) chaoticGateIntermittent6: !Seed

52
chaoticGateIntermittent:
Categories: random, triggers & gates

!On chaoticGateIntermittent: !FirstDuration s


Range (-1,1)

Shortcut for an intermittent region of logistic map: !On chaoticGate: !FirstDuration s kFactor: 0.7 minDur: startDur *
0.5 maxDur: startDur * 2 dutyCycle: 0.5.

See chaoticGate:kFactor:minDur:maxDur:dutyCycle:

Examples:

!On chaoticGateIntermittent: !FirstDuration s

(0.9 - !Reset) chaoticGateIntermittent: !Seed

53
clipPositive
Categories: arithmetic, clipping

!aPositiveOrNegativeEventExpression clipPositive
Range (0,1]

Clip a positive or negative EventExpression such that the result is all positive values (excluding 0).

Use this when you want to avoid any negative or zero values. Any values less than or equal to zero are clipped to a
very small positive number.

Examples:

!aPositiveOrNegativeEventExpression clipPositive

-2 clipPositive

2 clipPositive

1 s random clipPositive ** 7.0

54
clipTo01
Categories: arithmetic, clipping

!PotentiallyLargeNumber clipTo01
Range [0,1]

Clip the range to lie between 0 and 1 (inclusive).

If you have an expression that can become arbitrarily large or small, you can use clipTo01 to ensure that it never gets
larger than 1 or smaller than 0. You can also use it to exclude negative values (they will stick at 0) or values larger
than 1 (which will stick at 1).

Examples:

!PotentiallyLargeNumber clipTo01

6 clipTo01

-6 clipTo01

1 repeatingFullRamp clipTo01

!WiiPitch clipTo01 smoothed * 0.5

((1 - (2 * !Morph) abs) clipTo01 * 2 s)

(!Scale * (1 repeatingTriangle: 2 s) + !Offset) clipTo01

55
clipToAbs1
Categories: arithmetic, clipping, range

!LargePosOrNegNumber clipToAbs1
Range [-1,1]

Clip a positive or negative value so that it always lies between -1 and 1 (inclusive).

When !LargePosOrNegativeNumber is larger than 1, the value of this expression will stick at 1. Similarly, if it goes
lower than -1, the value of this expression will stick at -1.

Examples:

!LargePosOrNegNumber clipToAbs1

6 clipToAbs1

-6 clipToAbs1

(!Scale * (1 repeatingFullRamp: 2 s) + !Offset) clipToAbs1

!Interval clipToAbs1

56
clipToAbs2
Categories: arithmetic, clipping, range

!LargePosOrNegNumber clipToAbs2
Range [-2,2]

Clip the range to lie between -2 and 2 (inclusive).

If you have an expression whose absolute value could be larger than 2, but you want to limit the range to [-2,2] you
can clip the numbers so they are within the desired range using clipToAbs2.

Examples:

!LargePosOrNegNumber clipToAbs2

6 clipToAbs2

-6 clipToAbs2

!Interval clipToAbs2
---
| sum |

sum := 0.

1 to: 10 do: [ :i | sum := sum + (i * !DurScale s random * (i * !ValScale))].

sum clipToAbs2

57
closestIntegerWithHysteresis:
Categories: arithmetic, integer, rounding

!FractionalNumber closestIntegerWithHysteresis: !Hysteresis


Range (-infinity, infinity)

If !FractionalNumber differs from the previous result of this expression by more than !Hysteresis, the output result
changes to the closest integer to !FractionalNumber. Otherwise, the result is left unchanged.

For !Hysteresis values < 0.5, this is the same as rounding (no memory effects). For !Hysteresis > 0.5, the output
sticks with the previous result until the input changes by more than !Hysteresis distance away from the current output.

Examples:

!FractionalNumber closestIntegerWithHysteresis: !Hysteresis

!KeyPitch closestIntegerWithHysteresis: 0.625

58
closestPowerOfTwo
Categories: arithmetic, powersOf2

!Number closestPowerOfTwo
Range (-infinity, infinity)

Return the power of 2 that is closest to !Number.

Examples:

!Number closestPowerOfTwo

3 closestPowerOfTwo

2.9 closestPowerOfTwo

0.1 closestPowerOfTwo

!Interval closestPowerOfTwo

!Frequency * (!FScale closestPowerOfTwo)

59
compensatedLevel
Categories: level, eq

!Frequency hz compensatedLevel
Range [0,1]

Send this message to a frequency or pitch with units (nn or hz), to get a level that will compensate for the
psychoacoustic loudness of that frequency.

When played at two different pitches, the same exact Sound can have two different perceived loudness (even if the
physical amplitudes are identical). For example, a sine wave oscillator at 4000 hz can sound much louder than the
same oscillator played at 30 hz, even if the amplitudes are identical. Using an approximate of an equal loudness
curve, the compensatedLevel does a rough adjustment of the amplitude based on the current frequency to
compensate for the perceptual loudness of that frequency.

Examples:

!Frequency hz compensatedLevel

!Level * (!KeyPitch compensatedLevel)

!AmpLow smoothed * (!logFreq smoothed nn compensatedLevel)

60
copies:
Categories: arrays, controllers

!anEventValue copies: <anInteger>


Range N/A

This is a handy shortcut for creating an Array of uniquely numbered EventValues, numbered starting from 0 (or
starting from the number on the end of !anEventValue). It can be used in parameter fields that expect an Array of
values (for example, in a SyntheticSpectrumFromArray or an AnalogSequencer),

Note: if the number of copies includes any green variables, create the eventValue (by sending asEventValue to a
string name) and then send the copies: message to the newly created EventValue (for example, ’fader’ asEventValue
copies:). For parameter fields that expect an Array, place the expression within curly braces {} to let the compiler
know that it should evaluate the expression to create the Array (rather than treat each character of the expression as
one element of the Array).

Examples:

!anEventValue copies: <anInteger>

{!Fader3 copies: 2}

{!Amp copies: 8}

{!Freq copies: 8}

{!Dur copies: 4}

{’Fader3’ asEventValue copies: ?NumberVoices}

((1 bpm: !BPM) nextIndexMod: ?NumberVoices) of: (’F’ asEventValue copies: ?NumberVoices)

61
cos
Categories: arithmetic, trigonometric

!EventExpression cos
Range [-1,1]

Cosine of an EventExpression.

The hyperbolic functions are trigonometry expanded to apply to more than just circles.

Examples:

!EventExpression cos

0 cos

(2 * Double pi) cos

Double pi cos

(2 * Double pi * (1 repeatingRamp)) cos

62
cosh
Categories: arithmetic, trigonometric

!EventExpression cosh
Range [1, infinity)

Hyperbolic cosine of an EventExpression. The shape of the function is like an upturned cup with a minimum value of
1 when !EventExpression is 0. For !EventExpression values greater than or less than 0, the cosh grows without
bound.

Just as the point (cos t, sin t) is a point on a circle, the point (cosh t, sinh t) is a point on a hyperbola. The hyperbolic
cosine is the average of an increasing and a decreasing exponential function (e ** x + (e ** x negated) / 2).

For more information, see:


http://en.wikipedia.org/wiki/File:Sinh_cosh_tanh.svg

Examples:

!EventExpression cosh

0 cosh

1 cosh

(1 repeatingFullRamp cosh * 2 - 2

63
countTriggers
Categories: count, counting, detection

!Trigger countTriggers
Range [1, infinity)

The value increases by 1 each time the !Trigger changes from 0 to a positive value. The initial value before the first
trigger is 0.

Note that this expression starts counting from 1 (and its initial state before the first trigger is 0). To start counting at 0
(with an initial state of -1 before the first trigger), see nextIndex.

Examples:

!Trigger countTriggers

1 s tick countTriggers

(1 bpm: !BPM) countTriggers

64
countTriggersMod:
Categories: count, counting, detection

!Trigger countTriggersMod: !Modulus


Range [0, (!Modulus - 1)]

Like countTriggers, except when the count reaches the value of !Modulus, it becomes 0 and starts counting from
there. Counts up by 1 each time the value of !Trigger changes from 0 to a positive value.

Note that this expression starts counting from 1 and wraps around to 0 when the count reaches the value of !Modulus.
To start counting at 0 and wrap around to 0, see nextIndexMod:

Examples:

!Trigger countTriggersMod: !Modulus

1 s tick countTriggersMod: 16

(1 bpm: !BPM) countTriggersMod: !Beats

((1 bpm: !BPM) countTriggersMod: 8) + 1

65
countTriggersMod: reverse:
Categories: count, counting, detection

!Trigger countTriggersMod: !Modulus reverse: !Rev01


Range [0, (!Modulus - 1)]

Like countTriggersMod: except with an extra argument, !Rev01 (0 or 1), that changes the increment (counting up) to a
decrement (counting down). Counts up or down by 1 each time the !Trigger changes from a value <= 0 to a positive
value.

To count beats starting from 1, rather than 0, add 1 to the result of the entire expression. Note that when you use
bpm: or tick to generate the triggers for countTriggers, you should take the absolute value of the generated trigger
(since both bpm: and tick generate triggers that start at -1 for five milliseconds before going up to 1 in order to allow a
previously triggered envelope time to ramp down to zero when you are doing voice-stealing.

Examples:

!Trigger countTriggersMod: !Modulus reverse: !Rev01

1 s tick countTriggersMod: 16 reverse: 1

(1 bpm: !BPM) countTriggersMod: !Beats reverse: !Rev01

((1 bpm: !BPM) countTriggersMod: 8 reverse: !Rev01) + 1

66
countTriggersMod: reverse: reset:
Categories: count, counting, detection

!Trigger countTriggersMod: !Modulus reverse: !Reverse reset: !Reset


Range [0, (!Modulus - 1)]

Like countTriggersMod:reverse: but resets to 1 when !Reset changes from a value <= 0 to a positive value.

Examples:

!Trigger countTriggersMod: !Modulus reverse: !Reverse reset: !Reset

1 s tick countTriggersMod: 12 reverse: !Reverse reset: !Reset

(1 bpm: !BPM) countTriggersMod: 12 reverse: ((1 bpm: !BPM) nextRandom gt: 0.5) reset: ((1 bpm: !BPM)
nextRandom gt: 0.9)

67
countTriggersReset:
Categories: count, counting, detection

!Trigger countTriggersReset: !Reset


Range [0, (!Modulus - 1)]

Like countTriggers but resets to 0 when !Reset changes from a value <= 0 to a positive value.

Examples:

!Trigger countTriggersReset: !Reset

1 s tick countTriggersReset: !Reset

((1 bpm: !BPM) countTriggersReset: (!BPM bpm s random gt: 0))

((1 bpm: !BPM) countTriggersReset: (!Reset alignWith: (1 bpm: !BPM))) mod: 12

68
cubed
Category: arithmetic

!aValue cubed
Range [0, infinity)

!aValue cubed is equivalent to the expressions (!aValue ** 3) and (!aValue * !aValue * !aValue)

Cubing a number less than 1 makes that number smaller, so cubed can be used as a way to warp or bias a fader
toward smaller values (while still mapping zero to zero and 1 to 1). Additionally, cubed numbers keep the same sign,
so you can cube negative numbers without losing their sign information.

Examples:

!aValue cubed

1 s random cubed

!Brightness cubed

1 repeatingRamp cubed

!LogFreq nn + (((!Trigger ramp: 2 s) cubed) * 12 nn)

69
db
Categories: units, amplitude, level

!aNegativeLevelInDecibels db
Range (infinitesimal, infinite)

See dB.

Unity gain is 0 db so attenuation should be expressed as a negative number followed by db. The linear amplitude for
positive dB values will be larger than 1; bear in mind that some parameter fields expect a maximum of 1 and will clip
at 1. Note that a negative value in dB can correspond to a very small linear amplitude but it can never get to 0.

Examples:

!aNegativeLevelInDecibels db

0 db

-3 db

-90 db

!Gain db

70
dB
Categories: units, amplitude, level

!aNegativeLevelInDecibels dB
Range (infinitesimal, infinite)

Translates an EventValue in log amplitude (decibels) to a linear amplitude (where 0 dB = 1.0).

Unity gain is 0 dB so attenuation should be expressed as a negative number followed by dB. The linear amplitude for
positive dB values will be larger than 1; bear in mind that some parameter fields expect a maximum of 1 and will clip
at 1. Note that a negative value in dB can correspond to a very small linear amplitude but it can never get to 0.

Examples:

!aNegativeLevelInDecibels dB

0 dB

-3 dB

-90 dB

!Gain dB

71
derivative
Categories: arithmetic, feature extraction

!anEventExpression derivative
Range (0,1)

This expression tells you the rate of change in !anEventExpression. It tells you how much !anEventExpression is
changing per second.

Once per millisecond, this expression revises its estimate of the rate of change per second in !anEventExpression.

Examples:

!anEventExpression derivative

!Fader smoothed derivative abs gt: !Threshold

!x derivative accumulateWithHalfLife: !Tc s

72
doNotTrigger
Category: triggers

!anEventValue doNotTrigger
Range ()

Prevents anEventValue from causing any expression that contains it be evaluated when it changes.

When you have set up a feedback loop in a SoundToGlobalController such that the generatedEventValue depends
on itself, you can prevent the unbounded re-evaluation of the expression by sending doNotTrigger to the self
referential EventValue.

Examples:

!anEventValue doNotTrigger

(!Size * !Direction) accumulate01While: !Accumulate initialValue: !ResetToValue doNotTrigger reset: !Reset

73
durationBetweenTriggers
Categories: duration, triggers & gates, timing, feature extraction

!Trigger durationBetweenTriggers s
Range [0,infinity]

The value of this expression is the duration in seconds between the two most recent occasions that !Trigger has
changed from a 0 to 1. This expression is one way to measure the duration between events or the period of a
repeating trigger.

You can use this expression to measure the duration between events. If you take the inverse of this duration, you can
get the frequency or the rate of events.

Examples:

!Trigger durationBetweenTriggers s

(1 bpm: !BPM) durationBetweenTriggers s

(1 bpm: !BPM) durationBetweenTriggers s bpm

1 bpm: ((1 s random gt: 0) durationBetweenTriggers s bpm removeUnits)

(1 s random gt: 0) durationBetweenTriggers s tick

74
durationBetweenTriggers:
Categories: duration, triggers & gates, timing, feature extraction

!Trigger durationBetweenTriggers: !NumberOfTriggers


Range [0,infinity]

How many seconds did it take for the last !NumberOfTriggers triggers to occur? The value of this expression is the
duration in seconds that it took for !Trigger to make !NumberOfTriggers transitions from 0 to 1.

For example, you could use this expression to measure the duration of a bar of 4 beats or to extract the tempo of an
audio signal by measuring how often it crosses a threshold amplitude.

Examples:

!Trigger durationBetweenTriggers: !NumberOfTriggers

(1 bpm: !BPM) durationBetweenTriggers: 4

(1 bpm: !BPM) durationBetweenTriggers s bpm

(!JitteryTrigger durationBetweenTriggers: 8) s bpm removeUnits * 8

(1 bpm: ((1 s random gt: 0) durationBetweenTriggers: 8) s bpm removeUnits)

(1 s random gt: 0) durationBetweenTriggers s tick

75
durationOfGate
Categories: duration, triggers & gates, timing, feature extraction

!Gate durationOfGate
Range [0,infinity]

Returns the number of seconds a !Gate is held down. When !Gate changes from a zero to a non-zero value, the timer
starts; when !Gate value returns to 0, the value of this expression updates to be the number of seconds the !Gate was
non-zero. It holds this value until the next time !Gate makes a transition from 0 to non-zero and back to 0.

You could use this expression to measure the amount of time a key was held down or the number of seconds that a
threshold value was exceeded.

Examples:

!Gate durationOfGate

!KeyDown durationOfGate

(1 bpm: !BPM) durationOfGate

(!Fader gt: !Threshold) durationOfGate s

!Gate durationOfGate s bpm

76
editCopy
Categories: notebooks, sounds

[aPastedSound] editCopy
Range N/A

To edit a copy of a Sound that has been pasted into a parameter field or a Notebook, send the editCopy message.
This opens a Sound editor on a copy of the Sound, so any changes you make in the editor will not affect the original,
pasted Sound.

Examples:

[aPastedSound] editCopy

77
eq:
Categories: equal, test, logic, comparison

!EventExpr1 eq: !EventExpr2


Range (0, 1)

Tests whether two events have equal values. Returns 1 when the value of !EventExpr1 equals that of !EventExpr2.

See also ne: (not equal), lt: (less than), gt: (greater than), ge: (greater than or equal to), le: (less than or equal to).

Examples:

!EventExpr1 eq: !EventExpr2

!KeyNumber eq: 72

(!KeyNumber mod: 12) eq: 3

(!Fader lt: 0.6) * (!Fader ge: 0.4)

(!Fader lt: 0.6) * (!Fader gt: 0.4)

78
euclideanForBeats: pulses: offset:
Categories: time functions, trigger modifiers

(1 bpm: !BPM) euclideanForBeats: !BeatsPerBar pulses: !PulsesPerBar offset: !OffsetBeats


Range (-1,1)

Convert a regular pattern of triggers into a pattern with pulses and silences by distributing !PulsesPerBar as evenly as
possible within a measure containing !BeatsPerBar.

Generates a pattern of triggers that places !PulsesPerBar in the time of !BeatsPerBar and delays or offsets the
pattern by !OffsetBeats. The algorithm distributes the pulses evenly within !BeatsPerBar while quantizing to the
nearest integer beat. Interesting asymmetric patterns result when !PulsesPerBar is not an even submultiple of
!BeatsPerBar.

Examples:

(1 bpm: !BPM) euclideanForBeats: !BeatsPerBar pulses: !PulsesPerBar offset: !OffsetBeats

79
euclideanPulseDurationForBeats: pulses:
Categories: time functions, trigger modifiers, duration, sequences

!PulseNumber euclideanPulseDurationForBeats: !BeatsPerBar pulses: !PulsesPerBar


Range [0, Infinity)

The duration of !PulseNumber in a sequence of pulses generated by the Euclidean beat pattern created by
distributing !PulsesPerBar as evenly as possible within a measure containing !BeatsPerBar.

The Euclidean algorithm distributes some number of events (!PulsesPerBar) evenly within !BeatsPerBar, quantizing
to the nearest integer beat. This message gives you the duration of the receiver (!PulseNumber) which is the ordinal
number of a particular pulse. For example, if you wanted to know the duration of the third pulse in a Euclidean beat
pattern, you would send this message to the integer, 3. All of the EventValues are expected to be integers. See also
euclideanForBeats:pulses:offset: (which generates a pattern of Euclidean triggers) and
isOnForEuclideanBeats:pulses:offset: (which returns true (1) if the receiver (the beat number) would be switched on
in a Euclidean beat pattern defined by the pulses, beats, and offset.)

Examples:

!PulseNumber euclideanPulseDurationForBeats: !BeatsPerBar pulses: !PulsesPerBar

1 euclideanPulseDurationForBeats: 4 pulses: 3

1 euclideanPulseDurationForBeats: !Beats pulses: !Pulses

1 to: 3 collect: [:pn | pn euclideanPulseDurationForBeats: 4 pulses: 3]

1 to: 6 collect: [:pn | pn euclideanPulseDurationForBeats: 8 pulses: 6]

80
euclideanStartBeatForBeats: pulses: offset:
Categories: time functions, trigger modifiers, duration, sequences

!PulseNumber euclideanStartBeatForBeats: !BeatsPerBar pulses: !PulsesPerBar offset: !Offset


Range [1, !BeatsPerBar)

The starting time (in beats) of !PulseNumber in a sequence of pulses generated by the Euclidean beat pattern created
by distributing !PulsesPerBar as evenly as possible within a measure containing !BeatsPerBar.

The Euclidean algorithm distributes a number of events (!PulsesPerBar) evenly within !BeatsPerBar, quantizing to the
nearest integer beat. This message gives you the start time in beats of the receiver (!PulseNumber) which is the
ordinal number of a particular pulse. For example, if you wanted to know when the third pulse in a Euclidean beat
pattern starts, you would send this message to the integer, 3. All of the EventValues are expected to be integers. See
also euclideanPulseDurationForBeats:pulses: (which tells you the duration of the !PulseNumber you send it to),
euclideanForBeats:pulses:offset: (which generates a pattern of Euclidean triggers) and
isOnForEuclideanBeats:pulses:offset: (which returns true (1) if the receiver (the beat number) would be switched on
in a Euclidean beat pattern defined by the pulses, beats, and offset.)

Examples:

!PulseNumber euclideanStartBeatForBeats: !BeatsPerBar pulses: !PulsesPerBar offset: !Offset

3 euclideanStartBeatForBeats: 4 pulses: 3 offset: 0

3 euclideanStartBeatForBeats: 4 pulses: 3 offset: 1

1 to: 3 collect: [:pn | pn euclideanStartBeatForBeats: 4 pulses: 3 offset: 0]

81
evaluate:
Categories: evaluation, conditional evaluation, programming, savingState

!Trigger evaluate: !ChangingExpression


Range [-Infinity, Infinity]

When !Trigger becomes true (greater than 0), evaluate the CapyTalk code in !ChangingExpression exactly once.
Return the value of that expression until !Trigger becomes false (less than or equal to 0) and then changes to true
(greater than 0) again.

Useful for evaluating iterative expressions in which the state is saved in a variable for use in the next interation. Note
that, unlike with other CapyTalk expressions, changes to EventValues within the argument to evaluate: will NOT
trigger the evaluation of the expression; only the !Trigger argument can trigger evaluation of that expression. Thus,
care should be taken when using any CapyTalk messages that depend on time (for example ramp: or bpm:) within an
expression used as the argument to evalute: as these functions will not update continuously, but update ONLY when
!Trigger changes to a positive nonzero value.

Examples:

!Trigger evaluate: !ChangingExpression


---
| cur prev prevPrev |

prevPrev := EventVariable new initialValue: 1.


prev := EventVariable new initialValue: 0.
cur := EventVariable new initialValue: 0.

1 s tick evaluate: (
(cur <+ (prev + prevPrev)),
(prevPrev <+ prev),
(prev <+ cur)),

cur
---
| cur prev prevPrev |

prevPrev := EventVariable new initialValue: 1.


prev := EventVariable new initialValue: 0.
cur := EventVariable new initialValue: 0.

((cur gt: 89)


true: ((cur <+ (prev <~ 0)), (prevPrev <+ 1))
false: (
(1 bpm: !BPM) evaluate: (
(cur <+ (prev + prevPrev)),
(prevPrev <+ prev),
(prev <+ cur))
)
),
cur

82
exp
Categories: arithmetic, exponential

!Exponent exp
Range (infinitesimal, infinity)

This is Eulers number, e (~2.71828), raised to the power of !Exponent. e is the base of the natural logarithms. To see
an approximation of Eulers number, evaluate 1 exp (which is e ** 1)

You can use exp to compute how your bank account is growing with compounding interest: (!Rate * !Time) exp. If
your bank gives you 1% of continuously compounding interest per year and you put 100 ingots in the account, in two
years you should have 100 * (0.01 * 2) exp = 102.02 ingots. Similarly, you can create an exponential growth (or
decay) in a parameter value using an expression of the form !LocalTime exp. Or better yet, you can gate a timer so
you can control when the growth begins, for example, (!Gate ramp: 3 s) exp * 300 hz.

Examples:

!Exponent exp

1 exp

4 exp

-2 exp

2 exp ln

1 repeatingRamp exp - 1 / (1 exp - 1)

1 bpm: 30 + (330 * ((!Accelerando smooth: !Dur s) exp - 1))

((!Trigger triangle: !Dur s) - 1) exp * 200 hz

83
false: true:
Categories: conditional, Boolean, true, false, logic

!TestExpr false: !ValueIfFalse true: !ValueIfTrue


Range [-Infinity, Infinity]

When !TestExpr is false (less than or equal to 0), the value of this expression is !ValueIfFalse. When !TestExpr is true
(non-zero), the value of the expression is !ValueIfTrue.

See true:false: if it makes more sense to put the true condition first.

Examples:

!TestExpr false: !ValueIfFalse true: !ValueIfTrue

!Invert false: !Interval negated true: !Interval

1 false: 512 true: 256

(1 s random gt: 0) false: ((0.25 s tick nextIndexMod: 4) of: #(60 62 65 67 69)) true: !KeyNumber)

84
floor
Categories: arithmetic, integer, rounding

!NumberWithAFractionalPart floor
Range [-infinity, infinity]

The floor of a !NumberWithAFractionalPart is the next smaller integer.

When you take the floor, you get the next smaller integer; this is true for both positive and negative numbers.
Compare this against truncated which simply drops the digits after the decimal (for negative numbers, truncated gives
you the next larger integer).

Examples:

!NumberWithAFractionalPart floor

3.1 floor

-3.9 floor

(0.25 s tick nextRandom abs * 4) floor * 12 nn + !LogFreq

85
followFromPosition: rate: friction:
Category: control modifiers

!Leader followFromPosition: 0 rate: !Rate friction: !Friction


Range (-infinity, infinity)

When you move !Leader to a new position, the output of this expression follows the leader to the new position at the
given !Rate. If !Friction is low enough it will overshoot its target and oscillate at !Rate times per second. !Friction
controls the rate of decay in the amplitude of the oscillations (when !Friction = 0, it oscillates indefinitely). This can
become even more interesting when used in a parameter field of a Sound in a Replicator, where each argument
depends in some way on ?VoiceNumber, so each copy of the control moves and oscillates differently. The position
argument is a constant specifying the initial starting position.

Examples:

!Leader followFromPosition: 0 rate: !Rate friction: !Friction

86
fullRamp
Category: time functions

!Trigger fullRamp
Range (-1,1)

fullRamp is equivalent to using fullRamp: with a duration of 1 second. It is a linear function that increases from -1 to 1
over the course of 1 s and then sticks at 1 until it is retriggered.

See fullRamp: for more details and examples.

Examples:

!Trigger fullRamp

!PenDown fullRamp

87
fullRamp:
Category: time functions

!Trigger fullRamp: !Dur s


Range (-1,1)

Linear function that increases from -1 to 1 over the course of !Duration s and then sticks at 1 until it is retriggered.
Retriggered whenever !Trigger changes from a value <= 0 to a value > 0.

Its (-1,1) range makes fullRamp an ideal function to use as a TimeIndex. Because it increases linearly over a given
duration, it is also a good function to use as the time argument for other functions such as exp or normCos.

Examples:

!Trigger fullRamp: !Dur s

!Trigger fullRamp: ’frase’ fileDuration s

1 - (!Trigger fullRamp: !Dur s) abs

!KeyDown fullRamp: ’056_3g#_99_principale.L.gaf’ fileDuration s

(!Trigger fullRamp: 2 s) exp + !Offset * !Scale

!PenDown fullRamp: (3 s + ((!PenZ gt: 0.9) * 10))

(!Trigger fullRamp: 0.17 s) clipTo01

88
gateTimeToNext: dutyCycle:
Category: triggers & gates

!On gateTimeToNext: !TimeIntervalBetweenGates dutyCycle: !FractionOfTimeIntervalBetweenGates


Range [-1,1]

While !On is true, this expression generates a gate (with voice-stealing) that lasts for
(!FractionOfTimeIntervalBetweenGates * !TimeIntervalBetweenGates) and continues to generate gates every
!TimeIntervalBetweenGates. For example, the expression (1 gateTimeToNext: 1 s dutyCycle: 0.5) would generate a
new gate once per second and each gate would last for a 0.5 s. Each time !On becomes false and then true again, a
gate is emitted and !TimeIntervalBetweenGates and !FractionOfTimeIntervalBetweenGates are re-sampled. If you
want a 1 ms trigger, rather than a gate with dutyCycle, use triggerTimeToNext: instead.

Each time a gate is generated, the value of !TimeIntervalBetweenGates and!FractionOfTimeIntervalBetweenGates


are sampled and the value of !TimeIntervalBetweenGates is used as the time to wait until emitting the next gate. In
other words, this expression generates a sequence of gates every !TimeIntervalBetweenGates. !On turns the
generation of the stream of gates on or off. The first gate is generated when !On turns off (<= 0) and then on (> 0)
again. The minimum time interval between triggers is 6.5 ms (to allow for voice-stealing).

Examples:

!On gateTimeToNext: !TimeIntervalBetweenGates dutyCycle: !FractionOfTimeIntervalBetweenGates

1 gateTimeToNext: 1 s dutyCycle: 0.5

(1 gateTimeToNext: 6 s dutyCycle: 0.5) gateTimeToNext: 15 hz s dutyCycle: 0.5

{| files ranIndex dur rate |


files := ’1WN3.aif’ fileNamesOfSameTypeInSameFolder.
ranIndex := (0.2 s random abs seededWith: 29) * files size.
dur := ranIndex of: (files collect: [:sf | sf fileDuration]).
rate := 1 + (!Random * !RateJitter).

Array with: ranIndex


with: (1 gateTimeToNext: (dur / rate + ((1 s random abs * !InterDelay))) dutyCycle: 1)
with: rate}

((1 gateTimeToNext: !long s dutyCycle: !Duty) gateTimeToNext: !Medium s dutyCycle: !Duty) gateTimeToNext:
!Short s dutyCycle: !Duty

89
gateWhen:
Category: triggers & gates

!aGate gateWhen: !aBooleanExpression


Range [-1, 1]

Generates a gate (a value of 1) only when !aGate is on (> 0) and !aBooleanExpression is true (> 0).

You can use gateWhen: to generate a gate that will only take effect under certain combinations of circumstances, for
example only when a key is down and the pitch is within a certain range or to gate only specific voices in a Replicator,
channelizer, or MIDIVoice. When !aGate becomes true, the value of gateWhen: becomes -1 for 5 milliseconds to
allow for voice-stealing, before it goes up to 1.

Examples:

!aGate gateWhen: !aBooleanExpression

!KeyDown gateWhen: (!KeyNumber eq: 61)

!KeyDown gateWhen: ((!KeyNumber gt: 60) * (!KeyNumber lt: 72))

0.25 s tick gateWhen: (0.25 s random gt: 0.5)

!Gate gateWhen: (((1 bpm: !BPM) countTriggersMod: ?NumberVoices) eq: (?VoiceNumber - 1))

1 gateWhen: (((1 bpm: !BPM) nextChaotic: !k seed: 0.07 reset: !Reset) gt: !Thresh)

90
ge:
Categories: logic, arithmetic, comparison

!Expression1 ge: !Expression2


Range [0, 1]

ge: or ’greater than or equal to ( )’ tests the value of !Expression1 compared to the value of !Expression2. The value
of the test is true (1) when the value of !Expression1 is greater than or equal to the value of !Expression2. If
!Expression1 is less than !Expression2, the value of the test is false (0).

Use ge: ( ) to test whether the value of one expression is greater than or equal to that of another. The result is a logic
1 (true) or a logic 0 (false). See also eq: (=), ne: ( ), lt: (<), gt: (>), and le: ( ).

Examples:

!Expression1 ge: !Expression2

!Fader1 ge: !Fader2

(!KeyNumber mod: 12) ge: 0

91
gt:
Categories: logic, arithmetic, comparison

!Expression1 gt: !Expression2


Range [0, 1]

gt: or ’greater than (>)’ tests the value of !Expression1 compared to the value of !Expression2. The result of the test is
true (1) when the value of !Expression1 is greater than the value of !Expression2. If !Expression1 is less than or equal
to !Expression2, the value of the test is false (0).

Use gt: (>) to test whether the value of one expression is larger than that of another. The result is a logic 1 (true) or a
logic 0 (false). See also eq: (=), ne: ( ), lt: (<), le: ( ), and ge: ( ).

Examples:

!Expression1 gt: !Expression2

!Fader1 gt: !Fader2

(!KeyNumber mod: 12) gt: 0

92
h
Categories: units, unitsOfFrequencyAndDuration

!aDurationInHours h
Range N/A

h (hours) is a unit of duration equal to 60 m or 3600 s. When you evaluate this (or other durations), such as m
(minutes), h (hours), day (days), ms (milliseconds), or usec (microseconds), the result will be expressed in terms of
seconds (s).

In Kyma, a unit of frequency or duration is a message that you send to a number (or EventValue) to create a new
object called a ScalarWithUnits. You can cascade units of frequency and duration to convert from one to another (for
example, from frequency to pitch or from duration to a tempo in terms of beats-per-minute or even from a duration to
a frequency (where the duration is interpreted as the length of one cycle at that frequency). Try selecting and
evaluating some of the expressions below using Ctrl+Y (Edit>Evaluate).

Examples:

!aDurationInHours h

1 h / 60 / 60

1h

24 h

1 h samp

93
hasChangedInLast:
Categories: detection, test, logic

!EventExpr hasChangedInLast: !Duration s


Range (0, 1)

Detects whether !EventExpr has changed within the last !Duration seconds. When !EventExpr changes, return 1 for
!Duration s; then return to 0.

Useful for filtering out bounces or jitter in a controller; for example, if you accidentally trigger something twice within
0.1 s and you have the !Duration set to 1 s, the accidental trigger will be ignored because it happened less than 1 s
after the first trigger.

Examples:

!EventExpr hasChangedInLast: !Duration s

!Fader hasChangedInLast: !Duration s

!Trigger hasChangedInLast: 3 s

!Trigger hasChangedInLast: ’pottery break 7.aif’ fileDuration s

94
hasChangedReset:
Categories: detection, test, logic

!EventExpr hasChangedReset: !Reset


Range (0, 1)

Detects whether !EventExpr has become true (> 0) since the last !Reset. While !Reset is true (> 0), the output state is
0. If !Reset is false (<= 0), and !EventExpr is true (> 0), the output state is 1. If !Reset is false (<= 0), and !EventExpr
is false (<= 0), the output state is unchanged.

Useful for detecting the first time something happens (with the option to reset the state so you can trigger it again).

Examples:

!EventExpr hasChangedReset: !Reset

!Gate hasChangedReset: !Reset

(!FirstTime hasChangedReset: 0) trackAndHold: !Control

95
hz
Categories: units, unitsOfFrequencyAndDuration

!CyclesPerSecond hz
Range N/A

To express a frequency in terms of cycles per second, use units of hz (Hertz). To convert from linear frequency (hz) to
log frequency or pitch (nn), cascade the units of hz and nn, for example 440 hz nn.

In Kyma, a unit of frequency or duration is a message that you send to a number (or EventValue) to create a new
object called a ScalarWithUnits. You can cascade units of frequency and duration to convert from one to another (for
example, from frequency to pitch or from duration to a tempo in terms of beats-per-minute.

Examples:

!CyclesPerSecond hz

261.6256d hz nn

441 hz samp

(!NoteNumber + 12 nn) hz

96
hzToSignal
Categories: frequency, feature extraction

!anEventExpression0ToHalfSR hzToSignal
Range [0, 1]

Assumes that !anEventExpression0ToHalfSR is a frequency in hertz in the range (0, SR/2) and converts it to a
normalized frequency in the range (0,1) with the hz units removed.

See also signalToHz.

Examples:

!anEventExpression0ToHalfSR hzToSignal

97
inDB
Categories: units, amplitude, level

!aAmplitudeLevel inDB
Range (-Infinity, Infinity)

Translates an EventValue in linear amplitude to log amplitude (decibels, where 0 dB = 1.0).

Unity gain is 0 dB so attenuation will result in a negative dB value and gain will result in a positive dB value. Note that
negative and zero linear amplitudes have no corresponding decibel values.

Examples:

!aAmplitudeLevel inDB

1 inDB

0.5 inDB

0.001 inDB

!Gain inDB

98
indexOfValueIn:
Categories: arrays, choice, selection

!Value indexOfValueIn: #( 0 0.25 0.5 0.75 1 )


Range (0, arrayOfNumbers size)

From an array of constant values in order from smallest to largest, return the index of the smallest value in the Array
larger than !Value.

If !Value is less than the first element, the result is zero; if !Value is greater than the last value, the result is the size of
the array.

Examples:

!Value indexOfValueIn: #( 0 0.25 0.5 0.75 1 )

7.5 indexOfValueIn: #( 5 6 7 8 )

10 indexOfValueIn: #( 5 6 7 8 )

2 indexOfValueIn: #( 5 6 7 8 )

(1 s random abs * 9) indexOfValueIn: #( 1 2 4 8 )

99
indexToOrdinalIn:
Categories: arrays, choice, selection

!Index indexToOrdinalIn: #(!Expr0 !Expr1 !Expr2)


Range (-infinity, infinity)

From an array of EventExpressions, return the order of the !Index-th largest one. Positions in the array are numbered
from (0 to sizeOfArray - 1). !index should be in the range of [0, (sizeOfArray - 1)) to access all elements of the array.

The array of EventExpresions is indexed by !Index, then sorted into ascending order; the value of this expression is
the location of the indexed value in the sorted array of EventExpressions.

!Index is truncated and clipped to lie within (0, sizeOfArray - 1) so if your index is zero or smaller, you will get the
location of the first element of the original array in the sorted array or if your index is larger than the array size, you
will get the index of the last element of the original array in the sorted array.

Examples:

!Index indexToOrdinalIn: #(!Expr0 !Expr1 !Expr2)

0 indexToOrdinalIn: #( 8 7 6 5)

3 indexToOrdinalIn: #( 8 7 6 5)

(!Fader01 * 3) indexToOrdinalIn: #(!Expr0 !Expr1 !Expr2)

2 indexToOrdinalIn: #(10 9 8 7)

(1 s random abs * 3) indexToOrdinalIn: #(!Interval1 !Interval2 !Interval3)

100
initialSampleAndHold:
Categories: sampleAndHold, capture

!Trigger initialSampleAndHold: !ChangingExpression


Range [-Infinity, Infinity]

Like sampleAndHold: except it samples and holds the initial value of the !ChangingExpression. Then when !Trigger
becomes true (greater than 0), sample the current value of !ChangingExpression. Return that value until !Trigger
becomes false (less than or equal to 0) and then true (greater than 0) again.

Examples:

!Trigger initialSampleAndHold: !ChangingExpression

101
inOctaves
Categories: units, unitsOfFrequencyAndDuration

!aPitch nn inOctaves
Range (-Infinity, Infinity)

Converts !aPitch into units of octaves and fractions of an octave. For example 4 c inOctaves = 4.0 and 4 f sharp = 4.5
(because, in pitch space, the tritone is halfway between 4 c and 5 c).

Examples:

!aPitch nn inOctaves

4 c inOctaves

4 f sharp inOctaves

261.6256d hz inOctaves

78 nn inOctaves

!KeyPitch inOctaves

4 a inOctaves

1 repeatingTriangle: (((60 nn + !Interval nn) inOctaves / 4) s)

102
interpolateFrom: to:
Categories: arithmetic, control modifiers

!Position interpolateFrom: !Value0 to: !Value1


Range [-Infinity, Infinity]

Linearly interpolate between !Value0 and !Value1 according to the value of !Position, where a !Position of 0 gives you
!Value0; a !Position of 1 gives you !Value1; and a !Position of 0.5 gives you a value halfway between !Value0 and
!Value1. This is equivalent to the expression:

((1 - !Position) * !Value0) + (!Position * !Value1). Typically, the value of the !Position control ranges from 0 to 1. (You
can use any range for !Position, but the [0,1] range is the easiest one to reason with). The ranges of !Value0 and
!Value1 are unrestricted and they can also be EventExpressions.

You can think of interpolateFrom:to: as a mix of two controls (!Value0 and !Value1) with !Position controlling the
strength or the weighting of one control over the other. You can use it as a way to cross-fade between two sources of
control.

Examples:

!Position interpolateFrom: !Value0 to: !Value1

0.5 interpolateFrom: 0.1 to: 0.2

0.5 interpolateFrom: 2 to: -2

-1 interpolateFrom: 1 to: 2

!Position interpolateFrom: 1 repeatingTriangle to: 1 repeatingFullRamp normSin

(1 repeatingTriangle: 5 s) interpolateFrom: 1 repeatingTriangle to: 1 repeatingFullRamp normSin

((1 repeatingTriangle: 5 s) interpolateFrom: (1 s tick countTriggersMod: 5) to: (1 repeatingFullRamp: 7 s)


normSin) interpolateFrom: 6 to: 0

103
intervalAtStepInScaleIndex:
Categories: pitch, scales, tuning, frequency

!aScaleStep intervalAtStepInScaleIndex: scaleIndex012


Range [0, 12]

Given !ScaleStep, this message returns the interval in half steps between the tonic and that scale step within a
traditional equal-tempered musical scale indexed as follows:

Index Name Intervals

0 PentatonicMinor #(0 3 5 7 10 12)

1 PentatonicMajor #(0 2 4 7 9 12)

2 Wholetone #(0 2 4 6 8 10 12)

3 Major #(0 2 4 5 7 9 11 12)

4 Dorian #(0 2 3 5 7 9 10 12)

5 Phrygian #(0 1 3 5 7 8 10 12)

6 Lydian #(0 2 4 6 7 9 11 12)

7 Mixolydian #(0 2 4 5 7 9 10 12)

8 Aeolian #(0 2 3 5 7 8 10 12)

9 Locrian #(0 1 3 5 6 8 10 12)

10 Octatonic2 #(0 2 3 5 6 8 9 11 12)

11 Octatonic1 #(0 1 3 4 6 7 9 10 12)

12 Chromatic #(0 1 2 3 4 5 6 7 8 9 10 11 12)

You can use this expression wherever you need an interval specified in terms of half steps, for example in the Interval
field of SimplePitchShifter. It is not a Frequency or a Pitch, it is an interval in half steps.

Examples:

!aScaleStep intervalAtStepInScaleIndex: scaleIndex012

(!ScaleStep intervalAtStepInScaleIndex: !ScaleIndex012) + (12 * !Octave) + !Interval

104
intervalToScaleStepOfEuclideanScaleWithNumberSteps: octaves: mode:
octaveDivisions:
Categories: pitch, scales, tuning, frequency

!Interval intervalToScaleStepOfEuclideanScaleWithNumberSteps: !NumberSteps octaves: !Octaves mode:


!Mode octaveDivisions: !DivisionsPerOctave
Range (0, !ScaleSteps * !Octaves - 1)

Given an interval in halfsteps, this message returns the closest scale step of the Euclidean scale that is specified by
the other arguments (the number of steps in the scale, the number of divisions of the octave (the quantization), and
the mode).

See ofEuclideanScaleSteps:octaves:mode:stepsPerOctave: for converting from scaleStep to interval (in half steps).

Examples:

!Interval intervalToScaleStepOfEuclideanScaleWithNumberSteps: !NumberSteps octaves: !Octaves mode:


!Mode octaveDivisions: !DivisionsPerOctave

0 to: 11 collect: [:intvl | intvl intervalToScaleStepOfEuclideanScaleWithNumberSteps: 7 octaves: 1 mode: 1


octaveDivisions: 12]

((1 bpm: !BPM) nextIndexMod: 12) intervalToScaleStepOfEuclideanScaleWithNumberSteps: 7 octaves: 1


mode: 1 octaveDivisions: 12

105
into:
Categories: arrays, mapping, map, inputOutputCharacteristic, nonlinear, function, warping

!InputValue into: #({0 @ 0} {0.5 @ 0.125} {1 @ 0.25})


Range (-infinity, infinity)

Uses the InputValue to look up an output value from an array of points in the form {input @ output}. If the exact
InputValue is not present in the array, into: does a linear interpolation to determine what the output would be if that
input were included between two existing points.

To perform an into: operation on signals, rather than in CapyTalk, see InputOutputCharacteristic.

Examples:

!InputValue into: #({0 @ 0} {0.5 @ 0.125} {1 @ 0.25})

1.5 into: #({0@2} {1@3} {2@4})

!Amp into: #({0 @ 0} {0.5 @ 0.75} {1 @ 2})

(1 repeatingRamp into: #({0 @ 0} {0.5 @ 1} {1 @ 1})

1 repeatingRamp into: #({0@0} {0.5@1} {1@0})

106
inverse
Categories: arithmetic, division, quotient, ratio

!Number inverse
Range (-infinity, infinity)

The multiplicative inverse of aNumber is 1.0 / aNumber.

The multiplicative inverse of a number is that number which, if multiplied by the original number, yields a result of 1.
The result is a double-precision float (indicated by a the letter d following the number). Note that you cannot take the
inverse of 0 as that would require dividing by 0.

Examples:

!Number inverse

2.0 inverse

2.0 inverse * 2.0

0.5 inverse

!Gain inverse

107
inversePhon70ForMinimumNotenumber:
Categories: loudness, amplitude

!anAmplitude inversePhon70ForMinimumNotenumber: !lowestNotenumber


Range (1.0, 18.66)

Used in conjunction with phon70ForNotenumber which sets low pitches to unity gain and attenuates higher pitches. If
you know that you will not go below a given minimum pitch, you can use this expression to boost all the amplitudes
while still maintaining the equal loudness curve.

On a phon curve, the lowest pitch is at unity gain and other pitches are attenuated. If you know the minimum
expected pitch, you can boost all the amplitudes and still maintain the shape of the curve by using
inversePhon70ForMinimumNumber: either directly after phon70ForNotenumber: or in another module to the right of
where it is used in the signal flow graph.

Examples:

!anAmplitude inversePhon70ForMinimumNotenumber: !lowestNotenumber

(1 phon70ForNotenumber: 108) inversePhon70ForMinimumNotenumber: 60

108
isOnForEuclideanBeats: pulses: offset:
Categories: triggers & gates, trigger modifiers

!Beat isOnForEuclideanBeats: !BeatsPerBar pulses: !PulsesPerBar offset: !OffsetBeats


Range (0,1)

Returns a 1 if the integer beat number, !Beat, should be switched on in a Euclidean beat pattern defined by
!BeatsPerBar !PulsesPerBar and !OffsetBeats.

A Euclidean beat pattern is a pattern of triggers that places !PulsesPerBar in the time of !BeatsPerBar and delays or
offsets the pattern by !OffsetBeats. It tries to distribute the pulses evenly with the number of beats. Interesting
patterns result when !PulsesPerBar is not an even submultiple of !BeatsPerBar. Send this message to a particular
integer beat number to determine whether that beat should be on (1) or off (0) in the pattern.

Examples:

!Beat isOnForEuclideanBeats: !BeatsPerBar pulses: !PulsesPerBar offset: !OffsetBeats

3 isOnForEuclideanBeats: 16 pulses: 7 offset: 0

(1 bpm: !BPM) gateWhen: ((((1 bpm: !BPM) nextIndexMod: 8) + 1) isOnForEuclideanBeats: !Beats pulses:
!Pulses offset: !Offset)

109
L
Categories: Sounds, control signals

[aSound] L
Range [-1,1]

When sent to [a Sound] that has been copied and pasted into a parameter field, L means to sample and hold the
value of the left channel of [aSound] once per millisecond. (See L: for more details).

Examples:

[aSound] L

[LFO] L * SignalProcessor halfSampleRate hz

110
L:
Categories: Sounds, control signals

[aSound] L: <millisecondsToHold>
Range [-1,1]

When sent to [a Sound] that has been copied and pasted into a parameter field, L: means to sample and hold the
value the left channel of [aSound] every <millisecondsToHold> milliseconds. The Sound itself updates at the sample
rate; the parameter value is updated by sampling and holding the value of [aSound] once every
<millisecondsToHold> milliseconds. To sample and hold the value of [aSound] once per millisecond (1000 times per
second), use L by itself, without the colon or <millisecondsToHold> argument.

Capytalk expressions that include [aSound] L: <millisecondsToHold> will be evaluated once every
<millisecondsToHold> milliseconds. Thus, the larger number you use for <millisecondsToHold> the less often the
expression will be evaluated and the less computation it requires.

For certain critical amplitude parameters, you can remove the L altogether to indicate that the parameter should read
the Sound and update the parameter value at the full sample rate. These parameters include:

Oscillator Envelope

ModalFilter Envelope

TriggeredSampleAndHold Trigger

VCF Amplitude and Resonance

PsiPlayer AmpScale and TimeIndex

When in doubt about whether a parameter can be updated at the full sample rate, check the parameter help.

Examples:

[aSound] L: <millisecondsToHold>

([LFO] L: 10) * SignalProcessor halfSampleRate hz

111
le:
Categories: logic, arithmetic, comparison

!Expression1 le: !Expression2


Range [0, 1]

le: or ’less than or equal to ( )’ tests the value of !Expression1 compared to the value of !Expression2. The result of
the test is true (1) when the value of !Expression1 is less than or equal to the value of !Expression2. If !Expression1 is
greater than !Expression2, the value of the test is false (0).

Use le: ( ) to test whether the value of one expression is less than or equal to that of another. The result is a logic 1
(true) or a logic 0 (false). See also eq: (=), ne: ( ), lt: (<), gt: (>), and ge: ( ).

Examples:

!Expression1 le: !Expression2

!Fader1 le: !Fader2

(!KeyNumber mod: 12) le: 6

112
lengthQuantizedForStart: beats:
Category: looping

!LoopLength lengthQuantizedForStart: !quantizedStart beats: !NumberBeatsInLoop


Range [0,1]

Typically used in the End field of a Sample, this expression will quantize the !LoopLength to the nearest beat, given
that there are !NumberBeatsInLoop in the sample.

See also startQuantizedForBeats:

Examples:

!LoopLength lengthQuantizedForStart: !quantizedStart beats: !NumberBeatsInLoop

!Reverse true: (!LoopStart startQuantizedForBeats: !Beats) + (!LoopLength lengthQuantizedForStart: !LoopStart


beats: !Beats) false: 1

113
ln
Categories: arithmetic, exponential

!aValue ln
Range (-Infinity, Infinity)

The natural log is the log base e of !aValue, where e is Eulers number (~2.71828). When !aValue is linearly
increasing, the shape of the natural log curve starts as a steep curve and gets shallower (increases more slowly) for
higher values of !aValue. It is the inverse of the exp function (so, x exp ln = x).

The natural log tells you how long it will take an exponentially increasing function to reach a given level: (target /
initialValue) ln / rate. For example, say you had 100 ingots in a savings account that offers 1% continuously
compounding interest per year and you want to know how many years it will take for your account to be worth 1000
ingots. You can select and evaluate this expression to find out: (1000.0/100) ln / 0.01. This makes it clear why !aValue
must be positive (not zero or negative), because the target level for a savings account would not be 0 or negative.
The natural log has a steep curve for low numbers and a shallow curve for larger numbers

Examples:

!aValue ln

1 ln

2.71828 ln

1.0e-6 ln

2 exp ln

1 repeatingRamp ln * 0.25 + 1

114
log
Categories: arithmetic, exponential

!aValue log
Range (-Infinity, Infinity)

log is the log base 10 of !aValue. In other words, it is the power of 10 that equals !aValue. When !aValue is linearly
increasing, the shape of the logarithmic curve starts as a steep curve and gets shallower (increases more slowly) for
higher values of !aValue. It is the inverse of the tenExp function (in other words 10 tenExp log = 10). See also the
related functions: ln, twoLog, exp, twoExp, and tenExp.

The log base 10 of a number is sometimes known as its order of magnitude. For example 100 differs from 10 by an
order of magnitude (10 log + 1 = 100 log) and 1000 differs from 10 by two orders of magnitude. You can also think of
it as one less than the number of digits to the left of the decimal point. Just as you can think of its inverse, tenExp, as
a way of shifting a number to the left by a certain number of digits, for example 2 tenExp is the numeral 1 shifted left
by 2 digits (100), and -2 tenExp is a 1 shifted two decimal places to the RIGHT. A typical use of log is to convert from
linear units of amplitude or frequency to log space units like dB and pitch. For example, dB is defined as (20 * (!amp /
!ReferenceAmp) log). And the pitch can be computed as (!Freq / 8.1758) log * 39.863138465187d. However, it is
clearer and more direct to use the built-in Capytalk messages inDB and nn, for example, 0.5 inDB dB or 440 hz nn.
Try selecting and evaluating some of the examples below using Ctrl+Y or Evaluate from the Edit menu.

Examples:

!aValue log

1 log

10 log

1e-6 log

10 tenExp log

1000 log

1 repeatingRamp log * 0.25 + 1

115
lt:
Categories: logic, arithmetic, comparison

!Expression1 lt: !Expression2


Range [0, 1]

lt: or ’less than (<)’ tests the value of !Expression1 compared to the value of !Expression2. The result of the test is true
(1) when the value of !Expression1 is less than the value of !Expression2. If !Expression1 is greater than or equal to
!Expression2, the value of the test is false (0).

Use lt: (<) to test whether the value of one expression is smaller than that of another. The result is a logic 1 (true) or a
logic 0 (false). See also eq: (=), ne: ( ), le: ( ), gt: (>), and ge: ( ).

Examples:

!Expression1 lt: !Expression2

!Fader1 lt: !Fader2

(!KeyNumber mod: 12) lt: 6

116
M
Categories: Sounds, control signals

[aSound] M
Range [-1,1]

When sent to [a Sound] that has been copied and pasted into a parameter field, M means to sample and hold the
value of a mix of the right and left channel outputs of [aSound] once per millisecond. (See M: for more details).

Examples:

[aSound] M

[LFO] M * SignalProcessor halfSampleRate hz

117
m
Categories: units, unitsOfFrequencyAndDuration

!aDurationInMinutes m
Range N/A

Minutes (m) is a unit of time or duration in Capytalk. When you evaluate durations, such as m (minutes), h (hours),
day (days), ms (milliseconds), or usec (microseconds), the result will be expressed in terms of seconds (s).

In Kyma, a unit of frequency or duration is a message that you send to a number (or EventValue) to create a new
object called a ScalarWithUnits. You can cascade units of frequency and duration to convert from one to another (for
example, from frequency to pitch or from duration to a tempo in terms of beats-per-minute or even from a duration to
a frequency (where the duration is interpreted as the length of one cycle at that frequency). Try selecting and
evaluating some of the expressions below using Ctrl+Y (Edit>Evaluate).

Examples:

!aDurationInMinutes m

!Duration m hz

1 m samp

1 samp s

(Time now seconds + !LocalTime truncated) mod: 60

1 bpm: (!Tap durationBetweenTriggers s bpm removeUnits)

118
M:
Categories: Sounds, control signals

[aSound] M: <millisecondsToHold>
Range [-1,1]

When sent to [a Sound] that has been copied and pasted into a parameter field, M: means to sample and hold the
value of a mix of the left and right channel outputs of [aSound] every <millisecondsToHold> milliseconds. The Sound
itself updates at the sample rate; the parameter value is updated by sampling and holding the value of [aSound] once
every <millisecondsToHold> milliseconds. To sample and hold the value of [aSound] once per millisecond (1000
times per second), use M by itself, without the colon or <millisecondsToHold> argument.

Capytalk expressions that include [aSound] M: <millisecondsToHold> will be evaluated once every
<millisecondsToHold> milliseconds. Thus, the larger number you use for <millisecondsToHold> the less often the
expression will be evaluated and the less computation it requires.

For certain critical amplitude parameters, you can remove the R, L or M altogether to indicate that the parameter
should read the Sound and update the parameter value at the full sample rate. These parameters include:

Oscillator Envelope

ModalFilter Envelope

TriggeredSampleAndHold Trigger

VCF Amplitude and Resonance

PsiPlayer AmpScale and TimeIndex

When in doubt about whether a parameter can be updated at the full sample rate, check the parameter help.

Examples:

[aSound] M: <millisecondsToHold>

([LFO] M: 10) * SignalProcessor halfSampleRate hz

119
max:
Categories: arithmetic, maximum, nonlinear

!anExpression max: !anotherExpression


Range (-infinity, infinity)

max: returns the larger of the receiver and the argument.

Examples:

!anExpression max: !anotherExpression

2.0 max: 3.0

-2.0 max: -3.0

!StartLoop max: !EndLoop

1 repeatingFullRamp max: (1 repeatingFullRamp: 3 s)

120
maxHarmonic
Category: arithmetic

!aFundamentalFreq hz maxHarmonic
Range [1, Infinity]

When sent to a fundamental frequency, maxHarmonic tells you the number of harmonics of that fundamental that
could be generated without exceeding the Nyquist limit of half the current sampleRate (which you can see by
selecting and evaluating: SignalProcessor halfSampleRate).

Examples:

!aFundamentalFreq hz maxHarmonic

20 hz maxHarmonic

1 c hz maxHarmonic

2 c maxHarmonic

4 a maxHarmonic

!KeyPitch maxHarmonic

22.05 hz maxHarmonic * 22.05 SignalProcessor halfSampleRate / 1000.0

121
mel
Categories: units, unitsOfFrequencyAndDuration

!aNumber mel
Range N/A

The mel scale is one method of dividing up a range of frequencies into perceptually equal steps, where 1000 hz ~=
1000 mel. For comparison the formula used is: m = 2595 log(1 + f/700)

In Kyma, a unit of frequency or duration is a message that you send to a number (or EventValue) to create a new
object called a ScalarWithUnits. You can cascade units of frequency and duration to convert from one to another (for
example, from frequency to pitch or from duration to a tempo in terms of beats-per-minute. Try selecting and
evaluating some of the expressions below using Ctrl+Y (Edit>Evaluate).

Examples:

!aNumber mel

1000 hz mel

1000 mel hz

83 nn mel

0.001d s mel

((1 bpm: !BPM) nextRandom abs * 127) rounded mel

!logFreq nn mel

122
min:
Categories: arithmetic, minimum, nonlinear

!anExpression min: !anotherExpression


Range (-infinity, infinity)

min: returns the smaller of the receiver and the argument.

Examples:

!anExpression min: !anotherExpression

2.0 min: 3.0

-2.0 min: -3.0

!StartLoop min: !EndLoop

1 repeatingFullRamp min: (1 repeatingFullRamp: 3 s)

123
mod:
Categories: arithmetic, modulo

!Dividend mod: !Divisor


Range [0, (modulus - 1))

Modulo. !Dividend mod: !Divisor is the remainder when you do the operation !Dividend / !Divisor.

You can think of the mod: operation as restricting your arithmetic operations to numbers on a circle (instead of on an
infinite number line). For example, if you place twelve numbers 0, 1, .., 11 around a circle, then you can do addition
and subtraction by moving clockwise or counterclockwise around this circle. The modulus is the number of elements
(in this case, 12). For example, (5 + 6) mod: 12, would mean to start at 5, move 6 clicks in the clockwise direction,
and land on 11. Now try (11 + 2) mod: 12. You start at 11, move 2 clicks in the clockwise direction and land on 1.
Another way to think of this is that, no matter how many times you go around the circle 12 clicks, you will always end
up back where you started from; however, if you go around the circle 12 clicks plus 1, then you will end up 1 click to
the right of where you started. Whatever is left over, whatever the remainder, after going around some multiple of 12
clicks, will be your answer. Thus, the standard definition from Wikipedia is: Given two positive numbers, a (the
dividend) and n (the divisor), a modulo n (abbreviated as a mod n) can be thought of as the remainder, on division of
a by n.

For more information, see:


http://en.wikipedia.org/wiki/Modulo_operation

Examples:

!Dividend mod: !Divisor

3 mod: 2

2 mod: 2

!Interval mod: 12

1 repeatingFullRamp min: (1 repeatingFullRamp: 3 s)

124
ms
Categories: units, unitsOfFrequencyAndDuration

!aDurationInMilliseconds ms
Range N/A

Milliseconds (ms) is a unit of time or duration in Capytalk. One millisecond is one one-thousandth of a second. When
you evaluate durations, such as m (minutes), h (hours), day (days), ms (milliseconds), or usec (microseconds), the
result will be expressed in terms of seconds (s).

In Kyma, a unit of frequency or duration is a message that you send to a number (or EventValue) to create a new
object called a ScalarWithUnits. You can cascade units of frequency and duration to convert from one to another (for
example, from frequency to pitch or from duration to a tempo in terms of beats-per-minute or even from a duration to
a frequency (where the duration is interpreted as the length of one cycle at that frequency). Try selecting and
evaluating some of the expressions below using Ctrl+Y (Edit>Evaluate).

Examples:

!aDurationInMilliseconds ms

!Duration ms hz

1 ms samp

1000 ms

125
ne:
Categories: equal, test, logic, comparison

!EventExpr1 ne: !EventExpr2


Range (0, 1)

Tests whether the values of two events are not equal. Returns 1 when the value of !EventExpr1 is different from that
of !EventExpr2.

See also eq: (equal), lt: (less than), gt: (greater than), ge: (greater than or equal to), le: (less than or equal to).

Examples:

!EventExpr1 ne: !EventExpr2

(!KeyNumber mod: 12) ne: 3

(!Fader lt: 0.6) * (!Fader ge: 0.4)

(!Fader lt: 0.6) * (!Fader ne: 0.4)

126
neg: zero: pos:
Category: logic

!TestExpression neg: !ValueIfLessThanZero zero: !ValueIfZero pos: !ValueIfGreaterThanZero


Range [-Infinity, Infinity]

When !TestExpression changes value, it is tested. If its value is less than zero, the first argument is evaluated; if its
value is zero, the second argument is evaluated; if its value is larger than zero, the last argument is evaluated.

Conditionally evaluate one of three expressions, depending on the sign of the value of !TestExpression.

Examples:

!TestExpression neg: !ValueIfLessThanZero zero: !ValueIfZero pos: !ValueIfGreaterThanZero

0 neg: -20 zero: 1000 pos: -30

((!KeyTimbre - 0.5) neg: 1 zero: 2 pos: 0.01) s


---
((1 bpm: !BPM) nextRandom
neg: (((1 bpm: !BPM) nextRandom abs * 8) of: #(0 2 4 6 8 10 12 14))
zero: (0)
pos: (((1 bpm: !BPM) nextRandom abs * 8) of: #(1 3 5 7 9 11 13 15))) nn + !logFreq nn

127
neg: zero: pos: initially:
Category: logic

!TestExpression neg: !ValueIfLessThanZero zero: !ValueIfZero pos: !ValueIfGreaterThanZero initially: !InitialValue


Range [-Infinity, Infinity]

The initial value is !InitialValue. Then, each time !TestExpression changes value, it is tested. If its value is less than
zero, the first argument is evaluated; if its value is zero, the second argument is evaluated; if its value is larger than
zero, the last argument is evaluated.

See neg:zero:pos: for more details and examples.

Examples:

!TestExpression neg: !ValueIfLessThanZero zero: !ValueIfZero pos: !ValueIfGreaterThanZero initially: !InitialValue

128
negated
Categories: arithmetic, sign, negation

!Expression negated
Range (-infinity, infinity)

Flip the sign of a number from negative to positive (or positive to negative).

Examples:

!Expression negated

3 negated

-1 negated

129
nextChaotic
Categories: random, stochastic, chaos

!Gate nextChaotic
Range (0,1)

Shortcut to get a chaotic (or very long cycle) region of the logistic map: !Gate nextChaotic: 1.0 seed: 0.93701

See nextChaotic:seed:reset:.

Examples:

!Gate nextChaotic

!On nextChaotic

130
nextChaotic7
Categories: random, stochastic, chaos

!Gate nextChaotic7
Range (0,1)

Shortcut for a 7-cycle !Gate nextChaotic: 0.70164

See nextChaotic:seed:reset:.

Examples:

!Gate nextChaotic7

!On nextChaotic7

131
nextChaotic:
Categories: random, stochastic, chaos

!Gate nextChaotic: !K
Range (0,1)

Same as nextChaotic:seed:reset: but without an initial value and without the option to reset to the seed value.

Examples:

!Gate nextChaotic: !K

132
nextChaotic: seed:
Categories: random, stochastic, chaos

Range (0,1)

Same as nextChaotic:seed:reset: but without the option to reset to the seed value.

133
nextChaotic: seed: reset:
Categories: random, stochastic, chaos

!Trigger nextChaotic: !K seed: !Seed reset: !Reset


Range (0,1)

When !Trigger becomes true, return the next value of the logistic map:

x(n+1) = R * x(n) * (1 - x(n))

where !K has a range of (0,1) corresponding to an R in the range (3,4).

!Seed should be in the range (0,1); it is the initial value of x(n) and the value of x(n) whenever !Reset becomes true.

Each value of this expression depends only on its previous value and the value of !K. For some values of !K the
output is cyclic, for some it is quasi-cyclic, and for others it is chaotic.

Examples:

!Trigger nextChaotic: !K seed: !Seed reset: !Reset

((1 bpm: !BPM) nextChaotic: !k seed: 0.62 reset: !Reset)

1 gateWhen: (((1 bpm: !BPM) nextChaotic: !k seed: 0.08 reset: !Reset) gt: !Thresh)

134
nextChaoticIntermittent
Categories: random, stochastic, chaos

!Gate nextChaoticIntermittent
Range (0,1)

Shortcut for an intermittent region of logistic map: !Gate nextChaotic: 0.7

See nextChaotic:seed:reset:.

Examples:

!Gate nextChaoticIntermittent

135
nextChaoticIntermittent3
Categories: random, stochastic, chaos

!Gate nextChaoticIntermittent3
Range (0,1)

Shortcut for an intermittent region of logistic map: !Gate nextChaotic: 0.828

See nextChaotic:seed:reset:.

Examples:

!Gate nextChaoticIntermittent3

136
nextChaoticIntermittent6
Categories: random, stochastic, chaos

!Gate nextChaoticIntermittent6
Range (0,1)

Shortcut for an intermittent region of logistic map: !Gate nextChaotic: 0.6262

See nextChaotic:seed:reset:.

Examples:

!Gate nextChaoticIntermittent6

137
nextIndex
Categories: count, counting, index, arrays, sequences

!Trigger nextIndex
Range [0, infinity)

Starts at 0 and counts up by 1 each time the !Trigger changes from 0 to a positive value.

Since nextIndex starts at 0, it is ideal for stepping through values in an array using the of: expression.

Examples:

!Trigger nextIndex

1 s tick nextIndex

(1 bpm: !BPM) nextIndex

138
nextIndexMod:
Categories: count, counting, index, arrays, sequences

!Trigger nextIndexMod: !Modulus


Range [0, (!Modulus - 1)]

Like nextIndex except when the count reaches the !Modulus, it wraps around to 0. Starts at 0 and counts up by 1
each time the !Trigger changes from 0 to a positive value.

Since nextIndexMod: starts at 0, it is ideal for repeatedly cycling through values in an array using of:.

Examples:

!Trigger nextIndexMod: !Modulus

1 s tick nextIndexMod: 8

(1 bpm: !BPM) nextIndexMod: !Modulus

((1 s tick nextIndexMod: 8) of: #(60 62 64 65 67 69 71 72 )) nn

(((1 bpm: !BPM) nextIndexMod: !Modulus) + !Start) mod: 8

139
nextIndexMod: reset:
Categories: count, counting, detection

!Trigger nextIndexMod: !Modulus reset: !Reset


Range [0, infinity]

Like nextIndex but resets to 0 whenever !Reset changes from a value <= 0 to a positive value.

Examples:

!Trigger nextIndexMod: !Modulus reset: !Reset

140
nextIndexMod: reverse: reset:
Categories: count, counting, index, arrays, sequences

!Trigger nextIndexMod: !Modulus reverse: !Reverse reset: !Reset


Range [0, (!Modulus - 1)]

Like nextIndexMod:reverse: except with an extra argument, !Reset (0 or 1), that resest the count to 0 again. Starts at
0 and counts up by 1 each time the !Trigger changes from 0 to a positive value.

Since nextIndexMod: starts at 0, it is ideal for repeatedly cycling through values in an array using of:.

Examples:

!Trigger nextIndexMod: !Modulus reverse: !Reverse reset: !Reset

1 s tick nextIndexMod: 8 reverse: 1 reset: 1 s random abs

(1 bpm: !BPM) nextIndexMod: !Modulus reverse: !Reverse reset: !Reset

141
nextIndexReset:
Categories: count, counting, detection

!Trigger nextIndexReset: !Reset


Range [0, infinity]

Like nextIndex but resets to 0 whenever !Reset changes from a value <= 0 to a positive value.

Examples:

!Trigger nextIndexReset: !Reset

(((1 bpm: !BPM) nextIndexMod: !Modulus reverse: !Reverse reset: (!Reset alignWith: (1 bpm: !BPM))) + !Start)
mod: 8

142
nextNormal
Categories: random, stochastic

!Trigger nextNormal
Range (-1,1)

Each time !Trigger becomes true, return the next random number (-1,1) in a sequence of random numbers having a
normal (Gaussian) distribution with a mean value of ~0 and a standard deviation of ~0.151. For a variable standard
deviation, scale the result by !SD/0.151. For a variable mean value, add !Mean to the result. The numbers closer to
zero are more likely. To create a random sequence that is repeatable, see nextNormalWithSeed:.

The message, nextNormal, is always sent to a trigger; for another variation on this message that you would send to a
time in units, see normal. For other distributions see nextRandom and nextRandExp.

Examples:

!Trigger nextNormal

1 s tick nextNormal

0.2 s tick nextNormal * !SD/0.151 + !Mean

(1 bpm: !BPM) nextNormal * !Interval nn + 3 c

143
nextNormalWithSeed:
Categories: random, stochastic

!Trigger nextNormalWithSeed: 0.2


Range (-1,1)

Like nextNormal, except that you make the random sequence repeatable by providing a seed in the range of (-1,1).
Equivalently, you can send the message seed: to any random expression, for example (!Trigger nextNormal seed:
0.2).

Seed should be a constant in the range (-1, 1). See also seed:.

Examples:

!Trigger nextNormalWithSeed: 0.2

1 s tick nextNormalWithSeed: aNumberBetweenMinusOneAndOne

144
nextRandExp
Categories: random, stochastic

!Trigger nextRandExp
Range (-1,1)

Each time !Trigger becomes true, return a random number in (0,24) from an Exponential distribution. Typically these
numbers are interpreted as intervals of time (or pitch). There are lots of small intervals and fewer large intervals. To
create a random sequence that is repeatable, see nextRandExpWithSeed: or send the seed: message to the
nextRandExp expression (for example, !Trigger nextRandExp seed: 0.116).

The message, nextRandExp, is always sent to a trigger; for another variation on this message that you send to a time
in units, see randExp. For other distributions see nextRandom and nextNormal.

Examples:

!Trigger nextRandExp

1 s tick nextRandExp

(1 bpm: !BPM) nextRandExp nn + 3 c

145
nextRandExpWithSeed:
Categories: random, stochastic

!Trigger nextRandExpWithSeed: -0.01.


Range (-1,1)

Like nextRandExp, except that you can make the random sequence repeatable by providing a fixed seed in the range
of (-1,1). Equivalently, you can send the message seed: to any random expression, for example (!Trigger
nextRandExp seed: -0.01)

If two different parameter fields or two different Sounds should share the same random sequence, you can use this
seeded version of the expression to ensure that both parameter fields use the exact same sequence. See also seed:

Examples:

!Trigger nextRandExpWithSeed: -0.01.

1 s tick nextRandExpWithSeed: 0.6

((1 bpm: !BPM) nextRandExpWithSeed: 0.2) nn + 3 c

146
nextRandom
Categories: random, stochastic

!Trigger nextRandom
Range (-1,1)

Each time !Trigger becomes true, return the next random number (-1,1) in a sequence of random numbers having a
uniform distribution. Any number in the (-1,1) range is equally likely on each trigger. To create a random sequence
that is repeatable, see nextRandomWithSeed: and seed:.

For other than uniform distributions see nextNormal and nextRandExp.

Examples:

!Trigger nextRandom

1 s tick nextRandom

(1 bpm: !BPM) nextRandom * !Interval nn + 3 c

147
nextRandomElementOf:
Categories: arrays, random

!Trigger nextRandomElementOf: #(!First !Second !Third)


Range [Depends on the values in Array argument]

When triggered, randomly select an element from anArray. No two adjacent items are ever repeats of each other.

Randomly access values in an array without any immediate repetitions (you will never get the same element twice in
a row).

Examples:

!Trigger nextRandomElementOf: #(!First !Second !Third)

1 s tick nextRandomElementOf: #(!Interval1 !Interval2 !Interval3 !Interval4

1 bpm: !BPM nextRandomElementOf: #(!Interval1 !Interval2 !Interval3 !Interval4

((1 s tick nextRandomElementOf: #(60 62 64 65 67 69 71 72 )) nn

!logFreq + ((1 bpm: !BPM) nextRandomElementOf: {(1 to: 12 collect: [:n | (!Interval suffix: n printString)])}) nn

148
nextRandomFromAllArrays: arrayIndex:
Categories: random, stochastic

!Trigger nextRandomFromAllArrays: #( #( anArrayOfArrays ) ) arrayIndex: !ArrayIndex


Range The range of values found in #( #( anArrayOfArrays ) )

When triggered this selects a random element in all the arrays of #( #( anArrayOfArrays ) ) simultaneously. The value
of !ArrayIndex determines which of the arrays to look at, and the value of that Array at the random index is returned
as the value of this expression.

This is similar to nextRandomOf: except that you provide several different arrays in the #( #( anArrayOfArrays ) )
argument. A random element is selected from all of the arrays and the !ArrayIndex (which can be changing) selects
which Array from which to read the randomly selected entry. The range of values for !ArrayIndex should be integers in
the range of 0 to one less than the number of collections in #( #( anArrayOfArrays ) ).

See nextRandomOf: for a simpler version that uses a single collection instead of an Array of several different
collections.

Examples:

!Trigger nextRandomFromAllArrays: #( #( anArrayOfArrays ) ) arrayIndex: !ArrayIndex

0.5 s tick nextRandomFromAllArrays: #( #(0 1 0) #(0 0 1) ) arrayIndex: !ArrayIndex

1 nextRandomFromAllArrays: #( #(1 2 3 4) #(5 6 7 8) ) arrayIndex: 0

1 nextRandomFromAllArrays: #( #(1 2 3 4) #(5 6 7 8) ) arrayIndex: 1

(1 bpm: !BPM) nextRandomFromAllArrays: #( #(1 0 0 0) #(0 1 0 0) #(0 0 1 0) #(0 0 0 1)) arrayIndex: !Index

149
nextRandomFromArrays: sampledArrayIndex:
Categories: random, stochastic

!Trigger nextRandomFromArrays: #( #( anArrayOfArrays ) ) sampledArrayIndex: !ArrayIndex


Range The range of values found in #( #( anArrayOfArrays ) )

This is similar to nextRandomFromAllArrays:arrayIndex: except that, in this version, an array is selected by


!ArrayIndex and an element within that array is selected at random. In this variant, the !ArrayIndex is sampled and
held at the time the expression is triggered, so the !ArrayIndex cannot continue to change once a random element
has been selected. (See also nextRandomFromAllArrays:arrayIndex: and nextRandomElementOf:)

See nextRandomOf: for a simpler version that uses a single collection instead of an Array of several different
collections.

Examples:

!Trigger nextRandomFromArrays: #( #( anArrayOfArrays ) ) sampledArrayIndex: !ArrayIndex

0.5 s tick nextRandomFromArrays: #( #(0 1 0) #(0 0 1) ) sampledArrayIndex: !ArrayIndex

1 nextRandomFromArrays: #( #(1 2 3 4) #(5 6 7 8) ) sampledArrayIndex: 0

1 nextRandomFromArrays: #( #(1 2 3 4) #(5 6 7 8) ) sampledArrayIndex: 1

(1 bpm: !BPM) nextRandomFromArrays: #( #(1 0 0 0) #(0 1 0 0) #(0 0 1 0) #(0 0 0 1)) sampledArrayIndex: !Index

150
nextRandomIndexFromDistribution:
Categories: random, stochastic

!Trigger nextRandomIndexFromDistribution: #(aStatisticalDistribution)


Range An integer index in the range of [0, #(aStatisticalDistribution) size - 1)

Each time !Trigger becomes true, return a random integer according to the statistical distribution given in the array
argument, #(aStatisticalDistribution). Each element in the #(aStatisticalDistribution) array is the frequency of
occurrence of that index in that (0-based) Array; for example, if #(aStatisticalDistribution) is #(0 0.5 0.25 0.25), there is
a zero likelihood of selecting a 0, a 50% chance of selecting 1, and a 25% chance of selecting 2 or 3.

You can also use the output of this expression as the integer index into an Array of EventExpressions (using the of:
message). #(aStatisticalDistribution) can also be populated by counting the number of times you see a particular
value in a data set; then you can use nextRandomIndexFromDistribution: to select from those values at random, but
with the same statistical likelihood as you found in the original data.

Examples:

!Trigger nextRandomIndexFromDistribution: #(aStatisticalDistribution)

0.5 s tick nextRandomIndexFromDistribution: #(0 1 0 1 0 1 0 1)

1 to: 100 collect: [ :i | 1 nextRandomIndexFromDistribution: #(0 0 0.25 1)]

(1 bpm: !BPM) nextRandomIndexFromDistribution: (0 to: 15 collect: [ :i | i twoExp])

{((1 bpm: !BPM) nextRandomIndexFromDistribution: (0 to: 15 collect: [ :i | i twoExp])) of: (0 to: 15 collect: [ :i |
!Interval suffix2: i])}

151
nextRandomIndexFromDistribution: jitter:
Categories: random, stochastic

!Trigger nextRandomIndexFromDistribution: #(aStatisticalDistribution) jitter: !Jitter


Range An integer index in the range of [0, #(aStatisticalDistribution) size - 1)

This is the same as nextRandomIndexFromDistribution: but with an added control called !Jitter. Each time it is
triggered, this expression returns a random integer from the distribution you have specified in the
#(aStatisticalDistribution) array argument. The larger the value of !Jitter, the closer the random indexes will be to a
uniform distribution. In other words, the larger the value of !Jitter, the less attention is paid to #(aStatisticalDistribution)
and the closer the output is to a uniform distribution. When !Jitter is at its maximum value of 1, all indexes of
#(aStatisticalDistribution) are equally likely; when !Jitter is at its minimum value of 0, the likelihood of each integer
index is determined by the magnitude of the value stored at that index in the #(aStatisticalDistribution).

See also nextRandomIndexFromDistribution:.

Examples:

!Trigger nextRandomIndexFromDistribution: #(aStatisticalDistribution) jitter: !Jitter

(1 bpm: !BPM) nextRandomIndexFromDistribution: #(0 1 0 0) jitter: !Jitter

1 to: 100 collect: [ :i | 1 nextRandomIndexFromDistribution: #(0 0 0.25 1) jitter: 0.25]

(!Gate nextRandomIndexFromDistribution: (0 to: 7 collect: [ :i | (i + 1) mod: 2]) jitter: !Jitter) of: (0 to: 7 collect: [
:i | !Interval suffix2: i])

152
nextRandomIndexFromDistributions: distributionIndex:
Categories: random, stochastic

!Trigger nextRandomIndexFromDistributions: #( #( anArrayOfStatisticalDistributions ) ) distributionIndex:


!DistributionIndex
Range An integer index in the range of [0, #( #( anArrayOfStatisticalDistributions ) ) first size - 1)

This is similar to nextRandomIndexFromDistribution: except in this expression, you provide several different
distributions in the #( #( anArrayOfStatisticalDistributions ) ) argument, and use !DistributionIndex to select which one
is being used. Each time the expression is triggered, it returns a random index from the currently selected distribution.
You can use this expression to change the likelihood of each integer index, ranging from 0 to one less than the size of
each distribution within #( #( anArrayOfStatisticalDistributions ) ), by changing which distribution is currently selected.
The range of values for !DistributionIndex should be integers in the range of 0 to one less than the number of
distributions in #( #( anArrayOfStatisticalDistributions ) ).

See nextRandomIndexFromDistribution: for a simpler version that uses a single statistical distribution instead of an
Array of several different distributions. If you prefer to interpolate or morph from one statistical distribution to the next,
see nextRandomIndexFromDistributions:interpolatedDistributionIndex:.

Examples:

!Trigger nextRandomIndexFromDistributions: #( #( anArrayOfStatisticalDistributions ) ) distributionIndex:


!DistributionIndex

0.5 s tick nextRandomIndexFromDistributions: #( #(0 1 0) #(0 0 1) ) distributionIndex: !Distribution

1 nextRandomIndexFromDistributions: #( #(1 0 0 0) #(0 0 0 1) ) distributionIndex: 0

1 nextRandomIndexFromDistributions: #( #(1 0 0 0) #(0 0 0 1) ) distributionIndex: 1

(1 bpm: !BPM) nextRandomIndexFromDistributions: #( #(1 0 0 0) #(0 1 0 0) #(0 0 1 0) #(0 0 0 1))


distributionIndex: !Distribution

| distributions |
distributions := Array with: (0 to: 16 collect: [ :i | i negated twoExp]) with: (0 to: 16 collect: [ :i | (i + 1) inverse])
with: (0 to: 16 collect: [ :i | ((i - 8) squared / (-2 * 2 squared)) exp]) with: (0 to: 16 collect: [ :i | 1]).
2 raisedTo: ((!Gate nextRandomIndexFromDistributions: distributions distributionIndex: !Distribution) negated)

153
nextRandomIndexFromDistributions: distributionIndex: jitter:
Categories: random, stochastic

!Trigger nextRandomIndexFromDistributions: #( #( anArrayOfStatisticalDistributions ) ) distributionIndex:


!DistributionIndex jitter: !Jitter
Range An integer index in the range of [0, #( #( anArrayOfStatisticalDistributions ) ) first size - 1)

This is similar to nextRandomIndexFromDistributions:distributionIndex: except with an additional control called !Jitter.


Each time the expression is triggered, it returns a random index from the currently selected distribution, but the larger
the value of !Jitter, the less attention is paid to the selected distribution and the closer you get to a completely uniform
distribution. When !Jitter is at its maximum value of 1, all indexes of the selected distribution are equally likely; when
!Jitter is at its minimum value of 0, the likelihood of each index is determined by the magnitude of the value stored at
that index relative to the values stored at other indexes in the selected distribution.

See nextRandomIndexFromDistribution: for a version that uses a single statistical distribution instead of an Array of
several different distributions. If you prefer to interpolate or morph from one statistical distribution to the next, see
nextRandomIndexFromDistributions:interpolatedDistributionIndex:.

Examples:

!Trigger nextRandomIndexFromDistributions: #( #( anArrayOfStatisticalDistributions ) ) distributionIndex:


!DistributionIndex jitter: !Jitter

(1 bpm: !BPM) nextRandomIndexFromDistributions: #( #(1 0 0 0) #(0 1 0 0) #(0 0 1 0) #(0 0 0 1))


distributionIndex: !Distribution jitter: !Jitter

1 to: 100 collect: [ :i | 1 nextRandomIndexFromDistributions: #( #(1 0 0 0) #(0 0 0 1)) distributionIndex: 0 jitter:


0.5]

| distributions |
distributions := Array with: (0 to: 8 collect: [ :i | i negated twoExp]) with: (0 to: 8 collect: [ :i | (i + 1) inverse]) with:
(0 to: 8 collect: [ :i | ((i - 4) squared / (-2 * 2 squared)) exp]) with: (0 to: 8 collect: [ :i | 1]).
2 raisedTo: ((!Gate nextRandomIndexFromDistributions: distributions distributionIndex: !Distribution jitter: !Jitter
) negated)

154
nextRandomIndexFromDistributions: interpolatedDistributionIndex:
Categories: random, stochastic

!Trigger nextRandomIndexFromDistributions: #( #( anArrayOfStatisticalDistributions ) )


interpolatedDistributionIndex: !DistributionIndex
Range An integer index in the range of [0, #( #( anArrayOfStatisticalDistributions ) ) first size - 1)

This is similar to nextRandomIndexFromDistributions:distributionIndex: except that !DistributionIndex can vary


continuously from 0 to one less than the number of distributions in #( #( anArrayOfStatisticalDistributions ) ) and the
likelihoods of the random indexes are interpolated from one distribution to the next, depending on how close
!DistributionIndex is to the integer index of that distribution. For example, if !DistributionIndex is exactly 2, then each
time the expression is triggered, it will return a random index from the third distribution in the (zero-based) #( #(
anArrayOfStatisticalDistributions ) ). However, if !DistributionIndex is 0.5 the likelihoods of each index will be halfway
between the likelihood given in the first distribution and the likelihood given for that index in the second distribution in
#( #( anArrayOfStatisticalDistributions ) ). This gives the effect of morphing from one probability distribution to
another.

See nextRandomIndexFromDistribution: for a simpler version that uses a single statistical distribution instead of an
Array of several different distributions. For additional control, see
nextRandomIndexFromDistributions:interpolatedDistributionIndex:jitter:.

Examples:

!Trigger nextRandomIndexFromDistributions: #( #( anArrayOfStatisticalDistributions ) )


interpolatedDistributionIndex: !DistributionIndex

(1 bpm: !BPM) nextRandomIndexFromDistributions: #( #(1 0 0 0) #(0 1 0 0) #(0 0 1 0) #(0 0 0 1))


interpolatedDistributionIndex: !Distribution

1 to: 100 collect: [ :i | 1 nextRandomIndexFromDistributions: #( #(1 0 0 0) #(0 0 0 1))


interpolatedDistributionIndex: 0.5]
---
| distributions |
distributions := Array with: (0 to: 16 collect: [ :i | i negated twoExp]) with: (0 to: 16 collect: [ :i | (i + 1) inverse])
with: (0 to: 16 collect: [ :i | ((i - 8) squared / (-2 * 2 squared)) exp]) with: (0 to: 16 collect: [ :i | 1]).
2 raisedTo: ((!Gate nextRandomIndexFromDistributions: distributions interpolatedDistributionIndex:
!Distribution) negated)

155
nextRandomIndexFromDistributions: interpolatedDistributionIndex: jitter:
Categories: random, stochastic

!Trigger nextRandomIndexFromDistributions: #( #( anArrayOfStatisticalDistributions ) )


interpolatedDistributionIndex: !DistributionIndex jitter: !Jitter
Range An integer index in the range of [0, #( #( anArrayOfStatisticalDistributions ) ) first size - 1)

This is similar to nextRandomIndexFromDistributions:interpolatedDistributionIndex: but with an additional (0,1) control


called !Jitter. The closer !Jitter is to its maximum value of 1, the closer you get to a uniform probability distribution.
The closer !Jitter is to its minimum value of 0, the closer you get to the distribution found at !DistributionIndex in the #(
#( anArrayOfStatisticalDistributions ) ) argument. If !DistributionIndex is not an integer, the probability of each index is
interpolated between two neighboring distributions in the Array (see
nextRandomIndexFromDistributions:interpolatedDistributionIndex: for more details.

See the documentation for all expressions that begin nextRandomIndexFromDistribution: additional details and for
alternate versions that have fewer controls.

Examples:

!Trigger nextRandomIndexFromDistributions: #( #( anArrayOfStatisticalDistributions ) )


interpolatedDistributionIndex: !DistributionIndex jitter: !Jitter

(1 bpm: !BPM) nextRandomIndexFromDistributions: #( #(1 0 0 0) #(0 1 0 0) #(0 0 1 0) #(0 0 0 1))


interpolatedDistributionIndex: !Distribution jitter: !Jitter

1 to: 100 collect: [ :i | 1 nextRandomIndexFromDistributions: #( #(1 0 0 0) #(0 0 0 1))


interpolatedDistributionIndex: 0.5 jitter: 0.5]

| distributions |
distributions := Array with: (0 to: 16 collect: [ :i | i negated twoExp]) with: (0 to: 16 collect: [ :i | (i + 1) inverse])
with: (0 to: 16 collect: [ :i | ((i - 8) squared / (-2 * 2 squared)) exp]) with: (0 to: 16 collect: [ :i | 1]).
2 raisedTo: (!Gate nextRandomIndexFromDistributions: distributions interpolatedDistributionIndex: !Distribution
jitter: !Jitter) negated

156
nextRandomIndexMod:
Categories: index, arrays, random

!Trigger nextRandomIndexMod: !Modulus


Range [0, (!Modulus - 1)]

On each trigger, generate a random index in the range (0, !Modulus). NB: !Modulus must be at least 3. No adjacent
indexes are ever repeated.

Since nextRandomIndexMod: starts at 0, it is ideal for randomly accessing values in an array of size !Modulus without
any immediate repetitions. You will never get the same index twice in a row.

Examples:

!Trigger nextRandomIndexMod: !Modulus

2 s tick nextRandomIndexMod: 4

(1 bpm: !BPM) nextRandomIndexMod: !Modulus

((1 s tick nextRandomIndexMod: 8) of: #(60 62 64 65 67 69 71 72 )) nn

(((1 bpm: !BPM) nextRandomIndexMod: !Modulus) + !Start) mod: 8

157
nextRandomOf:
Categories: arrays, random

!Trigger nextRandomOf: #(!First !Second !Third)


Range [Depends on the values in Array argument]

When triggered, randomly select an element from anArray. (If you want to ensure that no two subsequent values are
the same, use nextRandomElementOf: instead. Note that nextRandomElementOf: is more computationally expensive
than nextRandomOf:).

Randomly access values in an array (with no protection against getting the same element twice in a row).

Examples:

!Trigger nextRandomOf: #(!First !Second !Third)

1 s tick nextRandomOf: #(!Interval1 !Interval2 !Interval3 !Interval4

1 bpm: !BPM nextRandomOf: #(!Interval1 !Interval2 !Interval3 !Interval4

((1 s tick nextRandomOf: #(60 62 64 65 67 69 71 72 )) nn

!logFreq + ((1 bpm: !BPM) nextRandomOf: {(1 to: 12 collect: [:n | (!Interval suffix: n printString)])}) nn

158
nextRandomWithSeed:
Categories: random, stochastic

!Trigger nextRandomWithSeed: 0.5.


Range (-1,1)

Like nextRandom, except that you make the random sequence repeatable by providing a seed in the range of (-1,1).
Equivalently, you can send the message seed: to any random expression, for example (!Trigger nextRandom seed:
0.5)

If two different parameter fields or two different Sounds should share the same random sequence, you can use this
seeded version of the expression to ensure that both parameter fields use the exact same sequence. See also seed:

Examples:

!Trigger nextRandomWithSeed: 0.5.

1 s tick nextRandomWithSeed: -0.6

((1 bpm: !BPM) nextRandomWithSeed: 0.2) * !Interval nn + 3 c

159
nn
Categories: units, unitsOfFrequencyAndDuration

!aNumber nn
Range N/A

nn stands for NoteNumber: a naming scheme for pitches where middle C is equal to 60 nn. 1 nn equals one half-step,
so you can alter a pitch up or down by adding or subtracting the desired number of half steps followed by the
messsage nn. This is not limited to integer half-steps; for example, you could add 3 cents to a pitch by adding 0.03
nn. An alternate way of naming pitches takes the form of <octave> <pitchClass>, for example 4 c. When you evaluate
4 c, the result is expressed in notenumbers as 60 nn.

In Kyma, a unit of frequency or duration is a message that you send to a number (or EventValue) to create a new
object called a ScalarWithUnits. You can cascade units of frequency and duration to convert from one to another (for
example, from frequency to pitch or from duration to a tempo in terms of beats-per-minute. Try selecting and
evaluating some of the expressions below using Ctrl+Y (Edit>Evaluate).

Examples:

!aNumber nn

60 nn hz

261.6256d hz nn

60 nn bpm / 100

4c

!NoteNumber + 12 nn

!KeyPitch + !Interval nn

!KeyPitch + (0.01 * !Cents nn)

((1 bpm: !BPM) nextRandom abs * 127) rounded nn

!logFreq nn + (!FineTune nn)

160
normal
Categories: random, stochastic

!aDuration s normal
Range (-1,1)

Every !Duration seconds, the value is a new random number taken from a normal distribution between -1 and 1 and
centered around 0. Random numbers closer to zero are more likely.

Normal is zero and since most members of the population are pretty normal, most of the generated numbers will be
close to zero. Of course there are still interesting outliers possible at any value between -1 and 1, even at the
extremes. To generate random numbers having a completely uniform distribution, see random; for random numbers
having an exponential distribution see randExp. For a triggered random number from a normal distribution see the
nextNormal message.

Examples:

!aDuration s normal

1 s normal

!BPM bpm normal * !Interval nn + 3 c

161
normalGate:
Categories: random, triggers & gates

!On normalGate: !CenterDuration s


Range (-1,1)

Shortcut equivalent of !On normalGate: !AverageDur s deviation: !AverageDur s * 0.5 dutyCycle: 0.5

See normalGate:deviation:dutyCycle:

Examples:

!On normalGate: !CenterDuration s

162
normalGate: deviation: dutyCycle:
Categories: random, triggers & gates

!On normalGate: !CenterDuration s deviation: !Deviation s dutyCycle: !DutyCycle


Range (-1,1)

Generates a gate at time intervals computed as: !CenterDuration + (nextNormal * !Deviation s), where nextNormal is
the next random number from a normal distribution.

In other words, the duration between the current gate and the next gate is the !CenterDuration plus or minus a value
from a random sequence that has a normal distribution scaled by !Deviation s. !On turns the generation of gates on or
off. A gate is generated when the !On changes from off (<= 0) to on (> 0). The minimum time interval between gates
is the larger of (!CenterDuration s - !Deviation s) and 6 ms to allow for voice stealing. The maximum time interval is
!CenterDuration s + !Deviation s.

The time intervals between gates will tend to remain close to the !CenterDuration. This is because the random
deviations have a normal distribution so the random numbers in the sequence tend to be close to zero.

Examples:

!On normalGate: !CenterDuration s deviation: !Deviation s dutyCycle: !DutyCycle

1 normalGate: !CenterDuration s deviation: !CenterDuration * 0.01 dutyCycle: !DutyCycle

!KeyDown normalGate: !BPM bpm s deviation: !BPM bpm s * 0.5 dutyCycle: !DutyCycle

!Sw01 normalGate: !BPM bpm s deviation: !BPM bpm s * 0.5 dutyCycle: 0.5

163
normalTrigger:
Categories: random, triggers & gates

!Gate normalTrigger: !CenterDuration s


Range (0,1)

Generates a trigger at time intervals computed as: !CenterDuration + (nextNormal * !CenterDuration).

The minimum interval between triggers is 2 ms; the maximum interval is !CenterDuration * 2.

This is like normalTriggerCenter:deviation: with !DeviationScale set to half the center duration. (See
normalTriggerCenter:deviation:)

Examples:

!Gate normalTrigger: !CenterDuration s

1 normalTrigger: !CenterDuration s

!Sw01 normalTrigger: !BPM bpm s

164
normalTriggerCenter: deviation:
Categories: random, triggers & gates

!Gate normalTriggerCenter: !CenterDuration s deviation: !DeviationScale


Range (0,1)

Generates a trigger at time intervals computed as: !CenterDuration + (nextNormal * !DeviationScale).

In other words, the duration between the current trigger and the next trigger is the !CenterDuration plus or minus a
value from a random sequence that has a normal distribution and is scaled by !DeviationScale. !Gate turns the
generation of triggers on or off. A trigger is generated when the gate turns off (<= 0) and then on (> 0) again. The
minimum time interval between triggers is 2 ms. The maximum time interval is !CenterDuration + !DeviationScale. The
duration of each generated trigger is 1 ms. Triggers are positive 1 only (no voice stealing).

Timing deviations will tend to be small and the intervals between triggers will tend to remain close to the
!CenterDuration. This is because the random deviations have a normal distribution so the random numbers in the
sequence will tend to be close to zero.

Examples:

!Gate normalTriggerCenter: !CenterDuration s deviation: !DeviationScale

1 normalTriggerCenter: !CenterDuration s deviation: !CenterDuration * 0.01

!Sw01 normalTriggerCenter: !BPM bpm s deviation: !BPM bpm s * 0.5

165
normCos
Categories: arithmetic, trigonometric

!EventExpression normCos
Range [-1,1]

Normalized cosine multiplies the event expression by pi and takes the cosine.

Examples:

!EventExpression normCos

0 normCos

2 normCos

1 normCos

(2 * (1 repeatingRamp)) normCos

(4 * (1 repeatingRamp)) normCos

166
normCosh
Categories: arithmetic, trigonometric

!EventExpression normCosh
Range [1, infinity]

Hyperbolic cosine of an EventExpression * pi. See the entry for cosh.

Examples:

!EventExpression normCosh

0 normCosh

1 normCosh

167
normSin
Categories: arithmetic, trigonometric

!EventExprTimesPi normSin
Range [-1,1]

Normalized sine multiplies the event expression by pi and takes the sine.

This is convenient because it lets you take the sine of numbers as if they had been multiplied by pi.

Examples:

!EventExprTimesPi normSin

0 normSin

1.5 normSin

(2 * (1 repeatingRamp)) normSin

(4 * (1 repeatingRamp)) normSin

168
normSinh
Categories: arithmetic, trigonometric

!EventExpression normSinh
Range [1, infinity]

Hyperbolic sine of an EventExpression * pi. See the entry for sinh.

Examples:

!EventExpression normSinh

0 normSinh

1 normSinh

169
normTan
Categories: arithmetic, trigonometric

!aNormAngle normTan
Range [-infinity, infinity]

As the absolute value of !aNormAngle increases from 0 to 1, normTan starts at 0, increases quickly to positive infinity
when !aNormAngle is 0.5, drops to negative infinity and increases until it reaches 0 again when !aNormAngle is at its
maximum of 1.

The tangent of an angle is the ratio of the sine of that angle and the cosine of that angle. The normalized tangent is
the ratio of the normalized sine and normalized cosine, where the angle range of (0, 2 * pi) is rescaled to a range of
(0,1). So !aNormAngle normTan = (!aNormAngle normSin / !aNormAngle normCos).

Examples:

!aNormAngle normTan

0 normTan

0.4999 normTan

0.5001 normTan

1.0d normTan

170
not
Category: logic

!Value1 not
Range (0, 1)

Logical NOT.

Use this to logically negate a value; if the receiver is true, the result will be 0 (false), otherwise, the result will be 1
(true). In Capytalk, TRUE is represented by positive values and FALSE by zero or negative values.

Examples:

!Value1 not

1 not

0 not

!KeyDown not

(!KeyNumber le: 60) not

!sw01 not

171
number
Category: keyboard events

!Note number
Range N/A

The note number (pitch) of the given bundled note event.

The predefined Event Variable !Note bundles the pitch, velocity, timbre and gate of an incoming keyboard event into a
single value. Use this message to extract the note number from the bundle.

The expression !Note number is functionally equivalent to !KeyNumber.

Examples:

!Note number

!Note number nn

172
octavePointPitchClass
Categories: pitch, scales, tuning, frequency

7.02 octavePointPitchClass
Range [0, 127]

Returns the value in nn that corresponds to a floating point number in the form
octave.pc

Examples:

7.02 octavePointPitchClass

(!ScaleStep intervalAtStepInScaleIndex: !ScaleIndex012) + (12 * !Octave) + !Interval

173
of:
Categories: arrays, choice, selection

!Index of: #(!Expr0 !Expr1 !Expr2)


Range (-infinity, infinity)

From an array of EventExpressions, select the one at location !Index. Positions in the array are numbered from (0 to
sizeOfArray - 1). !Index should be in the range of [0, (sizeOfArray - 1)) to access all elements of the array.

!Index is truncated and clipped to lie within (0, sizeOfArray) so if your index is larger than the array size, you will get
the last element of the array. For 2d Array accessing, see select:of:

Examples:

!Index of: #(!Expr0 !Expr1 !Expr2)

0 of: #( 8 7 6 5)

10 of: #( 8 7 6 5)

(!Fader01 * 3) of: #(!Expr0 !Expr1 !Expr2)

2 of: #(7 8 9 10)

(1 s random abs * 3) of: #(!Interval1 !Interval2 !Interval3)

174
ofEuclideanScaleSteps:
Categories: pitch, scales, tuning, frequency

!Step ofEuclideanScaleSteps: !StepsInScale


Range (0,11)

A Euclidean scale is a new kind of scale that divides the octave into !ScaleSteps intervals as equally as possible,
quantized to half steps. Use !Index to ask for a specific scale step. The scale will wrap around at the octave. The
result of this expression is an interval expressed in half steps. To generate more than one octave, different modes, or
microtonal scales, use the longer message, ofEuclideanScaleSteps:octaves:mode:stepsPerOctave:

!Step should be an integer corresponding to which step of the scale you want to compute. !StepsInScale is the
number of steps in the scale (for example, use 5 to generate a pentatonic scale, use 8 to generate an octatonic scale,
etc).

Examples:

!Step ofEuclideanScaleSteps: !StepsInScale

0 to: 7 collect: [:i | i ofEuclideanScaleSteps: 7]

0 to: 5 collect: [:i | i ofEuclideanScaleSteps: 5]

((1 bpm: !BPM) nextIndex) ofEuclideanScaleSteps: 7

!Tonic nn + ((!X * !StepsInScale * !Octaves) ofEuclideanScaleSteps: !StepsInScale) nn

((1 bpm: !BPM) nextIndex) ofEuclideanScaleSteps: 5

!Tonic nn + ((((1 bpm: !BPM) euclideanForBeats: 16 pulses: !Pulses offset:!Offset) nextRandom abs * 5 *
!Octaves) truncated ofEuclideanScaleSteps: 5) nn

175
ofEuclideanScaleSteps: octaves:
Categories: pitch, scales, tuning, frequency

!Step ofEuclideanScaleSteps: !StepsInScale octaves: !Octaves


Range (0,11)

A Euclidean scale is a new kind of scale that divides the octave into !ScaleSteps intervals as equally as possible,
quantized to half steps. Use !Index to ask for a specific scale step. The scale will wrap around when !Index exceeds
(!NumberOctaves * 12). The result of this expression is an interval expressed in half steps. The octave is divided into
12 equal intervals (half steps). To generate different modes or microtonal scales, use the longer message,
ofEuclideanScaleSteps:octaves:mode:stepsPerOctave:

!Step should be an integer corresponding to which step of the scale you want to compute. !StepsInScale is the
number of steps in the scale (for example, use 5 to generate a pentatonic scale, use 8 to generate an octatonic scale,
etc). !Octaves should be an integer ranging from 1 to the number of octaves you want the scale cover before it wraps
around, modulo (12 * !Octaves).

Examples:

!Step ofEuclideanScaleSteps: !StepsInScale octaves: !Octaves

0 to: 7 collect: [:i | i ofEuclideanScaleSteps: 7 octaves: 2]

0 to: 5 collect: [:i | i ofEuclideanScaleSteps: 5 octaves: 2]

((1 bpm: !BPM) nextIndex) ofEuclideanScaleSteps: 7 octaves: 2

!Tonic nn + ((!X * !StepsInScale * !Octaves) ofEuclideanScaleSteps: !StepsInScale octaves: !Octaves) nn

((1 bpm: !BPM) nextIndex) ofEuclideanScaleSteps: 5 octaves: 2

!Tonic nn + ((((1 bpm: !BPM) euclideanForBeats: 16 pulses: !Pulses offset:!Offset) nextRandom abs * 5 *
!Octaves) truncated ofEuclideanScaleSteps: 5 octaves: !Octaves) nn

176
ofEuclideanScaleSteps: octaves: mode:
Categories: pitch, scales, tuning, frequency

!Step ofEuclideanScaleSteps: !StepsInScale octaves: !Octaves mode: !Mode


Range (0,11)

A Euclidean scale is a new kind of scale that divides the octave into !ScaleSteps intervals as equally as possible,
quantized to half steps. Use !Index to ask for a specific scale step. The scale will wrap around when !Index exceeds
(!NumberOctaves * 12). The result of this expression is an interval expressed in half steps. For scales that have
asymmetric patterns of larger and smaller steps, you can get different interval patterns by changing the !Mode (just as
you can get Aeolian, Dorian, and other modes from the diatonic scale by starting on different steps of the diatonic
scale). The octave is divided into 12 equal intervals (half steps). To generate microtonal scales, use the longer
message, ofEuclideanScaleSteps:octaves:mode:stepsPerOctave:

!Step should be an integer corresponding to which step of the scale you want to compute. !StepsInScale is the
number of steps in the scale (for example, use 5 to generate a pentatonic scale, use 8 to generate an octatonic scale,
etc). !Octaves should be an integer ranging from 1 to the number of octaves you want the scale cover before it wraps
around, modulo (12 * !Octaves). !Mode is the scale step (not half step, but the scalestep number) on which to begin
the pattern of intervals.

Examples:

!Step ofEuclideanScaleSteps: !StepsInScale octaves: !Octaves mode: !Mode

0 to: 7 collect: [:i | i ofEuclideanScaleSteps: 7 octaves: 2 mode: 1]

0 to: 5 collect: [:i | i ofEuclideanScaleSteps: 5 octaves: 2 mode: 1]

((1 bpm: !BPM) nextIndex) ofEuclideanScaleSteps: 7 octaves: 2 mode: 1

!Tonic nn + ((!X * !StepsInScale * !Octaves) ofEuclideanScaleSteps: !StepsInScale octaves: !Octaves mode:


!Mode) nn

((1 bpm: !BPM) nextIndex) ofEuclideanScaleSteps: 5 octaves: 2 mode: 1

!Tonic nn + ((((1 bpm: !BPM) euclideanForBeats: 16 pulses: !Pulses offset:!Offset) nextRandom abs * 5 *
!Octaves) truncated ofEuclideanScaleSteps: 5 octaves: !Octaves mode: !Mode) nn

177
ofEuclideanScaleSteps: octaves: mode: stepsPerOctave:
Categories: pitch, scales, tuning, frequency

!Step ofEuclideanScaleSteps: !StepsInScale octaves: !Octaves mode: !Mode stepsPerOctave: !StepsPerOctave


Range (0,11)

Given a scalestep !Step (where tonic = step 0), this message returns the interval in halfsteps correponding to that
step of a Euclidean scale. Euclidean scale is a new kind of scale that divides the octave into !ScaleSteps intervals as
equally as possible, quantized to a grid set by !StepsPerOctave. Use !Index to ask for a specific scale step. The scale
will wrap around when !Index exceeds (!NumberOctaves * !StepsPerOctave). The result of this expression is an
interval expressed in half steps (or fractions of half steps, if you have specified more than 12 steps per octave). For
scales that have asymmetric patterns of larger and smaller steps, you can get different interval patterns by changing
the !Mode (just as you can get Aeolian, Dorian, and other modes from the diatonic scale by starting on different steps
of the diatonic scale). When !StepsPerOctave is 12, the octave is divided into 12 equal intervals (half steps). To
generate microtonal scales, set the !StepsPerOctave to a number larger than 12.

!Step should be an integer corresponding to which step of the scale you want to compute. !StepsInScale is the
number of steps in the scale (for example, use 5 to generate a pentatonic scale, use 8 to generate an octatonic scale,
etc). !Octaves should be an integer ranging from 1 to the number of octaves you want the scale cover before it wraps
around, modulo (!StepsInScale * !Octaves). !Mode is the scale step (not half step, but the scalestep number) on
which to begin the pattern of intervals. !StepsPerOctave controls the quantization of intervals within each octave. For
example, to quantize to halfsteps, use 12, for quartertones, use 24, for eighthtones, 48, etc. ).

Examples:

!Step ofEuclideanScaleSteps: !StepsInScale octaves: !Octaves mode: !Mode stepsPerOctave: !StepsPerOctave

0 to: 7 collect: [:i | i ofEuclideanScaleSteps: 7 octaves: 2 mode: 1 stepsPerOctave: 12]

0 to: 5 collect: [:i | i ofEuclideanScaleSteps: 5 octaves: 2 mode: 1 stepsPerOctave: 48]

((1 bpm: !BPM) nextIndex) ofEuclideanScaleSteps: 7 octaves: 2 mode: 1 stepsPerOctave: 12

!Tonic nn + ((!X * !StepsInScale * !Octaves) ofEuclideanScaleSteps: !StepsInScale octaves: !Octaves mode:


!Mode stepsPerOctave: !StepsPerOctave) nn

((1 bpm: !BPM) nextIndex) ofEuclideanScaleSteps: 5 octaves: 2 mode: 1 stepsPerOctave: 24

!Tonic nn + ((((1 bpm: !BPM) euclideanForBeats: 16 pulses: !Pulses offset:!Offset) nextRandom abs * 5 *
!Octaves) truncated ofEuclideanScaleSteps: 5 octaves: !Octaves mode: !Mode stepsPerOctave: 12) nn

178
onOff
Category: keyboard events

!Note onOff
Range N/A

The gate of the given bundled note event.

The predefined Event Variable !Note bundles the pitch, velocity, timbre and gate of an incoming keyboard event into a
single value. Use this message to extract the gate from the bundle.

The expression !Note onOff is functionally equivalent to !KeyDown.

Examples:

!Note onOff

179
ordinalToIndexIn:
Categories: arrays, choice, selection

!Order ordinalToIndexIn: #(!Expr0 !Expr1 !Expr2)


Range (-infinity, infinity)

From an array of EventExpressions, return the index of the !Order-th largest one. Positions in the array are numbered
from (0 to sizeOfArray - 1). !Order should be in the range of [0, (sizeOfArray - 1)) to access all elements of the array.

The array of EventExpresions is sorted into ascending order, indexed by !Order; the value of this expression is the
location of the selected value in the original array of EventExpressions.

!Order is truncated and clipped to lie within (0, sizeOfArray - 1) so if your order is zero or smaller, you will get the
index of the smallest element of the array or if your order is larger than the array size, you will get the index of the
largest element of the array.

Examples:

!Order ordinalToIndexIn: #(!Expr0 !Expr1 !Expr2)

0 ordinalToIndexIn: #( 8 7 6 5)

3 ordinalToIndexIn: #( 8 7 6 5)

(!Fader01 * 3) ordinalToIndexIn: #(!Expr0 !Expr1 !Expr2)

2 ordinalToIndexIn: #(10 9 8 7)

(1 s random abs * 3) ordinalToIndexIn: #(!Interval1 !Interval2 !Interval3)

180
phon70ForNotenumber:
Categories: loudness, amplitude

!anAmplitude phon70ForNotenumber: !aNotenumber


Range (0.0536, 1.0)

Given an input amplitude, this expression returns an amplitude adjusted to provide equal loudness for a sine wave at
the given notenumber (where 60 is middle C, or 261.6256 hz). These adjustments fit the 70 phon, equal-loudness
contour published in the ISO 226:2003 standard, for generating sine waves of equal loudness at different pitches.
This is to compensate for differences in the sensitivity of the ear to different pitches and tends to boost the amplitude
of lower pitches, while generally attenuating higher pitches (plus a couple of bumps in the curve around 87 nn and
123 nn).

On this curve, 35 nn (and below) are at unity gain and other pitches are adjusted accordingly through 127 nn. If you
know the minimum expected pitch, you can boost all the amplitudes and still maintain the shape of the curve by using
inversePhon70ForMinimumNumber: after this (or in a Sound to the right of this one in the signal flow).

Examples:

!anAmplitude phon70ForNotenumber: !aNotenumber

1 phon70ForNotenumber: 108

1 phon70ForNotenumber: 90

1 phon70ForNotenumber: 24

181
prefix2:
Categories: EventValues, Hot variables

!Fader prefix2: <aOneOrTwoDigitNumber>


Range N/A

See prefix:. You can use prefix2: to add mixtures of 1 and 2 digit numbers to the beginnings of EventValues, padding
the single digit numbers with a leading zero so that the controls automatically sort in alphabetical and numerical order
in the VCS.

Examples:

!Fader prefix2: <aOneOrTwoDigitNumber>

{1 to: 50 collect: [ :n | !Fader prefix2: n]}

182
prefix3:
Categories: EventValues, Hot variables

!Fader prefix3: <aNumber>


Range N/A

See suffix:. You can use prefix3: to add mixtures of 1, 2 and 3 digit numbers to the beginnings of EventValues,
padding with leading zeroes so that the controls automatically sort in alphabetical and numerical order in the VCS.

Examples:

!Fader prefix3: <aNumber>

{90 to: 100 collect: [ :n | !Fader prefix3: n]}

183
prefix4:
Categories: EventValues, Hot variables

!Fader prefix4: <aNumber>


Range N/A

See prefix:. You can use prefix4: to add mixtures of 1, 2, 3, and 4 digit numbers to the beginnings of EventValues,
padding with leading zeroes so that the controls automatically sort in alphabetical and numerical order in the VCS.

Examples:

!Fader prefix4: <aNumber>

{(100 to: 1000 by: 100) collect: [ :n | !Fader prefix4: n]}

184
prefix5:
Categories: EventValues, Hot variables

!Fader prefix5: <aNumber>


Range N/A

See prefix:. You can use prefix5: to add mixtures of 1, 2, 3, 4, and 5 digit numbers to the beginnings of EventValues,
padding with leading zeroes so that the controls automatically sort in alphabetical and numerical order in the VCS.

Examples:

!Fader prefix5: <aNumber>

{(100 to: 15000 by: 500) collect: [ :n | !Fader prefix5: n]}

185
prefix:
Categories: EventValues, Hot variables

!Fader prefix: <anObjectOrString>


Range N/A

To add a prefix to an EventValue name, send the prefix: message to the EventValue. The argument to prefix: is
converted to a string and added to the beginning of the EventValue name. You can use this message to assign
unique names or numbers to each controller in an array of algorithmically generated controls.

Technically, the prefix: message is a Smalltalk rather than Capytalk message since it takes effect during the compile
stage and creates the newly named EventValues before the Sound actually starts playing. If the prefix includes any
green variables, create the eventValue first (by sending asEventValue to a string name) and then send the prefix:
message to the newly created EventValue (for example, ’fader’ asEventValue prefix: (?VoiceNumber - 1)).

Examples:

!Fader prefix: <anObjectOrString>

{1 to: 9 collect: [ :n | !Fader prefix: n]}

{ | controls |
controls := OrderedCollection new.
1 to: 2 do: [ :n | 1 to: 2 do: [ :m |
controls add: (!Timbre prefix: (Array with: m with: n))]].
controls asArray}

(’BW’ asEventValue prefix: ?VoiceNumber) * 10 hz

186
prefix: positions:
Categories: EventValues, Hot variables

!Fader prefix: <aNumber> position: <digits>


Range N/A

See prefix:. You can use prefix:position: to add mixtures of numbers having <digits> number of digits in them to the
beginning of EventValues, padding with leading zeroes so that the controls automatically sort in alphabetical and
numerical order in the VCS.

Examples:

!Fader prefix: <aNumber> position: <digits>

{| r |
r := Random new.
1 to: 50 collect: [ :n | !Fader prefix: (r next * 1000000) truncated positions: 7]}

187
px
Category: units

!Size px
Range N/A

To express a graphical size or position in terms of pixels, use px (for pixels).

When specifying positions or sizes of graphical objects of Sprites in the VCSSprites Sound, by default, values are
interpreted to be in the coordinate system specified by the ValueLeft, ValueRight, ValueTop, and ValueBottom
parameters. Use px to specify a position or size in unscaled pixels.

Examples:

!Size px

188
R
Categories: Sounds, control signals

[aSound] R
Range [-1,1]

When sent to [a Sound] that has been copied and pasted into a parameter field, R means to sample and hold the
value of the right channel of [aSound] once per millisecond. (See R: for more details).

Examples:

[aSound] R

[LFO] R * SignalProcessor halfSampleRate hz

189
R:
Categories: Sounds, control signals

[aSound] R: <millisecondsToHold>
Range [-1,1]

When sent to [a Sound] that has been copied and pasted into a parameter field, R: means to sample and hold the
value the right channel of [aSound] every <millisecondsToHold> milliseconds. The Sound itself updates at the sample
rate; the parameter value is updated by sampling and holding the value of [aSound] once every
<millisecondsToHold> milliseconds. To sample and hold the value of [aSound] once per millisecond (1000 times per
second), use R by itself, without the colon or <millisecondsToHold> argument.

Capytalk expressions that include [aSound] R: <millisecondsToHold> will be evaluated once every
<millisecondsToHold> milliseconds. Thus, the larger number you use for <millisecondsToHold> the less often the
expression will be evaluated and the less computation it requires.

For certain critical amplitude parameters, you can remove the R, L or M altogether to indicate that the parameter
should read the Sound and update the parameter value at the full sample rate. These parameters include:

Oscillator Envelope

ModalFilter Envelope

TriggeredSampleAndHold Trigger

VCF Amplitude and Resonance

PsiPlayer AmpScale and TimeIndex

When in doubt about whether a parameter can be updated at the full sample rate, check the parameter help.

Examples:

[aSound] R: <millisecondsToHold>

([LFO] R: 10) * SignalProcessor halfSampleRate hz

190
ramp
Category: time functions

!Trigger ramp
Range (0,1)

This is a shortcut for !Trigger ramp: 1 s. It generates a function that increases linearly from 0 to 1 over the course of 1
s. See ramp: for more details.

Examples:

!Trigger ramp

!TrigPan ramp

191
ramp00:
Categories: time functions, evaluatedEveryMillisecond

!Trigger ramp00: !Duration s


Range [0,1]

The value is 0 until the Gate becomes 1, then it increases linearly from 0 to 1 over the course of Duration seconds.
Once it reaches 1, it resets automatically to 0.

Not affected by WaitUntil.

Examples:

!Trigger ramp00: !Duration s

!Trigger ramp00: 5 s

(!Trigger turnOnAfter: 3 s for: 1 s) ramp00: 5 s

192
ramp0:
Categories: time functions, evaluatedEveryMillisecond

!Trigger ramp0: !Duration s


Range [0,1]

The value is 0 until the Gate becomes 1, then it increases linearly from 0 to 1 over the course of Duration seconds.
Once it reaches 1, it stays at 1.

Not affected by WaitUntil.

Examples:

!Trigger ramp0: !Duration s

!Trigger ramp0: 5 s

(!Trigger turnOnAfter: 3 s for: 1 s) ramp0: 5 s

193
ramp0: reset:
Categories: time functions, evaluatedEveryMillisecond

!Trigger ramp0: !Duration s reset: !Reset


Range [0,1]

The value is 0 until the Gate becomes 1, then it increases linearly from 0 to 1 over the course of Duration seconds.
Once it reaches 1, it stays at the value until Reset changes from 0 to a positive value.

Not affected by WaitUntil.

Examples:

!Trigger ramp0: !Duration s reset: !Reset

!Trigger ramp0: 5 s reset: !Reset

(!Trigger turnOnAfter: 3 s for: 1 s) ramp0: 5 s reset: (1 - (!Value hasChangedInLast: 4 s))

194
ramp:
Category: time functions

!Trigger ramp: !Duration s


Range (0,1)

Linear function that increases from 0 to 1 over the course of !Duration s and then sticks at 1 until it is retriggered (see
ramp00: for a ramp that does not stick at 1). Retriggered whenever !Trigger changes from a value <= 0 to a value > 0.

Because it increases linearly from 0 to 1 over a given duration, ramp: can also be used as a timer. (See also ramp0:
and fullRamp:)

Examples:

!Trigger ramp: !Duration s

!TrigPan ramp: !PanDur s

1 - (!Start ramp: 10 s ) * 10

(!BPM bpm s * 32) tick ramp: (!BPM bpm s * 32) s

((!Trigger ramp: !Dur s) * ?NumberVoices - (?VoiceNumber - 1)) clipTo01

195
randExp
Categories: random, stochastic

!aDuration s randExp
Range (0,24)

Every !Duration seconds, the value is a new random interval in the range of (0,24) taken from an Exponential
distribution. Smaller intervals are more likely than larger ones.

Typically random numbers from an exponential distribution are interpreted as intervals of time or pitch. There are lots
of small intervals and fewer large intervals. To generate random numbers having a completely uniform distribution,
see random; for random numbers having a normal distribution see normal.

Examples:

!aDuration s randExp

1 s randExp

!BPM bpm randExp nn + 3 c

196
randExpGate:
Categories: random, triggers & gates

!On randExpGate: !AverageDur s


Range (-1,1)

Shortcut for the equivalent !On randExpGate: !AverageDur s minDur: 6 ms maxDur: !AverageDur s * 2 dutyCycle: 0.5.

See randExpGateminDur:maxDur:dutyCycle: for additional controls.

Examples:

!On randExpGate: !AverageDur s

197
randExpGate: minDur: maxDur: dutyCycle:
Categories: random, triggers & gates

!On randExpGate: !AverageDuration s minDur: !MinDuration s maxDur: !MaxDuration s dutyCycle: !DutyCycle


Range (-1,1)

Generates a sequence of gates where the duration between the current gate and the next gate is a random time
interval from an exponential distribution. !On switches the generation of gates on or off; when !On switches from off
(<=0) to on (>0), the expression starts generating gates. To ensure an initial gate at the beginning, set !On to a
negative value and then switch it on (>0) as you would for voice-stealing. The minimum time interval between gates is
!MinDuration s (or 6 ms, whichever is larger). The maximum time interval is the smaller of !MaxDur s or
(!AverageDuration s * 32), whichever is smaller. The duration of each generated gate is the duration between gates
scaled by !DutyCycle. The generated gates are -1 for the first 5 ms to allow for voice stealing, then they become 1 for
the remainder of the dutyCycle.

Imagine an exponential decay that starts at time 0 and reaches the halfway point at !AverageDuration s. This gives
you an idea of the likelihood of a duration being selected. Durations near zero will be highly likely; longer durations
become less and less likely (but still possible). The !AverageDuration has about a 50/50 chance of being selected. In
simulations of systems like airports and bank teller windows, the exponential distribution is often used for generating
random time intervals between events.

Examples:

!On randExpGate: !AverageDuration s minDur: !MinDuration s maxDur: !MaxDuration s dutyCycle: !DutyCycle

1 randExpGate: !CenterDuration * 0.01 minDur: 0.2 s maxDur: !MaxDur s dutyCycle: 0.125

1 randExpGate: (1 - !Density * ?VoiceNumber) s minDur: 0.2 s maxDur: 5 s dutyCycle: !DutyCycle

198
randExpTrigger:
Categories: random, triggers & gates

!Gate randExpTrigger: !AverageDuration s


Range (0,1)

Generates triggers at time intervals computed as: !AverageDuration * nextRandom abs twoLog negated.

In other words, the duration between the current trigger and the next trigger is a random value from a sequence of
random numbers having an exponential distribution. !Gate turns the generation of triggers on or off. A trigger is
generated when the gate turns off (<= 0) and then on (> 0) again. The minimum time interval between triggers is 2
ms. There is no maximum time interval. The duration of each generated trigger is 1 ms. Triggers are positive 1 only
(no voice stealing).

Imagine an exponential decay that starts at time 0 and reaches the halfway point after !AverageDuration s. This gives
you an idea of the likelihood of a duration being selected. Durations near zero will be highly likely; longer durations
become less and less likely (but still possible). The !AverageDuration has about a 50/50 chance of being selected. In
simulations of systems like airports and bank teller windows, the exponential distribution is often used for generating
random time intervals between events.

Examples:

!Gate randExpTrigger: !AverageDuration s

1 randExpTrigger: !CenterDuration s

1 randExpTrigger: (1 - !Density * ?VoiceNumber) s

((1 randExpTrigger: !AverageDuration s) nextRandom abs * 0.1) seed: 0.7

199
randExpTrigger: minimumDuration:
Categories: random, triggers & gates

!Gate randExpTrigger: !AverageDuration s minimumDuration: !MinDuration s


Range (0,1)

Generates triggers at time intervals computed as: !AverageDuration * nextRandom abs twoLog negated.

In other words, the duration between the current trigger and the next trigger is a random value from a sequence of
random numbers having an exponential distribution. !Gate turns the generation of triggers on or off. A trigger is
generated when the gate turns off (<= 0) and then on (> 0) again. The minimum time interval between triggers is
!MinDuration s (or 2 ms, whichever is larger). There is no maximum time interval. The duration of each generated
trigger is 1 ms. Triggers are positive 1 only (no voice stealing).

Imagine an exponential decay that starts at time 0 and reaches the halfway point after !AverageDuration s. This gives
you an idea of the likelihood of a duration being selected. Durations near zero will be highly likely; longer durations
become less and less likely (but still possible). The !AverageDuration has about a 50/50 chance of being selected. In
simulations of systems like airports and bank teller windows, the exponential distribution is often used for generating
random time intervals between events.

Examples:

!Gate randExpTrigger: !AverageDuration s minimumDuration: !MinDuration s

1 randExpTrigger: !CenterDuration * 0.01 minimumDuration: 0.2 s

1 randExpTrigger: (1 - !Density * ?VoiceNumber) s minimumDuration: 0.2 s

((1 randExpTrigger: !AverageDuration s minimumDuration: 0.1 s) nextRandom abs * 0.1) seed: 0.7

200
random
Categories: random, stochastic

!aDuration s random
Range (-1,1)

Every !Duration seconds, the value is a new random number taken from a uniform distribution between -1 and 1. Any
number in the (-1,1) range is equally likely to occur.

To generate random numbers having a normal distribution, see normal; for random numbers having an exponential
distribution see randExp.

Examples:

!aDuration s random

1 s random

!BPM bpm random * !Interval nn + 3 c

201
randomGate:
Categories: random, triggers & gates

!On randomGate: !AverageDur s


Range (-1,1)

Shortcut that is the equivalent of !On randomGate: !AverageDur s deviation: !AverageDur s * 0.5 dutyCycle: 0.5.

See randomGate:deviation:dutyCycle:.

Examples:

!On randomGate: !AverageDur s

202
randomGate: deviation: dutyCycle:
Categories: random, triggers & gates

!On randomGate: !CenterDuration s deviation: !Deviation s dutyCycle: !DutyCycle


Range (-1,1)

Generates a gate at time intervals computed as: !CenterDuration + (nextRandom * !Deviation s), where nextRandom
is the next random number from a uniform random distribution.

In other words, the duration between the current gate and the next gate is the !CenterDuration plus or minus a
random number between 0 and !Deviation s. !On turns the generation of gates on or off. A gate is generated when the
!On changes from negative (<0) to on (> 0). The minimum time interval between gates is the larger of
(!CenterDuration s - !Deviation s) and 6 ms to allow for voice stealing. The maximum time interval is !CenterDuration s
+ !Deviation s. Each generated gate stays on for !DutyCycle * the total duration between gates.

The time intervals between gates is uniformly distributed around !CenterDuration.

Examples:

!On randomGate: !CenterDuration s deviation: !Deviation s dutyCycle: !DutyCycle

1 randomGate: !AverageDur s deviation: !AverageDur s * 0.01 dutyCycle: !DutyCycle

1 randomGate: !AverageDur s deviation: !Deviation s dutyCycle: !DutyCycle

1 randomGate: (1 - !Density) * 10 s deviation: !Jitter s dutyCycle: !DutyCycle

!Sw01 randomGate: !BPM bpm s deviation: !BPM bpm s * 0.5 dutyCycle: 0.5

203
randomTrigger:
Categories: random, triggers & gates

!Gate randomTrigger: !CenterDuration s


Range (0,1)

Generates a trigger at time intervals computed as: !CenterDuration + (nextRandom * !CenterDuration * 0.5).

In other words, the duration between the current trigger and the next trigger is the !CenterDuration plus or minus a
value from a random sequence that has a uniform distribution and is scaled by half the !CenterDuration. (See
randomTrigger:deviation:)

Timing deviations are equally likely to be any value between 2 ms and (!CenterDuration * 1.5).

Examples:

!Gate randomTrigger: !CenterDuration s

1 randomTrigger: !CenterDuration s

!Sw01 randomTrigger: !BPM bpm s

204
randomTriggerCenter: deviation:
Categories: random, triggers & gates

!Gate randomTriggerCenter: !CenterDuration s deviation: !DeviationScale


Range (0,1)

Generates a trigger at time intervals computed as: !CenterDuration + (nextRandom * !DeviationScale).

In other words, the duration from the current trigger to the next trigger is the !CenterDuration plus or minus a value
from a random sequence that has a uniform distribution and is scaled by !DeviationScale. !Gate turns the generation
of triggers on or off. A trigger is generated when the gate turns off (<= 0) and then on (> 0) again. The minimum time
interval between triggers is 2 ms. The maximum time interval is !CenterDuration * 2. The duration of each generated
trigger is 1 ms. Triggers are positive 1 only (no voice stealing).

Timing deviations are equally likely to be any value between 2 ms and (!CenterDuration + !DeviationScale).

Examples:

!Gate randomTriggerCenter: !CenterDuration s deviation: !DeviationScale

1 randomTriggerCenter: !CenterDuration s deviation: !CenterDuration * 0.01

!Sw01 randomTriggerCenter: !BPM bpm s deviation: !BPM bpm s * 0.5

205
randomWalk
Category: random

!Trigger randomWalk
Range (-1,1)

A shortcut for sending the message !Trigger randomWalkStartingFrom: 0 stepSize: 0.25 reset: 0

Examples:

!Trigger randomWalk

1 s tick randomWalk * !Range + !Offset

206
randomWalkStartingFrom: stepSize: reset:
Category: random

!Trigger randomWalkStartingFrom: !StartValue stepSize: !SizeOfStep reset: !Reset


Range (-1,1)

Each time !Trigger becomes true, take the next step in a random walk. Each output is the value of the previous output
plus a random number (-1,1) from a uniform distribution scaled by !StepSize squared. The first value is !StartValue
and the range is restricted to (-1,1). If the next value would lie outside the range, it wraps around in a modulo fashion
so it remains within the (-1,1) interval. When !Reset becomes true (1), the value is reset to !StartValue and on the
next !Trigger, the value will be the !StartValue plus the next uniform random value scaled by !SizeOfStep squared.
For a repeatable random walk, send the seed: message to your randomWalk expression.

For a shortcut, see also randomWalk.

For more details on brownian motion, random walks and Weiner processes see:
http://en.wikipedia.org/wiki/Random_walk
http://mathworld.wolfram.com/WienerProcess.html

Examples:

!Trigger randomWalkStartingFrom: !StartValue stepSize: !SizeOfStep reset: !Reset

1 s tick randomWalkStartingFrom: initialValue stepSize: stepSize reset: reset

(!Gate randomWalkStartingFrom: 0 stepSize: 1 reset: (!Reset alignWith: !Gate)) * !Interval nn + !logFreq nn

207
removeUnits
Categories: units, unitsOfFrequencyAndDuration

!aNumber nn removeUnits
Range N/A

You can use removeUnits to strip the units off a frequency or duration expression that includes units (such as hz, nn,
s, ms, etc). For example, the expression (!OnDur s * !AtkDur s) would not make sense because the result would be in
units of seconds squared. The more likely intention is to scale the size of !OnDur s by a unitless scale factor: (
(!OnDur s * !AtkDur s removeUnits). Apart from Frequency or Duration fields, most parameter fields expect unitless
arguments. For example, if you wanted to use an expression with units (such as !Frequency hz inverse) in a
parameter field that expects unitless values, you can use removeUnits to strip the units from the expression (for
example, !Frequency hz removeUnits inverse).

In Kyma, units (for example hz, nn, s, ms) are implemented as messages that you send to a number (or
EventExpression) to create a new kind of object called a ScalarWithUnits. When you send the removeUnits message
to a ScalarWithUnits, the result is a Scalar.

Examples:

!aNumber nn removeUnits

0.5 s removeUnits * 10 s

!KeyPitch + (0.01 s inverse removeUnits * !Cents nn)

SignalProcessor halfSampleRate /!FreqLow hz removeUnits

208
repeatingFullRamp
Category: time functions

!Gate repeatingFullRamp
Range (-1,1)

Shortcut for !Gate repeatingFullRamp: 1 s. See repeatingFullRamp: for more details.

Examples:

!Gate repeatingFullRamp

209
repeatingFullRamp:
Category: time functions

!Gate repeatingFullRamp: !Duration s


Range (-1,1)

Linear function that increases from -1 to 1 over the course of !Duration s and then, if !Gate is still 1, repeats ad
infinitem (or until !Gate is no longer 1, whichever comes first). Changing !Gate from 1 to 0 and back to 1 resets the
function to -1 and restarts the !Duration timer at 0.

Its (-1,1) range makes repeatingFullRamp useful as a looping TimeIndex. Because it is periodic and increases linearly
over a given duration, it is also a good function to use as the time argument for other periodic functions such normSin.
(See also ramp: ramp0: and fullRamp:)

Examples:

!Gate repeatingFullRamp: !Duration s

!Gate repeatingFullRamp: ’frase’ fileDuration s

1 repeatingFullRamp: !Dur s

(1 repeatingFullRamp: (!Rate hz inverse)) normSin

(1 repeatingFullRamp: !PanDur s) + 0.5

!PenDown repeatingFullRamp: (3 s + ((!PenZ gt: 0.9) * 10))

(1 repeatingFullRamp: (!BPM / 8.0) bpm s) + (!TimeJitter * (1 bpm: !BPM) nextRandom smooth: (!BPM bpm s))

210
repeatingRamp
Category: time functions

!Gate repeatingRamp
Range (0,1)

Shortcut for !Gate repeatingRamp: 1 s. See repeatingRamp: for more details.

Examples:

!Gate repeatingRamp

211
repeatingRamp:
Category: time functions

!Gate repeatingRamp: !Duration s


Range (0,1)

Linear function that increases from 0 to 1 over the course of !Duration s and then, if !Gate is still 1, repeats.
Retriggered whenever !Gate changes from a value <= 0 to a value > 0.

Because it increases linearly from 0 to 1 over a given duration, repeatingRamp: can also be used as the time
argument to another function such as twoExp. (See also ramp: ramp0: and fullRamp:)

Examples:

!Gate repeatingRamp: !Duration s

1 repeatingRamp: !PanDur s

1 - (!Start repeatingRamp: 10 s ) * 10

212
repeatingTriangle
Categories: envelopes, time functions

!Gate repeatingTriangle
Range (0,1)

While !Gate is 1, repeatedly generate a linear function from 0, to 1, and back to 0 again, over the course of 1 s.

See repeatingTriangle: and triangle:.

Examples:

!Gate repeatingTriangle

1 repeatingTriangle

213
repeatingTriangle:
Categories: envelopes, time functions

!Gate repeatingTriangle: !Duration s


Range (0,1)

While !Gate is 1, repeatedly generate a linear function from 0, to 1, and back to 0 again, over the course of !Duration
s.

Generate a triangle-shaped function repeatedly for as long as !Gate remains at 1. For faster repetitions, shorten the
!Duration argument.

Examples:

!Gate repeatingTriangle: !Duration s

1 repeatingTriangle: 2 s

!Gate repeatingTriangle: !BPM bpm s * 8

214
rounded
Categories: arithmetic, integer, rounding

!FractionalNumber rounded
Range (-infinity, infinity)

Rounds to the nearest integer.

When you round, you drop the fractional part of the number by moving to the nearest integer. The halfway point, 0.5,
moves to the next larger magnitude integer; for fractional parts less than 0.5, it will move to the next smaller
magnitude integer (no matter what the sign).

Examples:

!FractionalNumber rounded

3.49 rounded

3.5 rounded

-3.9 rounded

215
roundTo:
Categories: arithmetic, rounding

!aValue roundTo: !aNumber


Range N/A

Round !aValue to nearest multiple of !aNumber. For example, to round !aValue to two decimal points, you would use
!aValue roundTo: 0.01. To round !aValue the nearest multiple of 4, you would use !aValue roundTo: 4.

Computed as (!aValue / !aNumber) rounded * !aNumber

Examples:

!aValue roundTo: !aNumber

Double pi roundTo: 0.01

1024 roundTo: 10

0.6 roundTo: 0.25

!Interval roundTo: 12

216
s
Categories: units, unitsOfFrequencyAndDuration

!aDuration s
Range N/A

To express a duration in terms of seconds, use s (for seconds), the canonical unit of time or duration in Capytalk.
When you evaluate other durations, such as m (minutes), h (hours), day (days), ms (milliseconds), or usec
(microseconds), the result will be expressed in terms of seconds (s). An value expressed in units of samples at the
current sample rate (samp) remains in units of samples when evaluated; to convert to seconds, cascade the units of
samples (samp) and seconds (s).

In Kyma, a unit of frequency or duration is a message that you send to a number (or EventValue) to create a new
object called a ScalarWithUnits. You can cascade units of frequency and duration to convert from one to another (for
example, from frequency to pitch or from duration to a tempo in terms of beats-per-minute or even from a duration to
a frequency (where the duration is interpreted as the length of one cycle at that frequency). Try selecting and
evaluating some of the expressions below using Ctrl+Y (Edit>Evaluate).

Examples:

!aDuration s

!Duration s hz

1ms

1h

1 usec * 1.0e6

1 s bpm

2 s hz

44100 samp s

(Time now seconds + !LocalTime truncated) mod: 60

1 bpm: (!Tap durationBetweenTriggers s bpm removeUnits)

217
sameForLast: tolerance:
Categories: detection, test, logic, controllers

!Controller sameForLast: !NumberMeasurements tolerance: !Tolerance


Range (0, 1)

Test the stability of a !Controller by detecting when it has held the same value (plus or minus a !Tolerance) for the last
!NumberMeasurements.

Useful for detecting when a physical controller is at rest (returning the same value plus-or-minus the !Tolerance for
the last !NumberMeasurements). Also useful for detecting when a performer has sustained the same pitch, amplitude,
timbre or other parameter extracted from the microphone input signal.

Examples:

!Controller sameForLast: !NumberMeasurements tolerance: !Tolerance

!Amplitude sameForLast: 100 tolerance: !SmallestChange

!KeyNumber sameForLast: 500 tolerance: 0.01

!WiiAccelX sameForLast: 100 tolerance: !NoiseLevel

218
samp
Categories: units, unitsOfFrequencyAndDuration

!DurationInSamples samp
Range N/A

To express a duration in terms of the number of samples at the current sample rate, use samp. To convert from units
of samp to units of seconds or frequency, cascade the units; for example, 100 samp hz would tell you the frequency
of a periodic waveform whose period was 100 samples long.

In Kyma, a unit of frequency or duration is a message that you send to a number (or EventValue) to create a new
object called a ScalarWithUnits. You can cascade units of frequency and duration to convert from one to another (for
example, from frequency to pitch or from duration to a tempo in terms of beats-per-minute. Try selecting and
evaluating some of the expressions below using Ctrl+Y (Edit>Evaluate).

Examples:

!DurationInSamples samp

SignalProcessor sampleRate samp s

100 samp hz

44100 samp s

512 samp hz

219
sampleAndHold:
Categories: sampleAndHold, capture

!Trigger sampleAndHold: !ChangingExpression


Range [-Infinity, Infinity]

When triggered, sample and hold the current value of !ChangingExpression.

When !Trigger becomes true (greater than 0), sample the current value of !ChangingExpression. Return that value
until !Trigger becomes false (less than or equal to 0) and then true (greater than 0) again

Examples:

!Trigger sampleAndHold: !ChangingExpression

!KeyDown sampleAndHold: !KeyNumber

(!Value gt: 0.5) sampleAndHold: (0.01 s random)

((!Gate countTriggersMod: ?NumberVoices) eq: (?VoiceNumber - 1)) sampleAndHold: !Rate

220
seed:
Categories: random, stochastic, seed

!EventExpression seed: 0.2


Range (-1,1)

Send seed: to any Event Value or complex Event Expression in order to make its random sequence repeatable or to
ensure that two different parameter fields can share the same random sequence. Seed should be a constant in the
range (-1, 1)

All random number generators within the Event Expression will share the same seed.

Examples:

!EventExpression seed: 0.2

(1 s tick nextRandom) seed: 0.44

((1 bpm: !BPM) nextRandom * !Interval nn + 3 c) seed: 0.24

221
seeded
Categories: random, stochastic, seed

!EventExpression seeded
Range (-1,1)

Send seeded to an EventValue or complex EventExpression to ensure that its random sequence is independent of
any other random sequences in the same Sound.

All random number generators within the Event Expression will share the same seed but that seed will be different
each time the Sound is evaluated and played.

Examples:

!EventExpression seeded

(1 s tick nextRandom) seeded

((1 bpm: !BPM) nextRandom * !Interval nn + 3 c) seeded

222
seededWith:
Categories: random, stochastic, seed

!EventExpression seededWith: 0.2


Range (-1,1)

Send seededWith: to any Event Value or complex Event Expression in order to make its random sequence
repeatable or to ensure that two different parameter fields can share the same random sequence. Seed should be a
constant in the range (-1, 1)

All random number generators within the Event Expression will share the same seed.

Examples:

!EventExpression seededWith: 0.2

(1 s tick nextRandom) seededWith: 0.44

((1 bpm: !BPM) nextRandom * !Interval nn + 3 c) seededWith: 0.24

223
segmentOfGrid:
Categories: test, grids

!aValue segmentOfGrid: <a grid spacing or an array of markers>


Range (-1,1)

Imagine that the full range of !aValue is divided up into segments (either evenly by !Grid or non-uniformly by an Array
of markers such as #(!M1 !M2 !M3). This expression returns the number of the segment (above or below zero) that
contains !aValue. The segment number has the same sign as !aValue (so it returns negative segment numbers for
values less than zero).

Examples:

!aValue segmentOfGrid: <a grid spacing or an array of markers>

10 segmentOfGrid: 0.1

0.25 segmentOfGrid: #(!Marker1 !Marker2 !Marker3)

!aValue segmentOfGrid: 0.1

(((1 repeatingTriangle: (!BPM bpm s * 4)) segmentOfGrid: #(!W1 !W2 !W3 !W4)) ofEuclideanScaleSteps: 5) nn +
!Tonic nn

224
select: of:
Categories: arrays, choice, selection

!OuterIndex select: !InnerIndex of: #(#(!Expr0 !Expr1 !Expr2) #(!Expr3 !Expr4 !Expr5))
Range (-infinity, infinity)

From a 2d nested array of EventExpressions, select the collection at !OuterIndex. Then look up the value at
!InnerIndex. Indexes in the array are numbered from (0 to sizeOfArray - 1). Each Index should be in the range of 0 to
one less than the size of the dimension in order to access all elements of the array. In the example, the range of
!OuterIndex is [0,1] and the range of !InnerIndex is [0,2].

Each !Index is truncated and clipped to lie within (0, sizeOfArray - 1) so if your index is larger than the array size, you
will get the last element of the array. For 3d Array accessing, see !X select: !Y select: !Z of: <array>

Examples:

!OuterIndex select: !InnerIndex of: #(#(!Expr0 !Expr1 !Expr2) #(!Expr3 !Expr4 !Expr5))

4 select: 0 of: #((0 1 2 3 4) (5 6 7 8 9) (10 11 12 13 14))

0 select: 1 of: #((0 1 2 3 4) (5 6 7 8 9) (10 11 12 13 14))

2 select: 2 of: #((0 1 2 3 4) (5 6 7 8 9) (10 11 12 13 14))

(1 s random abs * 2) select: (4 s random abs * 3) of: #( #(!Interval1 !Interval2 !Interval3) #(!Interval4 !Interval5
!Interval6))

225
select: select: of:
Categories: arrays, choice, selection

!X select: !Y select: !Z of: #(#((!Expr0 !Expr1 !Expr2) (!Expr3 !Expr4 !Expr5)) #((!Expr6 !Expr7 !Expr8) (!Expr9
!Expr10 !Expr11)))
Range (-infinity, infinity)

From a 3d nested array of EventExpressions, first select the !X collection, then the !Yth collection within that, and
finally the value at the !Zth collection. Positions in the array are numbered from (0 to sizeOfArray - 1). Each Index
should be in the range of [0, (sizeOfArray - 1)) to access all elements of the array.

Each !Index is truncated and clipped to lie within (0, sizeOfArray - 1) so if your index is larger than the array size, you
will get the last element of the array. For arbitrarily nested array accessing, see !X withAdditionalSelectors: #(!Col1
!Col2 !Col3) of: <nested arrays>

Examples:

!X select: !Y select: !Z of: #(#((!Expr0 !Expr1 !Expr2) (!Expr3 !Expr4 !Expr5)) #((!Expr6 !Expr7 !Expr8) (!Expr9
!Expr10 !Expr11)))

0 select: 0 select: 0 of: #(((0 1) (2 3) ) ((5 6) (7 8)) ((10 11) (12 13)))

0 select: 1 select: 1 of: #(((0 1) (2 3) ) ((5 6) (7 8)) ((10 11) (12 13)))

2 select: 2 select: 2 of: #(((0 1) (2 3) ) ((5 6) (7 8)) ((10 11) (12 13)))

(4 s random abs * 3) select: (2 s random abs * 2) select: (1 s random abs) of: #( #(#(0 1) #(2 3) #(4 5) ) #( #(10
11) #(12 13) #(14 15) ) #(#(20 21) #(22 23) #(24 25) ) #(#(30 31) #(32 33) #(34 35)) )

226
setReset:
Categories: detection, logic, triggers

!SetWhenTrue setReset: !ResetWhenTrue


Range (0, 1)

When !SetWhenTrue becomes true (> 0), the value of setReset: becomes true (1) and remains true unless and until
!ResetWhenTrue becomes true(> 0). Otherwise, the expression is false (0).

setReset: is like a one-bit memory or a latch: you set it once and it retains its state forever (or until you reset it). You
can use it to indicate that !SetWhenTrue was ever true (even if it is not currently true).

Examples:

!SetWhenTrue setReset: !ResetWhenTrue

!Set setReset: !Reset

((!KeyNumber eq: 61) setReset: (!KeyNumber eq: 66))

(!confidence gt: (!Threshold + !Hyst)) setReset: (!confidence lt: (!Threshold - !Hyst))

(!First setReset: !Second) durationOfGate

227
shiftRegister: length:
Categories: sampleAndHold, capture

!Trigger shiftRegister: !ChangingExpression length: 2


Range [-Infinity, Infinity]

When triggered, capture the current value of !ChangingExpression and output the value captured on the previous
trigger.

When !Trigger becomes true (greater than 0), sample the current value of !ChangingExpression. Return the value
captured length-1 times previously until !Trigger becomes false (less than or equal to 0) and then true (greater than 0)
again

Examples:

!Trigger shiftRegister: !ChangingExpression length: 2

!KeyDown shiftRegister: !KeyNumber length: 2

(!Value gt: 0.5) shiftRegister: (0.01 s random) length: 2

((!Gate countTriggersMod: ?NumberVoices) eq: (?VoiceNumber - 1)) shiftRegister: !Rate length: 2

228
sign
Categories: arithmetic, sign

!PosOrNegNumber sign
Range [-1, 0, 1]

Returns -1 if the receiver is negative, 1 if the receiver is positive, 0 if the receiver is 0.

Examples:

!PosOrNegNumber sign

-8500000000 sign

5 sign

0 sign

1 s random sign

229
signalToHz
Categories: frequency, feature extraction

!anEventExpression01 signalToHz
Range [0, SR/2]

Assumes that !anEventExpression01 is a normalized frequency in the range of (0,1) and evaluates to a frequency in
hertz in the range (0, SR/2).

The receiver of this message is typically a Sound that extracts the frequency envelope from a signal (for example a
FrequencyTracker or SpectrumFundamental) or a Capytalk message that asks a PSI file for its normalized frequency
envelope (for example: ’aFileName.psi’ normFrequencyEnvelopeWithTimeIndex: <aTimeIndex>. The result is a
frequency in hertz (so it is not necessary to add hz after the expression, but will not hurt anything if you do). To
instead go from the full frequency range to the normalized range of (0,1), see hzToSignal

Examples:

!anEventExpression01 signalToHz

230
sin
Categories: arithmetic, trigonometric

!EventExpression sin
Range [-1,1]

Sine of an EventExpression.

Examples:

!EventExpression sin

0 sin

(1.5 * Double pi) sin

(2 * Double pi * (1 repeatingRamp)) sin

231
sinc
Categories: arithmetic, trigonometric

!anEventExpr sinc
Range [-infinity, infinity]

The sinc function is the same as (x sin / x), except at zero, where its value is one.

The sinc function is famous for being the impulse response of an ideal low pass filter.

Examples:

!anEventExpr sinc

0 sinc

(Double pi / 4) sinc

1 repeatingFullRamp sinc

232
sinh
Categories: arithmetic, trigonometric

!EventExpression sinh
Range [-Infinity,Infinity]

Hyperbolic sine of an EventExpression. The shape of the function looks like a fullRamp but with a slight curve to it. It
passes through zero when !EventExpression is 0.

Just as the point (cos t, sin t) is a point on a circle, the point (sinh t, sinh t) is a point on a hyperbola. The hyperbolic
sine is (e ** x - e ** x negated / 2).

For more information, see:


http://en.wikipedia.org/wiki/File:Sinh_cosh_tanh.svg

Examples:

!EventExpression sinh

0 sinh

1 sinh

-1 sinh

1 repeatingFullRamp sinh * 0.85

233
skipNext: triggersFrom:
Category: triggers & gates

!StartSkipping skipNext: !NumberOfTriggers triggersFrom: !aTriggerOrGateGenerator


Range (-1,1)

When !StartSkipping becomes true, skip the next !NumberOfTriggers generated by !aTriggerOrGateGenerator. Then,
do not skip again unless !StartSkipping changes to 0 and back to 1 again.

You can use this expression to trigger periodic breaks or silences in a stream of triggers or gates or to prevent a gate
or trigger generator from triggering immediately at the start of a Sound.

Examples:

!StartSkipping skipNext: !NumberOfTriggers triggersFrom: !aTriggerOrGateGenerator

1 skipNext: 1 triggersFrom: (1 bpm: !BPM)

((1 bpm: !BPM) triggerEvery: !Factor) skipNext: !NumberTriggers triggersFrom: (1 bpm: !BPM)

!StartSkipping skipNext: !NumberTriggers triggersFrom:


(1 brownianGate: 0.5 s
deviation: 0.125 s
minDur: 0.25 s
maxDur: 1 s
dutyCycle: 0.5)

234
smooth:
Categories: time functions, control modifiers

!FaderOrSoundOrExpression smooth: !Duration s


Range N/A

Transforms the discrete jumps in a controller value into a continuous linear interpolation from the previous value to
the current value. Imagine drawing a smooth line from the previous value of !FaderOrSoundOrExpression to the
current value over the course of !Duration. The value of this expression is updated once per millisecond. When you
first play a Sound, the value of this expression immediately jumps to current value of !FaderOrSoundOrExpression.

This is useful for smoothing out changes in controllers. If you hear zipper noise in an amplitude control or discrete
jumps in a frequency control, adding a smooth: to the parameter expression will result in smoother changes. See
also, smoothed, which is a shortcut for smooth: 100 ms. Note that the argument, !Duration s, is updated only when
!Duration changes; if you replace !Duration with a function of time, use the variant of this message, smoothFor:, which
continuously updates its argument when it is a function of time..

Examples:

!FaderOrSoundOrExpression smooth: !Duration s

(1 s random abs smooth: 1 s)

!KeyPitch smooth: !GlideTime s

((!Vowel of: #(609 400 238 325 360 415 300 400)) smooth: 0.25 s) hz

!WiiAccel smooth: 0.2 s

235
smooth: jump:
Categories: time functions, control modifiers

!anEventExpression smooth: !aDuration s jump: !aTrigger


Range N/A

Like smooth:, this is for smoothing out changes in the value of a controller or an expression by linearly interpolating
between the previous value and the current value of !anEventExpression. To stop smoothing and jump immediately to
the exact value of !anEventExpression, set !aTrigger to 1 (or any positive value). This jumps to !anEventExpression
and returns to smoothing future changes with linear interpolation.

See smooth: and smoothed for alternative smoothing expressions. This version of the expression can be useful when
you want an event to jump to an exact value each time it is retriggered. If you use a gate (like !KeyDown,
!FingerDown, or !PenDown), it detects the leading edge of that gate. To reset or retrigger again, the value of !aTrigger
must return to zero (or a negative value) first before you can retrigger again.

Examples:

!anEventExpression smooth: !aDuration s jump: !aTrigger

!Target smooth: 3 s jump: !Jump

!KeyTimbre smooth: 100 ms jump: !KeyDown

!KeyNumber smooth: !TimeConstant s jump: !KeyDown

(!PenY smooth: 0.1 s jump: !PenDown) ** 2

((!Vowel of: #(609 400 238 325 360 415 300 400)) smooth: 0.25 s jump: !PenDown) hz

!WiiAccel smooth: 0.2 s jump: (!WiiAccel gt: 0.2)

236
smoothed
Categories: time functions, control modifiers

!FaderOrSoundOrExpression smoothed
Range N/A

Transforms the discrete jumps in a changing controller value into a continuous linear interpolation from the previous
value to the current value. Imagine drawing a smooth line from the previous value of !FaderOrSoundOrExpression to
the current value over the course of 0.1 s. The value of this expression is updated once per millisecond. When you
first play the Sound, the initial value of this expression is the current value of !FaderOrSoundOrExpression.

This is useful for smoothing out changes in controllers. If you hear zipper noise in an amplitude control or discrete
jumps in a frequency control, adding smoothed to the parameter expression will result in smoother changes. See
also, smooth:, which takes an additional argument for the duration of the smoothing time.

Examples:

!FaderOrSoundOrExpression smoothed

(1 s random abs)

!KeyPitch smoothed

((!Vowel of: #(609 400 238 325 360 415 300 400)) smoothed) hz

!WiiAccel smoothed

237
smoothFor:
Categories: time functions, control modifiers

!FaderOrSoundOrExpression smoothFor: <durationExpression> s


Range N/A

Transforms the discrete jumps in a controller value into a continuous linear interpolation from the previous value to
the current value. Imagine drawing a smooth line from the previous value of !FaderOrSoundOrExpression to the
current value over the course of !Duration. The value of this expression is updated once per millisecond. When you
first play a Sound, the value of this expression immediately jumps to current value of !FaderOrSoundOrExpression.

This is useful for smoothing out changes in controllers. If you hear zipper noise in an amplitude control or discrete
jumps in a frequency control, adding a smoothFor: to the parameter expression will result in smoother changes. Note
that if <durationExpression> argument is a function of time, its value will continue to be updated (in contradistinction
to the smooth: version of the expression which does not periodically re-evaluate its argument. The smooth: message
is more suitable for constant smoothing times or durations under the control of a simple fader.

Examples:

!FaderOrSoundOrExpression smoothFor: <durationExpression> s

(1 s random abs smoothFor: (1 s random abs + 0.1) s)

!KeyPitch smoothFor: (0.1 + (1 repeatingTriangle: 4 s)) s

((!Vowel of: #(609 400 238 325 360 415 300 400)) smoothFor: 0.25 s) hz

!WiiAccel smoothFor: 0.2 s

238
smoothFor: jump:
Categories: time functions, control modifiers

!anEventExpression smoothFor: !aDuration s jump: !aTrigger


Range N/A

Like smoothFor:, this is for smoothing out changes in the value of a controller or an expression by linearly
interpolating between the previous value and the current value of !anEventExpression. To stop smoothing and jump
immediately to the exact value of !anEventExpression, set !aTrigger to 1 (or any positive value). This jumps to
!anEventExpression and returns to smoothing future changes with linear interpolation.

See smoothFor: and smoothed for alternative smoothing expressions. This version of the expression can be useful
when you want an event to jump to an exact value each time it is retriggered. If you use a gate (like !KeyDown,
!FingerDown, or !PenDown), it detects the leading edge of that gate. To reset or retrigger again, the value of !aTrigger
must return to zero (or a negative value) first before you can retrigger again.

Examples:

!anEventExpression smoothFor: !aDuration s jump: !aTrigger

!Target smoothFor: 3 s jump: !Jump

!KeyTimbre smoothFor: 100 ms jump: !KeyDown

!KeyNumber smoothFor: !TimeConstant s jump: !KeyDown

(!PenY smoothFor: 0.1 s jump: !PenDown) ** 2

((!Vowel of: #(609 400 238 325 360 415 300 400)) smoothFor: 0.25 s jump: !PenDown) hz

WiiAccel smoothFor: 0.2 s jump: (!WiiAccel gt: 0.2)

239
sortedOf:
Categories: arrays, choice, selection

!Order sortedOf: #(!Expr0 !Expr1 !Expr2)


Range (-infinity, infinity)

From an array of EventExpressions, select the !Order-th largest one. Positions in the array are numbered from (0 to
sizeOfArray - 1). !Order should be in the range of [0, (sizeOfArray - 1)) to access all elements of the array.

The array of EventExpresions is sorted into ascending order and indexed by !Order.

!Order is truncated and clipped to lie within (0, sizeOfArray - 1) so if your order is zero or smaller, you will get the
smallest element of the array or if your index is larger than the array size, you will get the largest element of the array.

Examples:

!Order sortedOf: #(!Expr0 !Expr1 !Expr2)

0 sortedOf: #( 8 7 6 5)

3 sortedOf: #( 8 7 6 5)

(!Fader01 * 3) sortedOf: #(!Expr0 !Expr1 !Expr2)

2 sortedOf: #(10 9 8 7)

(1 s random abs * 3) sortedOf: #(!Interval1 !Interval2 !Interval3)

240
sqrt
Categories: arithmetic, exponential, curve

!PositiveNumber sqrt
Range [0, infinity)

Square root. The number that, if multiplied by itself gives the receiver.

Examples:

!PositiveNumber sqrt

4 sqrt

9 sqrt

(8.1 * 8.1) sqrt

(50 **2) sqrt

89 squared sqrt

0 sqrt

1 repeatingRamp sqrt

241
squared
Category: arithmetic

!aValue squared
Range [0, infinity)

!aValue multiplied by itself. Equivalent to the expressions (!aValue ** 2) and (!aValue * !aValue)

The result of squaring a value is always positive so you could use squared to avoid generating negative numbers.
Squaring a number less than 1 makes that number smaller, so you could use squared to change a linear time function
into a curve.

Examples:

!aValue squared

1 s random squared

!Brightness squared

1 repeatingRamp squared

!LogFreq nn + (((!Trigger ramp: 2 s) squared) * 12 nn)

242
startQuantizedForBeats:
Category: looping

!LoopStart startQuantizedForBeats: !NumberBeatsInLoop


Range [0,1]

Typically used in the Start field of a Sample, this expression will quantize the !LoopStart to the nearest beat, given
that there are !NumberBeatsInLoop in the sample.

See also lengthQuantizedForStart:beats:

Examples:

!LoopStart startQuantizedForBeats: !NumberBeatsInLoop

!Reverse true: 0 false: (!LoopStart startQuantizedForBeats: !Beats)

243
stayOnFor:
Categories: triggers & gates, trigger modifiers

!Trigger stayOnFor: !OnDur s


Range [0,1]

When triggered, change from 0 to 1 and stay at 1 for !OnDur seconds.

Can be used to transform a trigger or a condition of unknown duration into a gate that stays on for a specified
duration.

Examples:

!Trigger stayOnFor: !OnDur s

!KeyDown stayOnFor: !OnDuration s

244
suffix2:
Categories: EventValues, Hot variables

!Fader suffix2: <aOneOrTwoDigitNumber>


Range N/A

See suffix:. You can use suffix2: to add mixtures of 1 and 2 digit numbers to the ends of EventValues, padding the
single digit numbers with a leading zero so that the controls automatically sort in alphabetical and numerical order in
the VCS.

Examples:

!Fader suffix2: <aOneOrTwoDigitNumber>

{1 to: 50 collect: [ :n | !Fader suffix2: n]}

245
suffix3:
Categories: EventValues, Hot variables

!Fader suffix3: <aNumber>


Range N/A

See suffix:. You can use suffix3: to add mixtures of 1, 2 and 3 digit numbers to the ends of EventValues, padding with
leading zeroes so that the controls automatically sort in alphabetical and numerical order in the VCS.

Examples:

!Fader suffix3: <aNumber>

{90 to: 100 collect: [ :n | !Fader suffix3: n]}

246
suffix4:
Categories: EventValues, Hot variables

!Fader suffix4: <aNumber>


Range N/A

See suffix:. You can use suffix4: to add mixtures of 1, 2, 3, and 4 digit numbers to the ends of EventValues, padding
with leading zeroes so that the controls automatically sort in alphabetical and numerical order in the VCS.

Examples:

!Fader suffix4: <aNumber>

{(100 to: 1000 by: 100) collect: [ :n | !Fader suffix4: n]}

247
suffix5:
Categories: EventValues, Hot variables

!Fader suffix5: <aNumber>


Range N/A

See suffix:. You can use suffix5: to add mixtures of 1, 2, 3, 4, and 5 digit numbers to the ends of EventValues,
padding with leading zeroes so that the controls automatically sort in alphabetical and numerical order in the VCS.

Examples:

!Fader suffix5: <aNumber>

{(100 to: 15000 by: 500) collect: [ :n | !Fader suffix5: n]}

248
suffix:
Categories: EventValues, Hot variables

!Fader suffix: <anObjectOrString>


Range N/A

To add a suffix to an EventValue name, send the suffix: message to the EventValue. The argument to suffix: is
converted to a string and added to the end of the EventValue name. You can use this message to assign unique
names or numbers to each controller in an array of algorithmically generated controls.

Technically, the suffix: message is a Smalltalk rather than Capytalk message since it takes effect during the compile
stage and creates the newly named EventValues before the Sound actually starts playing. If the suffix includes any
green variables, create the eventValue first (by sending asEventValue to a string name) and then send the suffix:
message to the newly created EventValue (for example, ’fader’ asEventValue suffix: (?VoiceNumber - 1)).

Examples:

!Fader suffix: <anObjectOrString>

{1 to: 9 collect: [ :n | !Fader suffix: n]}

{ | controls |
controls := OrderedCollection new.
1 to: 2 do: [ :n | 1 to: 2 do: [ :m |
controls add: (!Timbre suffix: (Array with: m with: n))]].
controls asArray}

(’BW_’ asEventValue suffix: ?VoiceNumber) * 10 hz

249
suffix: max:
Categories: EventValues, Hot variables

!Fader suffix: <aNumber> max: <maxNumber>


Range N/A

This is a special form of suffix: that adds enough leading zeros to accomodate the number of digits in maxNumber.
You can use this message to assign unique numbers to each controller in an array of algorithmically generated
controls in such a way that the alphabetical order is also the numeric order (so they will appear in order in the Virtual
Control Surface).

Like other flavors of the suffix: message, the suffix:max: message is a Smalltalk rather than Capytalk message since
it takes effect during the compile stage and creates the newly named EventValues before the Sound actually starts
playing.

Examples:

!Fader suffix: <aNumber> max: <maxNumber>

{1 to: 9 collect: [ :n | !Fader suffix: n max: 9]}

{90 to: 100 collect: [ :n | !Fader suffix: n max: 100]}

{3 to: 15 collect: [ :n | !Fader suffix: n max: 15]}

250
sustainBy:
Categories: triggers & gates, trigger modifiers

!Gate sustainBy: !SustainPedal


Range (0,1)

When !Gate becomes true (greater than 0), it will remain true as long as !SustainPedal also remains true.

Traditionally used in implementing a sustain pedal for keyboard controllers.

Examples:

!Gate sustainBy: !SustainPedal

!Trigger sustainBy: !BooleanExpression

!KeyDown sustainBy: !SustainPedal

!KeyDown sustainBy: !cc64

251
swarmFollowFromPosition: velocity: acceleration: friction:
Category: control modifiers

!Leader swarmFollowFromPosition: 0 velocity: !velocity acceleration: !acceleration friction: !damping


Range (-1,1)

When you move !Leader to a new position, the output of this expression approaches the value of !Leader at a rate
that is related to the product of !velocity and !acceleration, overshooting and oscillating around the target value at a
frequency of (!Velocity * !Acceleration) sqrt * 5. The amplitude of these oscillations decays at rate related to !Friction.

A more efficient and intuitive expression with the same behavior is followFromPosition:rate:friction:

Examples:

!Leader swarmFollowFromPosition: 0 velocity: !velocity acceleration: !acceleration friction: !damping

!Pos swarmFollowFromPosition: 0 velocity: 1 acceleration: (!Rate / 5.0) squared friction: !Frict

252
switchedOff
Categories: detection, logic, triggers, trigger modifiers

!Gate switchedOff
Range (0, 1)

Detect the falling edge of !Gate (to detect the rising edge, see switchedOn). When !Gate changes from non-zero to
zero-or-negative, switchedOff becomes true (1) until the next time the expression is evaluated; it is false (0) at all
other times.

This can be useful when you want to transform a gate into an instantaneous trigger. switchedOff detects a CHANGE,
not the state. If you send switchedOff to an expression that involves time (and thus has to be evaluated once per
millisecond), then switchedOff may be true for one millisecond only.

Examples:

!Gate switchedOff

!Button switchedOff

!KeyDown switchedOff

(1 bpm: (0.2 s random * 500)) switchedOff

253
switchedOn
Categories: detection, logic, triggers, trigger modifiers

!Gate switchedOn
Range (0, 1)

Detect the rising edge of !Gate (to detect the falling edge, see switchedOff). When !Gate changes to a non-zero value
from a zero-or-negative vaue, switchedOn becomes true (1) until the next time the expression is evaluated; it is false
(0) at all other times.

This can be useful when you want to transform a gate into an instantaneous trigger.switchedOn detects a CHANGE,
not the state. If you send switchedOn to an expression that involves time (and thus has to be evaluated once per
millisecond), then switchedOn may be true for one millisecond only.

Examples:

!Gate switchedOn

!Button switchedOn

!KeyDown switchedOn

(1 bpm: (0.2 s random * 500)) switchedOn

254
tan
Categories: arithmetic, trigonometric

!anEventExpr tan
Range [-infinity, infinity]

The tangent of a value is the ratio of its sine to its cosine. In other words, (!anEventExpr tan) is equivalent to
(!anEventExpr sin / !anEventExpr cos).

You can use tan to warp a linear time function or fader such that it is slightly larger for negative values and slightly
smaller for positive values. The trigonometric functions (such as sin, cos, tan) are all functions of angle. Imagine a
circle whose center is at the origin; now imagine drawing a line from the origin out to intersect the circle at point P,
forming an angle between the x-axis and the line. The sine of that angle is the height of point P (its y-position). The
cosine of that angle is the x-position of P. And the tangent is slope of the line from the origin to P.

Examples:

!anEventExpr tan

0 tan

(Double pi / 4) tan

(Double pi / 4 * !aValue) tan

(!WarpFactor * !aValue) tan / !WarpFactor tan

1 repeatingFullRamp tan / (1 tan)

255
tenExp
Categories: arithmetic, exponential

!Exponent tenExp
Range (0, infinity)

10.0 raised to the power of !Exponent. It is equivalent to 10.0d ** !Exponent

You can use exp, twoExp, and tenExp to take a linear input value and make it grow exponentially.

Examples:

!Exponent tenExp

0 tenExp

1 tenExp

-1 tenExp

1 repeatingFullRamp tenExp / 10.0

256
threshold:
Categories: detection, test, logic

!EventExpr threshold: !Threshold


Range (0, 1)

True when the value of !EventExpr is greater than or equal to the value of !Threshold. Same as !EventExpr ge:
!Threshold.

See also the Kyma Sound called Threshold (which also includes a hysteresis value).

Examples:

!EventExpr threshold: !Threshold

(1 ramp threshold: 0.5

!Amp threshold: !MinAmp

257
threshold: hysteresis:
Categories: detection, test, logic

!EventExpr threshold: !Threshold hysteresis: !Hysteresis


Range (0, 1)

True when the value of !EventExpr is greater than or the value of !Threshold + !Hysteresis. False when !EventExpr is
less than or equal to !Threshold - !Hysteresis.

Hysteresis is the tendency for the result to stick in its current state. When this expression is true, !EventExpr has to do
more than simply drop below the threshold to become false; it must drop below the (threshold - hysteresis) before it
will change state. Similarly, if the expression is false, the !EventExpr must exceed the threshold PLUS the
hysteresis it must go beyond the threshold in order to change state from false to true. This can come in handy when
!EventExpr has a jittery value that keeps crossing the threshold and you do not want the expression to keep changing
state. See also threshold: and the Kyma Sound called Threshold (which also includes a hysteresis value).

Examples:

!EventExpr threshold: !Threshold hysteresis: !Hysteresis

(1 ramp threshold: 0.5 hysteresis: 0.1

!Amp threshold: !MinAmp hysteresis: !Hysteresis

258
tick
Category: triggers & gates

!aDuration s tick
Range [-1,1]

Generates a repeating gate: once every !Duration s the value changes from 0 to 1 and stays at 1 for half the !Duration
before dropping back to 0 again. To allow for voice-stealing, the value drops to -1 for 5 milliseconds at the beginning
of each gate.

The tick message generates gates with voice-stealing: at the beginning of each gate, the value goes to -1 for 5
milliseconds before it jumps up to 1; this allows the currently playing envelope to quickly ramp down to 0 before
beginning a new attack. To defeat the voice stealing, take the absolute value of the tick expression, for example: 6 s
tick abs. !aDuration s tick is equivalent to the expression: 1 bpm: !aDuration s bpm removeUnits dutyCycle: 0.5

Examples:

!aDuration s tick

0.2 s tick

0.2 s random abs * 0.2 s tick seed: 898

(1 s tick randomWalk abs s tick seed: 6) nextRandExp s

259
timbre
Category: keyboard events

!Note timbre
Range N/A

The timbre of the given bundled note event.

The predefined Event Variable !Note bundles the pitch, velocity, timbre and gate of an incoming keyboard event into a
single value. Use this message to extract the timbre from the bundle.

The expression !Note timbre is functionally equivalent to !KeyTimbre.

Examples:

!Note timbre

260
toggleWhen:
Category: triggers & gates

!aTrigger toggleWhen: !aBooleanExpression


Range [-1, 1]

Toggles between 0 and 1 each time !aTrigger changes from false (<=0) to true (>0) and !aBooleanExpression is also
true (>0).

You can use toggleWhen: to toggle only under a certain combination of circumstances, for example only when a key
is down and the pitch is within a certain range. Or, for example, to toggle specific voices in a Replicator, channelizer,
or MIDIVoice. For a voice-stealing gate (rather than a toggle), see gateWhen:

Examples:

!aTrigger toggleWhen: !aBooleanExpression

!KeyNumber toggleWhen: (!KeyNumber eq: 61)

!KeyDown toggleWhen: ((!KeyNumber gt: 60) * (!KeyNumber lt: 72))

0.25 s tick toggleWhen: (0.25 s random gt: 0.5)

!KeyDown toggleWhen: (!KeyNumber eq: (60 + ?VoiceNumber - 1))

!OnOff toggleWhen: (((1 bpm: !BPM) countTriggersMod: ?NumberVoices) eq: (?VoiceNumber - 1))

1 toggleWhen: (((1 bpm: !BPM) nextChaotic: !k seed: 0.07 reset: !Reset) gt: !Thresh)

261
trackAndHold:
Categories: sampleAndHold, trackAndHold, capture

!Gate trackAndHold: !ChangingExpression


Range [-Infinity, Infinity]

While !Gate is true (greater than 0), track the value of !ChangingExpression. When !Gate becomes false (less than or
equal to 0), hold the current value of !ChangingExpression until !Gate becomes true again.

This expression holds when the !Gate becomes false and tracks while the !Gate is true.

Examples:

!Gate trackAndHold: !ChangingExpression

(!Value gt: !Threshold) trackAndHold: !Value

(!Amp gt: !Threshold) trackAndHold: !Freq

(!KeyTimbre gt: 0.75) trackAndHold: !KeyPitch

262
transposeBySteps: scaleIndex: tonic:
Categories: pitch, scales, tuning, frequency

!aPitch transposeBySteps: !TrspScaleSteps0 scaleIndex: !ScaleIndex012 tonic: !aNoteNumber


Range (0 nn, 127 nn)

Given !aPitch, this message returns that pitch transposed by !TrspScaleSteps0 (where 0 equals no transposition)
within the traditional equal-tempered musical scale indexed as follows:

Index Name Intervals

0 PentatonicMinor #(0 3 5 7 10 12)

1 PentatonicMajor #(0 2 4 7 9 12)

2 Wholetone #(0 2 4 6 8 10 12)

3 Major #(0 2 4 5 7 9 11 12)

4 Dorian #(0 2 3 5 7 9 10 12)

5 Phrygian #(0 1 3 5 7 8 10 12)

6 Lydian #(0 2 4 6 7 9 11 12)

7 Mixolydian #(0 2 4 5 7 9 10 12)

8 Aeolian #(0 2 3 5 7 8 10 12)

9 Locrian #(0 1 3 5 6 8 10 12)

10 Octatonic2 #(0 2 3 5 6 8 9 11 12)

11 Octatonic1 #(0 1 3 4 6 7 9 10 12)

12 Chromatic #(0 1 2 3 4 5 6 7 8 9 10 11 12)

This is the form of the expression that you would use in a Frequency parameter field. If you need an interval instead
(for example, in the SimplePitchShifter), see transpositionIntervalBySteps:scaleIndex:tonic:

Examples:

!aPitch transposeBySteps: !TrspScaleSteps0 scaleIndex: !ScaleIndex012 tonic: !aNoteNumber

!KeyPitch transposeBySteps: !StepTransposition scaleIndex: !ScaleIndex012 tonic: !Tonic

263
transposeWithVoicing: scaleIndex: tonic:
Categories: pitch, scales, tuning, frequency

!aPitch transposeWithVoicing: <anArrayOfInStepToOutStep> scaleIndex: !ScaleIndex012 tonic: !aNoteNumber


Range 0 nn, 127 nn)

Given !aPitch, this message returns a transposed version of that pitch by first looking at what step of the scale this
pitch is and using that step as an index into <anArrayOfInStepToOutStep> to find the output step (where 1 is tonic) of
the traditional equal-tempered musical scale indexed as follows:

Index Name Intervals

0 PentatonicMinor #(0 3 5 7 10 12)

1 PentatonicMajor #(0 2 4 7 9 12)

2 Wholetone #(0 2 4 6 8 10 12)

3 Major #(0 2 4 5 7 9 11 12)

4 Dorian #(0 2 3 5 7 9 10 12)

5 Phrygian #(0 1 3 5 7 8 10 12)

6 Lydian #(0 2 4 6 7 9 11 12)

7 Mixolydian #(0 2 4 5 7 9 10 12)

8 Aeolian #(0 2 3 5 7 8 10 12)

9 Locrian #(0 1 3 5 6 8 10 12)

10 Octatonic2 #(0 2 3 5 6 8 9 11 12)

11 Octatonic1 #(0 1 3 4 6 7 9 10 12)

12 Chromatic #(0 1 2 3 4 5 6 7 8 9 10 11 12)

This is the form of the expression you would use in a Frequency field. For an Interval field (for example in the
SimplePitchShifter), see transpositionIntervalWithVoicing:scaleIndex:tonic:

Examples:

!aPitch transposeWithVoicing: <anArrayOfInStepToOutStep> scaleIndex: !ScaleIndex012 tonic: !aNoteNumber

(!KeyPitch transposeWithVoicing: (1 to: 8 collect: [:i | !VoiceStep suffix: i]) scaleIndex: !ScaleIndex012 tonic:
!Tonic) + (12 * !Octave) nn

264
transpositionIntervalBySteps: scaleIndex: tonic:
Categories: pitch, scales, tuning, frequency

!aPitch transpositionIntervalBySteps: !TrspScaleSteps0 scaleIndex: !ScaleIndex012 tonic: !aNoteNumber


Range 0 nn, 127 nn)

Given !aPitch, this message returns the interval in half steps that, when added to !aPitch gives you that pitch
transposed by !TrspScaleSteps0 (where 0 equals no transposition) within the traditional equal-tempered musical
scale indexed as follows:

Index Name Intervals

0 PentatonicMinor #(0 3 5 7 10 12)

1 PentatonicMajor #(0 2 4 7 9 12)

2 Wholetone #(0 2 4 6 8 10 12)

3 Major #(0 2 4 5 7 9 11 12)

4 Dorian #(0 2 3 5 7 9 10 12)

5 Phrygian #(0 1 3 5 7 8 10 12)

6 Lydian #(0 2 4 6 7 9 11 12)

7 Mixolydian #(0 2 4 5 7 9 10 12)

8 Aeolian #(0 2 3 5 7 8 10 12)

9 Locrian #(0 1 3 5 6 8 10 12)

10 Octatonic2 #(0 2 3 5 6 8 9 11 12)

11 Octatonic1 #(0 1 3 4 6 7 9 10 12)

12 Chromatic #(0 1 2 3 4 5 6 7 8 9 10 11 12)

This is the form of the expression that you would use in the Interval field of the SimplePitchShifter. It would not be the
expression you would use in a Frequency field; for that, see transposeBySteps:scaleIndex:tonic:

Examples:

!aPitch transpositionIntervalBySteps: !TrspScaleSteps0 scaleIndex: !ScaleIndex012 tonic: !aNoteNumber

!KeyPitch transpositionIntervalBySteps: !StepTransposition scaleIndex: !ScaleIndex012 tonic: !Tonic

265
transpositionIntervalWithVoicing: scaleIndex: tonic:
Categories: pitch, scales, tuning, frequency

!aPitch transpositionIntervalWithVoicing: <anArrayOfInStepToOutStep> scaleIndex: !ScaleIndex012 tonic:


!aNoteNumber
Range 0 nn, 127 nn)

Given !aPitch, this message returns an interval in half steps by first looking at what step of the scale !aPitch is and
using that step as an index into <anArrayOfInStepToOutStep> to find the output step (where 1 is tonic) of the scale. If
you were to add that interval to !aPitch, you would get that step of the traditional equal-tempered musical scale
indexed as follows:

Index Name Intervals

0 PentatonicMinor #(0 3 5 7 10 12)

1 PentatonicMajor #(0 2 4 7 9 12)

2 Wholetone #(0 2 4 6 8 10 12)

3 Major #(0 2 4 5 7 9 11 12)

4 Dorian #(0 2 3 5 7 9 10 12)

5 Phrygian #(0 1 3 5 7 8 10 12)

6 Lydian #(0 2 4 6 7 9 11 12)

7 Mixolydian #(0 2 4 5 7 9 10 12)

8 Aeolian #(0 2 3 5 7 8 10 12)

9 Locrian #(0 1 3 5 6 8 10 12)

10 Octatonic2 #(0 2 3 5 6 8 9 11 12)

11 Octatonic1 #(0 1 3 4 6 7 9 10 12)

12 Chromatic #(0 1 2 3 4 5 6 7 8 9 10 11 12)

For example, this is the expression you would use to compute the Interval parameter for SimplePitchShifter. It would
not be the expression you would use in a Frequency field; for that, see transposeWithVoicing:scaleIndex:tonic:

Examples:

!aPitch transpositionIntervalWithVoicing: <anArrayOfInStepToOutStep> scaleIndex: !ScaleIndex012 tonic:


!aNoteNumber

(!KeyPitch transpositionIntervalWithVoicing: (1 to: 8 collect: [:i | !VoiceStep suffix: i]) scaleIndex:


!ScaleIndex012 tonic: !Tonic) + (12 * !Octave) nn

266
triangle
Categories: envelopes, time functions

!Trigger triangle
Range (0,1)

When !Trigger changes from false (<= 0) to true (> 0), generate a linear function that changes from 0, to 1, and back
to 0 again, exactly once over the course of 1 s.

See also triangle: and repeatingTriangle:

Examples:

!Trigger triangle

(1 bpm: 30) triangle

!Trigger triangle

267
triangle:
Categories: envelopes, time functions

!Trigger triangle: !Duration s


Range (0,1)

When !Trigger changes from false (<= 0) to true (> 0), generate a linear function that changes from 0, to 1, and back
to 0 again, exactly once over the course of !Duration s.

Generate a triangle-shaped function whenever !Trigger changes from 0 to 1 (or in fact from any number less than or
equal to zero to a number greater than 0). To generate a triangle function that repeats as long as the gate is true, see
repeatingTriangle:

Examples:

!Trigger triangle: !Duration s

1 triangle: 2 s

!Trigger triangle: !Dur s

((1 bpm: !BPM) triangle: !BPM bpm s * !Duty)

268
triggerEvery:
Categories: triggers & gates, trigger modifiers

!TriggerGenerator triggerEvery: !Number


Range (0,1)

Emit a trigger every !Number times that !TriggerGenerator emits a trigger.

Emit a trigger once every !Number ticks.

Examples:

!TriggerGenerator triggerEvery: !Number

(1 bpm: !BPM) triggerEvery: !Number

(1 bpm: !BPM) triggerEvery: ((((1 bpm: !BPM) triggerEvery: !Number) nextIndexMod: 5) of: #(2 3 5 7 11))

269
triggerEvery: offset:
Categories: triggers & gates, trigger modifiers

!EventGenerator triggerEvery: !N offset: !Offset


Range (0,1)

Emits every !Nth event coming from !EventGenerator (skips the other !N-1 events). Offset this pattern by a positive
integer !Offset (less than !N, greater than or equal to 0).

In terms of beats, if you set the first argument to the number of beatsPerBar and the offset argument to the
numberOfRests, the result is a pattern of numberOfRests preceeding one beat per bar. In a Replicator, setting the
first argument to ?NumberVoices and the offset argument to (?VoiceNumber - 1), you can create a gate that will
respond in a round-robin pattern and allow for polyphonic overlap of the replicated copies.

Examples:

!EventGenerator triggerEvery: !N offset: !Offset

(1 bpm: !BPM) triggerEvery: !BeatsPerBar offset: !Rests

((1 randomTrigger: 1 s) seededWith: 29) triggerEvery: !count offset: !Offset

!Gate triggerEvery: ?NumberVoices offset: ?VoiceNumber - 1

270
triggerEvery: reset:
Categories: triggers & gates, trigger modifiers

!TriggerGenerator triggerEvery: !Number reset: !Reset


Range (0,1)

Like triggerEvery: except with an option to reset the count when !Reset is true (greater than 0). Emit a trigger every
!Number times that !TriggerGenerator emits a trigger.

Emit a trigger once every !Number ticks. Restart the count over again from the beginning whenever !Reset becomes
true.

Examples:

!TriggerGenerator triggerEvery: !Number reset: !Reset

(1 bpm: !BPM) triggerEvery: !Number reset: !KeyDown

271
triggerEverySampled:
Categories: triggers & gates, trigger modifiers

!TriggerGenerator triggerEverySampled: !Number


Range (0,1)

Like triggerEvery: except that !Number is sampled when you start counting so it will not change until after you finish
counting up to !Number. Emit a trigger every !Number times that !TriggerGenerator emits a trigger.

Use the sampled version of the expression when !Number is changing (and when you would like to finish counting up
to the previous value of !Number before switching to the new value for !Number).

Examples:

!TriggerGenerator triggerEverySampled: !Number

(1 bpm: !BPM) triggerEverySampled: !Number

(1 bpm: !BPM) triggerEverySampled: ((((1 bpm: !BPM) triggerEverySampled: !Number) nextIndexMod: 5) of: #(
2 3 5 7 11))

272
triggerTimeToNext:
Category: triggers & gates

!On triggerTimeToNext: !TimeIntervalBetweenTriggers


Range (0,1)

While !On, this expression generates a (1 ms duration) trigger every !TimeIntervalBetweenTriggers. For example, the
expression (1 triggerTimeToNext: 1 s) would generate a 1 ms trigger once per second. See also
gateTimeToNext:dutyCycle:

Each time a trigger is emitted, the value of !TimeIntervalBetweenTriggers is sampled and its value is used as the time
to wait until emitting the next trigger. !On turns the generation of triggers on or off. The minimum time interval between
triggers is 2 ms. The duration of each generated trigger is 1 ms. Triggers are positive 1 only (no voice stealing).

If !TimeIntervalBetweenTriggers is an expression that depends on time, it is always evaluated, but its value is
sampled only when the trigger is emitted. To evaluate the expression only when trigger is emitted use ttn: insead.

For randomly spaced triggers, you can use brownianTrigger:, normalTrigger:, randomTrigger:, or randExpTrigger:.

Examples:

!On triggerTimeToNext: !TimeIntervalBetweenTriggers

(1 triggerTimeToNext: !Random abs twoLog negated s) seededWith: 0.2),


dur

| durs indx |
durs := #(1 2 1 2).
indx := EventVariable new initialValue: -1 .
(((1 triggerTimeToNext: (((indx <~ (indx + 1)) mod: durs size) of: durs) s) nextIndexMod: durs size) of: durs)

273
tripWires:
Category: triggers & gates

!aValue tripWires: <a grid spacing or an array of markers>


Range [0,1]

Imagine that there are trip wires along the full range of !aValue. The wires are spaced evenly by !GridSpacing or
non-uniformly at the positions in an Array such as #(!Wire1 !Wire2 !Wire3). Each time !aValue crosses one of the trip
wires, this expression emits a trigger (the value 1 followed by 0). A trigger is emitted only when the value *crosses* a
wire, not when it is exactly equal to the wire position. For that reason, no triggers are emitted at the extreme (highest
or lowest) values of !aValue.

You can think of the receiver as a strumming function; this expression emits a trigger each time the strum crosses
one of the wires. By using an Array of wire positions and a periodic input, you can also generate different rhythmic
patterns that always re-align on the hyperbar (or the period of the input function). The shortest time between triggers
is 10 ms.

Examples:

!aValue tripWires: <a grid spacing or an array of markers>

10 tripWires: 0.1

0.25 tripWires: #(!Marker1 !Marker2 !Marker3)

!aValue tripWires: 0.1

{(1 repeatingTriangle: (!BPM bpm s * 4)) tripWires: #(!W1 !W2 !W3 !W4)}

274
true: false:
Categories: conditional, Boolean, true, false, logic

!TestExpr true: !ValueIfTrue false: !ValueIfFalse


Range [-Infinity, Infinity]

When !TestExpr is true (non-zero), output the !ValueIfTrue. When it is false (less than or equal to 0), output the
!ValueIfFalse.

See false:true: if you prefer to put the condition that should be evaluated if false as the first expression.

Examples:

!TestExpr true: !ValueIfTrue false: !ValueIfFalse

!Invert true: !Interval negated false: !Interval

1 true: 512 false: 256

(1 s random gt: 0.5) true: ((1 s tick nextIndexMod: 4) of: #(60 62 65 67 69)) false: !KeyNumber)

275
trueForLast:
Categories: detection, test, logic, controllers

!Controller trueForLast: !NumberMeasurements


Range (0, 1)

Test the stability of a !Controller (or a feature extracted from the audio signal) by detecting whether it has remained
true (1) for the last !NumberMeansurements.

Useful for detecting when a physical controller is ON (1) or when a certain condition has remained true (1) for the last
!NumberMeasurements. When the condition first becomes true, this expression becomes true after
!NumberMeasurements milliseconds. When the condition becomes false, this expression becomes immediately false.
This could also be useful for filtering out transient conditions that last for less than !NumberMeasurements.

Examples:

!Controller trueForLast: !NumberMeasurements

(!Amp gt: !Thresh) trueForLast: 1000

!FootPedal trueForLast: 1000

((!WiiAccelX gt: 0.2) * (!WiiPitch gt: 0)) trueForLast: 1000

276
trueIf: sameForLast:
Categories: detection, test, logic, controllers

!Trigger trueIf: !EventExpr sameForLast: !NumberRepetitions


Range (0, 1)

If !Trigger becomes true and !EventExpr has the same value it had on the previous !NumberRepetition triggers, return
a 1. Otherwise return 0..

Detect when a value has been repeated a given number of times. Useful for detecting specific numbers of repetitions.

Examples:

!Trigger trueIf: !EventExpr sameForLast: !NumberRepetitions

!KeyDown trueIf: !KeyNumber sameForLast: !NumberRepetitions

((1 bpm: !BPM) trueIf: ((1 bpm: !BPM) nextRandom * 5 of: #(57 59 62 64 68)) sameForLast: !NumberRepetitions)
seed: 67

277
truncated
Categories: arithmetic, integer, rounding

!FractionalNumber truncated
Range [-infinity, infinity]

Strip off the fractional part of the number to leave an integer.

Truncation removes the fractional part of the number, resulting in the next smaller integer for positive numbers (and
the next larger integer for negative numbers).

Examples:

!FractionalNumber truncated

3.1 truncated

-3.9 truncated

278
truncateTo:
Categories: arithmetic, rounding

!aValue truncateTo: !aNumber


Range N/A

Truncate !aValue to nearest multiple of !aNumber. For example, to truncate !aValue to two decimal points, you would
use !aValue truncateTo: 0.01. To truncate !aValue the nearest multiple of 4, you would use !aValue truncateTo: 4.

Computed as (!aValue / !aNumber) truncated * !aNumber

Examples:

!aValue truncateTo: !aNumber

Double pi truncateTo: 0.01

1024 truncateTo: 10

0.6 truncateTo: 0.25

!Interval truncateTo: 12

279
ttn:
Category: triggers & gates

!Gate ttn: <anEventVariableOrValueOrExpressionThatDoesNotDependOnTime>


Range (0,1)

For randomly spaced triggers, use brownianTrigger: (for durations between triggers generated by a random walk),
normalTrigger: (for random durations between triggers drawn from a normal distribution) randomTrigger: (for random
durations between triggers drawn from a uniform distribution), or randExpTrigger: (for random durations between
triggers drawn from an exponential distribution).

The interesting applications of ttn: require the use of an EventVariable. Please see the examples.

Each time a trigger is emitted, the value of !EventExpression is sampled and its value is used as the time to wait until
emitting the next trigger. Generates a trigger at the time interval(s) generated by !EventExpression. !Gate turns the
generation of triggers on or off. A trigger is generated when the gate turns off (<= 0) and then on (> 0) again. The
minimum time interval between triggers is 2 ms. The duration of each generated trigger is 1 ms. Triggers are positive
1 only (no voice stealing).

Examples:

!Gate ttn: <anEventVariableOrValueOrExpressionThatDoesNotDependOnTime>

| dur |

dur := EventVariable new.


((1 ttn: (dur <~ !Random abs twoLog negated) s) seed: 0.2),
dur

| durs indx |
durs := #(1 2 1 2).
indx := EventVariable new initialValue: -1 .
(((1 ttn: (((indx <~ (indx + 1)) mod: durs size) of: durs) s) nextIndexMod: durs size) of: durs)

280
turnOnAfter:
Categories: triggers & gates, trigger modifiers

!Trigger turnOnAfter: !Delay s


Range [0,1]

When triggered, wait for !Delay seconds, change from 0 to 1, stay at 1 unless or until triggered again.

This could be used as a watchdog or deadmans switch since it will stay at 0 as long as you keep triggering it, but as
soon as you forget to trigger it within a certain amount of time, it will go to 1.

Examples:

!Trigger turnOnAfter: !Delay s

(!Trigger turnOnAfter: 1 s) gateWhen: !toggle

!clickEvery5seconds turnOnAfter: 5 s

281
turnOnAfter: for:
Categories: triggers & gates, trigger modifiers

!Trigger turnOnAfter: !Delay s for: !OnDuration s


Range [0,1]

When triggered, wait for !Delay seconds, change from 0 to 1, stay at 1 for !OnDuration seconds, then return to 0.

Useful for triggering several parameter controls at different times.

Examples:

!Trigger turnOnAfter: !Delay s for: !OnDuration s

(!Trigger turnOnAfter: 1 s for: 5 s) ramp: 5 s

3 e flat - (((!Trigger turnOnAfter: 3 s for: 10 s) ramp: 10 s) * 12 nn)

!KeyDown turnOnAfter: ((?VoiceNumber - 1) * !Delay s) for: !OnDuration s

282
turnOnFor:
Categories: triggers & gates, trigger modifiers

!Trigger turnOnFor: !OnDur s


Range [0,1]

See stayOnFor:

Used for extending the duration of a trigger, turning it into a gate that stays on for the specified duration

Examples:

!Trigger turnOnFor: !OnDur s

283
twoExp
Categories: arithmetic, exponential

!Exponent twoExp
Range (0, infinity)

2 raised to the power of !Exponent.

To convert an interval in pitch space into a linear frequency scale, raise 2 to the power of the ratio of the desired
interval to an octave: (!Interval / 12.0) twoExp

Examples:

!Exponent twoExp

0 twoExp

1 twoExp

-1 twoExp

(!Interval / 12.0) twoExp

1 repeatingFullRamp twoExp - 0.5 / (2 - 0.5)

284
twoLog
Categories: arithmetic, exponential

!Number twoLog
Range (-infinity, infinity)

The log base 2 of a Number.

If you raised 2 to the power of the result of this expression, you would get the receiver. !Anything twoExp twoLog =
!Anything

Examples:

!Number twoLog

2 twoLog

0.5 twoLog

4 twoLog

2 twoExp twoLog

1 repeatingFullRamp twoExp - 0.5 / (2 - 0.5)

285
twoLogistic
Categories: arithmetic, exponential, curve

!Number twoLogistic
Range [0, 1)

Logistic function, base 2.

Returns the value of the logistic function base 2. That is, (1 + x negated twoExp) inverse.

Examples:

!Number twoLogistic

0 twoLogistic

9 twoLogistic

-9 twoLogistic

1 repeatingFullRamp twoLogistic

286
usec
Categories: units, unitsOfFrequencyAndDuration

!aDurationInMicroseconds usec
Range N/A

Microseconds (usec) is a unit of time or duration in Capytalk. One microsecond is one one-millionth of a second.
When you evaluate durations, such as m (minutes), h (hours), day (days), ms (milliseconds), or usec (microseconds),
the result will be expressed in terms of seconds (s).

In Kyma, a unit of frequency or duration is a message that you send to a number (or EventValue) to create a new
object called a ScalarWithUnits. You can cascade units of frequency and duration to convert from one to another (for
example, from frequency to pitch or from duration to a tempo in terms of beats-per-minute or even from a duration to
a frequency (where the duration is interpreted as the length of one cycle at that frequency). Try selecting and
evaluating some of the expressions below using Ctrl+Y (Edit>Evaluate).

Examples:

!aDurationInMicroseconds usec

!Duration usec hz

1000000 usec

287
velocity
Category: keyboard events

!Note velocity
Range N/A

The velocity of the given bundled note event.

The predefined Event Variable !Note bundles the pitch, velocity, timbre and gate of an incoming keyboard event into a
single value. Use this message to extract the velocity from the bundle.

The expression !Note velocity is functionally equivalent to !KeyVelocity.

Examples:

!Note velocity

288
vmax:
Categories: arithmetic, comparison

!anExpression vmax: !anotherExpression


Range (-infinity, infinity)

vmax: (variable max) returns the larger of !anExpression and !anotherExpression.

If you are taking the max of a Smalltalk or question mark variable and an EventExpression, use vmax: in place of
max:. For example, to take the max of the voice number and an EventExpression in a Replicator, you would use
vmax: because the receiver is a variable, ?VoiceNumber.

Examples:

!anExpression vmax: !anotherExpression


---
|v|
v := 0.1.
v vmax: !anotherExpression
---
?VoiceNumber vmax: !Value

289
vmin:
Categories: arithmetic, comparison

!anExpression vmin: !anotherExpression


Range (-infinity, infinity)

vmin: (variable min) returns the smaller of !anExpression and !anotherExpression.

If you are taking the min of a Smalltalk or question mark variable and an EventExpression, use vmin: in place of min:.
For example, to take the min of the voice number and an EventExpression in a Replicator, you would use vmin:
because the receiver is a variable, ?VoiceNumber.

Examples:

!anExpression vmin: !anotherExpression


---
|v|
v := 0.1.
v vmin: !anotherExpression
---
?VoiceNumber vmin: !Value

290
warpBy:
Category: control modifiers

!ValuePlusMinus1 warpBy: !WarpPlusMinus1


Range [-1,1]

Maps an input control [-1,1] through an adjustable nonlinear warping function that can vary from logarithmic, to linear,
to exponential. Useful for warping linear controls to be more logarithmic or more exponential, for tilting the brightness
by controlling spectral amplitudes, compressing/expanding clusters of frequencies or pan positions, warping a uniform
random distribution, and other situations where you would like an adjustable nonlinear control signal.

A control mapping function that is linear when !WarpFactor = 0; a logarithmic curve when !WarpFactor < 0; an
exponential curve when !WarpFactor > 0. For all input values [-1,1], the curves are fixed at -1, 0 and 1 but (potentially)
warped in between those fixed points. For example when !WarpFactor > 0, values of the input are mapped to smaller
output values, but input values of -1, 0 and 1 are unmodified. Conversely, when the !WarpFactor argument is
negative, input values are mapped to larger output values, but again, -1, 0 and 1 remain fixed. (See the example
’warpBy: to distribute frequencies & pan positions’, below)

Examples:

!ValuePlusMinus1 warpBy: !WarpPlusMinus1

0 to: 7 collect: [ :in | in / 7 warpBy: 0.0625]

0 to: 7 collect: [ :in | in / 7 warpBy: -0.0625]

0 to: 7 collect: [ :in | in / 7 warpBy: 0]

1 repeatingFullRamp warpBy: !direction

(!Gate nextRandom abs seededWith: ?VoiceNumber / ?NumberVoices) warpBy: !warp

291
whileTrue: timeStep:
Categories: conditional, Boolean, true, false, logic

!TestExpr whileTrue: !ValueIfTrue timeStep: !Duration s


Range [-Infinity, Infinity]

While !TestExpr is true (non-zero), output the !ValueIfTrue. When !TestExpr is not true, output the previous value
(initially this is 0). Test the value of !EventExpr once every !Duration in time units.

Examples:

!TestExpr whileTrue: !ValueIfTrue timeStep: !Duration s


---
((!WiiPitch gt: 0.2)
whileTrue: (!WiiPitch * 12)
timeStep: 0.2 s)

292
withAdditionalSelectors: of:
Categories: arrays, choice, selection

!Row withAdditionalSelectors: #(!Col1 !Col2 !Col3) of: # ((((!Fader01 !Fader02) (!Fader03 !Fader04)) ((!Fader05
!Fader06) (!Fader07 !Fader08))) (((!Fader09 !Fader10) (!Fader11 !Fader12)) ((!Fader13 !Fader14) (!Fader15
!Fader16))))
Range (-infinity, infinity)

This is for accessing an arbitrarily deeply nested array (of more than 3 dimensions). The first (row) index is the
receiver and the array of additional selectors are used to refine the selection.

Each !Index is truncated and clipped to lie within (0, sizeOfArray - 1) so if your index is larger than the array size, you
will get the last element of the array.

Examples:

!Row withAdditionalSelectors: #(!Col1 !Col2 !Col3) of: # ((((!Fader01 !Fader02) (!Fader03 !Fader04)) ((!Fader05
!Fader06) (!Fader07 !Fader08))) (((!Fader09 !Fader10) (!Fader11 !Fader12)) ((!Fader13 !Fader14) (!Fader15
!Fader16))))

3 withAdditionalSelectors: #(2 4 1) of: #((((1 2) (3 4) (5 6) (7 8) (9 10)) ((11 12) (13 14) (15 16) (17 18) (19 20)) ((21
22) (23 24) (25 26) (27 28) (29 30))) (((31 32) (33 34) (35 36) (37 38) (39 40)) ((41 42) (43 44) (45 46) (47 48) (49 50))
((51 52) (53 54) (55 56) (57 58) (59 60))) (((61 62) (63 64) (65 66) (67 68) (69 70)) ((71 72) (73 74) (75 76) (77 78) (79
80)) ((81 82) (83 84) (85 86) (87 88) (89 90))) (((91 92) (93 94) (95 96) (97 98) (99 100)) ((101 102) (103 104) (105
106) (107 108) (109 110)) ((111 112) (113 114) (115 116) (117 118) (119 120))))

293
withVoiceStealing
Categories: triggers & gates, trigger modifiers

!Gate withVoiceStealing
Range [-1,1]

When activated, allow 5 milliseconds for the currently playing Sound to decay to zero to allow for voice-stealing
before generating the gate.

Some gate generators (such as bpm:, tick, and !KeyDown) send a voice-stealing signal by first transitioning from 0 to
-1 for 5 milliseconds before transitioning to 1. However, if you are gating a Sound using a logic test or a Threshold,
the value will jump from 0 to 1 without sending the voice-stealing signal. By sending the withVoiceStealing message
to a simple [0,1] transition, you can allow for the current amplitude to be quickly attenuate to zero so it does not
produce a click when you steal this voice to generate the next event.

Examples:

!Gate withVoiceStealing

(!Fader gt: 0.5) withVoiceStealing

((1 repeatingTriangle: !Dur s) gt: 0.5) withVoiceStealing

294
withVoiceStealing:
Categories: triggers & gates, trigger modifiers

!Gate withVoiceStealing: !ReAttack


Range [-1,1]

When activated or reattacked, allow 5 milliseconds for the currently playing Sound to decay to zero to allow for
voice-stealing before generating the gate.

Like voiceStealing except there is an argument that can force the gate to re-attack. If the gate is currently on and
!ReAttack becomes true (1), the voice-stealing signal is sent so it will sound like a reattack, even though the gate was
already turned on.

Examples:

!Gate withVoiceStealing: !ReAttack

(!Fader gt: 0.5) withVoiceStealing: (!Fader gt: 0.9)

295
wrapTo02
Categories: arithmetic, modulo, wrapping, panning

!ExpressionLargerThan2 wrapTo02
Range [0, 2)

Useful for panning angles, wrap02, takes values of any size and maps them to the range from 0 to 2.

wrapTo02 is a more efficient way to do a mod: 2. (mod: is more general because you can specify any modulus, but if
you want to do mod:2, then wrapTo02 is more efficient.

Examples:

!ExpressionLargerThan2 wrapTo02

6.5 wrapTo02

!localTime wrapTo02

((1 bpm: !BPM) countTriggers) wrapTo02

296
\/
Category: logic

!Value1 \/ !Value2
Range (0, 1)

Logical OR.

Use this to test whether either of two conditions are true; if either one is true, the result will be 1 (true), if both are
false, the result will be 0 (false). In Capytalk, TRUE is represented by positive values and FALSE by zero or negative
values.

Examples:

!Value1 \/ !Value2

1 \/ 0

0 \/ 0

!KeyDown \/ (!KeyPitch gt: 60)

(!KeyNumber le: 60) \/ (!KeyNumber gt: 72)

!sw01 \/ !sw02

297
\\
Categories: arithmetic, modulo, integer

!Dividend \\ !Divisor
Range (-infinity, infinity)

This is the remainder you get when dividing !Dividend by !Divisor.

!x \\ !y is the same as !x mod: !y

Examples:

!Dividend \\ !Divisor

72 \\ 12

!KeyNumber \\ 12 + !LogFreq

298
Category Index

addition + 3
amplitude db 70
amplitude dB 71
amplitude inDB 98
amplitude inversePhon70ForMinimumNotenumber: 108
amplitude phon70ForNotenumber: 181
arithmetic * 1
arithmetic ** 2
arithmetic + 3
arithmetic - 5
arithmetic / 6
arithmetic // 7
arithmetic abs 13
arithmetic arcCosh 27
arithmetic arcSinh 28
arithmetic asLeftPan 29
arithmetic asRightPan 31
arithmetic ceiling 46
arithmetic clipPositive 54
arithmetic clipTo01 55
arithmetic clipToAbs1 56
arithmetic clipToAbs2 57
arithmetic closestIntegerWithHysteresis: 58
arithmetic closestPowerOfTwo 59
arithmetic cos 62
arithmetic cosh 63
arithmetic cubed 69
arithmetic derivative 72
arithmetic exp 83
arithmetic floor 85
arithmetic ge: 91
arithmetic gt: 92
arithmetic interpolateFrom:to: 103
arithmetic inverse 107
arithmetic le: 112
arithmetic ln 114

299
arithmetic log 115
arithmetic lt: 116
arithmetic max: 120
arithmetic maxHarmonic 121
arithmetic min: 123
arithmetic mod: 124
arithmetic negated 129
arithmetic normCos 166
arithmetic normCosh 167
arithmetic normSin 168
arithmetic normSinh 169
arithmetic normTan 170
arithmetic rounded 215
arithmetic roundTo: 216
arithmetic sign 229
arithmetic sin 231
arithmetic sinc 232
arithmetic sinh 233
arithmetic sqrt 241
arithmetic squared 242
arithmetic tan 255
arithmetic tenExp 256
arithmetic truncated 278
arithmetic truncateTo: 279
arithmetic twoExp 284
arithmetic twoLog 285
arithmetic twoLogistic 286
arithmetic vmax: 289
arithmetic vmin: 290
arithmetic wrapTo02 296
arithmetic \\ 298
arrays @< 12
arrays copies: 61
arrays indexOfValueIn: 99
arrays indexToOrdinalIn: 100
arrays into: 106
arrays nextIndex 138
arrays nextIndexMod: 139
arrays nextIndexMod:reverse:reset: 141
arrays nextRandomElementOf: 148

300
arrays nextRandomIndexMod: 157
arrays nextRandomOf: 158
arrays of: 174
arrays ordinalToIndexIn: 180
arrays select:of: 225
arrays select:select:of: 226
arrays sortedOf: 240
arrays withAdditionalSelectors:of: 293
assignment <+ 9
assignment <~ 10
assignment @< 12
Boolean asLogicValue 30
Boolean false:true: 84
Boolean true:false: 275
Boolean whileTrue:timeStep: 292
bpm bpm 35
capture initialSampleAndHold: 101
capture sampleAndHold: 220
capture shiftRegister:length: 228
capture trackAndHold: 262
chaos nextChaotic 130
chaos nextChaotic7 131
chaos nextChaotic: 132
chaos nextChaotic:seed: 133
chaos nextChaotic:seed:reset: 134
chaos nextChaoticIntermittent 135
chaos nextChaoticIntermittent3 136
chaos nextChaoticIntermittent6 137
choice indexOfValueIn: 99
choice indexToOrdinalIn: 100
choice of: 174
choice ordinalToIndexIn: 180
choice select:of: 225
choice select:select:of: 226
choice sortedOf: 240
choice withAdditionalSelectors:of: 293
clipping clipPositive 54
clipping clipTo01 55
clipping clipToAbs1 56

301
clipping clipToAbs2 57
comparison eq: 78
comparison ge: 91
comparison gt: 92
comparison le: 112
comparison lt: 116
comparison ne: 126
comparison vmax: 289
comparison vmin: 290
conditional false:true: 84
conditional true:false: 275
conditional whileTrue:timeStep: 292
conditional evaluation evaluate: 82
control modifiers followFromPosition:rate:friction: 86
control modifiers interpolateFrom:to: 103
control modifiers smooth: 235
control modifiers smooth:jump: 236
control modifiers smoothed 237
control modifiers smoothFor: 238
control modifiers smoothFor:jump: 239
control modifiers swarmFollowFromPosition:velocity:acceleration:friction: 252
control modifiers warpBy: 291
control signals L 110
control signals L: 111
control signals M 117
control signals M: 119
control signals R 189
control signals R: 190
controllers accumulateWithHalfLife: 24
controllers copies: 61
controllers sameForLast:tolerance: 218
controllers trueForLast: 276
controllers trueIf:sameForLast: 277
count countTriggers 64
count countTriggersMod: 65
count countTriggersMod:reverse: 66
count countTriggersMod:reverse:reset: 67
count countTriggersReset: 68
count nextIndex 138
count nextIndexMod: 139

302
count nextIndexMod:reset: 140
count nextIndexMod:reverse:reset: 141
count nextIndexReset: 142
counting countTriggers 64
counting countTriggersMod: 65
counting countTriggersMod:reverse: 66
counting countTriggersMod:reverse:reset: 67
counting countTriggersReset: 68
counting nextIndex 138
counting nextIndexMod: 139
counting nextIndexMod:reset: 140
counting nextIndexMod:reverse:reset: 141
counting nextIndexReset: 142
curve sqrt 241
curve twoLogistic 286
delimiters , 4
detection countTriggers 64
detection countTriggersMod: 65
detection countTriggersMod:reverse: 66
detection countTriggersMod:reverse:reset: 67
detection countTriggersReset: 68
detection hasChangedInLast: 94
detection hasChangedReset: 95
detection nextIndexMod:reset: 140
detection nextIndexReset: 142
detection sameForLast:tolerance: 218
detection setReset: 227
detection switchedOff 253
detection switchedOn 254
detection threshold: 257
detection threshold:hysteresis: 258
detection trueForLast: 276
detection trueIf:sameForLast: 277
division / 6
division // 7
division inverse 107
duration durationBetweenTriggers 74
duration durationBetweenTriggers: 75
duration durationOfGate 76

303
duration euclideanPulseDurationForBeats:pulses: 80
duration euclideanStartBeatForBeats:pulses:offset: 81
envelopes repeatingTriangle 213
envelopes repeatingTriangle: 214
envelopes triangle 267
envelopes triangle: 268
eq compensatedLevel 60
equal eq: 78
equal ne: 126
evaluatedEveryMillisecond ramp00: 192
evaluatedEveryMillisecond ramp0: 193
evaluatedEveryMillisecond ramp0:reset: 194
evaluation evaluate: 82
EventValues prefix2: 182
EventValues prefix3: 183
EventValues prefix4: 184
EventValues prefix5: 185
EventValues prefix: 186
EventValues prefix:positions: 187
EventValues suffix2: 245
EventValues suffix3: 246
EventValues suffix4: 247
EventValues suffix5: 248
EventValues suffix: 249
EventValues suffix:max: 250
exponential ** 2
exponential exp 83
exponential ln 114
exponential log 115
exponential sqrt 241
exponential tenExp 256
exponential twoExp 284
exponential twoLog 285
exponential twoLogistic 286
exponentiation ** 2
false asLogicValue 30
false false:true: 84
false true:false: 275
false whileTrue:timeStep: 292

304
feature extraction derivative 72
feature extraction durationBetweenTriggers 74
feature extraction durationBetweenTriggers: 75
feature extraction durationOfGate 76
feature extraction hzToSignal 97
feature extraction signalToHz 230
frequency hzToSignal 97
frequency intervalAtStepInScaleIndex: 104
frequency
intervalToScaleStepOfEuclideanScaleWithNumberSteps:octaves:mode:octaveDivisions: 105
frequency octavePointPitchClass 173
frequency ofEuclideanScaleSteps: 175
frequency ofEuclideanScaleSteps:octaves: 176
frequency ofEuclideanScaleSteps:octaves:mode: 177
frequency ofEuclideanScaleSteps:octaves:mode:stepsPerOctave: 178
frequency signalToHz 230
frequency transposeBySteps:scaleIndex:tonic: 263
frequency transposeWithVoicing:scaleIndex:tonic: 264
frequency transpositionIntervalBySteps:scaleIndex:tonic: 265
frequency transpositionIntervalWithVoicing:scaleIndex:tonic: 266
function into: 106
grids segmentOfGrid: 224
Hot variables prefix2: 182
Hot variables prefix3: 183
Hot variables prefix4: 184
Hot variables prefix5: 185
Hot variables prefix: 186
Hot variables prefix:positions: 187
Hot variables suffix2: 245
Hot variables suffix3: 246
Hot variables suffix4: 247
Hot variables suffix5: 248
Hot variables suffix: 249
Hot variables suffix:max: 250
index nextIndex 138
index nextIndexMod: 139
index nextIndexMod:reverse:reset: 141
index nextRandomIndexMod: 157
inputOutputCharacteristic into: 106

305
integer ceiling 46
integer closestIntegerWithHysteresis: 58
integer floor 85
integer rounded 215
integer truncated 278
integer \\ 298
interface expressions accumulate 14
interface expressions accumulate01 15
interface expressions accumulate01If: 16
interface expressions accumulate01If:initialValue:reset: 17
interface expressions accumulate01While: 18
interface expressions accumulate01While:initialValue:reset: 19
interface expressions accumulateIf: 20
interface expressions accumulateIf:initialValue:reset: 21
interface expressions accumulateWhile: 22
interface expressions accumulateWhile:initialValue:reset: 23
interface expressions accumulateWithHalfLife: 24
keyboard events number 172
keyboard events onOff 179
keyboard events timbre 260
keyboard events velocity 288
level compensatedLevel 60
level db 70
level dB 71
level inDB 98
logic * 1
logic + 3
logic - 5
logic /\ 8
logic >< 11
logic asLogicValue 30
logic eq: 78
logic false:true: 84
logic ge: 91
logic gt: 92
logic hasChangedInLast: 94
logic hasChangedReset: 95
logic le: 112
logic lt: 116
logic ne: 126

306
logic neg:zero:pos: 127
logic neg:zero:pos:initially: 128
logic not 171
logic sameForLast:tolerance: 218
logic setReset: 227
logic switchedOff 253
logic switchedOn 254
logic threshold: 257
logic threshold:hysteresis: 258
logic true:false: 275
logic trueForLast: 276
logic trueIf:sameForLast: 277
logic whileTrue:timeStep: 292
logic \/ 297
looping lengthQuantizedForStart:beats: 113
looping startQuantizedForBeats: 243
loudness inversePhon70ForMinimumNotenumber: 108
loudness phon70ForNotenumber: 181
map into: 106
mapping into: 106
maximum max: 120
memory writers cancelUniqueMemoryWriterRecordingNames 45
minimum min: 123
modulo mod: 124
modulo wrapTo02 296
modulo \\ 298
negation negated 129
nonlinear into: 106
nonlinear max: 120
nonlinear min: 123
notebooks editCopy 77
panning asLeftPan 29
panning asRightPan 31
panning wrapTo02 296
pitch intervalAtStepInScaleIndex: 104
pitch
intervalToScaleStepOfEuclideanScaleWithNumberSteps:octaves:mode:octaveDivisions: 105
pitch octavePointPitchClass 173
pitch ofEuclideanScaleSteps: 175
pitch ofEuclideanScaleSteps:octaves: 176

307
pitch ofEuclideanScaleSteps:octaves:mode: 177
pitch ofEuclideanScaleSteps:octaves:mode:stepsPerOctave: 178
pitch transposeBySteps:scaleIndex:tonic: 263
pitch transposeWithVoicing:scaleIndex:tonic: 264
pitch transpositionIntervalBySteps:scaleIndex:tonic: 265
pitch transpositionIntervalWithVoicing:scaleIndex:tonic: 266
powersOf2 closestPowerOfTwo 59
programming , 4
programming <+ 9
programming <~ 10
programming @< 12
programming evaluate: 82
quotient / 6
quotient // 7
quotient inverse 107
random brownianGate: 40
random brownianGate:deviation:minDur:maxDur:dutyCycle: 41
random brownianTrigger: 42
random brownianTriggerStart:deviation: 43
random brownianTriggerStart:deviation:minDur:maxDur: 44
random chaoticGate7: 47
random chaoticGate: 48
random chaoticGate:kFactor: 49
random chaoticGate:kFactor:minDur:maxDur:dutyCycle: 50
random chaoticGateIntermittent3: 51
random chaoticGateIntermittent6: 52
random chaoticGateIntermittent: 53
random nextChaotic 130
random nextChaotic7 131
random nextChaotic: 132
random nextChaotic:seed: 133
random nextChaotic:seed:reset: 134
random nextChaoticIntermittent 135
random nextChaoticIntermittent3 136
random nextChaoticIntermittent6 137
random nextNormal 143
random nextNormalWithSeed: 144
random nextRandExp 145
random nextRandExpWithSeed: 146

308
random nextRandom 147
random nextRandomElementOf: 148
random nextRandomFromAllArrays:arrayIndex: 149
random nextRandomFromArrays:sampledArrayIndex: 150
random nextRandomIndexFromDistribution: 151
random nextRandomIndexFromDistribution:jitter: 152
random nextRandomIndexFromDistributions:distributionIndex: 153
random nextRandomIndexFromDistributions:distributionIndex:jitter: 154
random nextRandomIndexFromDistributions:interpolatedDistributionIndex: 155
random nextRandomIndexFromDistributions:interpolatedDistributionIndex:jitter:156
random nextRandomIndexMod: 157
random nextRandomOf: 158
random nextRandomWithSeed: 159
random normal 161
random normalGate: 162
random normalGate:deviation:dutyCycle: 163
random normalTrigger: 164
random normalTriggerCenter:deviation: 165
random randExp 196
random randExpGate: 197
random randExpGate:minDur:maxDur:dutyCycle: 198
random randExpTrigger: 199
random randExpTrigger:minimumDuration: 200
random random 201
random randomGate: 202
random randomGate:deviation:dutyCycle: 203
random randomTrigger: 204
random randomTriggerCenter:deviation: 205
random randomWalk 206
random randomWalkStartingFrom:stepSize:reset: 207
random seed: 221
random seeded 222
random seededWith: 223
range * 1
range clipToAbs1 56
range clipToAbs2 57
ratio / 6
ratio inverse 107
rounding ceiling 46
rounding closestIntegerWithHysteresis: 58

309
rounding floor 85
rounding rounded 215
rounding roundTo: 216
rounding truncated 278
rounding truncateTo: 279
sampleAndHold initialSampleAndHold: 101
sampleAndHold sampleAndHold: 220
sampleAndHold shiftRegister:length: 228
sampleAndHold trackAndHold: 262
savingState evaluate: 82
scales intervalAtStepInScaleIndex: 104
scales
intervalToScaleStepOfEuclideanScaleWithNumberSteps:octaves:mode:octaveDivisions: 105
scales octavePointPitchClass 173
scales ofEuclideanScaleSteps: 175
scales ofEuclideanScaleSteps:octaves: 176
scales ofEuclideanScaleSteps:octaves:mode: 177
scales ofEuclideanScaleSteps:octaves:mode:stepsPerOctave: 178
scales transposeBySteps:scaleIndex:tonic: 263
scales transposeWithVoicing:scaleIndex:tonic: 264
scales transpositionIntervalBySteps:scaleIndex:tonic: 265
scales transpositionIntervalWithVoicing:scaleIndex:tonic: 266
scaling * 1
seed seed: 221
seed seeded 222
seed seededWith: 223
selection indexOfValueIn: 99
selection indexToOrdinalIn: 100
selection of: 174
selection ordinalToIndexIn: 180
selection select:of: 225
selection select:select:of: 226
selection sortedOf: 240
selection withAdditionalSelectors:of: 293
separators , 4
sequences euclideanPulseDurationForBeats:pulses: 80
sequences euclideanStartBeatForBeats:pulses:offset: 81
sequences nextIndex 138
sequences nextIndexMod: 139
sequences nextIndexMod:reverse:reset: 141

310
sign negated 129
sign sign 229
Sounds L 110
Sounds L: 111
Sounds M 117
Sounds M: 119
Sounds R 189
Sounds R: 190
sounds editCopy 77
spatializing asLeftPan 29
spatializing asRightPan 31
stochastic nextChaotic 130
stochastic nextChaotic7 131
stochastic nextChaotic: 132
stochastic nextChaotic:seed: 133
stochastic nextChaotic:seed:reset: 134
stochastic nextChaoticIntermittent 135
stochastic nextChaoticIntermittent3 136
stochastic nextChaoticIntermittent6 137
stochastic nextNormal 143
stochastic nextNormalWithSeed: 144
stochastic nextRandExp 145
stochastic nextRandExpWithSeed: 146
stochastic nextRandom 147
stochastic nextRandomFromAllArrays:arrayIndex: 149
stochastic nextRandomFromArrays:sampledArrayIndex: 150
stochastic nextRandomIndexFromDistribution: 151
stochastic nextRandomIndexFromDistribution:jitter: 152
stochastic nextRandomIndexFromDistributions:distributionIndex: 153
stochastic nextRandomIndexFromDistributions:distributionIndex:jitter: 154
stochastic nextRandomIndexFromDistributions:interpolatedDistributionIndex: 155
stochastic nextRandomIndexFromDistributions:interpolatedDistributionIndex:jitter:156
stochastic nextRandomWithSeed: 159
stochastic normal 161
stochastic randExp 196
stochastic random 201
stochastic seed: 221
stochastic seeded 222
stochastic seededWith: 223

311
subtraction - 5
test eq: 78
test hasChangedInLast: 94
test hasChangedReset: 95
test ne: 126
test sameForLast:tolerance: 218
test threshold: 257
test threshold:hysteresis: 258
test trueForLast: 276
test trueIf:sameForLast: 277
test segmentOfGrid: 224
time functions euclideanForBeats:pulses:offset: 79
time functions euclideanPulseDurationForBeats:pulses: 80
time functions euclideanStartBeatForBeats:pulses:offset: 81
time functions fullRamp 87
time functions fullRamp: 88
time functions ramp 191
time functions ramp00: 192
time functions ramp0: 193
time functions ramp0:reset: 194
time functions ramp: 195
time functions repeatingFullRamp 209
time functions repeatingFullRamp: 210
time functions repeatingRamp 211
time functions repeatingRamp: 212
time functions repeatingTriangle 213
time functions repeatingTriangle: 214
time functions smooth: 235
time functions smooth:jump: 236
time functions smoothed 237
time functions smoothFor: 238
time functions smoothFor:jump: 239
time functions triangle 267
time functions triangle: 268
timing durationBetweenTriggers 74
timing durationBetweenTriggers: 75
timing durationOfGate 76
trackAndHold trackAndHold: 262
trigger modifiers alignGateWith: 25
trigger modifiers alignWith: 26

312
trigger modifiers asToggle 32
trigger modifiers euclideanForBeats:pulses:offset: 79
trigger modifiers euclideanPulseDurationForBeats:pulses: 80
trigger modifiers euclideanStartBeatForBeats:pulses:offset: 81
trigger modifiers isOnForEuclideanBeats:pulses:offset: 109
trigger modifiers stayOnFor: 244
trigger modifiers sustainBy: 251
trigger modifiers switchedOff 253
trigger modifiers switchedOn 254
trigger modifiers triggerEvery: 269
trigger modifiers triggerEvery:offset: 270
trigger modifiers triggerEvery:reset: 271
trigger modifiers triggerEverySampled: 272
trigger modifiers turnOnAfter: 281
trigger modifiers turnOnAfter:for: 282
trigger modifiers turnOnFor: 283
trigger modifiers withVoiceStealing 294
trigger modifiers withVoiceStealing: 295
triggers doNotTrigger 73
triggers setReset: 227
triggers switchedOff 253
triggers switchedOn 254
triggers & gates alignGateWith: 25
triggers & gates alignWith: 26
triggers & gates asToggle 32
triggers & gates barBPM:beats: 33
triggers & gates barBPM:beats:dutyCycle: 34
triggers & gates bpm: 36
triggers & gates bpm:dutyCycle: 37
triggers & gates bpm:updateEvery: 38
triggers & gates bpm:updateEvery:dutyCycle: 39
triggers & gates brownianGate: 40
triggers & gates brownianGate:deviation:minDur:maxDur:dutyCycle: 41
triggers & gates brownianTrigger: 42
triggers & gates brownianTriggerStart:deviation: 43
triggers & gates brownianTriggerStart:deviation:minDur:maxDur: 44
triggers & gates chaoticGate7: 47
triggers & gates chaoticGate: 48
triggers & gates chaoticGate:kFactor: 49

313
triggers & gates chaoticGate:kFactor:minDur:maxDur:dutyCycle: 50
triggers & gates chaoticGateIntermittent3: 51
triggers & gates chaoticGateIntermittent6: 52
triggers & gates chaoticGateIntermittent: 53
triggers & gates durationBetweenTriggers 74
triggers & gates durationBetweenTriggers: 75
triggers & gates durationOfGate 76
triggers & gates gateTimeToNext:dutyCycle: 89
triggers & gates gateWhen: 90
triggers & gates isOnForEuclideanBeats:pulses:offset: 109
triggers & gates normalGate: 162
triggers & gates normalGate:deviation:dutyCycle: 163
triggers & gates normalTrigger: 164
triggers & gates normalTriggerCenter:deviation: 165
triggers & gates randExpGate: 197
triggers & gates randExpGate:minDur:maxDur:dutyCycle: 198
triggers & gates randExpTrigger: 199
triggers & gates randExpTrigger:minimumDuration: 200
triggers & gates randomGate: 202
triggers & gates randomGate:deviation:dutyCycle: 203
triggers & gates randomTrigger: 204
triggers & gates randomTriggerCenter:deviation: 205
triggers & gates skipNext:triggersFrom: 234
triggers & gates stayOnFor: 244
triggers & gates sustainBy: 251
triggers & gates tick 259
triggers & gates toggleWhen: 261
triggers & gates triggerEvery: 269
triggers & gates triggerEvery:offset: 270
triggers & gates triggerEvery:reset: 271
triggers & gates triggerEverySampled: 272
triggers & gates triggerTimeToNext: 273
triggers & gates tripWires: 274
triggers & gates ttn: 280
triggers & gates turnOnAfter: 281
triggers & gates turnOnAfter:for: 282
triggers & gates turnOnFor: 283
triggers & gates withVoiceStealing 294
triggers & gates withVoiceStealing: 295

314
trigonometric arcCosh 27
trigonometric arcSinh 28
trigonometric cos 62
trigonometric cosh 63
trigonometric normCos 166
trigonometric normCosh 167
trigonometric normSin 168
trigonometric normSinh 169
trigonometric normTan 170
trigonometric sin 231
trigonometric sinc 232
trigonometric sinh 233
trigonometric tan 255
true asLogicValue 30
true false:true: 84
true true:false: 275
true whileTrue:timeStep: 292
truncatingDivide // 7
tuning intervalAtStepInScaleIndex: 104
tuning
intervalToScaleStepOfEuclideanScaleWithNumberSteps:octaves:mode:octaveDivisions: 105
tuning octavePointPitchClass 173
tuning ofEuclideanScaleSteps: 175
tuning ofEuclideanScaleSteps:octaves: 176
tuning ofEuclideanScaleSteps:octaves:mode: 177
tuning ofEuclideanScaleSteps:octaves:mode:stepsPerOctave: 178
tuning transposeBySteps:scaleIndex:tonic: 263
tuning transposeWithVoicing:scaleIndex:tonic: 264
tuning transpositionIntervalBySteps:scaleIndex:tonic: 265
tuning transpositionIntervalWithVoicing:scaleIndex:tonic: 266
units bpm 35
units db 70
units dB 71
units h 93
units hz 96
units inDB 98
units inOctaves 102
units m 118
units mel 122
units ms 125

315
units nn 160
units px 188
units removeUnits 208
units s 217
units samp 219
units usec 287
unitsOfFrequencyAndDuration h 93
unitsOfFrequencyAndDuration hz 96
unitsOfFrequencyAndDuration inOctaves 102
unitsOfFrequencyAndDuration m 118
unitsOfFrequencyAndDuration mel 122
unitsOfFrequencyAndDuration ms 125
unitsOfFrequencyAndDuration nn 160
unitsOfFrequencyAndDuration removeUnits 208
unitsOfFrequencyAndDuration s 217
unitsOfFrequencyAndDuration samp 219
unitsOfFrequencyAndDuration usec 287
variables <+ 9
variables <~ 10
variables @< 12
warping into: 106
wrapping wrapTo02 296

316
317
Selector index

* 1
** 2
+ 3
, 4
- 5
/ 6
// 7
/\ 8
<+ 9
<~ 10
>< 11
@< 12
abs 13
accumulate 14
accumulate01 15
accumulate01If: 16
accumulate01If:initialValue:reset: 17
accumulate01While: 18
accumulate01While:initialValue:reset: 19
accumulateIf: 20
accumulateIf:initialValue:reset: 21
accumulateWhile: 22
accumulateWhile:initialValue:reset: 23
accumulateWithHalfLife: 24
alignGateWith: 25
alignWith: 26
arcCosh 27
arcSinh 28
asLeftPan 29
asLogicValue 30
asRightPan 31
asToggle 32
barBPM:beats: 33
barBPM:beats:dutyCycle: 34
bpm 35
bpm: 36

318
bpm:dutyCycle: 37
bpm:updateEvery: 38
bpm:updateEvery:dutyCycle: 39
brownianGate: 40
brownianGate:deviation:minDur:maxDur:dutyCycle: 41
brownianTrigger: 42
brownianTriggerStart:deviation: 43
brownianTriggerStart:deviation:minDur:maxDur: 44
cancelUniqueMemoryWriterRecordingNames 45
ceiling 46
chaoticGate7: 47
chaoticGate: 48
chaoticGate:kFactor: 49
chaoticGate:kFactor:minDur:maxDur:dutyCycle: 50
chaoticGateIntermittent3: 51
chaoticGateIntermittent6: 52
chaoticGateIntermittent: 53
clipPositive 54
clipTo01 55
clipToAbs1 56
clipToAbs2 57
closestIntegerWithHysteresis: 58
closestPowerOfTwo 59
compensatedLevel 60
copies: 61
cos 62
cosh 63
countTriggers 64
countTriggersMod: 65
countTriggersMod:reverse: 66
countTriggersMod:reverse:reset: 67
countTriggersReset: 68
cubed 69
dB 71
db 70
derivative 72
doNotTrigger 73
durationBetweenTriggers 74
durationBetweenTriggers: 75
durationOfGate 76

319
editCopy 77
eq: 78
euclideanForBeats:pulses:offset: 79
euclideanPulseDurationForBeats:pulses: 80
euclideanStartBeatForBeats:pulses:offset: 81
evaluate: 82
exp 83
false:true: 84
floor 85
followFromPosition:rate:friction: 86
fullRamp 87
fullRamp: 88
gateTimeToNext:dutyCycle: 89
gateWhen: 90
ge: 91
gt: 92
h 93
hasChangedInLast: 94
hasChangedReset: 95
hz 96
hzToSignal 97
inDB 98
indexOfValueIn: 99
indexToOrdinalIn: 100
initialSampleAndHold: 101
inOctaves 102
interpolateFrom:to: 103
intervalAtStepInScaleIndex: 104
intervalToScaleStepOfEuclideanScaleWithNumberSteps:octaves:mode:octaveDivisions: 105
into: 106
inverse 107
inversePhon70ForMinimumNotenumber: 108
isOnForEuclideanBeats:pulses:offset: 109
L 110
L: 111
le: 112
lengthQuantizedForStart:beats: 113
ln 114
log 115

320
lt: 116
m 118
M 117
M: 119
max: 120
maxHarmonic 121
mel 122
min: 123
mod: 124
ms 125
ne: 126
neg:zero:pos: 127
neg:zero:pos:initially: 128
negated 129
nextChaotic 130
nextChaotic7 131
nextChaotic: 132
nextChaotic:seed: 133
nextChaotic:seed:reset: 134
nextChaoticIntermittent 135
nextChaoticIntermittent3 136
nextChaoticIntermittent6 137
nextIndex 138
nextIndexMod: 139
nextIndexMod:reset: 140
nextIndexMod:reverse:reset: 141
nextIndexReset: 142
nextNormal 143
nextNormalWithSeed: 144
nextRandExp 145
nextRandExpWithSeed: 146
nextRandom 147
nextRandomElementOf: 148
nextRandomFromAllArrays:arrayIndex: 149
nextRandomFromArrays:sampledArrayIndex: 150
nextRandomIndexFromDistribution: 151
nextRandomIndexFromDistribution:jitter: 152
nextRandomIndexFromDistributions:distributionIndex: 153
nextRandomIndexFromDistributions:distributionIndex:jitter: 154
nextRandomIndexFromDistributions:interpolatedDistributionIndex: 155

321
nextRandomIndexFromDistributions:interpolatedDistributionIndex:jitter: 156
nextRandomIndexMod: 157
nextRandomOf: 158
nextRandomWithSeed: 159
nn 160
normal 161
normalGate: 162
normalGate:deviation:dutyCycle: 163
normalTrigger: 164
normalTriggerCenter:deviation: 165
normCos 166
normCosh 167
normSin 168
normSinh 169
normTan 170
not 171
number 172
octavePointPitchClass 173
of: 174
ofEuclideanScaleSteps: 175
ofEuclideanScaleSteps:octaves: 176
ofEuclideanScaleSteps:octaves:mode: 177
ofEuclideanScaleSteps:octaves:mode:stepsPerOctave: 178
onOff 179
ordinalToIndexIn: 180
phon70ForNotenumber: 181
prefix2: 182
prefix3: 183
prefix4: 184
prefix5: 185
prefix: 186
prefix:positions: 187
px 188
R 189
R: 190
ramp 191
ramp00: 192
ramp0: 193
ramp0:reset: 194

322
ramp: 195
randExp 196
randExpGate: 197
randExpGate:minDur:maxDur:dutyCycle: 198
randExpTrigger: 199
randExpTrigger:minimumDuration: 200
random 201
randomGate: 202
randomGate:deviation:dutyCycle: 203
randomTrigger: 204
randomTriggerCenter:deviation: 205
randomWalk 206
randomWalkStartingFrom:stepSize:reset: 207
removeUnits 208
repeatingFullRamp 209
repeatingFullRamp: 210
repeatingRamp 211
repeatingRamp: 212
repeatingTriangle 213
repeatingTriangle: 214
rounded 215
roundTo: 216
s 217
sameForLast:tolerance: 218
samp 219
sampleAndHold: 220
seed: 221
seeded 222
seededWith: 223
segmentOfGrid: 224
select:of: 225
select:select:of: 226
setReset: 227
shiftRegister:length: 228
sign 229
signalToHz 230
sin 231
sinc 232
sinh 233
skipNext:triggersFrom: 234

323
smooth: 235
smooth:jump: 236
smoothed 237
smoothFor: 238
smoothFor:jump: 239
sortedOf: 240
sqrt 241
squared 242
startQuantizedForBeats: 243
stayOnFor: 244
suffix2: 245
suffix3: 246
suffix4: 247
suffix5: 248
suffix: 249
suffix:max: 250
sustainBy: 251
swarmFollowFromPosition:velocity:acceleration:friction: 252
switchedOff 253
switchedOn 254
tan 255
tenExp 256
threshold: 257
threshold:hysteresis: 258
tick 259
timbre 260
toggleWhen: 261
trackAndHold: 262
transposeBySteps:scaleIndex:tonic: 263
transposeWithVoicing:scaleIndex:tonic: 264
transpositionIntervalBySteps:scaleIndex:tonic: 265
transpositionIntervalWithVoicing:scaleIndex:tonic: 266
triangle 267
triangle: 268
triggerEvery: 269
triggerEvery:offset: 270
triggerEvery:reset: 271
triggerEverySampled: 272
triggerTimeToNext: 273

324
tripWires: 274
true:false: 275
trueForLast: 276
trueIf:sameForLast: 277
truncated 278
truncateTo: 279
ttn: 280
turnOnAfter: 281
turnOnAfter:for: 282
turnOnFor: 283
twoExp 284
twoLog 285
twoLogistic 286
usec 287
velocity 288
vmax: 289
vmin: 290
warpBy: 291
whileTrue:timeStep: 292
withAdditionalSelectors:of: 293
withVoiceStealing 294
withVoiceStealing: 295
wrapTo02 296
\/ 297
\\ 298

325
326

You might also like