Third-party Control Protocol
Introduction
This section is provided for Soundweb London users who wish to provide their own user interface or control system for a Soundweb London system. The user interface or control system can be based on a PC running a custom application, a dedicated show controller, a proprietary control system such as Crestron or AMX, or even a custom piece of hardware.
The Soundweb London third-party control protocol builds on the flexibility of the RAW_MSG extension protocol introduced with Soundweb Original and gives almost complete control of a Soundweb London network via RS-232 or TCP/IP.
Interface Options
Soundweb London devices accept third-party control commands via RS-232 or TCP/IP. It is only necessary to connect to a single device in a Soundweb London network. That device will forward control messages to other devices as necessary.
Serial/RS-232
The connection from the controller to the Soundweb London device should be made using a 3-wire null modem cable. In most cases it is fine if the other pins are connected, but some controllers will only work with 3-wire cables.
PC or Controller |
Soundweb London |
|||
RX |
Pin 2 |
TX |
Pin 3 |
|
TX |
Pin 3 |
RX |
Pin 2 |
|
GND |
Pin 5 |
GND |
Pin 5 |
|
Soundweb London devices use 8-bit data bytes, no parity, and one stop bit (i.e. '8N1').
- The default bit rate is 115,200 bps. This can be changed in HiQnet London Architect by clicking on the desired device in the system layout, opening the Properties window, and selecting the desired data rate. Other parameters, such as whether the device will expect messages to be acknowledged, can also be adjusted here.
TCP/IP
Soundweb London devices also accept third-party control messages via TCP/IP connections on port 1023. Refer to your controller's documentation for more information on connecting to a device via TCP/IP.
Protocol Description
The Soundweb London third-party control protocol (also called the 'Direct Inject' protocol) is a simple message-based protocol. Each message consists of a start byte, a message type ID byte, the message payload (which depends on the message type), a checksum byte, and an end byte. On serial connections, messages with a valid checksum are acknowledged with an ACK byte, while messages with an invalid checksum trigger a NAK response.
In a typical scenario, a controller might first send a series of SUBSCRIBE messages to learn the current state of the Soundweb London system. The Soundweb London device would respond with a SET message corresponding to each valid SUBSCRIBE message. The Soundweb London device will also notify the controller with a SET message each time a subscribed control parameter changes (unless the change is made by the controller itself). The controller could then send SET messages each time a control parameter should be changed based on user interaction or controller automation. When the controller is done controlling the Soundweb London system, it sends UNSUBSCRIBE messages corresponding to each SUBSCRIBE sent previously.
Message Format
Soundweb London third-party control messages have the following format:
STX |
ID |
Payload |
Checksum |
ETX |
0x02 |
Message body - see below |
0x03 |
The message body is constructed in three steps:
The ID and Payload are assembled according to the appropriate format for the given message type.
An XOR checksum of the ID and Payload is appended.
- Any control codes are escaped.
Message ID
There are nine message types. The behavior of each is described in the following table:
ID |
Message Type |
Description |
0x88 |
DI_SETSV |
Set a control parameter. |
0x89 |
DI_SUBSCRIBESV |
Return the current value of and subscribe to a control parameter. |
0x8A |
DI_UNSUBSCRIBESV* |
Unsubscribe from a control parameter. |
0x8B |
DI_VENUE_PRESET_RECALL |
Recall a Venue Preset. |
0x8C |
DI_PARAM_PRESET_RECALL |
Recall a Parameter Preset. |
0x8D |
DI_SETSVPERCENT |
Set a control parameter by percentage. |
0x8E |
DI_SUBSCRIBESVPERCENT |
Return the current value of and subscribe to a control parameter as a percentage of its total range. |
0x8F |
DI_UNSUBSCRIBESVPERCENT* |
Unsubscribe from a state variable previously subscribed as a percentage of its total range. |
0x90 |
DI_BUMPSVPERCENT |
Increment a control parameter by the given signed percentage of its total range. |
*DI_UNSUBSCRIBESV and DI_UNSUBSCRIBESVPERCENT are not interchangeable. |
Payload
The payload varies slightly with each message type. The message ID and payload together are 5 bytes for preset messages, 13 bytes for all other messages (before any control codes are escaped).
Message Type |
Payload Format |
|
0x88 |
DI_SETSV |
|
0x89 |
DI_SUBSCRIBESV |
|
0x8A |
DI_UNSUBSCRIBESV |
|
0x8D |
DI_SETSVPERCENT |
|
0x8E |
DI_SUBSCRIBESVPERCENT |
|
0x8F |
DI_UNSUBSCRIBESVPERCENT |
|
0x90 |
DI_BUMPSVPERCENT |
|
0x8B |
DI_VENUE_PRESET_RECALL |
|
0x8C |
DI_PARAM_PRESET_RECALL |
|
Address
Control parameters (also called 'State Variables') on a Soundweb London device are logically grouped into Virtual Devices (corresponding to categories of objects, such as Audio and Logic) and Objects (corresponding to individual processing objects). Each Object is uniquely identified on the Soundweb London network by its HiQnet address. HiQnet addresses are typically represented in hexadecimal and have the following format: 0xNodeVDObject.
Field |
Size |
Name |
Description |
Node |
2 |
HiQnet Node Address |
The HiQnet node address of the targeted Soundweb London device. Each physical Soundweb London device has a unique HiQnet node address assigned to it using the HiQnet London Architect software. If the node field is zero, the message will be sent to the device that is directly connected to the controller via RS-232 or TCP/IP. Otherwise the message will be forwarded to the corresponding device. |
VD |
1 |
Virtual Device ID |
The ID of the targeted virtual device. Objects (such as gains, mixer, logic elements, etc.) within the Soundweb London system are organized into Virtual Devices. A list of the Virtual Devices in a Soundweb London DSP device follows below. |
Object |
3 |
Object ID |
The ID of the targeted processing object. Each processing object, logic object, etc. has a unique object ID. |
Node
The node address of a Soundweb London device is shown in the Properties window when the device is selected in the system layout. It is also shown in the Network window when a device is selected in the network tree. See Connecting to a Soundweb London network for more information on changing a device's node address. The node address is the first four hexadecimal digits of the HiQnet address.
Virtual Device
Each Soundweb London DSP device contains four virtual devices. The Virtual Device ID is the third byte of the HiQnet address, or the fifth and sixth hexadecimal digits.
VD |
Description |
0x00 |
Basic settings |
0x01 |
Links |
0x02 |
Logic objects |
0x03 |
Audio processing objects |
Object
The Object ID is the last six hexadecimal digits of the HiQnet address shown in the Properties window when a processing object is selected in the device's audio configuration.
State Variable
Each control parameter of an Object is identified by a State Variable ID. State Variable IDs are consistently defined for each object type. For example, the mute control of every Gain object always has State Variable ID 0x01. If an object has a large number of control parameters, it is possible to use a formula to calculate the State Variable ID based on input and/or output channels, rather than hard-coding each control parameter ID. See Common Object and State Variable IDs for a list of objects and their corresponding State Variable IDs, including formulas for calculating State Variable IDs for some objects. The State Variable ID for a control parameter can be discovered by selecting the desired object, opening the Properties window, and clicking the desired control parameter in the Parameters list of the Properties window:
Gain Object: Gain SV ID is 0x00 |
The two-byte State Variable ID is always an unsigned 16-bit big-endian integer.
Data
The four-byte data section is always a signed 32-bit big-endian integer (i.e. the most significant byte is transmitted first). The contents of the data section are determined by the message type.
Message Type |
Data Type |
|
0x88 |
DI_SETSV |
Raw control value |
0x8D |
DI_SETSVPERCENT |
Percentage of control range |
0x90 |
DI_BUMPSVPERCENT |
|
0x89 |
DI_SUBSCRIBESV |
Zero for non-meter SVs, subscription rate for meter SVs |
0x8E |
DI_SUBSCRIBESVPERCENT |
|
0x8A |
DI_UNSUBSCRIBESV |
Zero |
0x8F |
DI_UNSUBSCRIBESVPERCENT |
|
0x8B |
DI_VENUE_PRESET_RECALL |
Preset ID |
0x8C |
DI_PARAM_PRESET_RECALL |
|
Raw Value
Each type of control parameter (i.e. gain, mute, frequency, time, etc.) has its own encoded format for raw values. See Appendix A for information on calculating raw values.
Percentage
The value of the control as a percentage of its total range (i.e. 0 to 100) multiplied by 65536 to allow for fractions of a percent. The accepted range of values is 0 to 6553600 for DI_SETSVPERCENT, -6553600 to 6553600 for DI_BUMPSVPERCENT.
Subscription Rate
The delay in milliseconds between updates sent by a meter. The Soundweb London device will round this value to 50ms increments. The rate must be zero when subscribing to a non-meter control parameter. Control system and logic performance may suffer if this value is too low.
Preset ID
Each preset on a Soundweb London network is assigned a unique ID when it is created. Once assigned, the Preset ID will not change when other presets are added or deleted. The message type corresponding to the preset's type (DI_VENUE_PRESET_RECALL for venue presets, DI_PARAM_PRESET_RECALL for parameter presets) must be used, as venue presets and parameter presets may have the same ID.
Preset IDs are shown in square brackets next to each preset in the design tree:
Note: Preset recall messages are broadcast across the network, so unexpected results may occur if presets are recalled with two separate HiQnet London Architect designs running on the same physical network.
Checksum
The checksum is a single-byte exclusive OR (XOR) of all the bytes in the message body, computed before control codes are escaped and before STX and ETX are added.
Note: If the checksum is a reserved control code it must be escaped in the same way as bytes in the body of the message. See Control Codes below.
Control Codes
The following byte values have special meanings and must be escaped if they occur within the message body. If a byte in the message body is one of the control codes, insert ESC (0x1B) before the byte and add 0x80 (decimal 128) to its value. Any other byte can be used within the message body. Note that substitution must be performed on the message body after the checksum has been calculated and appended and before STX and ETX are added to the message, as the checksum itself may be a control code in need of substitution.
Code |
Substitution |
Name |
Description |
0x02 |
0x1B 0x82 |
STX |
ASCII Start of Text |
0x03 |
0x1B 0x83 |
ETX |
ASCII End of Text |
0x06 |
0x1B 0x86 |
ACK |
ASCII Acknowledge |
0x15 |
0x1B 0x95 |
NAK |
ASCII No-acknowledge |
0x1B |
0x1B 0x9B |
ESC |
ASCII Escape |
Examples
The following examples display the complete structure of an actual control message and demonstrate a possible approach to sending and receiving control messages.
A Sample Message
This sample direct inject message will flash the locate light on the device indicated by the address.
Start |
Type |
Address |
State Variable |
Data |
Check- |
End |
|||||||||
Node |
VD |
Object |
|||||||||||||
02 |
88 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
04 |
00 |
00 |
00 |
00 |
8C |
03 |
The bytes in the message body used to calculate the checksum. |
|||||||||||||||
Sending Messages
The following pseudocode procedure sends a correctly formatted message by computing the checksum, escaping control characters, and adding STX and ETX.
char checksum
= 0 /* Stores
the running checksum */
send (STX) /* Send
the start-of-text character */
for each
character in message body /* Loop
through each character of the message */
{
checksum
= checksum XOR character /* Add the current character
to the checksum */
if (is_special
(character))
{
send
(ESC)
send
(character + 128) /* Escape
special characters */
}
else
{
send
(character) /* Send
non-special characters normally */
}
}
if (is_special
(checksum)) /* Escape
the checksum if needed */
{
send
(ESC)
send
(checksum + 128)
}
else
{
send
(checksum)
}
send (ETX) /* Send
the end-of-text character */
if (connected
via RS-232) /* Wait
for the device to get the message */
{
waitfor
(ACK or NAK)
}
Receiving Messages
The following pseudocode procedure receives a message, processes escaped control characters, and makes sure the message is valid by verifying the checksum.
bool got_escape /* Indicates
whether the previous character was ESC
*/
char checksum
= 0 /* Stores
the running checksum */
on received character
{
if (character
equals STX)
{
/* This
is the start of a new message */
checksum
= 0 /* Clear
the checksum */
clear_message_buffer() /* Clear
the message buffer */
got_escape
= false /* Clear
the "escape received" status */
}
else if (character
equals ETX)
{
/* This
is the end of a message, verify the checksum */
if (get_last_byte_in_message_buffer()
equals checksum)
{
send
(ACK) /* The
received checksum matched the computed checksum */
}
else
{
send
(NAK) /* The
received checksum was invalid */
}
got_escape
= false /* Clear
the "escape received" status */
}
else if (character
= ESC)
{
got_escape
= true /* Set
the "escape received" status */
}
else
{
if (got_escape
= true)
{
/* The
last character was ESC
- this must be an escaped control code */
add_byte_to_message_buffer
(character - 128)
checksum
= checksum XOR (character - 128)
}
else
{
/* The
last character was not ESC
- this must be an ordinary byte */
add_byte_to_message_buffer
(character)
checksum
= checksum XOR character
}
got_escape
= false /* Clear
the "escape received" status */
}
}