RPN Logic Scripter

Overview

MediaMatrix features a simple logic scripting function called RPN Scripting.  This functionality has existed since the first 3.x versions, but has been hidden from view in the standard release of MWare.  This is because we feel that this programming is more appropriate for those with a basic knowledge of procedural computer languages.  Even so, it takes most people a while to hone their scripting technique to produce more complex behavior.

There are many devices included with MWare that utilize RPN Scripting to function.  With relatively simple commands, Control Logic devices such as the Control Inverter, Flip Flop (and Dual), Opposite, Control Modifier, and the Event Counter all use RPN script.  More complicated devices came later, which is why they are located inside the Advanced folder:  Router Sequencer and Range Selector.

A complex example of RPN Logic Scripting can be found in every instance of the PageMatrix II devices.  In this case, each zone has its own script to respond to a shared set of PTT (Push-to-talk) switches and a series of "pre-select" buttons that enable the respective station's PTT to page to that zone.  Have a look at the code.  One interesting thing about it is that it automatically scales the output to the value table of the attached Router with the Router Size field.

In more depth...

The RPN Logic Scripter in MediaMatrix MWare has some similarities to HP calculator RPN, but also some things borrowed from Forth and C++.  Here is an attempt at layman’s explanations of the operation of the RPN Logic Scripter.

HP's RPN has a stack that is 4 registers tall.  The bottom or display register is called “X”, while the ones above it are called “Y”, “Z”, and “t”.  New entries always go onto the bottom of the stack and generally push the other items in the stack up.  When an operation is done on two entries, they are the bottom two on the stack.  The result is usually one number and is placed on the bottom of the stack.  Since the bottom two entries are removed, and only one entry put in their place, the stack falls one register.  If the stack grows all the way up to the top before falling, the contents of the “t” register are copied down one, instead of just falling down.

MWare's RPN Logic Scripter has a stack that grows to any height needed.  As a result it does not have a “top of stack” register that behaves differently from the others.  All registers behave the same.  The stack convention used in this document is that entries go on the top of the stack, and the stack grows down instead of up.

HP's RPN requires an Enter key to tell it when you are done entering a number and wish to push it up the stack.  MM RPN does not have a keyboard entry, and every number gets entered as a complete number.  Each entry goes on the top of the stack, and all prior entries are automatically pushed down one register.

How to use MWare RPN Scripting (tips)

MWare RPN Script is written in 1 through 50 Script Fields in a RPN Scripter device.  The script will do exactly the same thing no matter how many Script Fields it is spread across.  Multiple fields are just used for ease of editing.  Since the Script Field is a string type of Control Object, it is possible to Control Group any number of these fields together as long as they are in different copies of the RPN Scripter device.  Then if you edit one field, you will be editing all the Control Grouped fields the same way.  This can be a major time saver.

Script fields are edited in control mode.  If the view file is compiled, then the contents of Script fields may be copied, cut, and pasted between fields, or between fields and the ControlScript ScratchPad (a modified "Strings" device).  Each Script field must either be typed in its entirety, or may have characters removed from the end of the field using the backspace key, and if it is desired, new characters appended to its end.  No other ordinary text editing functions are available.

RPN Script runs from the first field through the last field in sequence.  It does not repeat, but only makes one pass through at a time.  It is triggered to make a pass through the entire Script by a change in the value of any input parameter.

All operations are performed in double-precision floating point. Boolean operations use 0 as a logical 0 and non-zero values as a logical 1.  All Boolean operations use positive logic.

Control Wiring

Another technique to know is that you can create a more efficient control sequence if you learn to use Control Wiring (top and bottom wiring) to pass control outputs to device inputs instead of using Control Groups (which are slower).  You must write your code to match the expected range(s) of the Control Node Inputs on the destination device.  Some experimentation is almost always necessary to ensure that the target device will function as expected.  Here is a short list of devices that can be used with control wiring and their input characteristics:

Other RPN Script-based Devices (You can program the behavior of the nodes)
Level (Controls the Trim Control)
Ramp (Lower 1/3: Ramp to A; Middle 1/3: Ramp off; Upper 1/3: Ramp to B)
Mixer (on primitives, converts decimal integer RPN output to reverse binary mute buttons)
Router (Control mirrors router Value Table; each column requires its own control node)
Crossfading Router and Crossfading DAB Router (wired to RPN device inside)

RPN Scripter Types and the Algorithm String

