Vendor helgoboss/helgobox (ReaLearn) as basis for custom UI fork

Stripped upstream git history; starting point for replacing the native
SWELL/Win32 mapping UI with something more suited to bulk editing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Paul Lipscomb
2026-07-15 17:38:29 -04:00
parent 583ed77a67
commit e58f06d9fa
2232 changed files with 685575 additions and 1 deletions
@@ -0,0 +1,118 @@
= Control Playtime with items
Because Playtime is an instrument plug-in, it can be controlled via MIDI. Not just via external MIDI controllers, but also from within REAPER. You can just put MIDI items on the Playtime track and start REAPER playback, exactly as you would do it with a synthesizer.
== 1. Set up matrix
Click xref:user-interface/matrix-area.adoc#matrix-cell-settings[] to open the xref:user-interface/inspector/matrix.adoc[] and make the following settings:
|===
| Setting | Value | Reason
| xref:user-interface/inspector/matrix/playback.adoc#inspector-matrix-start-timing[]
| xref:user-interface/inspector/clip.adoc#inspector-clip-start-timing-immediately[]
.2+| Position and length of a note in the MIDI editor should correspond exactly to the position and length of clip playback.
| xref:user-interface/inspector/matrix/playback.adoc#inspector-matrix-trigger-mode[]
| xref:user-interface/inspector/column/playback.adoc#inspector-column-trigger-mode-momentary[]
| xref:user-interface/inspector/matrix/playback.adoc#inspector-matrix-activate-slot-on-trigger[]
| Off
| We don't want the Playtime selection to jump around like crazy.
|===
Also ensure that you haven't overridden the first two properties on column or clip level!
Additionally, you might want to switch off xref:user-interface/inspector/column/playback.adoc#inspector-column-exclusive-mode[] for columns, in order to get more freedom of playing.
== 2. Create MIDI triggers
Before you can control Playtime with MIDI notes, you need to set up MIDI triggers.
=== Option A: Learn MIDI triggers manually
One way to do this is to learn the necessary MIDI triggers manually by using the xref:user-interface/toolbar.adoc#toolbar-show-hide-midi-triggers[] feature. See xref:usage/play.adoc#feature-keys[].
[[assign-midi-triggers-automatically]]
=== Option B: Assign MIDI triggers automatically
Another way to do this is to automatically assign MIDI notes to each slot cell. We can easily do that by importing a snippet of Lua code into ReaLearn.
Below code snippet by default spreads MIDI notes row by row in groups of 8, starting at the note C3. You can change that by modifying the configuration section before importing it into ReaLearn.
. Copy below code to the clipboard
. Press xref:helgobox::app/user-interface/navigation-bar.adoc#navbar-show-helgobox-plugin[] in the navigation bar on the left. This should open the xref:realearn::user-interface/main-panel.adoc[ReaLearn main panel].
. Press the xref:realearn::user-interface/main-panel/menu-bar.adoc#import-from-clipboard[]
+
CAUTION: This will overwrite existing MIDI mappings in the xref:realearn::key-concepts.adoc#unit[ReaLearn main unit].
. After confirming the import, you should see a list of mappings in ReaLearn. But also in the xref:user-interface.adoc[Playtime user interface], when pressing xref:user-interface/toolbar.adoc#toolbar-show-hide-midi-triggers[showing the MIDI triggers].
[source,lua]
----
-- Configuration
-- The first mapped note (key 48 correponds to C3)
local first_key = 48
-- The first mapped column
local first_column = 0
-- The first mapped row
local first_row = 0
-- If true, assignments will be spread row by row, otherwise column by column
local row_wise = true
-- Make that many assignments until jumping to the next column or row
local group_size = 8
-- Build mappings
local mappings = {}
for k = first_key, 127 do
local i = k - first_key
local i1 = math.floor(i / group_size)
local i2 = i % group_size
local mapping = {
source = {
kind = "MidiNoteVelocity",
channel = 0,
key_number = k,
},
target = {
kind = "PlaytimeSlotTransportAction",
slot = {
address = "ByIndex",
column_index = first_column + if row_wise then i2 else i1,
row_index = first_row + if row_wise then i1 else i2,
},
action = "Trigger",
},
}
table.insert(mappings, mapping)
end
-- Return result
return {
kind = "MainCompartment",
value = {
mappings = mappings,
},
}
----
[[record-and-edit-midi-items]]
== 3. Record and edit MIDI items
Now we are ready to record some MIDI items that control our clips.
. Ensure that the Playtime track is armed in REAPER and that all other tracks are unarmed. You should be able to trigger Playtime clips with your MIDI keyboard!
. Start recording in REAPER
. Play stuff on your MIDI keyboard
. Stop recording in REAPER
. Play back the MIDI item which you just recorded on the Playtime track
REAPER should repeat what you just played, cool!
Now you can edit the MIDI item as desired, using REAPER's MIDI editor. For example, you could quantize all notes.
.Rendering advice
IMPORTANT: Do you want to render your project? As Playtime will not participate in rendering, you first need to turn your performance into a regular REAPER arrangement. Please read xref:usage/arrangement.adoc[] for more information.
@@ -0,0 +1,82 @@
= Generate a matrix using code
[[feature-import-export-lua]]
Just as it is possible to xref:advanced-usage-scenarios/control-with-items.adoc#assign-midi-triggers-automatically[generate ReaLearn mappings via Luau], you can also generate a Playtime xref:key-concepts.adoc#matrix[] via Luau.
.This guide is a work in progress
WARNING: The matrix generated by this example xref:key-concepts.adoc#matrix[] is viewable, but not yet playable! It will be improved in the future to be playable as well.
Proceed like this:
. Copy below Luau code to the clipboard
. Press the xref:helgobox::app/user-interface/navigation-bar.adoc#navbar-show-helgobox-plugin[] icon in the navigation bar on the left.
. Press xref:helgobox::plug-in/user-interface/menu-bar.adoc#import-from-clipboard[].
. After confirming the import, you should see a large and wildly colorful matrix.
.Colorful matrix
[source,lua]
----
local column_count = 10
local row_count = 200
-- Clip source
-- Build columns
local columns = {}
local clip_index = 0
for c = 0, column_count - 1 do
local slots = {}
for r = 0, row_count - 1 do
if (c % 2 == 0 and r % 2 == 0) or (c % 2 == 1 and r % 2 == 1) then
local slot = {
row = r,
clips = {
{
name = `Clip {c + 1}/{r + 1}`,
color = {
kind = "PaletteColor",
index = 5 + clip_index % 17,
},
source = {
kind = "MidiChunk",
chunk = [[
HASDATA 1 960 QN
E 3840 b0 7b 00 0
IGNTEMPO 1 120 4 4
]],
}
},
},
}
table.insert(slots, slot)
clip_index += 1
end
end
local column = {
slots = slots or nil,
}
table.insert(columns, column)
end
-- Build rows
local rows = {}
for r = 1, row_count do
local row = {
name = `Scene {r}`,
}
table.insert(rows, row)
end
-- Build matrix
local matrix = {
columns = columns,
rows = rows,
}
-- Return result
return {
kind = "ClipMatrix",
version = "2.16.15",
value = matrix,
}
----
@@ -0,0 +1,49 @@
= Meta clips
We can take the previous scenario xref:advanced-usage-scenarios/control-with-items.adoc[] a step further!
[[feature-meta-clips]]
== The idea
If we can control Playtime with MIDI items, shouldn't it be possible to control it with MIDI xref:key-concepts.adoc#clip[_clips_] as well? The answer is yes! I call such clips _meta clips_. *Playtime can basically play itself!*
Meta clips open up a whole new world of possibilities. Here are just some of the things you can do with them:
* Meta clips can be used as xref:key-concepts.adoc#scene[scenes] on steroids. You can trigger many other clips at once, no matter in which row they are.
* You can record sequences of clip invocations and play them back at the press of a button.
== Basic setup
. Prepare the matrix and set up MIDI triggers as explained in xref:advanced-usage-scenarios/control-with-items.adoc[]. This should make it possible to play clips using your MIDI keyboard. Make sure that part works.
. Select the track "Playtime" in your REAPER project (this is the track which contains the xref:helgobox::key-concepts.adoc#instance[Helgobox instance], by default the first track in the project)
. Right-click the xref:user-interface/matrix-area.adoc#column-cell-label[] of some column, for example the last column. Choose xref:user-interface/menus/matrix-menu.adoc#matrix-insert-column-for-each-selected-track[].
+
This should add a new column named "Playtime" that plays back its MIDI clips on the "Playtime" track, and can therefore be used to _play other clips_.
.
. Now simply record a clip into the new "Playtime" column, while playing clips in other columns using your MIDI keyboard.
. That's it! You recorded your first meta clip. When playing it back, it should trigger other clips in other columns. You can also edit that meta clip, e.g. quantize its notes.
You may look at the "Playtime" column as the *leader* column (which you trigger) and the other columns as *follower* columns (which are triggered by the leader column).
== Adjust the setup to your needs
This was just an example setup. You can adjust it to your needs. Here are some ideas:
* Introduce more leader columns
* Move the leader column to the very left to make it obvious that it is a very important column
* Set the xref:user-interface/inspector/column/playback.adoc#inspector-column-start-timing[] for the *Playtime* column to *1 bar*
* Set the xref:user-interface/inspector/column/playback.adoc#inspector-column-trigger-mode[] to xref:user-interface/inspector/column/playback.adoc#inspector-column-trigger-mode-toggle[]
IMPORTANT: Using MIDI clips to control Playtime is subject to the same considerations about _rendering_ as when using MIDI items. Read xref:usage/arrangement.adoc[] for more information.
[TIP]
.Meta clips are just the beginning
====
The simple fact that Playtime is a MIDI-controllable instrument opens up even more possibilities.
Here are some ideas:
* Use a MIDI arpeggiator to arpeggiate between different clips
* Write a MIDI link:https://www.reaper.fm/sdk/js/js.php[JSFX] effect that controls clips
====
@@ -0,0 +1,24 @@
= Multiple instances
[[feature-multiple-instances]]
Because Helgobox is implemented as an xref:helgobox::plug-in.adoc[instrument plug-in], you can add multiple xref:helgobox::key-concepts.adoc#instance[instances] of it. That also means you can have multiple xref:key-concepts.adoc#matrix[Playtime matrices] in the same project.
== How to do it
Assuming you have one Playtime instance already, here's how you add another one:
. Right-click REAPER's track control panel and choose menu:Insert virtual instrument on new track...[]
. Double-click instrument plug-in "VSTi: Helgobox - ReaLearn & Playtime (Helgoboss)"
. In the xref:helgobox::plug-in/user-interface.adoc[Helgobox plug-in window], press menu:Menu[Show app]
. In the xref:helgobox::app/user-interface.adoc[Helgobox app window], press the image:screenshots/playtime-toolbar-icon.png[Playtime,width=30] button in the xref:helgobox::app/user-interface/navigation-bar.adoc[] on the left.
. Press the button btn:[Create a Playtime Matrix]
That's it! You now have a second xref:key-concepts.adoc#matrix[] in the project, that runs independently of the first one.
TIP: Currently, the only way to open that second matrix is to open the xref:helgobox::plug-in/user-interface.adoc[plug-in window] of that second xref:helgobox::key-concepts.adoc#instance[Helgobox instance] and press menu:Menu[Show app]. In the future, a separate REAPER action is planned, to make that step easier.
== Why?
Up to you!
I'm keen to hear if and how you use this possibility. Let me know on my link:https://www.youtube.com/channel/UC5fE-sfXnXuAX3EC1VM85oA[YouTube channel], on link:https://github.com/helgoboss/helgobox/discussions[GitHub discussions], on link:https://forum.cockos.com/showthread.php?t=292969[the REAPER forum] or via mailto:info@helgoboss.org[] :)
@@ -0,0 +1,35 @@
= Record performance as multi-track audio
Due to the way Playtime works, it is possible to record your Playtime performance directly to the xref:key-concepts.adoc#column-track[column tracks] as audio items. This is basically a sort of multi-track online rendering approach. It can be used as an audio-only post-FX alternative to recording xref:key-concepts.adoc#matrix-sequence[matrix sequences].
.Drawbacks
[CAUTION]
====
Before you proceed, be aware that this technique has a few drawbacks:
. Below-mentioned step 2 will change the xref:user-interface/track-area.adoc#track-panel-input-monitoring[] setting for all xref:key-concepts.adoc#column-track[column tracks], which might not be what you want! You will need to restore the old input monitoring settings afterward.
. Step 4 obviously changes the record-arm state within Playtime, which might also not be what you want! You will need to restore the old arm states afterward.
. Playing back the resulting multi-track audio will naturally flow through the track FX chain again. However, since the recording was done post-FX, the track FX is already part of the recorded audio. In order to avoid applying the FX twice, you would need to temporarily disable the FX of the affected xref:key-concepts.adoc#column-track[column tracks].
====
It goes like this:
. Select all xref:key-concepts.adoc#column-track[column tracks] in the REAPER track control panel
. Right-click the record-arm button of one track in the selection and disable menu:Monitor input[]. This is a safety measure to prevent audio feedback.
. Right-click the record-arm button again and enable menu:Record: output[Record: output (stereo)]
+
TIP: This step doesn't have any effect on recording within Playtime. Playtime will still record from the xref:user-interface/track-area.adoc#track-panel-input[], not from the track output. So this step shouldn't have any negative consequences.
. Click the record-arm button. This should record-arm all column tracks.
. Start recording in REAPER
. Now play and stop clips in the Playtime xref:key-concepts.adoc#matrix[] as desired
. Stop recording in REAPER when you are finished
Each column track now contains a stereo recording of its audio output.
.Feedback wanted
[NOTE]
====
Recording the performance as multi-track audio is a sort of "accidental feature" that is technically possible but not "officially" supported, because Playtime has not been optimized for it! It comes with the mentioned drawbacks, but it is there when you need it. If you like this feature and wish there would be a more streamlined version of it, post your idea at link:https://github.com/helgoboss/helgobox/discussions[GitHub discussions].
====
@@ -0,0 +1,44 @@
= Start custom Playtime from template
[[start-custom-playtime]]
Would you like to adjust the default settings of new xref:key-concepts.adoc#instance[Playtime instances]? Then you are at the right place.
== Most settings in Playtime are instance-specific
When designing software with the concept of xref:key-concepts.adoc#instance[instances] or projects, a common challenge is deciding whether a particula setting should be **global** (immediately affecting all instances), **global template-like** (affecting all new instances) or **instance-specific** (affect only the current instance).
For Playtime, I chose to make most settings **instance-specific**. Only settings related to _appearance_ and _performance_ -- essentially everything in the xref:user-interface/dialogs/settings-dialog.adoc[] -- are global. The primary advantage of this approach is that it allows precise restoration of any instance, ensuring it behaves exactly as it was saved.
However, this approach has a drawback: You need to adjust settings for every new instance manually, especially if the default settings dont match your preferences.
== Track templates to the rescue
You can solve this issue by leveraging a feature that you probably already know: *REAPER track templates*!
. Create a Playtime instance as usual as explained in xref:usage/prepare.adoc#fire-up-playtime[].
. Modify the instance-specific settings to suit your needs. For example:
* Change settings in the xref:user-interface/inspector/matrix.adoc[].
* Change metronome settings in the xref:user-interface/dialogs/tempo-settings-dialog.adoc[].
* Add frequently used columns with specific track inputs.
. Right-click the "Playtime" track and all xref:key-concepts.adoc#column-track[column tracks] and choose menu:Save tracks as track template...[], saving the new track template as "Playtime.RTrackTemplate".
. Whenever you want to start with this custom Playtime instance in a new project, right-click the track control panel, choose
. In new projects, you can now right-click the track control panel and choose menu:Insert track from template[] to insert your custom "Playtime" track template.
Done! You immediately get a fresh Playtime instance with your favorite settings, including all columns.
== An action to make this approach more streamlined
The downside of this approach is that you can't use the beloved image:screenshots/playtime-toolbar-icon.png[Playtime,width=50, pdfwidth=8mm] button to add Playtime, because this one still creates the Playtime default instance, not your custom one.
This is where the action xref:reaper-actions.adoc#show-hide-custom-playtime[] comes into play. You can add a toolbar button for this action:
. Right-click an empty area of the desired toolbar and choose menu:Customize toolbar...[]
. Press btn:[Add...]
. Search for action "Helgobox/Playtime: Show/hide custom Playtime" and double-click it
. Press btn:[OK]
The default icon for this button is image:screenshots/playtime-custom-toolbar-icon.png[Playtime,width=50, pdfwidth=8mm]. When you press it, it looks for a track template called "Playtime" and loads it.
No default shortcut is assigned to this action, but you can assign your own in REAPER menu menu:Actions[Show action list...]. For example, you could remove the kbd:[Shift+Cmd/Ctrl+P] shortcut from the xref:reaper-actions.adoc#show-hide-playtime[] action and instead assign it to this action.