The sACN Merge Receiver API combines the functionality of the sACN Receiver and DMX Merger APIs. It provides the application with merged DMX levels, plus data with other start codes from each source, as sACN packets are received. This API exposes both a C and C++ language interface. The C++ interface is a header-only wrapper around the C interface.
An sACN merge receiver instance can listen on one universe at a time, but the universe it listens on can be changed at any time. A merge receiver begins listening when it is created. To create an sACN merge receiver instance, use the sacn_merge_receiver_create() function in C, or instantiate an sacn::MergeReceiver and call its Startup() function in C++. A merge receiver can later be destroyed by calling sacn_merge_receiver_destroy() in C or Shutdown() in C++.
The sACN Merge Receiver API is an asynchronous, callback-oriented API. Part of the initial configuration for a merge 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::MergeReceiver::NotifyHandler. Callbacks are dispatched from a background thread which is started when the first merge receiver instance is created.
A merge 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 merge 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 merge 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.
Change the universe and footprint this merge receiver is listening to. TODO: Not yet implemented.
Definition merge_receiver.h:468
Merging
Once a merge receiver has been created, it will begin listening for data on the configured universe and footprint. When DMX level or priority data arrives, or a source is lost, it performs a merge. This is where it determines the correct DMX level and source for each slot of the footprint, since there may be multiple sources transmitting on the same universe. It does this by selecting the source with the highest priority. If there are multiple sources at that priority, then it selects the source with the highest level. That is the Highest Takes Precedence (HTP) merge algorithm.
Receiving sACN Data
The merged data callback is called whenever there are new merge results, pending the sampling period. The sampling period occurs when a receiver starts listening on a new universe, new footprint, or new set of interfaces. Universe data is merged as it comes in during this period, but the notification of this data doesn't occur until after the sampling period ends. This removes flicker as various sources in the network are discovered.
This callback will be called in multiple ways:
When a new non-preview data packet or per-address priority packet is received from the sACN Receiver module, it is immediately and synchronously passed to the DMX Merger. If the sampling period has not ended, the merged result is not passed to this callback until the sampling period ends. Otherwise, it is immediately and synchronously passed to this callback.
When a sACN source is no longer sending non-preview data or per-address priority packets, the lost source callback from the sACN Receiver module will be passed to the merger, after which the merged result is passed to this callback pending the sampling period.
Please note that per-address priority is an ETC-specific sACN extension, and is disabled if the library is compiled with SACN_ETC_PRIORITY_EXTENSION set to 0 (in which case per-address priority packets received have no effect).
The merger will prioritize sources with the highest per-address priority (or universe priority if the source doesn't provide per-address priorities). If two sources have the same highest priority, the one with the highest NULL start code level wins (HTP).
There is a key distinction in how the merger interprets the lowest priority. The lowest universe priority is 0, but the lowest per-address priority is 1. This is because a per-address priority of 0 indicates that the source is not sending any levels to the corresponding slot. The solution the merger uses is to always track priorities per-address. If a source only has a universe priority, that priority is used for each slot, except if it equals 0 - in that case, it is converted to 1. This means the merger will treat a universe priority of 0 as equivalent to a universe priority of 1, as well as per-address priorities equal to 1.
Also keep in mind that if less than 512 per-address priorities are received, then the remaining slots will be treated as if they had a per-address priority of 0. Likewise, if less than 512 levels are received, the remaining slots will be treated as if they had a level of 0, but they may still have non-zero priorities.
This callback should be processed quickly, since it will interfere with the receipt and processing of other sACN packets on the universe.
The data callbacks include data originating from one or more sources transmitting on the current universe. Each source has a handle that serves as a primary key, differentiating it from other sources. The merge receiver provides information about each source, including the name, IP, and CID. This information is provided directly in the non-DMX callback. However, in the merged data callback, only the source handles are passed in. To obtain more details about a source, use the get source function.
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.
If sACN was compiled with SACN_DYNAMIC_MEM set to 1 (the default on non-embedded platforms), the library will check against the source_count_max value from the merge receiver config/settings, instead of SACN_RECEIVER_MAX_SOURCES_PER_UNIVERSE. The source_count_max value may be set to SACN_RECEIVER_INFINITE_SOURCES, in which case 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 (in this case it can be set to NULL in the config struct in C).