There are three types of RPN Logic Scripter, with the type being determined by the value of the last argument in the Algorithm String.  The basic RPN Logic Scripter (type 0) is the Integer version.  There is a Percent version (type 1), which translates all inputs and outputs as a percentage of control range. Last, there is a Logic version (type 2), which automatically does conversion to and from Boolean on all inputs and outputs.

Each Algorithm String starts with the Algorithm name CBLOGIC.  The first argument specifies the number of inputs from 1 to 50.  The second argument specifies the number of outputs from 1 to 50.  The third argument specifies the number of Script Fields from 1 to 50.  The number of memory registers is always 8.

Control ID Ranges

You can add more of each kind of control (input, output, register control or script field) by simply making copies of other controls and changing their Control ID to the next unused ID.  You have to make sure that you have the correct number of that kind of control in the CBLOGIC Algorithm String.  Also there can be no more than 50 of any control type within the following ranges:

Inputs: 10-41 (Hexadecimal 41 not decimal "41")
Outputs: 42-73

Script Fields: 74-a5

Registers: a6-ad
(only 8 registers available (no more can be created))

RPN Script Command Reference

In the following tables, when there is more than one input value, the order of the values given are as they must appear on the stack before the function is performed.  Since the stack pushes down, the lower value must be entered first.  Input values are removed from the stack and replaced with an output value (if any) on the top of the stack.

Constants

Identifier

Value

 

CBMIN

minimum control bus value

 

CBMAX

maximum control bus value

 

 

Math

Function

Input Stack

Output Stack

Description

+

V1 V2

( V1 + V2 )

add V1 to V2, put result on stack

-

V1 V2

( V1 - V2 )

subtract V2 from V1, put result on stack

*

V1 V2

( V1 * V2 )

multiply V1 times V2, put result on stack

/

V1 V2

( V1 / V2 )

divide V1 by V2, put result on stack

MIN

V1 V2

min( V1, V2 )

put minimum of V1 and V2 on stack

MAX

V1 V2

max( V1, V2 )

put maximum of V1 and V2 on stack

INV

V

( 1.0 - V )

put inverse of V on stack

 

Comparisons

Function

Input Stack

Output Stack

Description

TOBOOL

V

( V != 0 )

if V is equal to 0, put 0 on the stack, otherwise put 1

==

V1 V2

( V1 != V2 )

if V1 is equal to V2, put 1 on the stack, otherwise put 0

>

V1 V2

( V1 > V2 )

if V1 is greater than V2, put 1 on the stack, otherwise put 0

>=

V1 V2

( V1 >= V2 )

if V1 is greater than or equal to V2, put 1 on the stack, otherwise put 0

<

V1 V2

( V1 < V2 )

if V1 is less than V2, put 1 on the stack, otherwise put 0

<=

V1 V2

( V1 <= V2 )

if V1 is less than or equal to V2, put 1 on the stack, otherwise put 0

 

Boolean Operations

Function

Input Stack

Output Stack

Description

NOT

B

!B

 

OR

B1 B2

( B1 || B2 )

 

AND

B1 B2

( B1 && B2 )

 

XOR

B1 B2

( B1 ^ B2 )

 

?:

B V1 V2

( B ? V1 : V2 )

 

CHOOSE

V1 V2 B

( B ? V1 : V2 )

 

 

Conversion

Function

Input Stack

Output Stack

Description

CBTOBOOL

V

( V > CBMAX/2 )

converts a control value to a boolean. If V is greater than 50%, put 1 on the stack, otherwise put 0

BOOLTOCB

B

( B ? CBMAX : CBMIN )

converts a boolean to a control value. If V is 1, put CBMAX on the stack, otherwise put CBMIN

 

Stack Manipulation

Function

Input Stack

Output Stack

Description

DUP

V

V V

puts copy of V on stack ( without removing V )

DROP

V

-

removes V from stack

SWAP

V1 V2

V2 V1

swaps V1 with V2 on stack

 

Input/Output

Function

Input Stack

Output Stack

Description

TOUT

V

-

print V to terminal

PRINT

V

-

print V to device

IPCUR

-

( index of changed input )

puts index of last changed input on the stack

IPGET

I

( value of input I )

puts value of input at index I on the stack

IPCGET

V I

 

puts value of input at index I on stack. If input is missing, puts V on stack

IPGETLAST

I

( previous value of input I )

puts previous value of input at index I on the stack

OPGET

I

( value of output I )

puts value of output at index I on stack

OPSET

V I

-

sets value of output at index I to V

RGET

I

( value of register I )

puts value of register at index I on stack

RSET

V I

-

sets value of register at index I to V