NOTE
In the following examples we’ll use some other variable names — like — to represent numbers. Note thought that these cannot be used in the formula and must be replaced with a valid number.
Mutations are formula that can alter the value that is sent out to other plugins. The mutation is applied on the receiver of the data, not at the transmitter, which allows for emitting a single value from a receiving, and handling it differently on various receivers.
The received value is available within the formula as the variable .
Let’s take the following settings file as an example:
devices: - type: modbusTCP name: mb options: ip: 10.0.0.2
- type: websocket name: ws
- type: osc name: osc
mappings: - name: mb to ws - analog from: { name: mb, address: 0, type: int8 } to: { name: ws, address: input1, type: int16 } mutation: scale(i, int8, int16)
- name: mb to osc - analog from: { name: mb, address: 0, type: int8 } to: { name: osc, address: /fader/1, type: float } mutation: scale(i, int8, 100)
- name: mb to ws - digital from: { name: mb, address: 1, type: bool } to: { name: ws, address: led1, type: bool }
- name: mb to osc - digital from: { name: mb, address: 1, type: bool } to: { name: ws, address: /led/1, type: bool } mutation: not(i)The logical representation of these settings looks like this:
the only variable available in the functions is the variable which is the input value to be converted.
the following constants can be used in formula
| constant | value |
|---|---|
| int8 | 255 |
| int16 | 65535 |
| pi | 3.141592653589793 |
| epsilon | 1e-10 |
| inf | inf |
the mutation math supports the following basic arithmetic operations, functions and processes:
NOTE
In the following examples we’ll use some other variable names — like — to represent numbers. Note thought that these cannot be used in the formula and must be replaced with a valid number.
+ addition between and . eg:
i + 2with ⇒
mutation: i + 2| type | formula | input | result |
|---|---|---|---|
| double | i + 2 | 3.0 | 5.0 |
| int8 | i + 2 | 4 | 6 |
| double | i - 2 | 3.0 | 1.0 |
| int8 | i - 2 | 4 | 2 |
| double | i / 2 | 3.0 | 1.5 |
| int8 | i / 2 | 4 | 2 |
| double | i * 2 | 3.0 | 6.0 |
| int8 | i * 2 | 4 | 8 |
| double | i % 2 | 3.0 | 1.0 |
| int8 | i % 2 | 4 | 0 |
| double | i ^ 2 | 3.0 | 9.0 |
| int8 | i ^ 2 | 4 | 16 |
- subtraction between and . eg:
i - 2with ⇒
* multiplication between and . eg:
i * 2with ⇒
/ division between and . eg:
i / 2with ⇒
% modulus of with respect to . eg:
i % 2with ⇒
^ to the power of . eg:
i ^ 2with ⇒
:= assign the value of to . eg:
i := 2with ⇒
+= increment by the value of the expression on the right-hand side. eg:
i += abs(i - 4)with ⇒
-= decrement by the value of the expression on the right-hand side. eg:
i -= abs(i - 4)with ⇒
*= assign the multiplication of by the value of the expression on the right-hand side to .
eg:
i *= abs(i - 5)with ⇒
/= assign the division of by the value of the expression on the right-hand side to . eg:
i /= abs(i * -2)with ⇒
%= assign modulo the value of the expression on the right-hand side to . eg:
i %= i / 2.5with ⇒
= == true only if is strictly equal to . eg:
x == 3with ⇒
with ⇒
<> != True only if does not equal . eg:
i != 3with ⇒
with ⇒
< True only if is less than . eg:
i < 3with ⇒
with ⇒
with ⇒
<= True only if is less than or equal to . eg:
i <= 3with ⇒
with ⇒
with ⇒
> True only if is greater than . eg:
i > 3with ⇒
with ⇒
with ⇒
>= True only if greater than or equal to . eg:
i >= 3with ⇒
with ⇒
with ⇒
and & Logical AND, true only if and are both true. eg:
i and 2with ⇒
with ⇒
| Input A | Input B | Output |
|---|---|---|
| and | ||
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
mand Multi-input logical AND, true only if all inputs are true. Left to right short-circuiting of
expressions. eg:
mand(i > 2, i < 4)with ⇒
with ⇒
or | Logical OR, True if either or is true. eg:
(i == 2) or (i == 4)with ⇒
with ⇒
with ⇒
| Input A | Input B | Output |
|---|---|---|
| or | ||
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
mor Multi-input logical OR, true if at least one of the inputs are true. Left to right short-circuiting of
expressions. eg:
mor(i > 3, i < -3)with ⇒
with ⇒
nand Logical NAND, True only if either or is false. eg:
i nand 3with ⇒
with ⇒
| Input A | Input B | Output |
|---|---|---|
| nand | ||
| 0 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
nor Logical NOR, True only if the result of or is false eg:
i nor 0with ⇒
with ⇒
| Input A | Input B | Output |
|---|---|---|
| nor | ||
| 0 | 0 | 1 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 0 |
not Logical NOT, negate the logical sense of the input. eg:
not(i)with ⇒
with ⇒
| Input | Output |
|---|---|
| not | |
| 0 | 1 |
| 1 | 0 |
The not(i) function converts the input to a boolean, converts back to the input type and returns it. +
When using any number type it will always return either or .
mutation: not(i)| Type | Formula | Input | Result |
|---|---|---|---|
| int8 | not(i) | 1 | 0 |
| int8 | not(i) | 0 | 1 |
| int8 | not(i) | 4 | 0 |
| int16 | not(i) | 1 | 0 |
| int16 | not(i) | 0 | 1 |
| double | not(i) | 1.0 | 0.0 |
| double | not(i) | 0.0 | 1.0 |
| bool | not(i) | true | false |
| bool | not(i) | false | true |
xnor Logical XNOR, True if the biconditional of and is satisfied. eg:
i xnor 0with ⇒
with ⇒
| Input A | Input B | Output |
|---|---|---|
| xnor | ||
| 0 | 0 | 1 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
xor Logical XOR, True only if the logical states of and differ. eg:
i xor 0with ⇒
with ⇒
| Input A | Input B | Output |
|---|---|---|
| xor | ||
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
true True state or any value other than zero (typically 1). eg:
truewith ⇒
false False state, value of exactly zero. eg:
falsewith ⇒
map map a value from range to range where eg:
map(i, 50, 100, 100, 200)with ⇒
The map function scales a given input value from one value range (specified with a lower and upper bound) to another value range (again, specified with a lower and upper bound). eg:
mutation: map(i, in_min, in_max, out_min, out_max)| Type | Formula | Input | Result |
|---|---|---|---|
| int8 | map(i, 10, 80, 0, 100) | 0 | 0 |
| int8 | map(i, 10, 80, 0, 100) | 25 | 21 |
| int8 | map(i, 10, 80, 0, 100) | 75 | 92 |
scale scale a value from range to range where . eg:
scale(i, 100, 200)with ⇒
The scale function is similar to the map function, but assumes that the in_min and out_min values
are both 0. +
This function is useful to scale between let’s say a percentage and a number range
(be it the int8 number range 0 - 255, the int16 number range 0 - 65535, or any custom range starting at 0).
mutation: scale(i, in_max, out_max)| Type | Formula | Input | Result |
|---|---|---|---|
| int8 | scale(i, 255, 65535) | 0 | 0 |
| int8 | scale(i, 255, 65535) | 127 | 255 |
| int8 | scale(i, 255, 65535) | 255 | 255 |
| int16 | scale(i, 65535, 255) | 0 | 0 |
| int16 | scale(i, 65535, 255) | 32639 | 127 |
| int16 | scale(i, 65535, 255) | 65535 | 255 |
| bool | scale(i, 1, 255) | false | false |
| bool | scale(i, 1, 255) | true | true |
| int8 | scale(i, 1, 255) | 0 | 0 |
| int8 | scale(i, 1, 255) | 1 | 255 |
| int8 | scale(i, 1, 255) | 4 | 255 |
abs Absolute value of . eg:
abs(i)with ⇒
with ⇒
avg Average of all the inputs. eg:
avg(i, 2)with ⇒
with ⇒
ceil Smallest integer that is greater than or equal to . eg:
ceil(i)with ⇒
floor Largest integer that is less than or equal to . eg:
floor(i)with ⇒
clamp Clamp in range between and , where . eg:
clamp(0, i, 10)with ⇒
with ⇒
with ⇒
mutation: clamp(limit_low, i, limit_high)| Type | Formula | Input | Result |
|---|---|---|---|
| double | clamp(20, i, 80) | 3.0 | 20.0 |
| int8 | clamp(20, i, 80) | 4 | 20 |
| int8 | clamp(20, i, 80) | 25 | 25 |
| int8 | clamp(20, i, 80) | 125 | 80 |
iclamp Inverse-clamp outside the range and . Where .
If is within the range it will snap to the closest bound. eg:
iclamp(10, i, 20)with ⇒
with ⇒
with ⇒
round Round to the nearest integer. eg:
round(x)with ⇒
with ⇒
with ⇒
roundn Round to decimal places (eg: where and is
an integer. eg:
roundn(i, 4)with ⇒
equal Equality test between and using normalised epsilon. eg:
equal(i, 2.3)with ⇒
with ⇒
pow to the power of . eg:
pow(i, 3)with ⇒
mutation: pow(i, power)| Type | Formula | Input | Result |
|---|---|---|---|
| double | pow(i, 2) | 3.0 | 9.0 |
| int8 | pow(i, 2) | 4 | 16 |
exp to the power of . eg:
exp(i)with ⇒
expm1 to the power of minus 1, where is very small. eg:
expm1(i)with ⇒
sqrt Square root of , where >= 0. eg:
sqrt(i)with ⇒
root Nth-Root of . where is a positive integer. eg:
root(i, 3)with ⇒
log Natural logarithm (a logarithm to the base of ) of . eg:
log(i)with ⇒
log10 Base 10 logarithm of . eg:
log10(i)with ⇒
log2 Base 2 logarithm of . eg:
log2(i)with ⇒
log1p Natural logarithm of 1 + , where is very small. eg:
log1p(i)with ⇒
logn Base N logarithm of . where is a positive integer. eg:
logn(i, 8)with ⇒
trunc Integer portion of . eg:
trunc(i)with ⇒
frac Fractional portion of . eg:
frac(i)with ⇒
hypot Hypotenuse of and eg:
hypot(i, 4)with ⇒
inrange In-range returns true when is within the range and . Where . eg:
inrange(10, i, 20)with ⇒
with ⇒
with ⇒
max Largest value of all the inputs. eg:
max(i, 2, 5)with ⇒
with ⇒
min Smallest value of all the inputs. eg:
min(i, 2, 5)with ⇒
with ⇒
sum Sum of all the inputs. eg:
sum(i, 2, 3)with ⇒
mul Product of all the inputs. eg:
mul(i, 2, 3)with ⇒
with ⇒
ncdf Normal cumulative distribution function. eg:
ncdf(i)sgn Sign of , -1 where < 0, +1 where > 0, else zero. eg:
sgn(x)with ⇒
with ⇒
with ⇒
sin Sine of . eg:
sin(i)with ⇒
cos Cosine of . eg:
cos(i)with ⇒
tan Tangent of . eg:
tan(i)with ⇒
sinh Hyperbolic sine of . eg:
sinh(i)with ⇒
cosh Hyperbolic cosine of . eg:
cosh(i)with ⇒
tanh Hyperbolic tangent of . eg:
tanh(i)with ⇒
asin Arc sine of expressed in radians. Interval . eg:
asin(i)with ⇒
acos Arc cosine of expressed in radians. Interval . eg:
acos(i)with ⇒
atan Arc tangent of expressed in radians. Interval . eg:
atan(i)with ⇒
asinh Inverse hyperbolic sine of expressed in radians. eg:
asinh(i)with ⇒
acosh Inverse hyperbolic cosine of expressed in radians. eg:
acosh(i)with ⇒
atanh Inverse hyperbolic tangent of expressed in radians. eg:
atanh(i)with ⇒
sinc Sine cardinal of . eg:
sinc(i)with ⇒
cot Cotangent of . eg:
cot(i)with ⇒
csc Cosecant of . eg:
csc(i)with ⇒
sec Secant of . eg:
sec(i)with ⇒
atan2 Arc tangent of expressed in radians. . eg:
atan2(i, 1)with ⇒
rad2deg Convert from radians to degrees. eg:
rad2deg(i)with ⇒
deg2rad Convert from degrees to radians. eg:
deg2rad(i)with ⇒
grad2deg Convert from gradians to degrees. eg:
grad2deg(i)with ⇒
deg2grad Convert from degrees to gradians. eg:
deg2grad(i)with ⇒
NOTE
Note that the input type of mapping can be of type string, but the returned value of the
mutation formula must be a number (a number will be converted to a boolean or string if required).
It is currently not possible to mutate a string to a different string. The input string is
available as the variable , any other string must be enclosed in quotes.
= == != <> \<= >= < > All common equality / inequality operators are applicable to strings and
are applied in a case-sensitive manner. eg:
i == 'test'with ⇒
with ⇒
in True only if is a substring of . eg:
i in 'testing'with ⇒
with ⇒
like True only if the string matches the pattern . Available wildcard characters are *
and ? denoting zero or more and zero or one matches respectively. eg:
i like 'te?t*'with ⇒
with ⇒
with ⇒
with ⇒
ilike True only if the string matches the pattern in a case-insensitive manner.
Available wildcard characters are ’*’ and ’?’ denoting zero or more and zero or one matches respectively. eg:
i ilike 'te?t*'with ⇒
with ⇒
with ⇒
with ⇒
[r0:r1] Substring of starting at character index up to and including .
Both and are assumed to be integers, where . They may also be the result of an
expression; in the event they have a fractional component they will be truncated (eg: ). eg:
with :
i[1:4] == 'bcde'i[:10 / 2] == 'abcdef'i[3:] =='defgh'i[:] == 'abcdefgh'i[2:5] == 'cdef'[] The string size operator returns the size of the string being actioned. eg:
i[]with ⇒
if If is true then return else return . eg:
if (i, 100, 200)with ⇒
with ⇒
if-else The if-else/else-if statement. Subject to the condition branch the statement will return either the
value of the consequent or the alternative branch. eg:
if (i > 100) 1; else 2;with ⇒
with ⇒
switch The first true case condition that is encountered will determine the result of the switch. If none of
the case conditions resolve true, the default action is assumed as the final return value. eg:
switch{ case i == 'connected' : 1; case i == 'disconnected' : 0; default : -1;}with ⇒
with ⇒
with ⇒
?: Ternary conditional statement, similar to that of the above denoted if-statement. eg:
i > 100 ? 1 : 2with ⇒
with ⇒