Compartment concepts
Compartment preset
Main presets vs. controller presets
Factory preset vs. User preset
Factory preset
Factory presets are built-in compartment presets. You can’t change them yourself. But you can "make them your own" by making a copy of them. See Writing presets with Luau.
User preset
User presets are made by users, for example by you.
-
Saving your mappings as a preset is optional. All controller mappings are saved together with your current ReaLearn unit anyway, no worries. But as soon as you want to reuse these mappings in other ReaLearn unit or for Auto-load, it makes of course sense to save them as a preset!
-
All of your presets end up in the REAPER resource directory (REAPER → Options → Show REAPER resource path in explorer/finder) at
Data/helgoboss/realearn/presets
followed bymain
(for main compartment presets) orcontroller
(for controller compartment presets). They are JSON files and very similar to what you get when you press Export to clipboard. -
They can even be in a subdirectory. Please note that the subdirectory name becomes a part of the preset ID, so better don’t move existing presets around if you want preset references of existing ReaLearn units to stay intact.
-
JSON files can also contain custom data sections. For example, the ReaLearn Companion app adds a custom data section to controller presets in order to memorize the positions and shapes of all control elements.
Writing presets with Luau
It is possible to write compartment presets with the Luau language instead of building them via the user interface. Many of the more complex ReaLearn factory presets are written in Lua, e.g. the "DAW control" preset.
A good way to get started writing Luau presets is to create your personal compartment preset user workspace.
A preset workspace is a subdirectory within the compartment preset parent directory that may contain a bunch of presets and other files.
Important facts about preset workspaces/namespaces:
-
It may contain both Luau presets (
.preset.luau
) and conventional JSON presets (.json
)! -
The name of the workspace (subdirectory) is at the same time the first part of the preset ID. For example, if the subdirectory name is
helgoboss
and it contains a preset filemy-preset.json
, the final ID of that preset will behelgoboss/my-preset
. -
That also means that presets from different workspaces never conflict with each other.
-
Therefore, a preset "workspace" is at the same time a preset "namespace". Those terms are sometimes used interchangeably.
-
It’s important that the ID of a preset doesn’t change, especially if you want to use that preset with Auto-load. If you change the ID, it’s another preset from ReaLearn’s perspective!
-
Conversely, the name of the workspace directory and the name/path of the preset file within the workspace directory should not change!
-
The only thing that is allowed to change is the file extension. This makes it possible to convert a preset from JSON to Luau and vice versa.
-
Preset workspaces are self-contained. What does that mean? Luau presets can use the
require
statement to share common Luau code. However, this is only possible within one preset workspace. -
As a result, it is safe to have multiple completely different preset workspace, and it’s guaranteed that they don’t conflict with each other. This makes preset sharing easy (it’s just a matter of copying the preset workspace directory).
-
There’s one special preset workspace: The user workspace. It’s the workspace whose directory has the same name as your macOS/Windows/Linux user. Special features:
-
The user workspace is where ReaLearn puts your presets when you save them via the user interface (as
.json
files). -
All
require
statements in Luau code imported via Import from clipboard are resolved against this user workspace.
-
You can create a preset workspace by pressing Menu → Compartment presets → Create compartment preset workspace (including factory presets) (done for each compartment type separately). This will create a randomly-named preset workspace directory within the compartment preset parent directory. If this is your first preset workspace, it is best practice to turn it into your personal user workspace by renaming the generated directory to your macOS/Windows/Linux username (name must match exactly!).
Maybe the user workspace directory exists already. Most likely because you have saved presets from the user interface, in which case it should contain only JSON files. In that case you can safely move all files and directories from the generated preset workspace directory into that existing directory.
The generated workspace contains:
-
A README file with some general information and tips.
-
A copy of all ReaLearn factory presets for that compartment.
-
Mainly Luau presets (ending with
.preset.luau
). -
You can use them as inspiration for your own ones.
-
Most of the factory presets in the main compartment are quite advanced. One of the easier ones is
generic/numbered/fx-paraameters.preset.luau
.
-
-
A bunch of Luau SDK files in the first directory level of the workspace.
-
They contain Luau types and utility functions.
-
You can require them within your own Luau files in that workspace and use them to build presets.
-
However, the usage of the SDK files is completely optional! The only important thing about building ReaLearn presets is that the returned table conforms to the ReaLearn compartment API (= has the structure that you get when you do Export from clipboard → Export … compartment as Lua). It doesn’t matter if you use Luau’s type system to build that table or the provided utility functions or your own or none.
-
The SDK files can change in incompatible ways in newer ReaLearn versions. Only ReaLearn’s built-in compartment API is guaranteed to stay backward-compatible!
-
Luau presets have a YAML frontmatter comment section right at the top of the file that contain meta information about the preset. The following properties are possible:
|
required |
Preset display name |
|
required |
The ReaLearn version for which this preset was built. This can effect the way the preset is loaded, e.g. it can lead to different interpretation or migration of properties. So care should be taken to set this correctly! |
|
Preset author |
|
|
Preset description. Preferably in Markdown format, but can also be plain text. |
|
|
Setup instructions. Preferably in Markdown format, but can also be plain text. |
|
|
controller compartment only |
Manufacturer of the device represented by the controller preset. |
|
controller compartment only |
Name of the device represented by the controller preset. |
|
controller compartment only |
MIDI identity compatibility pattern. Will be used for auto-adding controllers and for finding the correct controller preset when calculating auto-units. |
|
controller compartment only |
Possible MIDI identity compatibility patterns. Will be used for auto-adding controllers and for finding the correct controller preset when calculating auto-units. It should only be provided if the device in question doesn’t reply to device queries or if it exposes multiple ports which all respond with the same device identity and only one of the ports is the correct one. Example: APC Key 25 mk2, which exposes a "Control" and a "Keys" port. ReaLearn will match any in the list. OS-prefixes are alowed, e.g. |
|
controller compartment only |
Provided virtual control schemes. Will be used for finding the correct controller preset when calculating auto units. The order matters! It directly influences the choice of the best-suited main presets. In particular, schemes that are more specific to this particular controller (e.g. "novation/launchpad-mk3") should come first. Generic schemes (e.g. "grid") should come last. When auto-picking a main preset, matches of more specific schemes will be favored over less specific ones. |
|
main compartment only |
Used virtual control schemes. Will be used for finding the correct controller preset when calculating auto units. |
|
main compartment only |
A set of features that a Helgobox instance needs to provide for the preset to make sense. Will be used for determining whether an auto unit should be created for a specific instance or not. Example: If the required feature is "playtime" and a controller is configured with this main preset but the instance doesn’t contain a Playtime Clip Matrix, this instance will not load the main preset. Currently, only feature |
Compartment parameter
Each ReaLearn compartment contains 100 freely assignable parameters. Compartment parameters can be used in the following ways:
-
For Conditional activation (lets the parameter value influence which mappings are active)
-
For Dynamic selector (lets the parameter value influence which object (track, FX etc.) is targeted for a specific mapping)
-
As Source "ReaLearn parameter" (lets the parameter value control any ReaLearn target)
They can be customized as described in Compartment parameters menu. Parameter customizations are saved together with the compartment preset. Parameter values will be reset whenever you load a preset (just the ones in that compartment).
Continuous vs. discrete compartment parameters
By default, compartment parameters have a Continuous value range. Although that makes them very versatile, it’s often easier to work with a Discrete value range.
Entering a value count (see Value count) makes the parameter have a Discrete value range with the given number of integer values. For example, a value count of 10 means that the parameter can represent exactly 10 values (0 to 9).
Choose the value count wisely and think twice before changing it to a different value at a later point in time! You probably want to refer to values of this parameter in certain parts of ReaLearn, e.g. in Target Min/Max controls. If you do that and later change the value count, these value references will not be valid anymore. They will point to other integers than you intended to. So if you are not sure, better pick a large value count and stick to it! |
Compartment-wide Lua code
Each compartment may contain arbitrary Luau code to be reused by multiple mapping MIDI source and feedback scripts. This avoids code duplication and decreases memory usage. It even allows the usage of shared state.
You can set the compartment-wide Lua code using Edit compartment-wide Lua code.
The code that you provide here is treated as a module that MIDI source scripts and Feedback scripts can import using require("compartment")
.
That means you need to export everything that you want the MIDI source and feedback scripts to see, simply by returning it.
The following compartment-wide Lua code exports 2 functions named get_text
and get_number
:
local module = {}
local function private_function()
return "i'm private"
end
function module.get_text()
return "hello world"
end
function module.get_number()
return 5
end
return module
These functions can then be reused in MIDI source and feedback scripts:
local compartment = require("compartment")
local text = compartment.get_text()
local number = compartment.get_number()
Compartment-wide Lua code is part of the compartment, that means it’s also saved as part of a compartment preset!
Virtual control
Virtual control makes it possible to create main presets that can be reused with many different controllers.
The idea is simple:
-
You define a Controller preset for a DAW controller, mapping each Real control element (e.g. its first fader, which emits MIDI CC7 messages) to a corresponding Virtual control element (e.g. named
ch1/fader
) by using a Virtual target. -
You define a Main preset, mapping each Virtual control element to some Real target by using a Virtual source. For example, you map
ch1/fader
to the Target "Track: Set volume". -
ReaLearn creates a sort of wire between the Controller compartment and the Main compartment. So you can now control the track volume by moving the first fader.
-
Most importantly, the main preset is now generic because it’s not built for a specific controller anymore!
See Using the controller compartment for more information how to do this in detail!
Virtual feedback
Virtual feedback is just like Virtual control, but in the opposite direction (from REAPER to your Controller).
Real vs. virtual control elements
Wait … control elements that are not real!? Yes! In ReaLearn, they exist. We can distinguish between Real control element and Virtual control element.
Real control element
A real control element is an element that really exists on a Controller, e.g. a fader that you can touch.
Virtual control element
A virtual control element is an abstraction of a Real control element. It enables Virtual control and Virtual feedback.
Each virtual control element has a type and an ID.
Virtual control element ID
A number or name that uniquely identifies the control element on the device.
Numbers are especially suited for the 8-knobs/8-buttons layouts. In a row of 8 knobs one would typically assign number 1 to the leftmost and number 8 to the rightmost one. It’s your choice.
For more advanced virtual control scenarios it can be useful to think in names instead of numbers. You can use up to 32 alphanumeric and punctuation characters (no exotic characters, e.g. no umlauts).
Virtual control element type
If you want to define a virtual control element, you should first decide which type is should have: Multi or Button. This distinction is used by ReaLearn to optimize its user interface.
For numbered control elements, the type is even part of the Virtual control element ID.
For example, "Multi 1" is considered a different virtual control element than "Button 1".
For named control elements, this is not the case. col1/row1/pad defined as Multi is considered the same as col1/row1/pad defined as Button.
|
- Multi
-
Represents a control element that you can "move", that is, something that allows you to choose between more than 2 values. Usually everything which is not a simple on/off button :) Here’s a list of typical multis:
-
Fader
-
Knob
-
Pitch wheel
-
Mod wheel
-
Endless encoder
-
XY pad (1 axis)
-
Touch strip
-
Rotary (endless) encoder
-
Velocity-sensitive pads or keys
-
- Button
-
Represents a control element that distinguishes between two possible states only (e.g. on/off), or even just one ("trigger"). Usually it has the form factor of a button that you can "press". Here’s a list of typical buttons:
-
Play button
-
Switch
-
Sustain pedal (a simple on/off one, not a half-pedaling one!)
-
Please note that velocity-sensitive keys should be exposed as Button - unless you know for sure that you are not interested in the velocity sensitivity.
Virtual control scheme
If you want your main preset to be compatible with as many controller presets as possible, try to use predefined names instead of inventing your own virtual control naming scheme.
When you define a virtual source or virtual target, there’s a convenient picker that provides names for the following standardized virtual control schemes:
- DAW control (
daw
) -
The names you see here are heavily inspired by the wording used on Mackie Control devices.
- Grid (
grid
) -
For controls divided into rows and column, as for example found on the Novation Launchpad.
- Numbered (
numbered
) -
Simply lets you pick among any number between 1 and 100.
Order in which mappings are processed
Since ReaLearn 2.10.0, mappings are processed from top to button, exactly in the order in which they are defined within the corresponding compartment. This matters if you want to map multiple targets to one button and the order of execution matters.
Important: There’s an exception. ReaLearn’s processing of its own VST parameters is always deferred.
-
That means changing a ReaLearn parameter in one mapping and relying on it in the next one (in terms of conditional activation or in a
<Dynamic>
expression), will not work! -
You can work around that by delaying execution of the next mapping via fire mode but that’s a dirty hack. ReaLearn’s parameters are not supposed to be used that way!
-
Imagine a railway: ReaLearn’s targets can be considered as trains. Triggering a target means moving the train forward. ReaLearn’s parameters can be considered as railway switches. Changing a parameter means setting a course. The course needs to be set in advance, at least one step before! Not at the same time as moving the train over the switch.