# Smart Multibox Programming Guide

This guide gives you the information you need to write custom scripts for the Smart Multibox

# About

# Introduction

The Smart Multibox is a 2-input, 4-output MIDI interface with a microprocessor "brain". You can use custom scripts to filter, route and translate incoming MIDI messages and send them to any or all of the MIDI outputs.

Scripts are written in [Micropython](https://www.micropython.org), which is similar to Python 3, but is optimized for running on small devices. As of this writing, the Smart Multibox uses version 1.24.1 of Micropython.

# Smart Multibox Editor

#### Setup

The Smart Multibox Editor app is used to edit scripts and send them to the Smart Multibox. It's available for these platforms:

- MacOS 12 (Monterey) or newer
- Windows 10 or newer

To use the app, connect the Smart Multibox's USB C connector to your computer, then start up the Smart Multibox Editor. In the upper right corner, it should show "Smart Multibox:26". If it instead reports "-not connected-", check your USB connection and click the dropdown menu (that currently says "-not connected-"). Select "Scan for Devices". It should connect immediately to the Smart Multibox at that point.

If you have more than one Smart Multibox, you can use the Global Settings window to assign a different name and Sysex ID number to each unit. It's important to have different IDs and names on them so that the computer can distinguish between each unit. When more than one unit is physically connected to your PC, the dropdown menu in the upper right will show all of the connected Smart Multiboxes. You can use that menu to select which device the editor is currently connected to.

When setting a Smart Multibox's name and sysex ID, it's best to only have one Smart Multibox connected to your computer. Once you've changed the name and ID, the editor app can tell them apart and you can plug more than one into your computer simultaneously.

#### Usage

On the left side of the screen, a list of all scripts you have downloaded or written is shown. On the right, the contents of the currently selected script is shown, and you can edit it there.

A new blank script can be created using the "+" button and the currently selected script can be deleted using the "-" button. The "Sort" button sorts the list of scripts by title.

At the bottom of the left column, there's a button titled "Download More Scripts", and this allows you to download any of the scripts we've put on our website. This list will continue to grow as we write more examples or users contribute their scripts.

To send the currently selected script to the Smart Multibox, press the button "Send Script To Device". Pressing "Read Script From Device" will read the current script from the Smart Multibox and save it as a new script in the list.

At the bottom of the screen is a message log. This displays any errors that occur during the running of the script, and also the output of any print() command in the script, as long as the Smart Multibox is connected.

# Accessories

#### TRS Port

The Smart Multibox has a 1/4-inch TRS input, which can be used to connect an expression pedal, a 1-button footswitch or 2-button footswitch, and scripts can act based on changes to the connected accessory.

Please see the [Hardware Access Functions](https://docs.rjmmusic.com/books/smart-multibox-programming-guide/page/hardware-access-functions "Hardware Access Functions") and [Callbacks](https://docs.rjmmusic.com/books/smart-multibox-programming-guide/page/callbacks "Callbacks") sections to find out how to write scripts using these accessories.

##### Expression Pedal

The Smart Multibox accepts a standard tip-to-wiper expression pedal. This is the most common kind, made by Roland/Boss, Mission Engineering, Fractal Audio, etc.

***NOTE:*** *This is different than all the older RJM Music products. We formerly used the other type of expression pedal, ring-to-wiper, but we're starting to move to the more common format, starting with this product.*

##### External Switch

The TRS port can also accept a 1 or 2 button footswitch. The footswitch should be a simple momentary or latching short-to-ground switch, with no LED in series with the switch. A 1 button footswitch can use a 1/4-inch TS (mono) cable, but please note that the ring switch will always be considered "on" when using a mono cable. When using a 2-button footswitch, a 1/4-inch TRS cable is required.

# Programming Reference

# General Guidelines

The Smart Multibox uses [Micropython](https://www.micropython.org) as its scripting language. General information can be found on the [Micropython website](https://www.micropython.org). Most reference materials that cover Python 3 will also apply.

As of this writing, the Smart Multibox uses Micropython 1.24.1

The Micropython build is fairly minimal, most optional features have not been included, for example, file I/O and threads. In addition to the minimal Micropython configuration, these are the optional features that *have* been included:

- bytearrays
- floating point math
- The **array** module
- The **collections** module *(deque and namedtuple types)*
- The **micropython** module
- The **random** module
- The **struct** module

This section will explain the extensions that have been added to Micropython for the sending, receiving and manipulation of MIDI messages.

#### Callback Driven Operation

The Smart Multibox is designed to primarily use callback functions. User code should not implement loops that run for a long time or infinitely. Doing so will prevent the Smart Multibox from operating properly. Callbacks are available for a number of events, including incoming MIDI messages, button presses and timer ticks. See the [Callbacks](https://docs.rjmmusic.com/books/smart-multibox-programming-guide/page/callbacks "Callbacks") section for more details.

# MIDI Functions

The Smart Multibox has quite a few functions that allow you to create, send and receive MIDI messages. MIDI messages can also be created manually - they are actually Python bytearrays, and can be manipulated with standard Python functions.

#### Message Creation Functions

##### midi\_msg\_make\_1byte(msg\_type)

Creates and returns a 1 byte MIDI message with the given message type. Message types can be found in the [Constants](https://docs.rjmmusic.com/books/smart-multibox-programming-guide/page/constants "Constants") section.

##### midi\_msg\_make\_cc(channel, number, value)

Creates and returns a MIDI CC (continuous controller) message with the given MIDI channel (1-16), number (0-127) and value (0-127).

##### midi\_msg\_make\_chan\_pressure(channel, value)

Creates and returns a MIDI channel pressure message with the given MIDI channel (1-16) and value (0-127).

##### midi\_msg\_make\_note(channel, note, velocity)

Creates and returns a MIDI note message with the given MIDI channel (1-16), note number (0-127) and velocity (0-127). Using velocity of 0 is equivalent to a "note off".

##### midi\_msg\_make\_pc(channel, number)

Creates and returns a MIDI PC (program change) message with the given MIDI channel (1-16) and number (0-127).

##### midi\_msg\_make\_pitch\_bend(channel, value)

Creates and returns a MIDI pitch bend message with the given MIDI channel (1-16) and value (0-16383).

##### midi\_msg\_make\_poly\_pressure(channel, note, value)

Creates and returns a MIDI polyphonic pressure message with the given MIDI channel (1-16), note number (0-127) and value (0-127).

#### Message Manipulation Functions

##### midi\_msg\_get\_channel(midi\_msg)

Given a MIDI message, returns the MIDI channel the message is on (1-16). Returns -1 if the MIDI message has no channel associated with it.

##### midi\_msg\_set\_channel(midi\_msg, channel)

Given a MIDI message, sets the MIDI channel of the message (1-16). Raises a ValueError exception if the channel value is not valid, or if the message does not have a specific channel.

##### midi\_msg\_get\_number(midi\_msg)

Given a MIDI message, returns the PC, CC or note number from the message is (0-127). Returns -1 if the MIDI message has no number associated with it.

##### midi\_msg\_set\_number(midi\_msg, number)

Given a MIDI message, sets the PC, CC or Note number of the message (0-127). Raises a ValueError exception if the channel value is not valid, or if the message does not have a number associated with it.

##### midi\_msg\_get\_type(midi\_msg)

Given a MIDI message, returns the MIDI message type, which is the status byte with the MIDI channel value zeroed out (128-250). Constants defined for each message type are defined in the [Constants](https://docs.rjmmusic.com/books/smart-multibox-programming-guide/page/constants) section. Returns -1 if the MIDI message is not valid.

##### midi\_msg\_set\_type(midi\_msg, msg\_type)

Given a MIDI message, sets the type of the message (128-250). Constants defined for each message type are defined in the [Constants](https://docs.rjmmusic.com/books/smart-multibox-programming-guide/page/constants) section. The existing MIDI channel of the message, if any, is left unchanged. Raises a ValueError exception if the type value or the MIDI message is not valid.

##### midi\_msg\_get\_value(midi\_msg)

Given a MIDI message, returns the CC, velocity or pressure value of the message (0-127). Returns -1 if the MIDI message has no value associated with it.

##### midi\_msg\_set\_value(midi\_msg, channel)

Given a MIDI message, sets the CC, velocity or pressure value of the message (0-127). Raises a ValueError exception if the value is not valid, or if the message does not have a value associated with it.

#### Other MIDI Related Functions

##### midi\_allow\_running\_status(in\_port, allow)

If allow is set to True, data bytes received on in\_port that have no status byte in front of them will have the most recently received status byte prepended to them, per the Running Status feature found in the MIDI specification. If allow is set to False, any data bytes received without a preceding status byte will be ignored. The default setting is False.

##### midi\_msg\_is\_valid(msg)

Returns True if the given value is a valid MIDI message, False if not.

##### midi\_route\_clear()

Removes all MIDI clock routes

##### midi\_route\_clock(in\_port, out\_port)

Adds a routing connection from in\_port to out\_port, where MIDI clock, start, stop and continue messages received at in\_port are automatically forwarded to out\_port. See the [Constants](https://docs.rjmmusic.com/books/smart-multibox-programming-guide/page/constants) section for port definitions.

##### midi\_send(port, msg)

Sends a MIDI message to a specified MIDI port. The MIDI port values are defined in the [Constants](https://docs.rjmmusic.com/books/smart-multibox-programming-guide/page/constants) section. Returns the number of bytes sent, or -1 if an error occurred.

##### usb\_route\_input(port, enable)

Enables or disables routing from a MIDI input to USB. This is the same type of routing used in the USB MIDI mode of the Smart Multibox. For example, messages coming in to MIDI In 1 will appear on a connected computer on Smart Multibox MIDI In 1. By default, all MIDI to USB routes are disabled.

##### usb\_route\_output(port, enable)

Enables or disables routing from USB to a MIDI output. This is the same type of routing used in the USB MIDI mode of the Smart Multibox. For example, sending a message to Smart Multibox MIDI Out 1 on a connected computer will result in that message coming out of MIDI Out 1 on the Smart Multibox. By default, all USB to MIDI routes are disabled.

# Hardware Access Functions

These functions allow you to directly control aspects of the Smart Multibox hardware

##### multibox\_blink\_led()

Turns the LED off for a short period of time (~20msec), then returns it to its previous color. This routine is regulated so that blinks are only allowed to happen once every 40msec. This prevents the LED from being off all the time when this routine is called frequently.

##### multibox\_set\_led(color)

Sets the LED to a specific color. Possible color values are LED\_OFF, LED\_GREEN, LED\_ORANGE and LED\_RED.

##### multibox\_set\_trs\_mode(mode)

Sets the operating mode of the TRS port. Valid values are TRS\_EXPPEDAL (enable expression pedal mode) and TRS\_EXTSWITCH (enable external switch mode). The default at power on is TRS\_EXPPEDAL mode.

# Callbacks

The Smart Multibox uses callbacks to communicate system events to the user code. Using one of the below functions, you specify another function that should be called when an event happens, then the system will call that function to report an event. On powerup, none of these callbacks are defined.

##### multibox\_set\_button\_cb(cb\_func)

Sets a callback function to be called when the button is pressed or released. The function should be in the following format:

**button\_cb(pressed)**

Where **pressed** is a Boolean value that is True indicating the button is pressed or False if the button is released.

##### multibox\_set\_exp\_pedal\_cb(cb\_func)

Sets a callback function to be called when the connected expression pedal moves. The function should be in the following format:

**exp\_pedal\_cb(value)**

Where value is the expression pedal's position, between 0 and 255.

##### multibox\_set\_ext\_switch\_cb(cb\_func)

Sets a callback function to be called when the connected external switch changes state. The function should be in the following format:

**ext\_switch\_cb(sw\_num, pressed)**

Where **sw\_num** is EXTSWITCH\_TIP or EXTSWITCH\_RING and **pressed**  is a Boolean value that is True indicating the button is pressed or False if the button is released.

##### multibox\_midi\_set\_receive\_cb(cb\_func)

Sets a callback function to be called every time a MIDI message is received. The function should be in the following format:

**midi\_receive\_cb(port, msg)**

Where **port** is the MIDI port the message was received on (see the [Constants](https://docs.rjmmusic.com/books/smart-multibox-programming-guide/page/constants "Constants") section), and **msg** is the contents of the MIDI message.

##### multibox\_set\_tick\_cb(cb\_func)

Sets a callback function to be called every time the system tick happens (every 1msec). The function should be in the following format:

**tick\_cb()**

# Constants

Some of the Smart Multibox functions take special constants as input parameters. These are defined below.

#### Expression Pedal Constants

\# Minimum and maximum values that are sent to the expression pedal callback  
EXPPEDAL\_MIN = 0  
EXPPEDAL\_MAX = 127

#### LED Constants  


\# Possible LED colors  
LED\_OFF = 0  
LED\_RED = 1  
LED\_GREEN = 2  
LED\_ORANGE = 3

#### MIDI Constants  


##### Message Types

MIDI\_NOTE\_OFF = 0x80  
MIDI\_NOTE\_ON = 0x90  
MIDI\_POLY\_PRESSURE = 0xA0  
MIDI\_CC = 0xB0  
MIDI\_PC = 0xC0  
MIDI\_CHAN\_PRESSURE = 0xD0  
MIDI\_PITCH\_BEND = 0xE0  
MIDI\_SYSEX\_START = 0xF0  
MIDI\_TIME\_FRAME = 0xF1  
MIDI\_SONG\_POS = 0xF2  
MIDI\_SONG\_SEL = 0xF3  
MIDI\_TUNE\_REQ = 0xF6  
MIDI\_SYSEX\_END = 0xF7  
MIDI\_CLOCK = 0xF8  
MIDI\_START = 0xFA,  
MIDI\_CONTINUE = 0xFB  
MIDI\_STOP = 0xFC  
MIDI\_ACTIVE\_SENSE = 0xFE  
MIDI\_RESET = 0xFF

##### Other Values

MIDI\_MIN\_VAL = 0  
MIDI\_MAX\_VAL = 127

#### Port ID Numbers

MIDI\_IN\_1 = 0x0  
MIDI\_IN\_2 = 0x1  
MIDI\_IN\_3 = 0x2 # Bidirectional input on MIDI\_OUT\_1  
MIDI\_IN\_USB = 0x8 # Used when the connected computer sends to the "SMB Internal" USB MIDI port  
MIDI\_OUT\_1 = 0x10  
MIDI\_OUT\_2 = 0x11  
MIDI\_OUT\_3 = 0x12  
MIDI\_OUT\_4 = 0x13  
MIDI\_OUT\_5 = 0x14 # Bidirectional output on MIDI\_IN\_1  
MIDI\_OUT\_USB = 0x18 # Used to send to the connected computer using the "SMB Internal" USB MIDI port

#### TRS Port Constants

\# External switch IDs used for a 2 button external switch. 1 button switches always use EXTSWITCH\_TIP  
EXTSWITCH\_TIP = 0  
EXTSWITCH\_RING = 1  
\# TRS port modes  
TRS\_EXPPEDAL = 0  
TRS\_EXTSWITCH = 1