05 ‐ FX Zones - FunkybotsEvilTwin/CSIUserGuide GitHub Wiki
Overview: Custom FX and Instrument Mappings
CSI allows users to create custom FX and instrument mappings that work across one or more control surfaces. FX Zones function similarly to surface Zones, as both involve mapping Widgets defined in our surface.txt files to desired behaviors. However, the primary difference lies in the nature of those behaviors:
- In a surface Zone, widgets are mapped to actions within Reaper itself.
- In an FX Zone, widgets are mapped to parameters of an FX plugin (e.g., VST, VSTi, VST3, VST3i, AU, AUi, CLAP, JSFX, etc.).
Tip: If you're having issues mapping a plugin in your preferred format, trying the same plugin in another format often resolves the problem. VST3 and VST consistently work best with CSI.
There are two main methods for creating FX Zones:
- Using CSI's Learn feature.
- Manually creating and editing fx.zon files in a text editor. See FX Mapping: Manual
Each plugin requires its own unique .zon
file, which should be placed inside your CSI/[SurfaceName]/FXZones/ folder. A .zon
file is a plain text file that you create and rename with the .zon
extension. The file name can be anything you prefer, but as a best practice, you typically want include the plugin format, plugin name, and manufacturer name when creating your own FX Zones (CSI will do this for you when using the Learn feature).
More details on using the Learn feature and activating FX Zones are provided in their respective sections.
Breaking Down an FX Zone
Let’s begin by reviewing a simple fx.zon
file and breaking it down into its component parts, then working backwards to explain how we got there. In this example, I’m using the UAD Teletronix LA-2A Silver plugin, mapped to the widgets on an MCU/X-Touch Universal-style device. This example may look complex at first, but it’s straightforward when examined line by line.
Zone "VST: UAD Teletronix LA-2A Silver (Universal Audio, Inc.)" "LA2ASlv"
Rotary1 FXParam 0
RotaryPush1 NoAction
DisplayUpper1 FixedTextDisplay "Thresh"
DisplayLower1 FXParamValueDisplay 0
Rotary2 FXParam 3
RotaryPush2 NoAction
DisplayUpper2 FixedTextDisplay "HF Emph"
DisplayLower2 FXParamValueDisplay 3
Rotary3 FXParam 1
RotaryPush3 NoAction
DisplayUpper3 FixedTextDisplay "Output"
DisplayLower3 FXParamValueDisplay 1
Rotary4 NoAction
RotaryPush4 FXParam 2 [ 0.0 1.0 ]
DisplayUpper4 FixedTextDisplay "CompLim"
DisplayLower4 FXParamValueDisplay 2
Rotary5 FXParam 4 [ 0.0 0.50 1.0 ]
RotaryPush5 NoAction
DisplayUpper5 FixedTextDisplay "Meter"
DisplayLower5 FXParamValueDisplay 4
Rotary6 NoAction
RotaryPush6 NoAction
DisplayUpper6 NoAction
DisplayLower6 NoAction
Rotary7 NoAction
RotaryPush7 NoAction
DisplayUpper7 NoAction
DisplayLower7 NoAction
Rotary8 FXParam 8
RotaryPush8 ToggleFXBypass
DisplayUpper8 FixedTextDisplay "Wet"
DisplayLower8 FXBypassedDisplay
ZoneEnd
The First and Last Lines of an FX Zone (Plugin Type, Plugin Name, Plugin Alias)
The first line of an FX zone file must include the plugin name exactly as it appears in Reaper. You can optionally add a plugin alias (short name) for clarity in FX lists.
In the example above, the first line is:
Zone "VST: UAD Teletronix LA-2A Silver (Universal Audio, Inc.)" "LA2ASlv"
-
Zone
: Required keyword. -
Plugin Name: This must match the name exactly as it appears in Reaper, including the plugin format (e.g., VST, VST3). Any typo will prevent the mapping from working. If you use multiple versions of a plugin (e.g. VST2, VST3, and CLAP), you would need to create a separate
.zon
file for type you use.
Tip: FXParams may differ between plugin formats, so renaming and reusing files may not always work. -
Alias: The second string,
"LA2ASlv"
, is an alias (or short name). While optional, it’s recommended to create a concise alias for better clarity on your control surface. Without an alias, you may see something generic likeVST: UAD
, which doesn’t specify the plugin.
The last line of the file is:
ZoneEnd
This is required to close the FX zone definition. Every CSI zone file, FX or otherwise, must end with this keyword.
Our first action
The first FX parameter that has been mapped to a widget in CSI, is FX Param 0 (which happens to be the Threshold control in this plugin) and that's mapped to the Rotary1 widget. So we add the widget name (Rotary1), followed by the CSI action FXParam and the number 0, which represents the plugin parameter to assign to the widget. Reminder: we identified the FXParam # by using the methods outlined in Finding FXParam Numbers.
Rotary1 FXParam 0
See FX Mapping Actions for the full list of available FX mapping actions.
Adding some displays for parameter name and value
We then see...
RotaryPush1 NoAction
DisplayUpper1 FixedTextDisplay "Thresh"
DisplayLower1 FXParamValueDisplay 0
RotaryPush1 "NoAction" says that when this FX.zon is active, RotaryPush1 should not do anything.
DisplayUpper1 will show the word “Thresh” when this zone is active. This is useful if you have limited character displays and FX Params may have long names. Alternately, you could have used the FXParamNameDIsplay action as shown below:
DisplayUpper1 FXParamNameDisplay 0
…this action will display the full parameter name, versus the alias that was created using the FixedTextDisplay action. The 0 that follows the FXParamNameDisplay action is FXParam #. We'll get into that in a second.
The next line shows
DisplayLower1 FXParamValueDisplay 0
This will display the value of the FX Parameter being controlled.
Our first "toggle" action and using NoAction to reserve parameters
Jumping further ahead you see...
Rotary4 NoAction
RotaryPush4 FXParam 2 [ 0.0 1.0 ]
DisplayUpper4 FixedTextDisplay "CompLim"
DisplayLower4 FXParamValueDisplay 2
Here, turning the Rotary encoder does nothing due to the NoAction line, but the RotaryPush4 will toggle the Comp/Limiter parameter when pressed. That's what the [ 0.0 1.0 ] means when it follows an FX Param. In CSI, all FX parameters are normalized to a range of 0.0 to 1.0 so that syntax is essentially saying, "each press should toggle between the minimum and maximum values". You'll also notice similar syntax used to step between 3 parameters on the rotary encoder with the "Meter" parameter in this .zon example. See the Stepped Params and Toggles page for more details.
The final thing I want to call out in this FX.zon is that I've used NoAction for any controls on my surface that don't have an action in the FX.zon. Why? This is a best-practice recommendation to make sure that you're not inadvertently changing parameters on your track or elsewhere that you don't intend to when the fx.zon is active. This will also ensure the displays clear out.
Rotary6 NoAction
RotaryPush6 NoAction
DisplayUpper6 NoAction
DisplayLower6 NoAction
FX SubZones
FX Sub Zones are helpful when you need to map plugins with more parameters than your surface can accommodate or when the plugin has multiple FX types or modes you'd like to organize into different zones. This is also useful for instruments, allowing you to separate controls for filters, oscillators, envelopes, LFOs, etc. The possibilities are endless.
To create FX Sub Zones, you’ll need these key elements:
-
Your primary fx.zon file:
- This file includes the parameter mappings you want to see initially when the plugin is mapped.
- It should be named to match the plugin (e.g., [plugin].zon).
-
Separate .zon files for each subzone:
- Each zone must be in a separate .zon file.
- It’s recommended to number these subzone files sequentially (e.g., [plugin]-1.zon, [plugin]-2.zon).
-
SubZone references in the primary file:
- The primary fx.zon file should include "SubZones" and "SubZonesEnd" to define which subzones are included.
-
GoSubZone actions in all files:
- Each .zon file must include GoSubZone actions to allow switching between zones.
FX SubZone Example
In this example, Limiter 6 GE from Tokyo Dawn Labs is mapped across three zones:
- The primary zone contains Compressor controls.
- The first subzone contains Peak Limiter controls.
- The second subzone contains High Frequency Limiter, Clip, and Output controls.
Dedicated buttons on the surface (e.g., BankA, BankB, and BankC) are used to switch between zones. Each zone file includes GoSubZone actions for navigation.
Primary zone: VST__TDR_Limiter_6_GE__Tokyo_Dawn_Labs_.zon
Zone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)" "Limiter6 GE"
SubZones
"VST: TDR Limiter 6 GE (Tokyo Dawn Labs)-1"
"VST: TDR Limiter 6 GE (Tokyo Dawn Labs)-2"
SubZonesEnd
/
BankA GoSubZone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)" "Compressor"
BankB GoSubZone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)-1" "Peak Lim"
BankC GoSubZone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)-2" "HF Lim+Clip"
/
RotaryA1 FXParam 6 "Comp Thresh"
RotaryA2 FXParam 8 "Comp Ratio"
RotaryA3 FXParam 9 "Comp Attack"
RotaryA4 FXParam 10 "Comp Release"
/
ZoneEnd
First Sub Zone file: VST__TDR_Limiter_6_GE__Tokyo_Dawn_Labs_-1.zon
Zone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)-1" "Peak Lim"
/
BankA GoSubZone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)" "Compressor"
BankB GoSubZone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)-1" "Peak Lim"
BankC GoSubZone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)-2" "HF Lim+Clip"
/
RotaryA1 FXParam 18 "Peak Lim Gain"
RotaryA2 FXParam 20 "Peak Lim Thresh"
RotaryA3 FXParam 25 "Peak Lim Focus"
RotaryA4 FXParam 26 "Peak Lim Release"
/
ZoneEnd
Second Sub Zone file: VST__TDR_Limiter_6_GE__Tokyo_Dawn_Labs_-2.zon
Zone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)-2" "HF Lim+Clip"
/
BankA GoSubZone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)" "Compressor"
BankB GoSubZone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)-1" "Peak Limiter"
BankC GoSubZone "VST: TDR Limiter 6 GE (Tokyo Dawn Labs)-2" "HF Lim+Clip"
/
RotaryA1 FXParam 34 "HF Lim Threshold"
RotaryA2 FXParam 38 "HF Lim Frequency"
RotaryA3 FXParam 36 "HF Lim Range"
RotaryA4 FXParam 41 "HF Lim Dry Amt"
/
ZoneEnd