sACN
2.0.2
Implementation of ANSI E1.31 (Streaming ACN)
|
View other versions:
|
The sACN Receiver API provides a method for applications to receive and process sACN data on one or more universes. This API exposes both a C and C++ language interface. The C++ interface is a header-only wrapper around the C interface.
The sACN library must be globally initialized before using the Receiver API. See Global Initialization and Destruction.
An sACN receiver instance can listen on one universe at a time, but the universe it listens on can be changed at any time. A receiver begins listening when it is created. To create an sACN receiver instance, use the sacn_receiver_create()
function in C, or instantiate an sacn::Receiver and call its Startup()
function in C++. A receiver can later be destroyed by calling sacn_receiver_destroy()
in C or Shutdown()
in C++.
The sACN Receiver API is an asynchronous, callback-oriented API. Part of the initial configuration for a receiver instance is to specify the callbacks for the library to use. In C, these are specified as a set of function pointers. In C++, these are specified as an instance of a class that implements sacn::Receiver::NotifyHandler. Callbacks are dispatched from a background thread which is started when the first receiver instance is created.
A receiver can listen to one universe at a time. The initial universe being listened to is specified in the config passed into create/Startup. There are functions that allow you to get the current universe being listened to, or to change the universe to listen to.
TODO: Custom footprints are not yet implemented, so the footprint will always be the full universe.
A receiver can also be configured to listen to a specific range of slots within the universe, which is called the footprint. For example, networked fixtures might use this to only retrieve data about slots within their DMX footprint. The footprint is initially specified in the receiver config, but it is optional, so it defaults to the full universe if it isn't specified in the config. There are also functions to get and change the footprint, including a function that can change both the universe and footprint at once.
The universe data callback forwards incoming DMX data to the application. See the callback's documentation for more information about when it is called and when it isn't.
There may be multiple sources transmitting data on a universe. The sampling period is used in order to remove flicker as sources are discoverd. There are notifications for when the sampling period begins, as well as when it ends, for each universe. The Universe Data callback also provides is_sampling (in universe_data) to indicate if the data was received during the sampling period. These notifications allow the application to know when to act on the universe data with assurance that all of the current sources are represented.
The sampling period occurs when a new receiver is created, as well as when the universe and/or footprint are changed.
Here is an example of the Sampling Period Ended callback:
The sACN library tracks each source that is sending DMX data on a universe. In sACN, multiple sources can send data simultaneously on the same universe. There are many ways to resolve conflicting data from different sources and determine the winner; some tools for this are given by the library and others can be implemented by the consuming application.
Each source has a Component Identifier (CID), which is a UUID that is unique to that source. Each source also has a handle that should be used as a primary key, differentiating it from other sources. Sources also have a descriptive name that can be user-assigned and is not required to be unique. This source data is provided in the SacnRemoteSource struct in the universe data callback, as well as in the SacnLostSource struct in the sources lost callback.
The sACN standard provides a universe priority value with each sACN data packet. This unsigned 8-bit value ranges from 0 to 200, where 0 is the lowest and 200 is the highest priority. The priority value for a packet is available in the universe_data parameter of the universe data callback. It is the application's responsibility to ensure that higher-priority data takes precedence over lower-priority data.
ETC has extended the sACN standard with a method of tracking priority on a per-address basis. This is implemented by sending an alternate START code packet on the same universe periodically - the START code is 0xdd
. When receiving a data packet with the start code 0xdd
, the values in that packet are to be interpreted as a priority value from 1 to 200 for the corresponding level in the DMX (NULL START code) packets. A value of 0 indicates "not sourced", meaning the source is not sending NULL START code data to that slot. Likewise, if less than 512 0xdd
values are received, then the values beyond the last 0xdd
slot should also be treated as not sourced. Receivers which wish to implement the per-address priority extension should make sure that SACN_ETC_PRIORITY_EXTENSION is set to 1, check for the 0xdd
start code, and handle the data accordingly.
When implementing the per-address priority extension, the source PAP lost callback should be implemented to handle the condition where a source that was previously sending 0xdd
packets stops sending them:
If the library is compiled with SACN_ETC_PRIORITY_EXTENSION set to 0, then 0xdd
packets will not be received, and the source PAP lost callback will not be called.
When multiple sources are sending on the same universe at the same priority, receiver implementations are responsible for designating a merge algorithm to merge the data from the sources together. The most commonly-used algorithm is Highest Takes Precedence (HTP), where the numerically highest level for each slot from any source is the one that is acted upon.
The sACN library provides a couple of APIs to facilitate merging. The first, the DMX merger API, provides a software merger that takes NULL start code and priority data as input and outputs the merged levels, along with source IDs and PAP for each level. For more information, see Using the sACN DMX Merger API. The second, the merge receiver API, combines the receiver and DMX merger APIs to offer a simplified solution for receiver functionality with merging built in. See Using the sACN Merge Receiver API for more information.
When a previously-tracked source stops sending data, the sACN library implements a custom source-loss algorithm to attempt to group lost sources together. See Source Loss Behavior for more information on this algorithm.
After the source-loss algorithm runs, the library will deliver a sources lost callback to indicate that some number of sources have gone offline.
If a source that was lost comes back again, then there will once again be universe data notifications for that source.
The sACN library will only forward data from sources that it is able to track. When the library is compilied with SACN_DYNAMIC_MEM set to 0, this means that it will only track up to SACN_RECEIVER_MAX_SOURCES_PER_UNIVERSE sources at a time. (You can change these compile options in your sacn_config.h; see Building and Integrating the sACN Library Into Your Project.)
When the library encounters a source that it does not have room to track, it will send a single source limit exceeded notification. Additional source limit exceeded callbacks will not be delivered until the number of tracked sources falls below the limit and then exceeds it again.
The library will also check against the source_count_max
value from the receiver config/settings, limiting it to SACN_RECEIVER_MAX_SOURCES_PER_UNIVERSE if SACN_DYNAMIC_MEM is 0. The source_count_max
value may be set to SACN_RECEIVER_INFINITE_SOURCES, which is the default. In this case, if SACN_DYNAMIC_MEM is 0, SACN_RECEIVER_MAX_SOURCES_PER_UNIVERSE will be the limit. Otherwise, if SACN_DYNAMIC_MEM is 1, the library will track as many sources as it is able to dynamically allocate memory for, and this callback will not be called in normal program operation (and can be set to NULL in the config struct in C).