As I discussed in my Reaper 4 review in SOS October 2011, the Windows Arrangement Logic Template Engine for Reaper (or 'WALTER') facility promises enormous flexibility for arranging the software's controls to suit your working methods, especially because you can set up several different Track Layouts for different tasks and easily switch between them. If you're not a programmer by trade, though, WALTER's bespoke scripting language might easily put you off taking advantage of it. I think that's a shame, because it's actually possible to get useful results comparatively quickly with only a basic understanding of the way the code works, simply by tinkering with the bundled default scripts. So in this month's column I'm going to provide my own 'tourist's guide' to this kind of tweakage, as well as suggesting some further resources you can follow up if you really get the bug.
Where's Wally?
The file the WALTER code lives in is called 'rtconfig.txt' and is located in the Reaper install's Color Themes folder. However, it's data-compressed into the 'Default_4.0.ReaperThemeZip' file, so you'll need to unpack it first. Simply renaming the file to change the file extension to '.zip' should make it recognisable as a compressed archive by most Windows or Mac OSX machines, but if not, try dragging the file to a dedicated archive utility, such as WinZip, instead. However you achieve it, you should end up with a 'Default_4.0_unpacked.ReaperTheme' file and an accompanying 'Default_4.0_unpacked' folder that contains 'rtconfig.txt'. Before you go any further, make a quick backup copy of this text file so you can always return to it if you get in a scripting tangle later on. Now you need to switch Reaper to the unpacked Theme. From the Theme Editor Preferences page, click the Load Theme button and choose 'Default_4.0_unpacked' from the little menu. Once this is done, make sure that both the page's tick boxes are active and that the 'Theme Uses Image Resources' field is also showing 'Default_4.0_unpacked'. Click OK to save the changes.
Finally, open up 'rtconfig.txt' in a text editor and scroll down past the '---WALTER---' heading to get your first taste of what the script actually looks like. It's a bit intimidating to begin with, but you only need to understand a few principles to begin to make sense of it. The first block of 50 lines or so contains default code that governs the Theme as a whole, but it's more or less overridden on a case-by-case basis by each of the individual Track Layouts presented between 'Layout' and 'EndLayout' tags further down the page. For the purposes of this introductory article, I'm going to draw illustrations from the 'Top Aligned' TCP Track Layout, but once you can pick that apart, you should be well on the way to understanding any of the others.
Understanding What You See
In order to decipher the script, it's important to grasp that WALTER's world revolves around things called Coordinate Lists, which are little lists of numbers (or Scalar Values, in the jargon) that can be fed to User Interface (UI) Elements such as buttons, faders and meters to define their position, size and other attributes. Both Coordinate Lists and UI Element tags are pretty easy to spot in the code: the former are in square brackets, with spaces separating the individual Scalar Values; the latter are single 'words' with at least one embedded full-stop character. The look-up table at www.reaper.fm/sdk/walter/walter.php#elements explains what graphical component each UI Element tag controls. Coordinate Lists can also be stored in user-defined variables, each again identified by a single WALTER 'word', usually containing at least one embedded underscore character.
Any time you see a line starting with the WALTER command 'set', it's either configuring a UI Element's Coordinate List, or storing a Coordinate List as a variable for future use. So, for instance, here are two of the simpler lines from the 'Top Aligned' layout:
set y_align h<51 [0 0 0 0 0 0.5 0 0.5] [0 0 0 0 0 0 0 0]
set tcp.mute + tcp_yanchor [338 0 17 18 1 y_align 1 y_align]
Already, you should be able to start picking some of this apart. The first line is setting the 'y_align' variable, with two Coordinate Lists involved, and the second line is configuring the 'tcp.mute' UI Element (the track's mute button, according to the look-up table), using a combination of some variables and a Coordinate List. To make more headway, you need to know a few more things.
Inside The Coordinate List
First of all, it helps to have an idea of what the eight Scalar Values in a typical Coordinate List refer to when it's used to configure a UI Element. The first four are dimensions in pixels, one pair specifying the distance between the left/top edges of the UI Element and the left/top boundaries of the TCP, followed by another pair specifying the UI Element's own width and height. The remaining four numbers determine how the position of each of the UI Element's edges (left, top, right and bottom respectively) follows changes in the TCP's size. As such, these numbers hold the key to various dynamic repositioning/resizing options. For most situations, these numbers are set either to '0' or '1', depending on whether you want a given UI Element's edge to track TCP size changes or not, but they can also be any fraction in between.
If you see any code with curly brackets (such as 'tcp.fx{w}', say), this is referring to a single Scalar Value from the Coordinate List of a variable or UI Element. The letter in the brackets indicates the Scalar Value's position in the Coordinate List, with 'x', 'y', 'w', 'h', 'ls', 'ts', 'rs' and 'bs' representing each of the eight entries in turn. There are also some pre-defined Scalar Values that aren't part of any Coordinate List, the most frequently encountered being 'h' and 'w', the height and width (in pixels) of the track as a whole, and 'recarm', which has a non-zero value only for tracks that are armed for recording. (The functions of other pre-defined Scalar Values are detailed at www.reaper.fm/sdk/walter/walter.php#scalars.)
Comparisons & Calculations
The way WALTER coders get their Track Layouts to adapt to a track's zoom/status changes is by monitoring the predefined Scalar Values. In the case of 'h' and 'w', the mathematical symbols '>' and '<' are widely used to provide 'more than' and 'less than' comparisons in conjunction with a fixed numeric value, as in the first of our two simple lines of code:
set y_align h<51 [0 0 0 0 0 0.5 0 0.5] [0 0 0 0 0 0 0 0]
Here the 'h<51' checks whether the track is less than 51 pixels in height, and the test is followed immediately by its true and false outcomes. In other words, if the track is less than 51 pixels high, the 'y_align' variable is set to '[0 0 0 0 0 0.5 0 0.5]', but if not, it's set to '[0 0 0 0 0 0 0 0]'. Several other less common comparative symbols are also available ('>=', '?', '!', '==', '!=', and so forth), and are clearly explained at www.reaper.fm/sdk/walter/walter.php#expressions. The '+' and '*' symbols allow addition and multiplication of Coordinate Lists, but you have to realise that the two Coordinate Lists to be added/multiplied both follow the symbol, rather than appearing on either side of it (as you'd expect in normal arithmetic). With this in mind, let's return to the second of our simple lines of code:
set tcp.mute + tcp_yanchor [338 0 17 18 1 y_align 1 y_align]
This can now be interpreted as configuring the 'tcp.mute' UI Element with the sum of the 'tcp_yanchor' variable and the '[338 0 17 18 1 y_align 1 y_align]' Coordinate List, but let me clarify a couple of important details. Firstly, the two 'y_align' entries in the Coordinate List indicate that those two numbers should be taken from the corresponding Scalar Values in the 'y_align' variable, as defined in the first code line; in other words, that they should be values of zero or 0.5, depending on the track height. (You can also refer to the Scalar Values of a UI Element's Coordinate List in a similar manner.) The second thing to realise is that adding/multiplying two Coordinate Lists effectively adds/multiplies each corresponding pair of Scalar Values, and where the two Coordinate Lists have different numbers of Scalar Values, any missing values count as zero. So, for example, adding '[3 2 1]' and '[5 4 3 2 1]' would give '[8 6 4 2 1]', whereas multiplying them would give '[15 8 3]'.
Nesting Instinct
One of the trickiest things to get your head around when trying to follow WALTER code is that comparison and calculation functions are frequently nested, as in this instance:
set tcp.meter + tcp_yanchor w<211 h<51 [0] [342 26 29 9 1 y_align 1 y_align] [286 4 42 9 1 y_align 1 y_align]
Notice that the 'w<211' is followed immediately by 'h<51', rather than by a Coordinate List or user-defined variable. What this does is nest a second comparison test within the first, such that, if the TCP's width is less than 211 pixels, its height is also checked to determine which of the two subsequent Coordinate Lists to use ('[0]' or '[342 26 29 9 1 y_align 1 y_align]'). Only if the TCP's width is 211 or more will the '[286 4 42 9 1 y_align 1 y_align]' Coordinate List be used. The '[0]' Coordinate List you can see here is used repeatedly when configuring UI Elements using nested comparisons, because it clears the UI Element's configuration and, therefore, makes it disappear from the screen, which is handy when there's not enough room for all the controls on a given size of TCP. If you're setting variables using nested comparisons, though, you may also come across the isolated full-stop character shown in this line:
set tcp_yanchor w<211 h>=51 [0 8] . h>=51 [0 8]
What the full-stop indicates here is that any existing contents of 'tcp_yanchor' should remain unchanged if the TCP's width is less than 211 pixels and its height is less than 51 pixels.
Nested calculations work in a very similar way, as you can see in this example:
set tcp.label + + reverse_margin tcp_label_fullmargin margin_to_width
Here the sum of the nested '+ reverse_margin tcp_label_fullmargin' expression is added to the 'margin_to_width' variable, and the total is then used to configure the 'tcp.label' UI Element.
Up & Toddling
You should now have enough knowledge of WALTER scripting to work out most of what's going on in the default 'rtconfig.txt' file, so what can you do with it? Well, first of all, choose the Track Layout you most like in Reaper, and try replacing the numbers in some of its UI Element Coordinate Lists. After each coding change, use the Switch To Previous/Next Color Theme Actions to unload/reload your edited Theme, so that tracks set to your custom Track Layout will reflect the alterations.
In the first instance, you might simply replace a few of those Coordinate Lists with '[0]' to eliminate buttons or read-outs you don't care for, adjusting the boundaries of fader or label UI Elements to fill the gaps, giving you more metering resolution or space for track names. Once you begin to feel a bit more adventurous, you can start putting in your own values of 'x' and 'y' to re-position/re-order the visual elements, although you'll quickly find that similar adjustments to several Coordinate Lists in a code line may be necessary where nested comparisons are present.
For more complicated reprogramming of a given UI Element, try copying WALTER code from a different UI Element (maybe even from a different Track Layout) that already responds in roughly the way you're looking for, so you don't have to delve too deeply into the workings of the 'ls', 'ts', 'rs' and 'bs' Scalar Values or any user-defined variables. However, if a particular variable does pique your curiosity, it's easy to use your text editor's Find facility to locate the preceding lines of WALTER code where that variable is set and manipulated.
Give or take a little trial and error, you'll be surprised by how much you can do. With no more knowledge than we've covered in this article, it only took me a few hours to extensively customise the default 'Top Aligned' Track Layout with copied elements from the 'Shy Meter' code, to produce a more streamlined Track Layout all of my own.
Comments
Wherever you see a semicolon character in WALTER, it means that any code between the semicolon and the end of the line is simply ignored by Reaper. This is useful for annotating your WALTER code as you work, and is also great for temporarily removing a line (to see what it's doing) without deleting the actual text.
Further Reading
If reading through this month's tutorial has whetted your appetite for WALTER programming and you'd like to learn more, the best place to start is White Tie's excellent and entertainingly written 'WALTER: A Themer's Guide' PDF document. Thorough technical reference material to support this can also be found amongst the Reaper site's software developers' resources.