Skip to content

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:

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.


★     ★