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.RS232

         

Image:nullmodem.png

 

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.

Image:blu_serial_properties.png

 

 

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:

  1. The ID and Payload are assembled according to the appropriate format for the given message type.

  2. An XOR checksum of the ID and Payload is appended.

  3. 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

Image:payload_format.png

0x89

DI_SUBSCRIBESV

0x8A

DI_UNSUBSCRIBESV

0x8D

DI_SETSVPERCENT

0x8E

DI_SUBSCRIBESVPERCENT

0x8F

DI_UNSUBSCRIBESVPERCENT

0x90

DI_BUMPSVPERCENT

 
 

Image:payload_preset.png

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.

Image:Network_view_node_address.png

 

 

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.

Image:Object_id.png

 

 

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

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:

Image:Presets_in_design_tree.png

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-
sum

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 */
        }
}