Skip to content

Dynamic Controller

Description

A controller whose value can be dynamically changed. In Modalys for Max environment, the value can be changed using messages (sent to modalys\~). In Lisp, it can be changed between (run) statements at the whim of the user (or a foreign-call controller!), using (send-message ... ) or (set-breakpoint ... ) to create a ramp to a given value over a certain amount of time.

Lisp, Modalys for Max and Lua Syntax

The dynamic controller can be created using the following Lisp, mlys (Max) or mlys.lua syntax:

(make-controller 'dynamic
                  dimension
                  period
                  (list initial_values ... )
                  name)

The dimension and period parameters are mandatory in Lisp.

[mlys.dynamic @name MyDynamic @value 1.2]

The dimension and period parameters are hidden: dimension = 1 and period = -1 (auto update). There is also a target-attribute optional parameter that can be used to control a specific attribute of a connected object.

modalys.create_controller{ kind="dynamic", name="MyDynamic1"
                           value={0.1,1.4,1.3e-8}, period=0 }

The dimension is automatic.
The period parameter is optional and set to -1 (auto update) by default.

Parameters and Default Values

The 'dynamic controller takes four arguments:

  • dimension: number of dimensions of the output controller
  • period: sampling period (seconds).
  • initial_values: a list of initial (default) values for the controller.
  • name: the name (in quotes) that is used for Max messenging.

As always, a sampling period of 0 indicates that the controller will be updated every sample. Additionally, you can provide a value of -1 for the sampling period to indicate that the controller will be updated only when it receives a new message (this is more efficient than forcing the dynamic controller to update every sample).

The number of initial values should correspond to the number of dimensions.

When using the dynamic controller to receive Max messages, the message name should be given as a string, i.e in quotes: "button1", etc...

Discussion

There are two ways a dynamic controller may be used. The "traditional" way, from the days before computers were fast enough to compute samples in real-time, is to instantiate the controller and then send messages to it, using (send-message ...) in-between (run) statements. First the controller is defined, with a message name as a final argument:

(setq my-dynamic-ctl (make-controller 'dynamic 1 0 '(0) "env1"))
Using the message name as a final argument allows the controller to be typed directly into other Modalys functions, without needing to use (setq ... ) to create a reference to it. The following series of runtime statements will create the breakpoints shown in the graph, above.

(run 0.25) ; run for 250 ms. the controller will be at the default value
(send-message "env1" 1 0.5) ; send a message to move the dynamic controller to 1 over 500 ms.
(run 0.25) ; run for 250 ms. the controller will begin to ramp upward to its destination value
(send-message "env1" -1 0.5) ; controller will be interrupted at  current value and a new ramp initiated from that point.
(run 0.5) ; run for 500 ms. the controller will ramp downwad to its destination value
(send-message "env1" 1) ; controller will jump to a value of 1 immediately (since no ramp time is provided)
(run 0.5) ; run for 500 ms. the controller will remain at the value 1
(send-message "env1" -1 0.5) ; message to move the dynamic controller to -1 over 500 ms.
(run 0.5)
This "runtime" functionality is still useful when testing out "instruments" inside the Lisp environment, before exporting them to a .mlys file to be used in real-time.

Formerly, the (set-breakpoint ...) function was used to set the ramp, Although this function still exists and can be used (It is documented below), we recommend using (send-message ...), instead.

In real-time contexts (such as when using modalys~ in Max/MSP or when using the (run-real-time) command within the Lisp implementation of Modalys) can also receive these messages using Max, or OSC (Open Sound Control). You will need to set the IP port to the same one on which OSC messages are being sent, such as port 4000, as in this example:

(listen-ip-port 4000)
(run-real-time)

Options

Retro-Compatibility

The set-breakpoint command was formerly used in place of (send-message ...) Although you may still use it, we recommend using the new syntax. In the old syntax, the dynamic controller can optionally be instantiated without a message name:

(setq my-ctl (make-controller 'dynamic dimension period (list initial_values ... )))
The set-breakpoint command is then used to change the controller values. Its syntax is as follows:

(set-breakpoint name_of_dynamic_controller
         (list time_to_reach_destination value value ... ))
As an example, the above example would be written like this:

(run 0.25) ; run for 250 ms. the controller will be at the default value
(set-breakpoint my-ctl  0.5 1) ; send a message to move the dynamic controller to 1 over 500 ms.
(run 0.25) ; run for 250 ms. the controller will begin to ramp upward to its destination value
(set-breakpoint my-ctl 0.5 -1) ; controller will be interrupted at  current value and a new ramp initiated from that point.
(run 0.5) ; run for 500 ms. the controller will ramp downwad to its destination value
(set-breakpoint my-ctl  0 1) ; controller will jump to a value of 1 immediately (since  ramp time is set to 0)
(run 0.5) ; run for 500 ms. the controller will remain at the value 1
(set-breakpoint my-ctl 0.5 -1) ; message to move the dynamic controller to -1 over 500 ms.
(run 0.5)
One advantage of using set-breakpoint is that it can easily control multi-dimensional controllers.

Additionally, there was briefly an 'osc controller using the same syntax as the dynamic controller. Its functionality has been merged into the dynamic controller. Old scripts should therefore be updated to use the dynamic controller, instead.


★     ★