Technical Reference:SignalSharingClient Library
The SignalSharingClient library provides a SignalSharing client, wrapped into a C interface. It may be used to tap into signal and state data at any point of processing from external applications. The SignalSharingClient library can be used from any programming language that allows using a shared library (DLL). Although the SignalSharingClient library is written in C++, its DLL interface is plain C, and can be used with compiled languages such as C, C++, C#, Pascal, but also with interpreted languages that can call functions in a DLL, such as Python, Matlab, VisualBasic, etc. Interfacing with Java requires a JNI (Java Native Interface) wrapper, which is currently not provided by BCI2000.
Functions provided by the Library
SSC_RESULT SSC_CreateConnector(const char* listeningAddress, SSC_HANDLE*)
Create a connector object, and obtain a handle to it. A connector object is necessary to handle a connection to BCI2000, and is specified as the first argument of the remaining SignalSharingClient library functions. The listening address is in the format <IP>:<port> with <IP> being a name or numeric address. SSC_CreateConnector() will immediately start an internal server thread, and listen at the given port. Only one client can connect to the server at a time (note that BCI2000 acts as a client).
SSC_CreateConnector() guarantees that the handle it returns will be either a valid handle, or nullptr (if an error occurs). This implies that SSC_DeleteConnector() may be called unconditionally on a handle returned by SSC_CreateConnector().
SSC_RESULT SSC_DeleteConnector(SSC_HANDLE)
Stop listening, terminate the internal server thread, and delete the given connector object. Must be called when connector object is no longer used.
Providing a nullptr handle to SSC_DeleteConnector() will result in an SSC_INVALID_ARG error but will otherwise cause no harm.
SSC_RESULT SSC_RegisterSignalCallback(SSC_HANDLE, SSC_CALLBACK, void* refdata)
Register a callback to be called whenever new signal data is available. For each connector object, it is only possible to register one signal callback at a time. To unregister a signal callback, call SSC_RegisterSignalCallback() with a nullptr argument. Use the <refdata> argument to specify auxiliary data which will be provided to the callback function when it is called.
SSC_RESULT SSC_RegisterStatesCallback(SSC_HANDLE, SSC_CALLBACK, void* refdata)
Register a callback to be called whenever new state data is available. For each connector object, it is only possible to register one states callback at a time. To unregister a signal callback, call SSC_RegisterStatesCallback() with a nullptr argument. Use the <refdata> argument to specify auxiliary data which will be provided to the callback function when it is called.
SSC_RESULT SSC_RegisterParametersCallback(SSC_HANDLE, SSC_CALLBACK, void* refdata)
Register a callback to be called whenever new parameter data is available. For each connector object, it is only possible to register one parameters callback at a time. To unregister a signal callback, call SSC_RegisterParametersCallback() with a nullptr argument. Use the <refdata> argument to specify auxiliary data which will be provided to the callback function when it is called.
SSC_RESULT SSC_LockSignal(SSC_HANDLE, const double** pSignal, int* channels, int* samples, const char* const** channelNames)
Lock signal data and obtain signal information. Typically, this function will be called from a signal callback. Locking blocks the arrival of new signal data, so call SCC_ReleaseSignal() as soon as possible. All pointer arguments are optional, may be nullptr.
The pSignal argument receives a pointer to an array in channel-major order, i.e. to compute a linear index into that array from both channel and sample index, use
idx = channel * samples + sample
SSC_RESULT SSC_ReleaseSignal(SSC_HANDLE)
Releases a locked signal. Call this function as soon as you are done with forwarding or processing signal data.
SSC_RESULT SSC_LockStates(SSC_HANDLE, const double** pStateData, int* count, int* samples, const char* const** pStateNames)
Lock state data and obtain state information. Typically, this function will be called from a state callback. Locking blocks the arrival of new state data, so call SCC_ReleaseStates() as soon as possible. All pointer arguments are optional, may be nullptr.
The pStateData argument receives a pointer to an array in channel-major format, i.e. use the following formula to compute a linear index from state and sample index:
idx = state * samples + sample
SSC_RESULT SSC_ReleaseStates(SSC_HANDLE)
Releases locked state information. Call this function as soon as you are done with forwarding or processing state data.
SSC_RESULT SSC_LockParameters(SSC_HANDLE, const char* const** parameterLines, int* count)
Lock parameter data and obtain parameter information. Typically, this function will be called from a parameter callback. Locking blocks the arrival of new parameter data, so call SCC_ReleaseParameters) as soon as possible. All pointer arguments are optional, may be nullptr.
SSC_RESULT SSC_ReleaseParameters(SSC_HANDLE)
Releases locked parameter information. Call this function as soon as you are done with forwarding or processing parameter data.
SSC_RESULT SSC_GetSignalDimensions(SSC_HANDLE, int* channels, int* samples)
Obtain signal dimensions for use with SSC_PushSignal().
SSC_RESULT SSC_PushSignal(SSC_HANDLE, const double* pSignal)
Push signal data to BCI2000. The pSignal pointer must point to a valid memory area that is at least as large as determined by a previous call to SSC_GetSignalDimensions. Pushing signal data will have no effect unless SSC_Commit() is called.
SSC_RESULT SSC_PushState(SSC_HANDLE, const char* name, unsigned int value)
Push a state value to BCI2000. Pushing a state value will have no effect unless SSC_Commit() is called.
SSC_RESULT SSC_Commit(SSC_HANDLE)
Commit pushed signal and state data to the BCI2000 pipeline. Any previously pushed signal or state data will be inserted into the BCI2000 pipeline when this function is called.
Callback Function Type
To be registered using SSC_Register*Callback(), a function must be a free (non-member) or static function, and have the following signature:
void MyCallback(void* refdata)
The refdata argument will hold the struct or object pointer specified as refdata when calling SSC_Register*Callback().
Error Codes
All of the above functions return an error code of type SSC_ERROR. The following codes are defined:
| SSC_SUCCESS | The operation completed successfully. |
| SSC_INVALID_ARG | One or more of the function's arguments were invalid. |
| SSC_CANNOT_LISTEN | The connector was created but could not bind to/listen on the given address. |
| SSC_CANNOT_FULFILL_REQUEST | The connector is in a state in which it cannot fulfill the request, try again later. |
See also
Programming Reference:SignalSharingClientLibDemo, Technical Reference:BCI2000Remote Library, Programming Reference:BCI2000Remote Class, Contributions:BCI2000Command, Contributions:BCI2000PresentationLink, Contributions:Applications