Expression Controller
Description
A controller whose output combines one or more input controllers using a simple C-language-like expression provided as a string.
⚠️ The Expression controller is no longer available since Modalys 3.6. In Lisp, use the Foreign Call controller and in Max context use the mlys.lua object.
(make-controller 'expression ... )
Syntax and Default Values
The 'expression controller can be created using the following Lisp syntax:
(make-controller 'expression dimension period expression_string controller1 controller2 ... )
(make-controller 'expression dimension period expression_string (list controller1 controller2 ... ))
Parameters
The 'expression controller takes the following arguments:
- dimension: number of dimensions for the output controller.
- period: the time between controller updates (in synthesis seconds).
- expression_string: a text string representing the expression to be evaluated. see details, below.
- controller1, controller2, etc...: controllers to "plug-in" to the math expression.
The output controller can be optionally re-sampled using the period argument. A period of 0, as always, indicates the controller will be updated every sample.
The C-like expression string syntax is described in detail, below.
A variable number of controllers may be provided as a series of arguments, or as a list.
Discussion
The expression controller is similar to the arithmetic controller, but with a richer syntax for mathematical expressions, and support for multi-dimensional controllers. It is available outside the Lisp environment, so it should be used, when and where possible, instead of a 'foreign-call controller, which is not only painfully slow, but also specific just to Modalys in the Lisp environment.
Note that the expression controller is now available in the Max/MSP Windows environment.
Here is a simple example of the 'expression controller's use to multiply two controllers (my-ctl1 and my-ctl2):
(make-controller 'expression 1 0 "in(1,1)*in(2,1)" my-ctl1 my-ctl2)
The expression also lets you use variables and separate an expression into multiple subsequent statements using a semicolon. The above example could be rewritten as:
(make-controller 'expression 1 0 "a=in(1,1); b=in(2,1); a*b" my-ctl1 my-ctl2)
(setq my-ramp (make-controller 'envelope 1 '((0 0) (1 1))))
(setq my-window (make-controller 'expression 1 0 "0.5+(0.5*cos((in(1,1)+0.5)*pi*2))" my-ramp))
(setq my-string (make-object 'mono-string))
(setq my-ctl (make-controller 'expression 1 0 "get_info('mode-frequency', in(1), 0)" my-string))
Options
Operations
The operations in the expression string can be any of the following:
- the four standard arithmetic operators:
-
-
-
- /
-
- exponential functions:
- sqrt(x)
- power(x,n)
- exp(x)
- log(x,n)
- log10(x)
- trigonometric functions:
- cos(x)
- sin(x)
- tan(x)
- acos(x)
- asin(x)
- atan(x)
- sinh(x)
- cosh(x)
- tanh(x)
- other functions:
- abs(x)
- min(x,y)
- max(x,y)
- sign(x)
- comparison:
- <
- <=
-
=
- logical operators:
- and
- or
- conditional statements:
- if (condition, if-true, if-false)
- constants
- pi
- local variables (statements separated by a semicolon):
- a = 1; b = a+1;
- controllers are indexed by
(numbering starts from 1): - in(1,1)
- objects are indexed by
(no dimension index! and numbering starts from 1) - in(1)
- the Modalys (get-info ... ) command can be accessed using get_info():
- get_info('sample-rate')
- get_info('mode-frequency', in(1), 0)
- multi-dimensional outputs are possible by separating multiple items with commas inside square brackets - each corresponds to a different dimension of the output controller
- [ expression_1 , expression_2 ]
Some practical examples to demonstrate the syntax in a complete expression string:
- cosine of an input-controller:
- "cos(in(1,1))"
- masking = maximum between 2 dimensions of two input-controllers:
- "max(in(1,1),in(1,2))"
- clipping a controller to lie between -1,1:
- "max(-1,min(1,in(1,1)))"
Also, within the Lisp environment, you could also use the Lisp (format ...) function to generate expressions for the expression controller:
(format nil "~{~[~; + ~]~cos~;sin~~}" (list-of-groups-of-4-numbers))