User Reference:SignalSharing
Synopsis
SignalSharing allows to tap into BCI2000 processing by receiving any filter output signal through a combination of a TCP connection, and shared memory.
Function
The SignalSharing component in BCI2000 shares its input signal through a GenericSignal object which has been linked to a shared memory block using GenericSignal::ShareAcrossModules(). A dedicated thread waits for signal updates, and sends signal data out to a separate application waiting on a TCP/IP connection.
When the client application is running on a separate machine, full signal data are sent over the network. When the client is running on the same machine, only a reference to a shared memory block is sent. On the client side, a flag in the signal data block indicates whether full signal data is transmitted, or just the name of a shared memory block to which the client may connect in order to read data.
To facilitate consistency with the BCI2000 model of operation, SignalSharing is operating as a TCP client rather than a server. When BCI2000 goes into Initialization state, the client tries to connect to a TCP server that will receive the data. This will appear confusing at first because the client application needs to act as a server, but it is more flexible as the BCI2000 SignalSharing component may open and close connections, and send data, as it fits the current BCI2000 state of operation.
Data Transmission
Immediately after opening the connection, SignalSharing sends a number of Parameter messages to share the parameters that are present in the system. The client may choose to ignore them, or use them for its own purposes.
Following parameter messages, SignalSharing sends a SignalProperties message to announce meta-information about the filter's output signal, such as channel names, physical units, etc.
If configured to send state information, SignalSharing will send another SignalProperties message conveying meta-information about a signal that accommodates state information.
Subsequently, signal data are sent whenever a signal leaves the filter for which SignalSharing is enabled. Signal data contains a flag that indicates whether full signal data is sent, or just the name of a shared memory block. For local connections (i.e., connections to a local address of the machine BCI2000 is running on), the name of a shared memory block is sent, so you may attach to that block and read data from there. Between two subsequent times the user presses "Set Config" in the Operator interface, the shared memory block will remain the same, i.e. the signal data message will always contain the same shared memory name. Still, the message is necessary to indicate that a new data block is available.
If configured to so, SignalSharing will follow each brain signal data message with another signal message which holds state information. The state information message is a signal data message in which individual states correspond to channels, and state samples correspond to elements. Depending on position in the signal processing chain, the number of state samples may differ from the number of signal samples/elements because the number of state samples will always be identical to brain signal source block size, whereas the number of signal samples/elements depends on the position in the chain.
Configuration
Similar to visualizations, the system creates two parameters for each active filter, and places those under the SignalSharing tab in the Operator's config dialog (or multiple SignalSharing tabs in more complex signal processing configurations).
By default, these parameters are empty strings; to activate SignalSharing for a certain filter, set the parameter Share<FilterName> to an ip address and port to connect to, e.g.
localhost:1879
To activate state sharing in addition to signal sharing, set the parameter Share<FilterName>States to a list of state names. In the transmitted signal that holds state information, channels will correspond to states in the order specified in the Share<FilterName>States parameter.
Client Examples
- An example for a SignalSharing client application in C++: SignalSharingDemoClient C++ App
- An example for a SignalSharing client application in Python: SignalSharing Python Demo
See also
Technical Reference:BCI2000 Messages, User Tutorial:BCI2000Remote, Programming Reference:GenericSignal Class, Programming Reference:SignalSharingDemoClient C++ App, SignalSharing Python Demo