Message Generators - FunkybotsEvilTwin/CSIUserGuide GitHub Wiki
Message Generators allow you to define what MIDI messages the surface sends to CSI. The following types of Message Generators exist in CSI, and which you use will depend on the type of control and your surface:
- Press - a simple generator that sends a single MIDI message on press, and optionally sends another message when released. Often, but not limited to, a button.
- AnyPress - a variation of Press needed for some devices.
- Fader7Bit - sends a MIDI message in a range specifying the current absolute value of the control. Used for faders and knobs with defined start and points.
- Fader14Bit - like Fader7Bit, but has a larger (or more fine grained) set of values.
- Touch - messages sent when a touching a Fader or Rotary.
- Control - used for OSC controls.
- MotorizedFaderWithoutTouch - added for the Behringer X32/xAir/MIDAS series consoles which have motirized faders with no touch sensitivity.
- FaderportClassicFader14Bit - for use with the Faderport Classic by Presonus.
- Encoders - unlike the Faders, an Encoder sends a relative value (increase/decrease).
- MFTEncoder - a special encoder only found on the MIDI Fighter Twister controller.
- Encoder7Bit - another special encoder for the X-Touch Compact and X-Touch Mini.
Additionally, the Default Encoder Customization and Custom Encoder Customization sections of this page describe some additional features around how to set defaults and otherwise customize encoders.
A widget is the CSI catch-all term for a control or display. Widgets can be:
- Message Generators: These generate messages when interacted with (e.g., faders, encoders, knobs).
- Feedback Processors: These provide feedback (e.g., displays).
- Both: Some widgets, like flying faders, act as both controls and feedback processors, as they require feedback from the DAW.
Widgets need to be defined and named in the surface.txt
file. These definitions tell CSI the following:
- Which controls exist on the surface
- What CSI should name each control
- What each control is capable of
- Whether the control is a Message Generator, Feedback Processor, or both
- The address to communicate with the control (MIDI or OSC)
In CSI, the Zone files will define what these widgets control in Reaper.
If a surface.txt
file doesn't already exist for your surface, you can create one by monitoring CSI for the values sent when each control is manipulated. For example, when pressing a button on your controller, you can observe the values that appear.
IN <- XTouchOne 90 5b 7f
IN <- XTouchOne 90 5b 00
The first line showed up when I pressed, the second one when I let go, so a reasonable assumption is the MIDI Generator in my widget should be:
Press 90 5b 7f 90 5b 00
You would then define the syntax in the surface.txt file by using the following syntax
Widget [Name Of Control]
[Message GeneratorType] [Message Generator Address]
WidgetEnd
..and you'd repeat that for each control
Simple example:
Widget Play
Press 90 5e 7f 90 5e 00
WidgetEnd
If your surface features feedback for the state of the Play button, we would also define that in the widget to alert CSI to the feedback capability.
Widget Play
Press 90 5e 7f 90 5e 00
FB_TwoState 90 5e 7f 90 5e 00
WidgetEnd
Press is typically used for message generators that send a message when pressed, and optionally send another message when released.
Defined using the following syntax:
Press 90 5e 7f 90 5e 00
where:
- 90 5e 7f is the message sent when the widget is pressed
- 90 5e 00 is the message sent when the widget is released (optional)
However, we still need to name our widget. So lets presume this is a Play button. In our surface.txt file, that widget would look like this:
Widget Play
Press 90 5e 7f 90 5e 7f
WidgetEnd
As mentioned in our earlier example, if the play button features feedback capabilities (i.e. a light that appears when Play is engaged), we must also define that in the widget.
Widget Play
Press 90 5e 7f 90 5e 00
FB_TwoState 90 5e 7f 90 5e 00
WidgetEnd
Tip: if your surface creates release messages, include them in your surface.txt file. You want to define all the capabilities of the surface, including release messages, if any.
For information on how to assign buttons using Press widgets to toggles and stepped parameters in a Zone file, see Stepped Parameters and Toggles.
AnyPress is Message Generator for use with surfaces whose buttons alternate between a press message (7f) on press, and on second press, a release message (00). Use AnyPress widgets for these types of surfaces.
Widget Solo1
AnyPress 90 2e 7f
WidgetEnd
This can also be used for OSC devices that may require an AnyPress widget (this was added to support the Behringer X32/Midas series).
Widget Solo1
AnyPress /solosw/01
WidgetEnd
If you're unsure whether to use a Press or AnyPress widget, follow these steps:
- Go to CSI's Preferences, then Advanced options. Under Monitoring, check the box for Show MIDI Input and click OK.
- Press the button on your surface once.
Result:
-
If you see two messages like
90 2e 7f
and90 2e 00
, then use a Press widget. -
If you only see one message, like
90 2e 7f
, press the button a second time:- If the next message is also
90 2e 7f
, then use a Press widget with a single message defined. - If the next message is
90 2e 00
, then you should use an AnyPress widget.
- If the next message is also
A Message Generator that represents a control that measures its current position using a 7bit value (ie. 128 possible values). While the name includes the word "Fader" this type of message would be used for both faders AND knobs with absolute values (i.e. a knob with a defined start and end location).
An example of a basic MIDI Rotary knob with no feedback would look like this:
Widget Rotary1
Fader7Bit b0 01 7f
WidgetEnd
An example of a flying fader (Fader7Bit
) widget with feedback might look like this:
Widget Fader1
Fader14Bit e0 7f 7f
FB_Fader14Bit e0 7f 7f
WidgetEnd
In the flying fader example, a message will be sent between e0 7f 00 and e0 7f 7f representing the current position of the fader.
When trying to decide if a Surface control should be represented using Fader7Bit
or Encoder
, look at what values are actually being sent by the Surface. Fader7Bit expects an absolute value, whereas Encoder expects an increment/decrement value.
- Go to CSI's Preferences, Advanced options and under Monitoring, check the "Show MIDI Input" box and click OK
- If you see a single value being sent when you turn the control clockwise and another when the control is turned anti-clockwise, go with Encoder.
- If you see a full range of values (from 00 to 7f or vice versa) sent when you turn the control (increasing in one direction, decreasing in the other) go with Fader7Bit.
A Message Generator that represents a control that measures its current position using a 14-bit value (ie. 16384 possible values).
It's defined using the following syntax:
Widget Fader1
Fader14Bit e0 7f 7f
FB_Fader14Bit e0 7f 7f
WidgetEnd
A message will be sent between e0 00 00 and e0 7f 7f representing the current position of the fader.
Note: To adjust the fader range in Reaper to match the motorized fader range on your hardware, go to Reaper's Preferences -> Appearance -> Track Control Panels and set the "Volume fader range" to match the maximum value on your hardware fader.
If the Fader or Rotary supports sending "Touch" messages (i.e. it uses capacitance to determine when a finger is touching the fader) you would want to also define that in your surface.txt
. In this example, touching Fader1 generates a message of 90 68 7f, and releasing Fader1 generates a second message of 90 68 00.
Widget Fader1
Fader14Bit e0 7f 7f
FB_Fader14Bit e0 7f 7f
Touch 90 68 7f 90 68 00
WidgetEnd
The Message Generator titled simple 'Control' exists for OSC devices. Example: here is what a touch-sensitive fader with feedback may look like in an OSC surface. You see Control followed by the OSC address of the fader, and corresponding rows for feedback and touch.
Widget Fader1
Control /Mixer/Fader1
FB_Processor /Mixer/Fader1
Touch /Mixer/Fader1/z
WidgetEnd
The MotorizedFaderWithoutTouch Message Generator was added to support surfaces like the X32, xAIR, MIDAS series consoles where the faders are motorized but lack touch sensitivity. Below is an example from the BehringerX32 surface.txt file showing how these would be used (note: these are OSC surfaces, not MIDI):
Widget MasterFader
MotorizedFaderWithoutTouch /main/st/mix/fader
FB_Processor /main/st/mix/fader
WidgetEnd
Widget Fader1
MotorizedFaderWithoutTouch /ch/01/mix/fader
FB_Processor /ch/01/mix/fader
WidgetEnd
The FaderportClassicFader14Bit widget exists to support the original Presonus Faderport (aka "Faderport Classic") and it's unique requirements. Below is an example of the syntax for using this widget and it's corresponding feedback processor.
Widget Fader1
FaderportClassicFader14Bit b0 00 7f b0 20 7f
FB_FaderportClassicFader14Bit b0 00 7f b0 20 7f
Touch a0 7f 01 a0 7f 00
WidgetEnd
Encoders are typically referred to as "Endless Rotary" knobs or "Relative Encoders" (i.e. knobs with no absolute begin and end positions). While CSI typically requires the use of Fader7Bit widgets for traditional rotary knobs that communicate absolute start and end values, Encoders are different in that they communicate a relative change in value (i.e. it sends one value or one set of values when it is increasing and one when it is decreasing).
One large benefit of encoders versus traditional Rotary knobs that would use a Fader7Bit widget, is that encoders typically allow for much higher resolution than 7bit MIDI.
In order to support the widest possible range of hardware encoders, CSI now allows users to customize which values their encoders transmit as well as define acceleration ranges for encoders that support it. EncoderPlain and EncoderPlainReverse are available if your surface has no acceleration.
Here's an example of a typical MCU Encoder widget in CSI.
Widget Rotary1
Encoder b0 10 7f
FB_Encoder b0 10 7f
WidgetEnd
Note: see the section regarding Acceleration Values section for instructions on how to cut down on the required syntax in your surface.txt files for the encoder acceleration steps.
Use this syntax only if your hardware encoder transmits a single-value for clockwise and counter-clockwise turns. Because each surface may be different, replace the "41" and "01" messages with the correct values for your hardware.
In this example, the hardware encoder only transmits a value of 41 when rotated counter-clockwise (decrement, as noted by the < symbol), and only transmits a value of 01 when being rotated clockwise (increment, as noted by the > symbol).
Widget Rotary1
Encoder b0 10 7f [ < 41 > 01 ]
FB_Encoder b0 10 7f
WidgetEnd
Note: see the section regarding Acceleration Values section for instructions on how to cut down on the required syntax in your surface.txt files for the encoder acceleration steps.
Use this syntax when surface transmits different acceleration values for increment (CW) and decrement (CCW) turns. However, your surface may skip values (notice 48 and 49 are missing as are 08 09).
Widget Rotary1
Encoder b0 10 7f [ < 41 42 43 44 45 46 47 4a > 01 02 03 04 05 06 07 0a ]
FB_Encoder b0 10 7f
WidgetEnd
Note: see the section regarding Acceleration Values section for instructions on how to cut down on the required syntax in your surface.txt files for the encoder acceleration steps.
Use this syntax when your encoder transmits a continuous range of acceleration values between a defined start and end range with no breaks or jumps in the data.
Widget Rotary1
Encoder b0 10 7f [ < 41-4a > 01-0a ]
FB_Encoder b0 10 7f
WidgetEnd
Note: see the section regarding Acceleration Values section for instructions on how to cut down on the required syntax in your surface.txt files for the encoder acceleration steps.
The MIDI Fighter Twister by DJ Tech Tools can be configured to work as an Encoder with Velocity Acceleration. However, because it uses a non-standard set of values when turning the knob clockwise and counter-clockwise, a special widget was developed for the MIDI Fighter Twister. The correct syntax for a MFTwister encoder is shown below, including the full set of acceleration steps when using the Velocity Sensitive encoder setting. As you can see, there are 11 acceleration levels in each direction.
Widget RotaryA1
MFTEncoder b0 00 7f [ < 3f 3e 3d 3c 3b 3a 39 38 36 33 2f > 41 42 43 44 45 46 47 48 4a 4d 51 ]
FB_Fader7Bit b0 00 00
WidgetEnd
Note: see the section regarding Acceleration Values section for instructions on how to cut down on the required syntax in your surface.txt files for the encoder acceleration steps.
Encoder7Bit exists because some encoders, like those in the X-Touch Compact and X-Touch Mini devices, can be configured as [absolute] rotary knobs that continue to send messages when turned beyond their maximum ranges. The encoders will continue to send 00 messages when at minimum and turned counter-clockwise, and 7f messages when at maximum and turned clockwise. In between, it sends standard absolute MIDI messages for the full 0-127 range. This effectively allows them to function as both traditional knobs and encoders. Use this widget type to enable that behavior.
Widget RotaryA1
Encoder7Bit b0 0a 7f
FB_Encoder b0 0a 7f
WidgetEnd
Thanks to mschnell for contributing a script that directly led to the development of this message generator.
CSI allows you to store default encoder customization curves, as well as default "tick" sizes (the step size for each encoder "tick") in your surface.txt file rather than being required to define this in each zone file. This approach is recommended to cut down on the complexity required for smooth acceleration curves in FX.zon files, which cuts down on the complexity and the amount of syntax required.
These settings are global. You can also further customize the encoder response for individual parameters/actions within your zone files as outlined in Encoder Customization.
RotaryWidgetClass is designed to help streamline how encoders are defined in surface.txt files and tell CSI which widgets are encoders. There are multiple elements to how this is used in an surface.txt file.
First, by putting the word RotaryWidgetClass after the widget name in the surface.txt file, you are telling CSI, "this widget belongs in the rotary widget class" (as shown below). In a moment, we'll show you what that allows for.
Widget RotaryA1 RotaryWidgetClass
Encoder b0 00 7f
FB_Fader7Bit b0 00 00
WidgetEnd
The same can be done with your JogWheel using the new JogWheelWidgetClass.
Widget JogWheel JogWheelWidgetClass
Encoder b0 3c 7f
WidgetEnd
Now that the RotaryWidgetClass and/or JogWheelWidgetClass is defined for our encdoers, we can set the encoder StepSize globally by adding this to the top of the surface.txt file. This represents how fine the resolution will be for each encoder "tick". A value of 0.001 will be very fine and move parameters one-tenth of one-percent, which is very fine. If you find that resolution a little too fine, resulting in slow encoders, you may have better luck with a value of 0.003 or some other higher value. It will really depend on your hardware surfaces and preferences.
Here is an example from the X-Touchsurface.txt showing both class types, each using a StepSize of 0.003.
StepSize
RotaryWidgetClass 0.003
JogWheelWidgetClass 0.003
StepSizeEnd
The encoders on MIDI Fighter Twister are very sensitive, so I might use a StepSize of 0.001 for that surface.
StepSize
RotaryWidgetClass 0.001
StepSizeEnd
Next, we can then remove the Encoder Acceleration step values from each individual widget and just create a global set of acceleration values at the top of the surface.txt file. The benefit of this approach is that rather than being required to define the Encoder Acceleration in each EZFXZone, CSI can now use a default for all encoders in the RotaryWidgetClass.
Here we are defining the Decrease values ("Dec") from slowest encoder turns to fastest, and the same for the Increase ("Inc") values. Below that, you will find one encoder acceleration value ("Val") for each encoder acceleration step. The actual values used will depend on what your encoder transmits. The values below are from a MIDI Fighter Twister and my own personal acceleration curve.
AccelerationValues
RotaryWidgetClass Dec 3f 3e 3d 3c 3b 3a 39 38 36 33 2f
RotaryWidgetClass Inc 41 42 43 44 45 46 47 48 4a 4d 51
RotaryWidgetClass Val 0.001 0.002 0.003 0.004 0.005 0.006 0.0075 0.01 0.02 0.03 0.04
AccelerationValuesEnd
So in the past, each of my MFTEncoder widgets looked like the this...
Widget RotaryA1
MFTEncoder b0 00 7f [ < 3f 3e 3d 3c 3b 3a 39 38 36 33 2f > 41 42 43 44 45 46 47 48 4a 4d 51 ]
FB_Fader7Bit b0 00 00
WidgetEnd
Now we've got this text at the top of the surface.txt
StepSize
RotaryWidgetClass 0.001
StepSizeEnd
AccelerationValues
RotaryWidgetClass Dec 3f 3e 3d 3c 3b 3a 39 38 36 33 2f
RotaryWidgetClass Inc 41 42 43 44 45 46 47 48 4a 4d 51
RotaryWidgetClass Val 0.001 0.002 0.003 0.004 0.005 0.006 0.0075 0.01 0.02 0.03 0.04
AccelerationValuesEnd
And the encoder widgets look like this (Note: MFTEncoder has been replaced with the standard Encoder widget since all the instructions are now up top).
Widget RotaryA1 RotaryWidgetClass
Encoder b0 00 7f
FB_Fader7Bit b0 00 00
WidgetEnd
Here is an example from the X-Touchsurface.txt where the step size is 0.003 and the AccelerationValues line up with MCU-style devices.
StepSize
RotaryWidgetClass 0.003
JogWheelWidgetClass 0.003
StepSizeEnd
AccelerationValues
RotaryWidgetClass Dec 41 42 43 44 45 46 47
RotaryWidgetClass Inc 01 02 03 04 05 06 07
RotaryWidgetClass Val 0.0006 0.001 0.002 0.003 0.008 0.04 0.08
JogWheelWidgetClass Dec 41 42 43 44 45 46 47
JogWheelWidgetClass Inc 01 02 03 04 05 06 07
JogWheelWidgetClass Val 0.0006 0.001 0.002 0.003 0.008 0.04 0.08
AccelerationValuesEnd
-
Some encoders like the MIDI Fighter Twister or Behringer BCR-2000 may require a FB_Fader7Bit processor instead of FB_Encoder to work properly. If you're not getting feedback, or your encoder is otherwise not working, you may want to try FB_Fader7Bit.
-
When trying to determine the values, don't pay attention to what is displayed on the plugin's GUI. Example: a decay time of 2.4 seconds will not equal a parameter value of 2.4. One trick is to enter Write mode and begin creating automation data for the parameter you're trying to map, then clicking on the nodes and making note of where the parameter steps jump and what their real automation values are (remember: they will be between 0.0 and 1.0).
-
When trying to decide if a Surface control should be represented using Fader7Bit or Encoder, look at what values are actually being sent by the Surface. Fader7Bit expects an absolute value, whereas Encoder expects an increment/decrement value.