
Overview
- The Hoff Solo is a programmable MIDI master clock and controller.
- It is based on a Raspberry Pi W micro-controller, which featues two cores and two hardware UARTS for MIDI control.
- One core is used for the user interface, whereas the other core is dedicated to controller and MIDI events.
- The user interface features a full colour resistive touch screen, with two robust and silent switches that can be comfortably operated by foot or hand.
- Everything is housed in a robust metal enclosure.
Connections
- There are two DIN-5 MIDI out ports. MIDI can also be sent over USB.
- It supports MIDI over Bluetooth LE.
- Two 5V sync outs are available through a 1/8" (3.5mm) TRS socket.
- Two 1/4" (6.35mm) TRS sockets allow up to four additional foot switches to be connected.
- Power is supplied through a USB Micro B port, which is also used for firmware & SYSEX updates.
Usage
Preset screen
The preset screen consists of a title area, BPM area and switches area. Press on the screen to select a function.
- Title area
- Shows the title of the current preset
- Short press on the title opens the preset menu screen
- Long press on the title shows the current preset settings
- BPM area
- Shows the current BPM
- Short press on the BPM expands/shrinks the size of the display
- Switches area
- Shows the label of each switch
- Long press on a label shows the current switch settings
Menu screen
The menu screen shows the list of avalable presets. Press on the screen to select a preset.
System screen
The system screen area shows utility functions.
Programming
Preset programming is done by downloading, modifying and uploading single text file via SYSEX. This text file contains a complete set of presets, with each preset configured through a set of properties.
Each named property is identified with angle brackets <>, followed by a property value. A property value van be either a label, description or an instruction.
There is no closing tag as such - the start of a new property denotes the end of the previous property's value.
<SYSTEM> //No value - denotes the start of the file, serves to identify the system attributes
<VERSION>DESCR //The firmware version
<DEFAULT>LABEL //The label of the preset that is active on startup
<PRESET> //No value - denotes the start of a new preset
<PST_LBL>LABEL //The label for this preset
<PST_DSC>DESCR //The description for this preset
<PST_CLK>INSTR //The instruction performed with each MIDI clock cycle
<PST_ENT>INSTR //The instruction performed once when entering this preset
<PST_EXT>INSTR //The instruction performed once when exiting this preset
<LS0_LBL>LABEL //The label for the left main switch 0
<LS0_INF>DESCR //The description for the left main switch 0
<LS0_PRS>INSTR //The instruction performed when the left main switch 0 is pressed
<LS0_RLS>INSTR //The instruction performed when the left main switch 0 is released after a short interval
<LS0_RLL>INSTR //The instruction performed when the left main switch 0 is released after a long interval
<LS1_LBL>LABEL //The label for the left external switch 1
<LS1_INF>DESCR //The description for the left external switch 1
<LS1_PRS>INSTR //The instruction performed when the left external switch 1 is pressed
<LS1_RLS>INSTR //The instruction performed when the left external switch 1 is released after a short interval
<LS1_RLL>INSTR //The instruction performed when the left external switch 1 is released after a long interval
<LS2_LBL>LABEL //The label for the left external switch 2
<LS2_INF>DESCR //The description for the left external switch 2
<LS2_PRS>INSTR //The instruction performed when the left external switch 2 is pressed
<LS2_RLS>INSTR //The instruction performed when the left external switch 2 is released after a short interval
<LS2_RLL>INSTR //The instruction performed when the left external switch 2 is released after a long interval
<RS0_LBL>LABEL //The label for the right main switch 0
<RS0_INF>DESCR //The description for the right main switch 0
<RS0_PRS>INSTR //The instruction performed when the right main switch 0 is pressed
<RS0_RLS>INSTR //The instruction performed when the right main switch 0 is released after a short interval
<RS0_RLL>INSTR //The instruction performed when the right main switch 0 is released after a long interval
<RS1_LBL>LABEL //The label for the right external switch 1
<RS1_INF>DESCR //The description for the right external switch 1
<RS1_PRS>INSTR //The instruction performed when the right external switch 1 is pressed
<RS1_RLS>INSTR //The instruction performed when the right external switch 1 is released after a short interval
<RS1_RLL>INSTR //The instruction performed when the right external switch 1 is released after a long interval
<RS2_LBL>LABEL //The label for the right external switch 2
<RS2_INF>DESCR //The description for the right external switch 2
<RS2_PRS>INSTR //The instruction performed when the right external switch 2 is pressed
<RS2_RLS>INSTR //The instruction performed when the right external switch 2 is released after a short interval
<RS2_RLL>INSTR //The instruction performed when the right external switch 2 is released after a long interval
The following property values are valid:
LABEL- All alphanumerics allowed except for Angle brackets, <> (ASCII 0x20 .. 0x7D, excluding 0x3C and 0x3E)
- Maximum length is 8 characters
- Example
- TRANSPRT
- All alphanumerics allowed except for Angle brackets, <> (ASCII 0x20 .. 0x7D, excluding 0x3C and 0x3E)
- Maximum length is 255 characters
- Line breaks can be forced by using \n
- Example
- This preset allows the LEFT\n button to set the BPM\nand the RIGHT button to\nstart/stop the transport
- Contains a list of FUNCTIONs, seperated by spaces
- Maximum length is 255 characters, or 10 FUNCTIONS
- Example
- [1,1]MSG_USB(0X90,1,127) [1,1]MSG_LFT(0X90,4,127) [1,1]MSG_RGT(0X90,7,127)
- A function consists of an interval and a function name with arguments
- Maximum length is 255 characters, or 10 FUNCTIONS
- Interval [index,total]
- Delimited by square brackets [ ] with two integer arguments, seperated by a comma
- The first argument is index, specifying on which interval to call the function (1-based)
- The second argument is total, specifying the total number of intervals (1-based) before starting again at 1
- Function ???_???(n1,n2,..)
- The function name is a seven character string consisting of two sets of three characters, seperated by an underscore _
- The function argument is delimited by round brackets ( ), with arguments seperated by commas
- Each function takes specific arguments
- MSG_BLE(n1,n2,n3)
- Send a MIDI MESSAGE over Bluetooth LE
- Each argument is a MIDI message byte
- Takes up to 3 unsigned integer arguments, specified as either decimal or hex (0x00)
- MSG_USB(n1,n2,n3)
- Send a MIDI MESSAGE to the USB port
- Each argument is a MIDI message byte
- Takes up to 3 unsigned integer arguments, specified as either decimal or hex (0x00)
- MSG_LFT(n1,n2,n3)
- Send a MIDI MESSAGE to the left DIN-5 port
- Each argument is a MIDI message byte
- Takes up to 3 unsigned integer arguments, specified as either decimal or hex (0x00)
- MSG_RGT(n1,n2,n3)
- Send a MIDI MESSAGE to the right DIN-5 port
- Each argument is a MIDI message byte
- Takes up to 3 unsigned integer arguments, specified as either decimal or hex (0x00)
- SET_BPM(n)
- Sets the MIDI clock to a specified BPM (tempo)
- The argument is the desired Beats Per Minute (tempo)
- Takes 1 unsigned integer argument, specified as either decimal or hex (0x00)
- TAP_BPM(n)
- Sets the MIDI clock to a BPM (tempo) determined by tap intervals.
- The argument is a BPM multiplier, multiplying the detected tap tempo by n
- Takes 1 unsigned integer argument, specified as either decimal or hex (0x00)
- SET_PST(????????)
- Switches to the specified preset.
- The argument is the label of the desired preset.
- Takes 1 string argument
- SET_VAR(v,n)
- Sets a variable (v) to a specified value (n).
- v is the index of the variable to set [0..9].
- n is the value (unsigned int) [0..65535].
- SET_SCx(l,t)
- Sets a sync output (x) to a specified level value (l), for a duration (t).
- x is the sync output to set [1..2].
- l is the level to set: 1 = 5V, 0 = 0V [0..1].
- t is the duration of the pulse in millisends (unsigned byte) [0..255].
- MSG_BLE(n1,n2,n3)
Variables
- There are 10 general purpose variables.
- Variables are referenced by index no. 0..9, and prefixed with an @ to get their value.
- You can use the @n variable reference in any function argument, even in SET_VAR if you need complex logic.
- E.g.
- Set variable 1 to 120, and use the variable to set the tempo: [1,1]SET_VAR(1,120) [1,1]SET_BPM(@1)
- Set variable 1 to 5, and set the nth variable to 100: [1,1]SET_VAR(1,5) [1,1]SET_VAR(@1,100)
- Set variable 3 to 0, and set the interval to 0 (to prevent it from executing): [1,1]SET_VAR(1,0) [@1,1]SET_BPM(100)
- Example: Send MIDI CLOCK message to USB port, once every clock interval (which is 24x per beat) if using the PST_CLK property
- [1,1]MSG_USB(0xF8)
- Example: Send MIDI CLOCK message to left DIN-5 port, every third clock interval (which is 8x per beat) if using the PST_CLK property
- [1,3]MSG_USB(0xF8)
- Example: Set tap tempo to double to BPM, i.e. if tap tempo is detected at 100 BPM, it will set the BPM to 200 if using the PST_CLK property
- [1,1]TAP_BPM(2)