Source concepts
Real vs. virtual sources
We distinguish between virtual and real sources.
Virtual source
A virtual source refers to a Virtual control element and can only be used in the Main compartment.
Examples: ch1/fader
Real source
A real source refers to a Real control element.
MIDI source character
MIDI control-change messages serve a very wide spectrum of MIDI control use cases. Even though some control-change controller numbers have a special purpose according to the MIDI specification (e.g. CC 7 = channel volume), nothing prevents one from using them for totally different purposes. In practice that happens quite often, especially when using general-purpose controllers. Also, there’s no strict standard whatsoever that specifies how relative values (increments/decrements) shall be emitted and which controller numbers emit them.
Therefore, you explicitly need to tell ReaLearn about it by setting the source character.
The good news is: If you use "Learn source", ReaLearn will try to guess the source character for you by looking at the emitted values. Naturally, the result is not always correct. The best guessing result can be achieved by turning the knob or encoder quickly and "passionately" into clockwise direction. Please note that guessing doesn’t support encoder type 3.
The possible source characters are:
- Range element (knob, fader, etc.)
-
A control element that emits continuous absolute values. Examples: Fader, knob, modulation wheel, pitch bend, ribbon controller. Would also include a endless rotary encoder which is (maybe unknowingly) configured to transmit absolute values.
- Button (momentary)
-
A control element that can be pressed and emits absolute values. It emits a > 0% value when pressing it and optionally a 0% value when releasing it. Examples: Damper pedal.
- Encoder (relative type x)
-
A control element that emits relative values, usually an endless rotary encoder. The x specifies how the relative values are sent. This 1:1 corresponds to the relative modes in REAPER’s built-in MIDI learn:
- Type 1
-
-
127 = decrement; 0 = none; 1 = increment
-
127 > value > 63 results in higher decrements (64 possible decrement amounts)
-
1 < value <= 63 results in higher increments (63 possible increment amounts)
-
- Type 2
-
-
63 = decrement; 64 = none; 65 = increment
-
63 > value >= 0 results in higher decrements (64 possible decrement amounts)
-
65 < value <= 127 results in higher increments (63 possible increment amounts)
-
- Type 3
-
-
65 = decrement; 0 = none; 1 = increment
-
65 < value <= 127 results in higher decrements (63 possible decrement amounts)
-
1 < value <= 64 results in higher increments (64 possible increment amounts)
-
- Toggle-only button (avoid!)
-
A control element that can be pressed and emits absolute values. ReaLearn will simply emit 100%, no matter what the hardware sends.
This is a workaround for controllers that don’t have momentary buttons! You should only use this character if there’s absolutely no way to configure this control element as a momentary button.
BackgroundReaLearn can make a momentary hardware button work like a full-blown toggle button. Its toggle mode is inherently more powerful than your controller’s built-in toggle mode!).
However, the opposite is not true. It can’t make a toggle hardware button act like a momentary button.
Combination with user-interface/mapping-panel/glue-section.adoc#incremental-buttonIf you use the toggle-only source character in combination with mode Incremental button mode, you must leave source max at the (default) theoretical maximum value for that source (e.g. 127 for MIDI CC). Even if your controller device only sends 0 and 1 and in all other mappings you would enter the controller’s concrete (instead of theoretically possible) maximum value. Otherwise, for this special case, a fixed out-of-range-behavior will set in that will just ignore all button presses.
MIDI source script
MIDI source scripts are EEL or Luau scripts to configure the Source "MIDI Script".
General mechanics
Each script receives an input and must produce an output.
- Script input
-
-
The main input is the current feedback value, which the script can access as a variable.
-
- Script output
-
-
The main output that the script is supposed to return is the MIDI message to be sent to the MIDI device.
-
Additionally, the script can provide a so-called feedback address, which is supposed to uniquely identify the LED, motor fader or display.
It’s important to provide an address if you want ReaLearn to handle feedback relay correctly, e.g. that it switches off the LED when not in use anymore and doesn’t switch it off if another mapping "takes over" the same LED. By convention, the constant (non-variable) bytes of the MIDI message should be used as address. The examples below might help to understand.
-
EEL script specifics
Scripts written in EEL work as follows.
- Script input
-
-
EEL scripts can access numeric feedback values only. The current numeric feedback value is available as variable
y
, a floating point number between 0.0 and 1.0. This is essentially the current normalized target value after being processed by the "Glue" section of the mapping.
-
- Script output
-
-
In order to provide the output MIDI message, you must assign the raw bytes of that message to subsequent slots of the EEL script’s virtual local address space (by indexing via brackets) and set the variable
msg_size
to the number of bytes to be sent. If you forget the latter step, nothing will be sent because that variable defaults to zero! -
In order to provide the address, simply assign an appropriate number to the
address
variable.
-
address = 0x4bb0;
msg_size = 3;
0[] = 0xb0;
1[] = 0x4b;
2[] = y * 64;
Luau script specifics
Scripts written in Luau work as follows.
- Script input
-
-
Luau scripts can access numeric, text and dynamic feedback values.
-
Here’s the list of input variables:
y
-
The feedback value, either numeric (
type(y) == "number"
) or text (type(y) == "string")
. context.feedback_event.color
-
The color as set in the Glue section section. Either the default color (
== nil
) or an RGB color (table with propertiesr
,g
andb
). context.feedback_event.background_color
-
The background color.
-
- Script output
-
-
A Luau script can even generate multiple output messages.
-
You need to return a table which contains the following keys:
address
-
The feedback address.
messages
-
An array containing all the messages, where each message itself is an array contaning the message bytes.
-
y
is a numeric normalized value.return {
address = 0x4bb0,
messages = {
{ 0xb0, 0x4b, math.floor(y * 10) }
}
}
local color = context.feedback_event.color
if color == nil then
-- This means no specific color is set. Choose whatever you need.
color = { r = 0, g = 0, b = 0 }
end
return {
address = 0x4b,
-- Whatever messages your device needs to set that color.
messages = {
{ 0xf0, 0x02, 0x4b, color.r, color.g, color.b, 0xf7 }
}
}
y
is a text value.local lookup_table = {
playing = 5,
stopped = 6,
paused = 7,
}
return {
messages = {
{ 0xb0, 0x4b, lookup_table[y] or 0 }
}
}
Please note that this kind of simple mapping from text values to integer numbers doesn’t need a script.
You can use the |
You can share code between multiple MIDI scripts by using Compartment-wide Lua code, with the following limitations (which hopefully will be lifted over time):
-
The shared code is not yet available to the Lua code editor window. That means writing
require("compartment")
will evaluate tonil
in the editor. You might see a corresponding error message when the editor tries to compile your code.
OSC feedback arguments expression
This expression is used to enable for more flexible feedback for the Source "OSC".
It allows you to define exactly which feedback value is sent at which argument position. If this field is non-empty, the argument type will be ignored for the Feedback direction.
The format of this field is very simple: You enter feedback value property keys separated by spaces. Each entered property key corresponds to one argument position.
If you want ReaLearn to send the current feedback value in text form at argument 1 and the color (see Feedback style menu (…)) as RRGGBB string at argument 2, you would enter:
value.string style.color.rrggbb
The following properties are available:
Property | Type | Description |
---|---|---|
|
|
Numeric feedback value interpreted as float |
|
|
Numeric feedback value interpreted as double |
|
|
Numeric feedback interpreted as bool (on/off only) |
|
|
Numeric or textual feedback value formatted as string |
|
|
Feedback value color formatted as RRGGBB string |
|
|
Feedback value background color formatted as RRGGBB string |
|
|
Feedback value color as native OSC color |
|
|
Feedback value background color as native OSC color |
|
|
Nil value |
|
|
Infinity value |