Scaling Controller Values

florian

2014-10-24 10:43:45

A user has this problem: the foot pedal only produces controller values between 40 and 70 (decimal). It should, however, control a controller with the full value range from 0 to 127.

The solution (in detail):

1) set up MT as "man in the middle", i.e. the external MIDI port is used by MT. It will route the calibrated MIDI data via the virtual MIDI port to the application where you want to use the pedal. The user manual describes this setup in the introductory chapters.

2) create a route in the MIDI Router so that by default all messages from the pedal are routed to the virtual port:
External MIDI Input --> Bome Virtual Out 1
(If you have multiple pedals, you can also merge all inputs to one virtual MIDI port by creating routes from the external ports to the same virtual output, or map each pedal to an individual virtual output).

3) create a preset, e.g. named "scale pedal 1". Invoke the preset properties and select the preset default MIDI ports: your External MIDI Input port as input, and the virtual output port 1 as output.

4) create a mapping by adding a translator in the preset. In the general options, make sure the "swallow" checkbox is checked. Assuming that the pedal sends on MIDI controller #0, the incoming and outgoing actions look like this:

Code: Select all

Incoming: MIDI C0 00 pp
Outgoing: MIDI C0 00 pp
Like that, the translator will simply output the same message that came in to the input port. The variable "pp" is a place holder for the controller value.

5) Use the rules for the actual calibration/scaling: the rules now have the task to "blow up" the value range from 40...70 to 0...127. This requires a bit math:

Code: Select all

                    (small_range_value - small_range_min) 
full_range_value = ---------------------------------------  *  (full_range_max - full_range_min)
                     (small_range_max - small_range_min)
(Note that actually, the ranges should be increased +1, but this causes an undesirable maximum scaled value).

When we put in the actual values, it looks a whole lot simpler:

Code: Select all

full_range_value = (small_range_value - 40) / 30 * 127
Here, we need to be careful, though: MT's variables only handle integer numbers, no fractions or decimals. Therefore, dividing by 30 will truncate the value and cause huge rounding errors. The solution is to always do the multiplication first, and then the division:

Code: Select all

full_range_value = (small_range_value - 40) * 127 / 30
The final rules section looks like this:

Code: Select all

pp=pp-40
if pp < 0 then pp=0
pp=pp*127
pp=pp/30
if pp > 127 then pp=127
As you can see, the rules in MT can only evaluate one mathematical statement per line. I've also added safeguards to not produce a controller value out of bounds. When all the rules are executed, pp has the full range value, i.e. something in between 0 and 127.

Hope this gets you started!
Florian