NamedControl
Overview
Controls added to the Intelligent Module UI and their underlying DSP parameters can be accessed from the script using the NamedControl interface.
The extensive remote-control system in Composer can then be used to link any named controls in the Intelligent Module UI to any other controls in the system using Remote Control Numbers.
NamedControl.
| Return Type | Return Range | Comment | |
|---|---|---|---|
| NamedControl.GetText(name) | String | String | Gets the Text of the Named Control |
| NamedControl.SetText(name, value) | Function | Sets the Text of the Named Control | |
| NamedControl.GetValue(name) | Float | User adjustable range | Gets the Value of the Named Control |
| NamedControl.SetValue(name, value) | Function | Sets the Value of the Named Control | |
| NamedControl.GetPosition(name) | Float | 0-1 | Gets the Position of the Named Control |
| NamedControl.SetPosition(name, position) | Function | 0-1 | Sets the Position of the Named Control |
| NamedControl.ModifyValue(name, offset) | Function | Modify the Value of the Named Control by an offset | |
| NamedControl.GetChanged(name) | Bool | Allows you to ask if a Control value has changed | |
| NamedControl.SubscribeText(name) | Function | Subscribe to a Control to get changes | |
| NamedControl.EventHandler(name, value) | Event Handler | Handle Changes from Subscribed Controls | |
| NamedControl.GetProperty(name, propertyName) | String | Gets the value of a Control's Property | |
| NamedControl.SetProperty(name, propertyName, v1...vN) | Function | Sets the value of a Control's Property |
The API uses an editable control “name” as an argument for each function. The names correspond to the editable property “Script Name” for each control.
Do not reuse Script Names. The script will choose the first placed control if there are multiple with the same name. Copying and pasting a control will result in duplicate names.
For more about these control properties, see Intelligent Module Control View Layout.
The NamedControl API works differently for each control type. Control types are described in detail here.
NamedControl.GetText(name)
Returns a String of the Text displayed on the control with the provided name.
Print(NamedControl.GetText("myLabel")) >> Ben
This works for the following control types:
| Control | Function |
|---|---|
| Fader | |
| Meter | |
| Knob | |
| Button | |
| Radio Button | |
| Toggle | |
| LED | |
| Readout | |
| Drop List | |
| Label |
NamedControl.SetText(name, value)
Sets the Text displayed on the control with the provided name, using the provided text.
NamedControl.GetText("myLabel", "Ben")) -- Set Label to Ben
This works for the following control types:
| Control | Function |
|---|---|
| Fader | |
| Meter | |
| Knob | |
| Button | |
| Radio Button | |
| Toggle | |
| LED | |
| Readout | |
| Drop List | |
| Label |
Remember that for Labels and Video Stream, you will use the .SetText function, while for all others control types, you will use .SetValue or .SetPosition described below.
All controls can have their text set to a static value using the Properties Panel.
NamedControl.GetValue(name)
Returns a Float of the Value of the control with the provided name.
Print(NamedControl.GetValue("myFader")) >> 40
The float value returned is the control's actual value, within the range specified by the Minimum and Maximum items in the Properties Panel for the control. Minimum refers to the value at minimum control position; similarly, Maximum is the value at the maximum control position. The values can be inverted if its desired to have the control operate backward. The Taper affects how Position maps to Value (see GetPosition / SetPosition), not a direct Value read or write.
This works for the following control types:
| Control | Function |
|---|---|
| Fader | |
| Meter | |
| Knob | |
| Button | |
| Radio Button | |
| Toggle | |
| LED | |
| Readout | |
| Drop List | |
| Label |
NamedControl.SetValue(name, value)
Sets the Value of the control with the provided name, to the specified value.
NamedControl.SetValue("myFader", 50) >> Fader value set to 50
The value is the control's actual value, within the range specified by the Minimum and Maximum items in the Properties Panel for the control. Minimum refers to the value at minimum control position; similarly, Maximum is the value at the maximum control position. The values can be inverted if its desired to have the control operate backward. The Taper affects how Position maps to Value (see GetPosition / SetPosition), not a direct Value read or write.
This works for the following control types:
| Control | Function |
|---|---|
| Fader | |
| Meter | |
| Knob | |
| Button | |
| Radio Button | |
| Toggle | |
| LED | |
| Readout | |
| Drop List | |
| Label |
Remember that while most controls use the .SetValue function, you will instead use .SetText for labels and Video Stream controls as described below above.
NamedControl.GetPosition(name)
Returns a Float of the Position of the control with the provided name.
Print(NamedControl.GetPosition("myFader")) >> 0.4
The Position is a 0-1 representation of where the Value sits between the control's Minimum and Maximum (from the Properties Panel). It is a linear mapping — Position = (Value − Minimum) / (Maximum − Minimum) — always clamped to the 0-1 range, and inverted controls (Minimum greater than Maximum) are handled automatically.
Because the mapping is linear, Position does not apply the control's Taper. For controls that use a non-linear taper (such as a logarithmic fader), the Position will therefore not match the physical knob or fader location. Use Position when you want a value normalized across the control's range, and Value when you want the control's actual value.
This works for the following control types:
| Control | Function |
|---|---|
| Fader | |
| Meter | |
| Knob | |
| Button | |
| Radio Button | |
| Toggle | |
| LED | |
| Readout | |
| Drop List | |
| Label |
NamedControl.SetPosition(name, position)
Sets the Position of the control with the provided name, to the specified value.
NamedControl.SetPosition("myFader", .5) >> Fader position set to .5
Again, the Position is a 0-1 value mapped linearly across the control's Minimum and Maximum — Value = (Position × (Maximum − Minimum)) + Minimum — and is clamped to the 0-1 range, with inverted controls handled automatically. Because the mapping is linear, it does not apply the control's Taper, so for controls with a non-linear taper (such as a logarithmic fader) a given Position will not correspond to the physical knob or fader location.
This works for the following control types:
| Control | Function |
|---|---|
| Fader | |
| Meter | |
| Knob | |
| Button | |
| Radio Button | |
| Toggle | |
| LED | |
| Readout | |
| Drop List | |
| Label |
NamedControl.ModifyValue(name, offset)
Sometimes you may need to modify the value by an offset. This is great for up/down increment/decrement buttons.
NamedControl.ModifyValue("myFader, 1") >> Fader value increased by 1
This works for the following control types:
| Control | Function |
|---|---|
| Fader | |
| Meter | |
| Knob | |
| Button | |
| Radio Button | |
| Toggle | |
| LED | |
| Readout | |
| Drop List | |
| Label |
NamedControl.GetChanged(name)
Returns a 1 if the Value or Text of the control with the provided name has changed since the last time it was checked, otherwise 0.
Print(NamedControl.GetChanged("myFader")) >> 1
This is a convenient alternative to storing a control's previous value and comparing it on each pass (see Example 2 below). Checking GetChanged clears the changed flag, so each change is only reported once. A subsequent call will return 0 until the control changes again.
Note
GetChanged and SubscribeText share the same internal "changed" flag for a control, and checking either one clears it. Do not use both on the same control, or they will steal change notifications from each other — a change consumed by GetChanged will not trigger the EventHandler, and vice versa. Pick one mechanism per control.
This works for the following control types:
| Control | Function |
|---|---|
| Fader | |
| Meter | |
| Knob | |
| Button | |
| Radio Button | |
| Toggle | |
| LED | |
| Readout | |
| Drop List | |
| Label |
NamedControl.SubscribeText(name)
To monitor a control for changes, you first need to subscribe to the control by Script Name.
NamedControl.SubscribeText("source") -- Subscribe to the control called "source"
Then you will need to used NamedControl.EventHandler(name, value) to handle the event when the control changes.
Note
Subscribed controls and GetChanged share the same internal "changed" flag for a control. If you also call GetChanged on a subscribed control, whichever runs first clears the flag and the other will miss the change. Do not use both mechanisms on the same control — pick one.
NamedControl.EventHandler(name, value)
This event handler handles changes to subscribed controls.
function MyHandler(controlName, value)
if controlName == "source" then -- Handle the particular source
NamedControl.SetValue("dest", value)
end
end
NamedControl.EventHandler = MyHandler -- Handler for NamedControl changes
NamedControl.SubscribeText("source") -- Subscribe to the "source"
This can also be done with an anonomous founction:
NamedControl.EventHandler = function (controlName, value) -- Handler for NamedControl changes
if controlName == "source" then -- Handle the particular source
NamedControl.SetValue("dest", value)
end
end
NamedControl.SubscribeText("source") -- Subscribe to the "source"
It's important to note that the value returned is a string. So if you need to test equality with a number (e.g. 0 or 1) you will need to convert it like this:
if (tonumber(value)) == 1.0 then
This works for the following control types:
| Control | Function |
|---|---|
| Fader | |
| Meter | |
| Knob | |
| Button | |
| Radio Button | |
| Toggle | |
| LED | |
| Readout | |
| Drop List | |
| Label |
NamedControl.GetProperty(name, propertyName)
Used to Get Properties from a Control or CPG. It has the following arguments and Return Values.
Arguments:
- name - the user assigned “script name” for a control or control panel group.
- property - a property from the table of properties supported.
Return Values:
- one or more values associated with the property as shown in properties table.
NamedControl.SetProperty(name, propertyName, v1...vN)
Used to Set Properties for a Control or CPG. It has the following arguments and Return Values.
Arguments:
- name - the user assigned “script name” for a control or control panel group.
- property - a property from the table of properties supported.
- value, one or more values as supported by the specified property.
Return Values
- nil if successful, otherwise an error string.
Control Properties
The following properties are supported by individual controls in a control panel group when using NamedControl.GetProperty(name, propertyName) or NamedControl.SetProperty(name, propertyName, v1...vN).
| Property | Read-only | Value(s) | Possible Errors |
|---|---|---|---|
| col | No | int/double - Column of control on control panel. Double is truncated to integer, must entirely fit on control panel. | Argument countOut of rangeWrong type |
| row | No | int/double - Row of control on control panel. Double is truncated to integer, must entirely fit on control panel. | Argument count,Out of rangeWrong type |
| cols | No | int/double - Number of column width of control on control panel. Double is truncated to integer, must entirely fit on control panel. | Argument count,Out of rangeWrong type |
| rows | No | int/double - Number of row height of control on control panel. Double is truncated to integer, must entirely fit on control panel. | Argument countOut of rangeWrong type |
| position | No | col, row - see above | Argument countOut of rangeWrong type |
| shape | No | col, row, cols, rows - see above | Argument countOut of rangeWrong type |
| panel | No | int/double - One based panel number containing control. Must be less than or equal to number of panels | Argument countOut of rangeWrong type |
| visible | No | Boolean/int/double - If the control is visible. double or int evaluated as zero or non-zero. | Argument countWrong type |
| min | No | int/double - The minimum value allowed for the control position. It can be outside the acceptable range for the assigned DSP parameter but the value will be clamped to that limit. | Argument countWrong type |
| max | No | int/double - The maximum value allowed for the control position. It can be outside the acceptable range for the assigned DSP parameter but the value will be clamped to that limit. | Argument countWrong type |
Control Panel Group Properties
The following properties are supported by the entire control panel group.
| Property | Read-only | Value(s) | Possible Errors |
|---|---|---|---|
| rows | Yes | double - Number of rows width of control panel. | |
| cols | Yes | double - Number of cols width of control panel. | |
| panel | No | int/double - One based panel number currently displayed. Must be less than or equal to number of panels | Argument countOut of rangeWrong type |
| panels | Yes | int - The number of panels | Read-only |
Usage Examples
The following examples illustrate how these can be used:
Example 1 - General Usage with Polling
A common way to use named controls is to poll them using a timer. Every TimerClick period, the values of the inputs are read, some processing is performed, and the user interface is updated. This takes the form of the example below:
function TimerClick ()
newValue = NamedControl.GetValue("MyFader")
-- Do some processing
newValue = newValue * 0.8
NamedControl.SetValue("MyMeter", newValue)
end
MyTimer = Timer.New()
MyTimer.EventHandler = TimerClick
MyTimer:Start(0.5) -- Update the UI every 0.5 sec
Example 2 - Storing Values and Comparing
It’s important to be as efficient as possible during these TimerClick() functions. Any UI processing that doesn’t update regularly, should be checked and handled separately. And you only want to update the controls on screen if they have changed.
In most cases, you will want to store the current state of a control and compare it with the updated state of the control at the next timer click. You can then perform some action based on the new value. If it hasn’t changed, you can skip a bunch of work. So Example 1 can be rewritten as.
currentValue = 0
function TimerClick ()
newValue = NamedControl.GetValue("MyFader")
if newValue ~= currentValue then --Compare Values
-- Do some processing
newValue * 0.8
NamedControl.SetValue("MyMeter", newValue)
currentValue = newValue --Update for the next pass
end
end
MyTimer = Timer.New()
MyTimer.EventHandler = TimerClick
MyTimer:Start(0.5)
While this uses more code, it is more efficient because we are only doing the processing and updating the UI when needed.
Example 3 - Self-Clearing Latching Button
In most cases, we recommend using a self-clearing Latching Button over a Momentary Button. This is because changes to a momentary button could be missed or misinterpreted, especially with slower timer intervals.
For example, if you pressed a momentary button and released it after one TimerClick but before the next, the action will be missed. Even at the fastest supported interval of 0.25 seconds, this can still happen. And you don’t want to have to run your timer at fast speeds just to try to catch these, as that will use up significantly more CPU than you might otherwise need. To ensure presses aren’t missed, it is best to use a Latching Button with code to clear its state after its value is read.
function TimerClick ()
newValue = NamedControl.GetValue("MyButton")
if newValue == 1 then --Check if pressed
-- Do some stuff when the button is pressed
-- Reset the button by turning it off
NamedControl.SetValue("MyButton", 0)
end
end
MyTimer = Timer.New()
MyTimer.EventHandler = TimerClick
MyTimer:Start(0.5)
Example 4 - Long Press Momentary Buttons
One good use for a Momentary Button is for implementing buttons that have different functions when held for long periods of time. For example, a button could have a different function when pressed for 5 seconds than 2 and in which there is a separate feedback mechanism to the user that the button press has been accepted. This still requires that the shortest acceptable press be longer than the Timer interval.
--Button Times
resultOneTime = 2000
resultTwoTime = 5000 --should be longer than resultOneTime
--State Variables
startTime = System.GetTime()
timeElapsed = 0
resultOneComplete = false
resultTwoComplete = false
runInProgress = false
function TimerClick ()
newButtonValue = NamedControl.GetValue("ButtonAction")
--Check if run in progress and button is pressed
if runInProgress == false and newButtonValue == 1 then
--Clear Results
resultOneComplete = false
resultTwoComplete = false
--start measuring time from now
startTime = System.GetTime()
timeElapsed = 0
--start run
runInProgress = true
elseif runInProgress == true and newButtonValue == 1 then
timeElapsed = System.GetTime() - startTime
if timeElapsed >= resultTwoTime then
--Do work when Time Two is reached
resultTwoComplete = 1
end
elseif runInProgress == true and newButtonValue == 0 then
if timeElapsed >= resultOneTime and timeElapsed < resultTwoTime then
--Do work when Time One is reached and button is released
resultOneComplete = 1
end
--end run
runInProgress = false
--stop measuring time
timeElapsed = 0
end
--update the UI
end
MyTimer = Timer.New()
MyTimer.EventHandler = TimerClick
MyTimer:Start(.25)
Example 5 - Radio Buttons
Because Radio Buttons return floats for NamedControl.GetValue and 16 bit math is used, the returned value may not exactly match the corresponding integer value. As such, a rounding function as shown below should be used.
--Handling 3 position Radio Button
if (0 == math.floor(NamedControl.GetValue("Button #1") + .5)) then
print("Position 1")
elseif (1 == math.floor(NamedControl.GetValue("Button #1") + .5)) then
print("Position 2")
elseif (2 == math.floor(NamedControl.GetValue("Button #1") + .5)) then
print("Position 3")
else
print("Button value"..NamedControl.GetValue("Button #1"))
end