Copyright © Glensound Electronics Ltd and individual contributors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Glensound nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Content based on github.com/github/opensource.guide used under the CC-BY-4.0 license.
The GetInfo message can be sent to any device, regardless of its connection state. The message header must not include any password.
This should be done only once, when the device is discovered on the network. The device returns an Info structure containing various items, of which most important are Product ID and device name. The Spark's PID is 30.
1) Host controller sends a GetInfo message to the device.
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 10 00 05 00 90 09 89 03 GS Ctrl.........
------------------------------------------------------
GS Header:
0000 47 53 20 43 74 72 6c 00 Magic
10 00 Size
05 Opcode
00 Flags
90 09 89 03 Controller ID
Magic: 4753204374726c00 (Must not use password)
Size: 0x0010 (Payload 0 bytes) Packet size, including this header
.000 0000 0001 0000 = Packet size: 16
0... .... .... .... = Multipacket: False Message has one packet (this one)
Opcode: 5 (GetInfo)
Flags: 0x00 (set to zero)
Controller ID: 0x03890990 Unique value on this network, identifies the sender
2) Spark responds with Info.
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 90 00 04 0c 7f 02 00 2c GS Ctrl........,
0010 04 10 17 df ef fe 32 7b 1e 00 00 01 02 00 00 00 ......2{........
0020 00 22 03 ff fe 02 00 2c 53 70 61 72 6b 2d 30 32 .".....,Spark-02
0030 30 30 32 63 00 00 00 00 00 00 00 00 00 00 00 00 002c............
0040 00 00 00 00 00 00 00 00 53 70 61 72 6b 2d 4d 61 ........Spark-Ma
0050 72 63 69 6e 00 00 00 00 00 00 00 00 00 00 00 00 rcin............
0060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0080 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 ................
------------------------------------------------------
GS Header:
0000 47 53 20 43 74 72 6c 00 90 00 04 0c 7f 02 00 2c
Magic: 4753204374726c00
Size: 0x0090 (Payload 128 bytes)
.000 0000 1001 0000 = Packet size: 144
0... .... .... .... = Multipacket: False
Opcode: 4 (Info)
Flags: 0x0c (ignore)
Sequence: 127 Sequence number for Info packets
Device ID: 02002c
Info:
0010 04 10 Firmware version
17 df Status port
ef fe 32 7b Status IP
1e 00 Product ID
00 Variant ID
01 Protocol version
02 00 Flags
00 00 Dante process ID
0020 00 22 03 ff fe 02 00 2c Dante ID
53 70 61 72 6b 2d 30 32 Host name
0030 30 30 32 63 00 00 00 00 00 00 00 00 00 00 00 00
0040 00 00 00 00 00 00 00 00
53 70 61 72 6b 2d 4d 61 Friendly name
0050 72 63 69 6e 00 00 00 00 00 00 00 00 00 00 00 00
0060 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 Domain name
0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0080 00 00 00 00 00 00 00 00
00 10 DNT version
00 00 DFU2 version
00 00 00 00 reserved
Firmware version: 0x1004
Status port: 6111
Status IP: 239.254.50.123 (239.254.50.123)
Product ID: 30 (Spark)
Variant ID: 0
Protocol version: 1
Flags: 0x0002
.... .... .... ...0 = DNT updateable: False
.... .... .... ..1. = DFU updateable: True
.... .... .... .0.. = DFU2 updateable: False
Dante process ID: 0x0000
Dante ID: 0x002203fffe02002c
Host name: Spark-02002c
Friendly name: Spark-Marcin
Domain name:
DNT version: 0x1000
DFU2 version: 0x0000
If the host controller wants to keep the device connected it should send it messages (other than GetInfo) at least every 5-6 seconds. While connected, the device sends periodic Status messages and state change reports to the controller. If the device doesn't receive a message (other than GetInfo) for 7 seconds it disconnects and stops sending any data.
Typically a controller sends a GetConfig message every 5-6 seconds as keepalive, because the Config response indicates the connection state. The GetConfig message also contains bits that indicate whether the controller wishes to establish an exclusive connection and whether it wants the Status messages sent 10 times per second or once per second.
If the controller prefers to send ad-hoc commands to the device it doesn't need to keep the device connected. Sending any command, other than GetInfo, will set the device in Connected state (if access is granted) for 7 seconds.
The device responds with a Config message, which contains bits indicating the connection state.
1) Host controller sends a GetConfig command to the device.
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 10 00 07 01 90 09 89 03 GS Ctrl.........
------------------------------------------------------
GS Header:
Magic: 4753204374726c00
Size: 0x0010 (Payload 0 bytes)
.000 0000 0001 0000 = Packet size: 16
0... .... .... .... = Multipacket: False
Opcode: 7 (GetConfig)
Flags: 0x01
.... ...1 = Exclusive: True Desired exclusive connection (unicast responses)
.... ..0. = No meter: False Desired Status period of 10 Hz
Controller ID: 0x03890990
2) Device responds with a Config message.
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 18 00 06 0d 01 02 00 2c GS Ctrl.........
0010 ef fe 32 7b 17 df 00 00 ..2{....
------------------------------------------------------
GS Header:
0000 47 53 20 43 74 72 6c 00 18 00 06 0d 01 02 00 2c
Magic: 4753204374726c00 Can be XORed with a 8-byte password value
Size: 0x0018 (Payload 8 bytes)
.000 0000 0001 1000 = Packet size: 24
0... .... .... .... = Multipacket: False
Opcode: 6 (Config)
Flags: 0x0d
.... ...1 = Exclusive: True Device is in Exclusive connection mode
.... .1.. = Password valid: True Password used in GetConfig was valid
.... 1... = Access granted: True Access granted to this host controller
Sequence: 1 Sequence number for Config packets
Device ID: 02002c
Config:
0010 ef fe 32 7b Status IP, if in Shared mode
17 df Status port, if in Shared mode
00 00 reserved
Status IP: 239.254.50.123
Status port: 6111
When the device is in Connected state it sends periodic Status messages. In Exclusive connection mode it unicasts the packets to the host controller which has the connection granted. In Shared connection mode the device multicasts the packets to the group address and port indicated in the Config message.
The frequency of the Status messages is controlled by the NoMeter bit in the GetConfig command. If the bit is cleared, the device sends Status 10 times per seconds. This is useful if the host controller displays live audio metering data provided in the Status messages. If NoMeter is set, the device sends Status once per second.
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 34 00 01 00 7f 02 00 2c GS Ctrl.4.......
0010 02 00 00 00 00 01 02 01 00 32 00 00 fd a1 fd fd .........2......
0020 fd fd fd 24 fd fd fd fd fd fd fd fd fe fe fe fe ...$............
0030 10 00 00 06 ....
------------------------------------------------------
GS Header:
0000 47 53 20 43 74 72 6c 00 34 00 01 00 7f 02 00 2c
Magic: 4753204374726c00
Size: 52 (Payload 36 bytes)
.000 0000 0011 0100 = Packet size: 52
0... .... .... .... = Multipacket: False
Opcode: 1 (Status)
Flags: 0x00
Sequence: 127
Device ID: 02002c
GS Status:
0010 02 00 00 00 Flags
00 Preset report generation
01 Device report generation
02 In channel names report generation
01 Out channel names report generation
Flags: 0x00000002
.... .... .... .... .... .... .... ...0 = Identify: False
.... .... .... .... .... .... .... ..1. = Clock locked: True
Preset rep. gen.: 0
Device rep. gen.: 1
In ch. names rep. gen.: 2
Out ch. names rep. gen.: 1
Spark status:
0010 00 UI report generation
32 Mic input report generation
00 00 reserved
fd a1 fd fd Meters
0020 fd fd fd 24 fd fd fd fd fd fd fd fd fe fe fe fe
0030 10 Leds
00 00 reserved
06 Temperature
UI rep. gen.: 0
Mic in rep. gen.: 50
Meters: fda1fdfdfdfdfd24fdfdfdfdfdfdfdfdfefefefe
Leds: 0x10
.... ...0 = PGM: False
.... ..0. = TB1: False
.... .0.. = TB2: False
.... 0... = TB3: False
...1 .... = Power: True
Temperature: 0x06 (47) Temperature is 0.5 * 6 + 44 = 47 Celsius
Audio meter values are in Dante format. The value is interpreted as the number of half-decibel steps below 0 dBFS. For example:
00 = 0 dBFs
01 = -0.5 dBFS
02 = -1 dBFs
...
fe = -127 dBFs
ff is reserved
Audio meters ordering for Spark:
0: Dante Out 1 (PGM)
1: Dante Out 2 (Lazy Mic)
2: Dante Out 3 (HP L)
3: Dante Out 4 (HP R)
4: Dante Out 5 (TB1)
5: Dante Out 6 (TB2)
6: Dante Out 7 (TB3)
7: Dante Out 8 (1kHz)
8: Dante In 1 (Cue1)
9: Dante In 2 (Cue2)
10: Dante In 3 (Cue3)
11: Dante In 4 (Cue4)
12: Dante In 5 (Aux1)
13: Dante In 6 (Aux2)
14: Dante In 7 (Bkg L)
15: Dante In 8 (Bkg R)
16: Mic input
17..19 reserved
Temperature is expressed as signed 8-bit value. To convert it to Celsius use the following formula:
T = 0.5 * Temperature + 44
If the device is in Connected state it sends a report whenever its internal state has changed, or as a response to an explicit Query message. The internal state may change as a result of a user manually operating the units UI, a command received from a controller, or an independent event.
Reports are sent using one or more packets of type Report. If the message size is greater than the packet size the Multipacket bit is set in the GS header and the message has to be re-assembled from multiple packets (Spark only sends single-packet messages). A Report message may contain one or more reports. Each report is prefixed with a Block Header indicating its type and size.
The example below shows the full report, consisting of a Device, Input Channel Names, Output Channel names and Spark-specific reports (type 4 and 5). In practice, the device can send any of these reports in any combination, so the host controller must parse the message and extract the reports from it.
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 ac 00 0a 00 80 02 00 2c GS Ctrl.........
0010 01 01 04 00 80 bb 00 00 00 00 00 00 00 00 00 00 ................
0020 01 00 00 00 02 02 0c 00 05 43 75 65 20 31 05 43 .........Cue 1.C
0030 75 65 20 32 05 43 75 65 20 33 05 43 75 65 20 34 ue 2.Cue 3.Cue 4
0040 05 41 75 78 20 31 05 41 75 78 20 32 05 42 6b 67 .Aux 1.Aux 2.Bkg
0050 20 4c 05 42 6b 67 20 52 03 01 0b 00 03 50 67 6d L.Bkg R.....Pgm
0060 08 4c 61 7a 79 20 4d 69 63 04 48 70 20 4c 04 48 .Lazy Mic.Hp L.H
0070 70 20 52 04 54 62 20 31 04 54 62 20 32 04 54 62 p R.Tb 1.Tb 2.Tb
0080 20 33 05 31 20 6b 48 7a 04 00 06 00 00 00 00 00 3.1 kHz........
0090 75 00 23 00 3c 00 00 00 5a 00 40 00 28 00 16 00 u.#.<...Z.@.(...
00a0 0e 00 00 00 05 32 01 00 2d 08 00 00 .....2..-...
------------------------------------------------------
GS Header:
0000 47 53 20 43 74 72 6c 00 ac 00 0a 00 80 02 00 2c
Magic: 4753204374726c00
Size: 172 (Payload 156 bytes)
.000 0000 1010 1100 = Packet size: 172
0... .... .... .... = Multipacket: False
Opcode: 10 (Report)
Flags: 0x00
Sequence: 128
Device ID: 02002c
Block Header:
0010 01 Type
01 Generation
04 00 Length in words
Type: 1 (Device)
Generation: 1
Length in words: 4 (16 bytes)
Device Report:
0010 80 bb 00 00 Sample rate in Hz
00 Srate choice (N.A. for Spark)
00 Clock source (N.A. for Spark)
00 Clock source choice (N.A. for Spark)
00 ADC filter code
00 DAC filter code
00 00 00 reserved
0020 01 00 00 00 Flags
Sample rate: 48000
Sample rate choice: 0 (Unknown)
Clock source: 0 (Dante)
Clock source choice: 0 (Dante)
ADC filter: 0 (Normal)
DAC filter: 0 (Normal)
Flags: 0x00000001
.... .... .... .... .... .... .... ...1 = Link 1: True
.... .... .... .... .... .... .... ..0. = Link 2: False
.... .... .... .... .... .... .... .0.. = PSU 1: False
.... .... .... .... .... .... .... 0... = PSU 2: False
.... .... .... .... .... .... ...0 .... = POE 1: False
.... .... .... .... .... .... ..0. .... = POE 2: False
ADC filter codes:
0: Normal
1: Slow roll-off
DAC filter codes:
0: Normal
1: Slow roll-off
2: Short delay
Block Header:
0020 02 Type
02 Generation
0c 00 Length in words
Type: 2 (In Channel Names)
Generation: 2
Length in words: 12 (48 bytes)
In Channel Names Report:
0020 05 43 75 65 20 31 05 43 Cue 1.C
0030 75 65 20 32 05 43 75 65 20 33 05 43 75 65 20 34 ue 2.Cue 3.Cue 4
0040 05 41 75 78 20 31 05 41 75 78 20 32 05 42 6b 67 .Aux 1.Aux 2.Bkg
0050 20 4c 05 42 6b 67 20 52 L.Bkg R
Block Header:
0050 03 Type
01 Generation
0b 00 Length in words
Type: 3 (Out Channel Names)
Generation: 1
Length in words: 11 (44 bytes)
Out Channel Names Report:
0050 03 50 67 6d .Pgm
0060 08 4c 61 7a 79 20 4d 69 63 04 48 70 20 4c 04 48 .Lazy Mic.Hp L.H
0070 70 20 52 04 54 62 20 31 04 54 62 20 32 04 54 62 p R.Tb 1.Tb 2.Tb
0080 20 33 05 31 20 6b 48 7a 3.1 kHz
Block Header:
0080 04 Type
00 Generation
06 00 Length in words
Type: 4 (Spark 4)
Generation: 0
Length in words: 6 (24 bytes)
Spark UI State Report:
0080 00 00 Button modes
00 00 Pot modes
0090 75 00 23 00 3c 00 00 00 5a 00 40 00 28 00 16 00 Volumes/Pans
00a0 0e PGM mute enables
00 00 00 reserved
Button modes: 0x0000
.... .... .... 0000 = PGM buttton mode: 0x0 (Intelligent)
.... .... 0000 .... = TB1 buttton mode: 0x0 (Intelligent)
.... 0000 .... .... = TB2 buttton mode: 0x0 (Intelligent)
0000 .... .... .... = TB3 buttton mode: 0x0 (Intelligent)
Pot modes: 0x0000
.... .... .... ..00 = Cue1 pot mode: 0x0 (Unlimited)
.... .... .... 00.. = Cue2 pot mode: 0x0 (Unlimited)
.... .... ..00 .... = Cue3 pot mode: 0x0 (Unlimited)
.... .... 00.. .... = Cue4 pot mode: 0x0 (Unlimited)
.... ..00 .... .... = HP pot mode: 0x0 (Unlimited)
.... 00.. .... .... = Sidetone pot mode: 0x0 (Unlimited)
..00 .... .... .... = Aux pot mode: 0x0 (Unlimited)
00.. .... .... .... = Bkg pot mode: 0x0 (Unlimited)
Volumes/Pans: 750023003c0000005a00400028001600
Cue1 vol/pan: 0x0075 (Vol=117, Pan=0)
Cue2 vol/pan: 0x0023 (Vol=35, Pan=0)
Cue3 vol/pan: 0x003c (Vol=60, Pan=0)
Cue4 vol/pan: 0x0000 (Vol=0, Pan=0)
HP vol/pan: 0x005a (Vol=90, Pan=0)
Sidetone vol/pan: 0x0040 (Vol=64, Pan=0)
Aux vol/pan: 0x0028 (Vol=40, Pan=0)
Bkg vol/pan: 0x0016 (Vol=22, Pan=0)
PGM mute enables: 0x0e
.... ..1. = TB1 mutes PGM: True
.... .1.. = TB2 mutes PGM: True
.... 1... = TB3 mutes PGM: True
Block Header:
00a0 05 Type
32 Generation
01 00 Length in words
Type: 5 (Spark 5)
Generation: 50
Length in words: 1 (4 bytes)
Spark Mic Input Report:
00a0 2d Gain
08 Flags
00 00 reserved
Gain: 45
Flags: 0x08
.... ...0 = Compressor: False
.... ..0. = Phantom: False
.... .0.. = Gain lock: False
.... 1... = Phantom lock: True
Commands are contained in messages with opcode 3 (SetControl). A SetControl message may include one or more commands. The message header indicates the desired connection type and status update frequency.
The structure of a SetControl message is:
GS Header
Command
Command
... (up to the packet capacity)
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 05 39 00 00 .9..
------------------------------------------------------
GS Header:
Magic: 4753204374726c00
Size: 20 (Payload 4 bytes)
.000 0000 0001 0100 = Packet size: 20
0... .... .... .... = Multipacket: False
Opcode: 3 (SetControl)
Flags: 0x01
.... ...1 = Exclusive: True
.... ..0. = No meter: False
Controller ID: 0x03890990
Command:
0010 05 Opcode
39 Volume
00 00 reserved
Opcode: 5
Gain: 57 0 to 63
Gain values (1 dB step):
0: -8 dB
...
63: +55 dB
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 06 01 00 00 ....
------------------------------------------------------
Command:
0010 06 Opcode
01 Enable
00 00 reserved
Opcode: 6
Enable: 1 0 or 1
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 07 01 00 00 ....
------------------------------------------------------
Command:
0010 07 Opcode
01 Enable
00 00 reserved
Opcode: 7
Enable: 1 0 or 1
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 08 4f 05 00 .O..
------------------------------------------------------
Command:
0010 08 Opcode
4f Volume
05 Channel ID
00 reserved
Opcode: 8
Volume: 79 0 to 127
Channel: 5 (Sidetone)
Volume value (0.5 dB step):
0: Mute
...
103: -0.5 dB
104: 0 dB
105: +0.5 dB
...
127: +11.5 dB
Channel IDs:
0: Cue1
1: Cue2
2: Cue3
3: Cue4
4: HP
5: Sidetone
6: Aux
7: Bkg
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 09 ff 05 00 ....
------------------------------------------------------
Command:
0010 09 Opcode
ff Volume
05 Channel ID
00 reserved
Opcode: 9
Pan: -1 -7 to 7
Channel: 5 (Sidetone) 0 to 7
Pan values (step of 1):
-7: hard left
...
0: centre
...
+7: hard right
Channel IDs:
0: Cue1
1: Cue2
2: Cue3
3: Cue4
4: HP
5: Sidetone
6: Aux
7: Bkg
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 0a 01 00 00 ....
------------------------------------------------------
Command:
0010 0a Opcode
01 State
00 Button ID
00 reserved
Opcode: 10
State: 1 (On) 0 or 1
Button: 0 (PGM) 0 to 3
Button IDs:
0: PGM
1: TB1
2: TB2
3: TB3
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 0b 01 01 00 ....
------------------------------------------------------
Command:
0010 0b Opcode
01 Button ID
01 Mode
00 reserved
Opcode: 11
Button: 1 (TB1) 0 to 3
Mode: 1 (Momentary) 0 to 5
Button IDs:
0: PGM
1: TB1
2: TB2
3: TB3
Button modes:
0: Intelligent
1: Momentary
2: Toggling
3: Cough
4: Always On
5: Always Off
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 0c 01 00 00 ....
------------------------------------------------------
Command:
0010 0c Opcode
01 Button ID
00 Enable
00 reserved
Opcode: 12
Button: 1 (TB1) 1 to 3
Enable: 0 0 or 1
Button IDs:
1: TB1
2: TB2
3: TB3
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 0d 05 01 00 ....
------------------------------------------------------
Command:
0010 0d Opcode
05 Channel ID
01 Enable
00 reserved
Opcode: 13
Channel: 5 (Sidetone) 0 to 7
Mode: 1 (Limited) 0 or 1
Channel IDs:
0: Cue1
1: Cue2
2: Cue3
3: Cue4
4: HP
5: Sidetone
6: Aux
7: Bkg
Pot modes:
0: Unlimited
1: Limited
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 0e 01 00 00 ....
------------------------------------------------------
Command:
0010 0e Opcode
0e Enable
00 00 reserved
Opcode: 14
Enable: 1 0 or 1
------------------------------------------------------
0000 47 53 20 43 74 72 6c 00 14 00 03 01 90 09 89 03 GS Ctrl.........
0010 0f 00 00 00 ....
------------------------------------------------------
Command:
0010 0f Opcode
00 Enable
00 00 reserved
Opcode: 15
Enable: 0 0 or 1
Updated: 16/Jun/2023