Using Controllers¶
Note
This is currently just a placeholder to capture the full horror of everything I
have to document for !controller.
Flitter supports interacting with running programs through the use of MIDI control surfaces. Currently, the list of supported devices is just the Ableton Push2 and the Behringer X-Touch mini, because those are the two devices that the author owns.
Controller Configuration¶
Controllers are configured by specifying an interface through a set of abstract controls, and then linking the output of these controls into the state mapping where the values can be accessed by the running program. The configuration of the control interface can be dynamically adjusted as the program runs.
The top-level node for controllers is !controller. This takes the single
attribute:
driver=DRIVERThe controller driver to use. Currently one of
:push2or:xtouch_mini.
The drivers are designed to be resilient to the control device being missing or disconnecting and reconnecting while Flitter is running.
Inside the !controller node, there should be a set of individual nodes that
configure each available control.
Common control attributes¶
There are a number of attributes that are common to all nodes.
id=IDA value that identifies the specific physical control (button, knob or otherwise) on the controller. These are defined by the driver and are listed below.
state=PREFIXThis provides a key/prefix to use in the state mapping for the outputs of this control. Generally the key PREFIX will be the primary output value of the control, but additional values may be available at keys such as PREFIX
;:beat. The individual control types list these.label=TEXTA label to use for this control. This is only expected to be useful on controllers that have some kind of display associated with particular controls.
color=COLORA single brightness value, or a 3-vector of red, green and blue values. For controls that have an associated LED, this will specify the output of that LED. This may just be a
0/1, on/off value if the LED does not support either brightness or color.action=ACTIONA symbol specifying an internal engine action to take when this control is activated. The valid actions will vary on whether the control is a button or a position control (such as a slider or rotary) and are documented below.
Positional controls¶
Positional controls are able to represent some value within a range. These include knobs, pressure pads and sliders. They support the following generic attributes:
lower=LOWERThe lower value of the output range. Defaults to
0.upper=UPPERThe upper value of the output range. Defaults to
1and must be greater thanlower.origin=ORIGINA value that specifies an “origin” value in the output range. This attribute only makes sense where the physical control has some kind of associated visual feedback that provides a bar graph style representation for the current value with a variable “zero” point. This defaults to
0ifloweris less than zero andupperis greater than zero, otherwise it will default tolower.lag=LAGSpecifies a coefficient to apply an exponential moving average to the control’s output value. This is used to “smooth out” the actual value and is particularly useful for controls that step slightly, like encoders, or just to limit the effect of jerky movements on the program. The default is specific to the driver.
The processed output value of a positional control is stored to the state
key.
Rotaries¶
Rotary controls are knobs, including potentiometers and encoders, that can be
mapped to a value in a range. They are configured with the !rotary node, which
accepts the positional control attrbutes above as well
as the following rotary-specific attributes:
turns=TURNSThe number of turns of an encoder that represents the full range of the output. Defaults to
1.wrap=(true|false)Specifies whether this value will wrap around between the
upperandlowerends of the range. This only makes sense for encoders that do not have a physical limit. Defaults tofalse.initial=INITIALSpecifies a value in the output range that this control will start at (or reset back to if resetting is supported). This only makes sense for encoders.
style=[:volume|:pan|:continuous]Specifies a behaviour for the control and a display style if the controller supports visual feedback. This indicates a preference for a volume style bar that fills as the knob is turned, a pan style that fills in either direction from the
originpoint, or a continuous style that indicates a position with a single mark (most useful with encoders andwrap=true). This defaults to:volumeunlessoriginis greater thanlower, in which case it defaults to:pan.
Setting style=:continuous and wrap=false on an encoder control will allow
the output value to range beyond lower and upper. The lower and upper
values will be used for display purposes, but turning the knob “beyond” these
points will cause the output value to continue to increase or decrease.
Pads¶
lower=
upper=
threshold=
Sliders¶
lower=
upper=
origin=
lag=
initial=