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 + 2
with ⇒
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 - 2
with ⇒
*
multiplication between and . eg:
i * 2
with ⇒
/
division between and . eg:
i / 2
with ⇒
%
modulus of with respect to . eg:
i % 2
with ⇒
^
to the power of . eg:
i ^ 2
with ⇒
:=
assign the value of to . eg:
i := 2
with ⇒
+=
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.5
with ⇒
=
==
true only if is strictly equal to . eg:
x == 3
with ⇒
with ⇒
<>
!=
True only if does not equal . eg:
i != 3
with ⇒
with ⇒
<
True only if is less than . eg:
i < 3
with ⇒
with ⇒
with ⇒
<=
True only if is less than or equal to . eg:
i <= 3
with ⇒
with ⇒
with ⇒
>
True only if is greater than . eg:
i > 3
with ⇒
with ⇒
with ⇒
>=
True only if greater than or equal to . eg:
i >= 3
with ⇒
with ⇒
with ⇒
and
&
Logical AND, true only if and are both true. eg:
i and 2
with ⇒
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 3
with ⇒
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 0
with ⇒
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 0
with ⇒
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 0
with ⇒
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:
true
with ⇒
false
False state, value of exactly zero. eg:
false
with ⇒
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 : 2
with ⇒
with ⇒