Lua: Create Controllers with create_controller
Description
In Lua context, modalys.create_controller creates Modalys controllers from a parameter table. The same function is also available as create_controller, make_controller, and modalys.make_controller.
Parameter names are normalized before use: names are lowercased, hyphens and underscores are removed, and common aliases are accepted. For example, dimension becomes dim, frequency, freqs, and frequencies become freq, and values becomes value.
Lua Syntax
local ctrl = modalys.create_controller{
kind = "dynamic",
value = { 0.1, 0.5, 1.0 },
name = "MyDynamic"
}
-- Equivalent aliases:
local ctrl2 = create_controller{ kind="constant", value=1 }
local ctrl3 = make_controller{ kind="random", dim=2, period=0.01 }
Parameters
The kind parameter selects the controller type. If kind is omitted, a dynamic controller is created.
- kind: controller type.
- name: optional Max/Modalys name. Names are made unique automatically.
- value: initial value, either a number or a table.
- dim or dimension: controller dimension. Used when the controller kind requires an explicit dimension, or when a dynamic controller has no value.
- period: update period where supported. A value of -1 means automatic.
- input, ctrl, controller, ctl, or ctlr: input controller for derived controllers.
Supported Kinds
The implementation currently handles the following values for kind:
- dynamic
- constant
- signal
- access-speed
- access-position
- access-force
- sine
- noise
- bandlimited-noise or band-limited-noise
- random
- dimension
- spread
- sum
- scale
- last-sample
- phasor
- bilinear-filter
- biquadratic-filter
- constant-second-order-filter
- variable-second-order-filter
- dimension-mapping
- arithmetic
- moment
- delay
- timer
- connection-state
Controller-Specific Parameters
dynamic
Creates a dynamic controller. This is the default when kind is omitted.
- value: initial value, either a number or a table. Default is { 0 }.
- dim or dimension: dimension used only when value is omitted. In that case the controller is initialized with zeros.
- period: update period. Default is -1.
- name: optional name. Default base name is Dynamic.
local ctrl = create_controller{ kind="dynamic", value={ 0.1, 0.2 } }
constant
Creates a constant controller.
- value: constant value, either a number or a table. Default is { 0 }.
- dim or dimension: dimension override.
local ctrl = create_controller{ kind="constant", value=1 }
signal
Creates a signal controller from a point input.
- input or inputs: required point input. The controller dimension is inferred from this input.
local input = create_point_input{ channel=1 }
local signal = create_controller{ kind="signal", input=input }
access-speed, access-position, access-force
Creates a controller that follows the speed, position, or force at an access.
- access or accesses: required Modalys access.
local speed = create_controller{ kind="access-speed", access=access }
sine
Creates a sine controller.
- freq, frequency, freqs, or frequencies: required frequency value or controller.
- phase or phases: phase value or controller. If omitted, zero is used for each dimension.
- name: optional name. Default base name is SineController.
Frequency and phase must have the same dimension.
local sine = create_controller{ kind="sine", freq={ 220, 440 }, phase={ 0, 0 } }
noise
Creates a noise controller.
- dim or dimension: dimension. Default is 1.
- period: update period. Default is 0.
- cutoff: cutoff controller or value. Default is 8000.
- delmin: minimum delay controller or value. Default is 0.3.
- delmax: maximum delay controller or value. Default is 0.7.
- outmin: minimum output controller or value. Default is 0.
- outmax: maximum output controller or value. Default is 1.
- taps: number of filter taps. Default is 10.
- name: optional name, also used to name generated subcontrollers.
local noise = create_controller{
kind = "noise",
dimension = 2,
cutoff = { 2200, 8000 },
delmin = { 0.3, 0.2 },
delmax = { 0.7, 0.9 },
outmin = { 0, -0.5 },
outmax = { 1, 2.5 },
taps = 30
}
bandlimited-noise, band-limited-noise
Creates a band-limited noise controller.
- cutoff: cutoff value or controller. If supplied, its dimension determines the controller dimension.
- dim or dimension: dimension used when cutoff is omitted. Default is 1.
- period: update period. Default is 0.
- taps: number of filter taps. Default is 10.
- name: optional name, also used to name generated subcontrollers.
local noise = create_controller{ kind="bandlimited-noise", cutoff={ 220, 440, 880 } }
random
Creates a random controller.
- dim or dimension: dimension. Default is 1.
- period: update period. Default is 0.01.
local random = create_controller{ kind="random", dim=3, period=0.005 }
dimension
Extracts one dimension from another controller.
- input, ctrl, controller, ctl, or ctlr: input controller.
- rank or index: zero-based dimension index. Default is 0.
local first = create_controller{ kind="dimension", input=input, rank=0 }
spread
Spreads a one-dimensional controller to several dimensions.
- input, ctrl, controller, ctl, or ctlr: required input controller.
- dim or dimension: required output dimension.
- period: update period. Default is -1.
local spread = create_controller{ kind="spread", input=input, dim=4 }
sum
Sums all dimensions of an input controller into a one-dimensional controller.
- input, ctrl, controller, ctl, or ctlr: required input controller.
- period: update period. Default is 0.
local total = create_controller{ kind="sum", input=input, period=0.01 }
scale
Scales an input controller from one range to another.
- input, ctrl, controller, ctl, or ctlr: required input controller.
- inmin: input minimum. Default is 0.
- inmax: input maximum. Default is 10.
- outmin: output minimum. Default is 0.
- outmax: output maximum. Default is 100.
local scaled = create_controller{ kind="scale", input=input, inmin=0, inmax=1, outmin=-1, outmax=1 }
last-sample
Creates a last-sample controller.
This kind does not require additional parameters.
local last = create_controller{ kind="last-sample" }
phasor
Creates a phasor controller.
- freq, frequency, freqs, or frequencies: required frequency value, table, or controller.
- phase or phases: phase value or table. If omitted, zero is used.
local phasor = create_controller{ kind="phasor", freq=2, phase=0 }
bilinear-filter
Creates a bilinear filter controller.
- input or inputs: required input controller.
- coefficients or coefficient: coefficient controller or table with exactly 3 values: { a0, a1, b1 }.
local filter = create_controller{
kind = "bilinear-filter",
input = input,
coefficients = { 1, 0, 0 }
}
biquadratic-filter
Creates a biquadratic filter controller.
- input or inputs: required input controller.
- coefficients or coefficient: coefficient controller or table with exactly 5 values: { a0, a1, a2, b1, b2 }.
local filter = create_controller{
kind = "biquadratic-filter",
input = input,
coefficients = { 1, 0, 0, 0, 0 }
}
constant-second-order-filter
Creates a constant second-order filter controller.
- input or inputs: required input controller.
- amp, amps, amplitude, or amplitudes: required amplitude value or table.
- freq, frequency, freqs, or frequencies: required frequency value or table.
- bw, bws, bandwidth, or bandwidths: required bandwidth value or table.
- period: update period. Default is -1.
The input, amplitude, frequency, and bandwidth dimensions must match.
local filter = create_controller{
kind = "constant-second-order-filter",
input = input,
amp = 1,
freq = 220,
bandwidth = 10
}
variable-second-order-filter
Creates a variable second-order filter controller.
- input or inputs: required one-dimensional input controller.
- freq, frequency, freqs, or frequencies: required frequency value or controller.
- bw, bws, bandwidth, or bandwidths: required bandwidth value or controller.
- amp, amps, amplitude, or amplitudes: amplitude value passed to the underlying controller.
- period: update period. Default is -1.
- name: optional name, also used to name generated frequency and bandwidth subcontrollers.
local filter = create_controller{
kind = "variable-second-order-filter",
input = input,
freq = 700,
bandwidth = 20
}
dimension-mapping
Creates a dimension-mapping controller.
- dim or dimension: required output dimension.
- input or inputs: required table of mapping rows.
Each mapping row starts with an input controller, followed by the source dimension index and one or more output dimension indexes.
local mapping = {
{ input1, 3, 0, 1, 2 },
{ input2, 1, 3 },
{ input3, 2, 4, 5 }
}
local ctrl = create_controller{
kind = "dimension-mapping",
dimension = 6,
input = mapping
}
arithmetic
Creates an arithmetic controller.
- operator: required arithmetic operator.
- input or inputs: required table of input controllers.
local product = create_controller{
kind = "arithmetic",
operator = "*",
input = { ctrl1, ctrl2 }
}
moment
Creates a moment controller.
- tofollow: required input controller to follow.
- delay: delay value or controller. Default is 0.
- power: moment power. Default is 1.
- dim or dimension: optional dimension override.
- name: optional name, also used to name the generated delay subcontroller.
local moment = create_controller{ kind="moment", tofollow=input, delay=0.1, power=2 }
delay
Creates a delay controller.
- input or inputs: required input controller.
- delay: delay value or controller. Default is 0.
- name: optional name. Default base name is DelayController.
local delayed = create_controller{ kind="delay", input=input, delay=0.6 }
timer
Creates a timer controller.
- time or times: time value or controller. Default is 0.
- autoreload: autoreload value or controller. Default is 0.
- name: optional name, also used to name generated subcontrollers.
local timer = create_controller{ kind="timer", time=1, autoreload=1 }
connection-state
Creates a controller that follows the state of a connection.
- connection: required Modalys connection.
local state = create_controller{ kind="connection-state", connection=connection }
Examples
Dynamic Controller
local amplitude = create_controller{
kind = "dynamic",
value = 0.5,
name = "Amplitude"
}
For multidimensional values, pass a Lua table:
local position = create_controller{
kind = "dynamic",
value = { 0.1, 0.2, 0.3 },
name = "Position"
}
If dim is provided without value, the controller is initialized with zeros:
local vector = create_controller{
kind = "dynamic",
dim = 4,
name = "Vector"
}
Constant Controller
local fixedGain = create_controller{
kind = "constant",
value = 2
}
Sine and Phasor Controllers
local sine = create_controller{
kind = "sine",
freq = 440,
phase = 0,
name = "Sine440"
}
local phasor = create_controller{
kind = "phasor",
freq = 2,
phase = 0
}
For sine, frequency and phase are internally converted to controllers and must have the same dimension. If phase is omitted, it defaults to zero for each frequency.
Derived Controllers
local input = create_controller{
kind = "dynamic",
value = { 1, 2, 3, 4 },
name = "Input"
}
local first = create_controller{
kind = "dimension",
input = input,
rank = 0
}
local total = create_controller{
kind = "sum",
input = input,
period = 0.01
}
local scaled = create_controller{
kind = "scale",
input = input,
inmin = 0,
inmax = 10,
outmin = -1,
outmax = 1
}
Filters
local input = create_controller{ kind="dynamic", value={ 0, 1, 2, 3 } }
local bilinear = create_controller{
kind = "bilinear-filter",
coefficients = { 1, 0, 0 },
input = input
}
local biquadratic = create_controller{
kind = "biquadratic-filter",
coefficients = { 1, 0, 0, 0, 0 },
input = input
}
The bilinear-filter kind requires three coefficients. The biquadratic-filter kind requires five coefficients.
Test Script
A focused test script is available in the Modalys source tree:
data/max/lab/testing/test_lua_create_controller.lua
It creates representative controllers and checks their dimensions and values with get_value and get_info.
★