Technical Reference:Operator Library
The Operator Library is a shared library that encapsulates the Operator Module's core functionality into an interface that allows to embed Operator functionality into one's own application. This way, is is possible to write your own Operator module, or to control BCI2000 from your own application, without having to deal with details of the BCI2000 protocol. The BCI2000 Operator library can be used from any programming language that allows using a shared library (DLL). Although the Operator 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.
For a C++ example that uses the Operator Library to implement a simple Operator Module, see the OperatorLibDemo program.
System State (State of Operation)
BCI2000 system state may be queried using BCI_GetStateOfOperation(), and modified using the BCI_SetConfig(), BCI_StartRun(), and BCI_StopRun() functions. These functions manipulate system state in a way that is analogous to the main buttons in the standard Operator module.
System state is one of the following:
The system is not available for changes to system state.
BCI_StateIdle
The system is initialized, but not started up, ie., not waiting for connections.
BCI_StateStartup
The Operator module is waiting for core modules to connect.
BCI_StateInitialization
Core modules are connected, the system is waiting to be parameterized via SetConfig().
BCI_StateResting
The system has been parameterized and is waiting for a StartRun() command.
BCI_StateSuspended
The system has been suspended via StopRun(), or from one of the modules setting the "Running" state variable to 0.
BCI_StateParamsModified
The system has been suspended, and parameters have been modified from one or more of the core modules.
BCI_StateRunning
The system is running.
BCI_StateTermination
The system is waiting for termination.
BCI_StateBusy
The system is currently busy, and not in one of the above states. It is not available for changes to system state.
System state may be manipulated calling one of the following functions:
int BCI_GetStateOfOperation()
Determines the externally visible state of the state machine, i.e. the state of operation of the BCI2000 system.
int BCI_SetConfig()
Asynchronously applies current parameter settings to the BCI2000 system, i.e. initiates the parameterization process, and returns immediately, indicating whether parameterization has been initiated.
- returns
- 1 if successful, 0 otherwise.
int BCI_StartRun()
Asynchronously starts a new run.
- returns
- 1 if successful, 0 otherwise.
int BCI_StopRun()
Asynchronously stops the current run.
- returns
- 1 if successful, 0 otherwise.
Parameterization
Parameterization functions allow to populate and modify of the Operator Library's internal parameter list, state list, event list, and visproperty list. When calling SetConfig(), parameter values are applied to the BCI2000 system.
int BCI_PutParameter( const char* parameterLine )
Parses a BCI2000 parameter definition line, and adds the resulting parameter object to the internal parameter list, or changes the value of a parameter if it exists.
- arguments
- Pointer to a null-terminated parameter line string.
- returns
- 1 if successful, 0 otherwise.
const char* BCI_GetParameter( long index )
Returns the parameter with the given index from the operator's internal parameter list, or NULL when the index is out of range.
- arguments
- Parameter index.
- returns
- Pointer to a null-terminated string containing a parameter line, or NULL. The output buffer is allocated by the library, and should be released by the caller using BCI_ReleaseObject().
int BCI_PutState( const char* stateLine )
Parses a BCI2000 state definition line, and adds the resulting state to the operator library's state list.
- arguments
- Pointer to a null-terminated state line string.
- returns
- 1 if successful, 0 otherwise.
const char* BCI_GetState( long index )
Returns the state with the given index from the DLL's internal state list. , or NULL when the index is out of range.
- arguments
- State index.
- returns
- Pointer to a null-terminated string containing a state line, or NULL. The output buffer is allocated by the library, and should be released by the caller using BCI_ReleaseObject().
int BCI_PutEvent( const char* eventLine )
Parses a BCI2000 event definition line, and adds the resulting event to the operator library's event list.
- arguments
- Pointer to a null-terminated event line string.
- returns
- 1 if successful, 0 otherwise.
const char* BCI_GetEvent( long index )
Returns the event with the given index from the DLL's internal event list. , or NULL when the index is out of range.
- arguments
- Event index.
- returns
- Pointer to a null-terminated string containing an event line, or NULL. The output buffer is allocated by the library, and should be released by the caller using BCI_ReleaseObject().
int BCI_PutVisProperty( const char* visID, int cfgID, const char* value )
Sets the a property to the given value, or adds the property to the property list if it is not present. A list of visualization properties is available at Technical Reference:Visualization Properties.
- arguments
- Pointer to a null-terminated vis ID string, numeric config ID, and a pointer to a null-terminated value string.
- returns
- 1 if successful, 0 otherwise.
const char* BCI_GetVisProperty( const char* visID, int cfgID )
Returns the property with the given cfgID from the DLL's internal property list. A list of visualization properties is available at Technical Reference:Visualization Properties.
- arguments
- Pointer to a null-terminated vis ID string, numeric config ID.
- returns
- Pointer to a null-terminated string containing a property line, or NULL. The output buffer is allocated by the library, and should be released by the caller using BCI_ReleaseObject().
Online Information
These functions allow to access information processed when the system is running. Modifying states and setting events will affect what is recorded in the data file.
int BCI_SetStateValue( const char* stateName, long value )
Sets the value of a state to a given value. Setting a state via BCI_SetStateValue() may result in a change to BCI2000 system state.
- arguments
- Pointer to a null-terminated state name string; new state value.
- returns
- 1 if successful, 0 otherwise.
long BCI_GetStateValue( const char* stateName )
Returns the value of a state. NOTE: During operation, state values will only be updated when sent by the last module in the chain of core modules. This is governed by the OperatorBackLink parameter on the System tab, which must be set to 1.
- arguments
- Pointer to a null-terminated state name string.
- returns
- State value, or 0 if the state does not exist.
int BCI_SetEvent( const char* eventName, long value )
Asynchronously sets the value of an event. In the data file, the point in time where SetEvent() was called will be associated with a single sample.
- arguments
- Pointer to a null-terminated event name string; new event value.
- returns
- 1 if successful, 0 otherwise.
int BCI_GetSignalChannels()
Returns the number of channels in the control signal.
int BCI_GetSignalElements()
Returns the number of elements in the control signal.
float BCI_GetSignal( int channel, int element )
Returns a value from the control signal. NOTE: During operation, control signal values will only be updated when sent by the last module in the chain of core modules. This is governed by the OperatorBackLink parameter on the System tab, which must be set to 1.
- arguments
- Channel index, element index (zero-based).
- returns
- Signal value.
Watches
Watches are expressions that are tied to callback events (see below). Whenever the expression's value changes, the associated callback event is triggered. Use BCI_AddWatch to create a watch a receive a unique callback event ID, followed with BCI_SetCallback() or BCI_SetExternalCallback() to register a callback function with the watch's event. Whenever the watch is triggered, your callback function will be called with the expression's current value in string format.
long BCI_AddWatch( const char* expressions )
Create a watch consisting of one or more expressions. An event is triggered whenever one of the expressions changes its value. Expressions are evaluated as described for the EVALUATE EXPRESSION scripting command. You may associate a callback with the created watch by specifying its watch ID as an event ID to any of the callback registration functions. To the callback function, an additional argument of type const char* will be provided, which contains a string representation of all current expression values, separated by tab characters, and terminated with a Windows newline sequence (CRLF). The argument is a string containing a list of expressions, separated by tab characters. The function returns a watch ID if successful, BCI_None otherwise. The function will fail if the list of expressions contains an invalid expression.
int BCI_SetWatchDecimation( long watchID, int decimation )
Set decimation for a watch. By default, decimation is 1, and expressions will be evaluated for each sample in a data block. For higher values of decimation, every n-th sample will be evaluated. The function returns 1 if successful, 0 if no watch was registered with the given ID.
int BCI_RemoveWatch( long watchID )
Removes a watch that was created using BCI_AddWatch(), and unregisters its associated callback function. The Watch ID argument is a watch ID as returned by BCI_AddWatch. Returns 1 if successful, 0 if no watch was registered with the given ID.
Callbacks
Whenever the Operator Library receives data, or its state is modified, a callback event is triggered. In response to this event, a callback function is called. Callback functions are registered with BCI_SetCallback() or BCI_SetExternalCallback(). The difference between the two registration functions is that the first registers a callback function to be called within the context of an internal thread of the Operator Library, while the second registers a callback function to be executed in a thread owned by the application that uses the Operator library, i.e. a thread that is "external" to the Operator library. That "external" thread needs to call BCI_CheckPendingCallback() regularly in order to execute callback functions. Typically, BCI_CheckPendingCallback() would be called from a GUI application's main thread within its message handling loop.
Callback events are listed with their event names, and their handler's arguments. A callback function has at least one argument, which is a void* named refdata. The refdata pointer is supplied by user code when registering the callback function, and provided to the callback function unchanged. Typically, it would be used to store an object pointer in C++, or to an application specific data structure in C.
In Windows, callbacks must follow the stdcall calling convention. In the Operator Library's header file, a macro STDCALL is provided that should be inserted after a callback function's return type in the function declaration. This macro allows setting the calling convention without confusing compilers when compiling for non-Windows systems.
When programming in C++, callback functions must be either global functions, or functions declared "static" within class scope. They may not be ordinary member functions of a class. In object oriented programming however, you will typically want an ordinary member function to be called as a callback. This is possible using the "refdata" pointer to store an object pointer, and then call a member function on that object from the callback function as in the following example:
class MyOperator { public: MyOperator() { BCI_SetCallback( BCI_OnSystemStateChange, BCI_Function( &OnSystemStateChangeCallback ), this ); } ~MyOperator() { BCI_SetCallback( BCI_OnSystemStateChange, NULL, NULL ); } private: void OnSystemStateChange() { ... // ordinary member function that gets executed when system state changes } static void STDCALL OnSystemStateChangeCallback( void* refdata ) { MyOperator* pObject = reinterpret_cast<MyOperator*>( refdata ); pObject->OnSystemStateChange(); } };
In the following, callbacks are listed as if they were ordinary functions. However, you will not use them this way. Rather, the "function name" is the name of the callback that is supplied as the first argument to BCI_SetCallback() or BCI_SetExternalCallback(). Your own callback function will have a different name, must return "void" or "int" as indicated, and must take the arguments listed as arguments to the callback. A pointer to your own callback function will then be specified as the second argument to BCI_SetCallback(), casted to the BCI_Function type.
Callback Constants
- BCI_Handled
- Return this constant to indicate that your callback handled the event. Only used with callback functions listed with an "int" return type.
- BCI_HandledWithError
- Return this constant to indicate that your callback handled the event but an error occurred. Only used with the BCI_OnUnknownCommand() callback function.
- BCI_NotHandled
- Return this constant to indicate that your callback did not handle the event in question. Only used with callback functions listed with an "int" return type.
BCI_OnSystemStateChange( void* refdata )
Occurs on any change to BCI2000 system state.
BCI_OnCoreInput( void* refdata )
Occurs on input from any of the BCI2000 core modules.
BCI_OnConnect( void* refdata )
Occurs when core modules have connected to the Operator Library.
BCI_OnSetConfig( void* refdata )
Triggered when SetConfig() has been called.
BCI_OnStart( void* refdata )
Triggered when StartRun() has been called.
BCI_OnSuspend( void* refdata )
Triggered when BCI2000 goes into suspended state.
BCI_OnResume( void* refdata )
Triggered when BCI2000 enters the running state again.
BCI_OnShutdown( void* refdata )
Triggered when BCI_Shutdown() is called.
BCI_OnQuitRequest( void* refdata, const char** pMsg )
Triggered when a script executes the QUIT command. The application may choose to ignore the quit request, and should set the "message" pointer to a constant or static C string in this case. That string should provide information why the quit request was ignored.
BCI_OnLogMessage( void* refdata, const char* msg )
Triggered for each log message arriving from one of the modules, including the Operator module itself.
BCI_OnWarningMessage( void* refdata, const char* msg )
Triggered for warning messages. Note that also a BCI_OnLogMessage event is triggered for warning messages.
BCI_OnErrorMessage( void* refdata, const char* msg )
Triggered for error messages. Note that also a BCI_OnLogMessage event is triggered for error messages.
BCI_OnDebugMessage( void* refdata, const char* msg )
Triggered for each debug message received by the Operator module.
BCI_OnParameter( void* refdata, const char* parameterline )
Triggered whenever a parameter message arrives at the Operator module.
BCI_OnState( void* refdata, const char* stateline )
Triggered whenever a state message arrives at the Operator module.
BCI_OnVisPropertyMessage( void* refdata, const char* visID, int cfgID, const char* value )
Triggered whenever a visproperty message arrives at the Operator module. For a list of available visualization properties, see Technical Reference:Visualization Properties. Constants for the cfgID parameter are defined in the src/shared/types/CfgID.h header file.
BCI_OnVisProperty( void* refdata, const char* visID, int cfgID, const char* value )
Triggered when a visualization property is modified from a script. For a list of available visualization properties, see Technical Reference:Visualization Properties. Constants for the cfgID parameter are defined in the src/shared/types/CfgID.h header file. The "value" parameter may be NULL to indicate that the property should be reset to default (e.g., by removing it from the property store).
BCI_OnInitializeVis( void* refdata, const char* visID, const char* kind )
Triggered when the first data message for a visualization window arrives. The kind argument contains a string describing the kind of visualization required for; it is one of "Graph", "Memo", or "Bitmap".
BCI_OnVisMemo( void* refdata, const char* visID, const char* msg )
Triggered for each memo data message to a visualization window. The visID argument specifies the window's visualization ID, the msg argument specifies the memo data.
BCI_OnVisSignal( void* refdata, const char* visID, int channels, int elements, float* data )
Triggered for each signal data message to a visualization window. Data are given such that the pair of indices (ch,el) corresponds to the single index ch*elements+el. Note that this is different from the layout of bitmap data.
BCI_OnVisBitmap( void* refdata, const char* visID, int width, int height, signed short* data )
Triggered for each bitmap data message to a visualization window. Data are given in ARGB 1444 format, where the 12 bits with lowest significance represent color, and the four most significant of these 12 bits represent the R component. When any of the 3 bits with higher significance is set, the pixel is assumed to be transparent.
In actual images, the most significant bit is never set but allows for transmission of difference images between frames. Difference frames are computed by subtracting pixel values as if they were signed 16 bit integers, i.e. without regard to their interpretation as ARGB colors. In transmission, empty bitmaps (width and height set to 0) are sent to indicate that the next bitmap will be a reference frame; between reference frames, difference frames are sent.
When addressing pixels, the pair of indices (x,y) corresponds to the single index y*width+x. Note that this is different from the layout of signal messages.
int BCI_OnUnknownCommand( void* refdata, const char* command )
Triggered when the Operator Module Scripting engine meets an unknown command. The event handler can be used to extend the set of commands by handling those commands that are unknown to the scripting engine. To report that a command has been handled, return BCI_Handled or BCI_HandledWithError from the callback function. Otherwise, return a value of BCI_NotHandled.
BCI_OnScriptHelp( void* refdata, const char** pMsg )
Triggered when the scripting engine's "Help" command is executed. Assign the address of a string constant to the memory location received in pMsg. The contents of the string will be printed last in the list of commands, preceded with "Application-defined commands: ".
BCI_OnScriptError( void* refdata, const char* msg )
Triggered when script execution results in an error condition. Note that unknown commands are reported through the BCI_OnUnknownCommand event handler.
Functions that manage callbacks
int BCI_SetCallback( long, BCI_Function, void* )
Register a callback function. To clear a callback function, specify NULL as a function pointer.
- arguments
- Event ID, callback function pointer, data pointer. The callback function pointer must be cast to the BCI_Function function pointer type. The data pointer may be any data that should be available to the callback function.
- returns
- 1 if successful, 0 otherwise.
int BCI_SetExternalCallback( long, BCI_Function, void* )
Register a callback function to be executed in an external thread on execution of BCI_CheckPendingCallback(). To clear a callback function, specify NULL as a function pointer.
- arguments
- Event ID, callback function pointer, data pointer. The callback function pointer must be cast to the BCI_Function function pointer type. The data pointer may point to any data that should be available to the callback function.
- returns
- 1 if successful, 0 otherwise.
int BCI_CheckPendingCallback()
Call this function regularly from within an external thread you want external callbacks to run in. Typically, is is called from a GUI application's main event loop.
- arguments
- None.
- returns
- 1 if a callback was executed, 0 otherwise.
BCI_Function BCI_GetCallbackFunction( long )
Get a registered callback function pointer.
- arguments
- Event ID.
- returns
- Callback function pointer, or NULL if no callback function has been registered for the specified event.
void* BCI_GetCallbackData( long )
Get registered callback data. Callback data is the first argument to callback functions, and specified when calling SetCallback() or SetExternalCallback().
- arguments
- Event ID.
- returns
- Callback data, or NULL if no callback data has been registered for the specified event.
int BCI_GetCallbackIsExternal( long )
Get information how callback was registered.
- arguments
- Event ID.
- returns
- 1 if the function was registered with BCI_SetExternalCallback(), and 0 if it was registered with BCI_SetCallback(), or when no callback was registered.
Miscellaneous Functions
const char* BCI_GetInfo( void )
Reports build and source version information.
- arguments
- None.
- returns
- Pointer to a null-terminated string holding the information requested. The output buffer is allocated by the library, and should be released by the caller using BCI_ReleaseObject().
const char* BCI_GetConnectionInfo( int index )
Obtains information about a core module connection.
- argument
- Zero-based index of core module connection.
- returns
- Pointer to a null-terminated string containing connection information, or NULL for an invalid index. The output buffer is allocated by the library, and should be released by the caller using BCI_ReleaseObject().
const char* BCI_GetCoreModuleStatus( int index )
Obtains a core module's current status message.
- argument
- Zero-based index of core module connection.
- returns
- Pointer to a null-terminated string containing status information, or NULL for an invalid index. The output buffer is allocated by the library, and should be released by the caller using BCI_ReleaseObject().
int BCI_Startup( const char* arguments )
Listens on core module connection ports.
- arguments
- A string defining a local IP address (such as "localhost", or "134.2.123.151", or "*" to listen on all local addresses), and core module names and listening ports in the form "<name1>:<port1> <name2:port2> ... <nameN:portN>" If NULL or empty, a value of "Source:4000 SignalProcessing:4001 Application:4002" representing a standard BCI2000 configuration is used, and the Operator module listens on all addresses.
- returns
- 1 if successful, 0 otherwise.
int BCI_Shutdown( void )
Close connections to core modules, and go into idle state.
- returns
- 1 if successful, 0 otherwise.
int BCI_Initialize( void )
Initialize the library. Must be called before any other library function is used. This function should be called from your application's main thread.
- returns
- 1 if no error occurred, 0 otherwise.
int BCI_Dispose( void )
Dispose of all resources allocated by the library. This function must be called from the thread that called BCI_Initialize().
- returns
- 1 if no error occurred, 0 otherwise.
int BCI_TelnetListen( const char* address )
Start a telnet server, listening at the given address. By opening a telnet connection, it is possible to execute scripting commands interactively.
- arguments
- Address as a string in <IP>:<port> format. May be NULL, in which case it defaults to "localhost:3999".
- returns
- 1 if no error occurred, 0 otherwise.
int BCI_TelnetClose( void )
Stop the telnet server, closing any open connections.
- returns
- 1 if no error occurred, 0 otherwise.
int BCI_WebsocketListen( const char* address )
Start a WebSocket server, listening at the given address. By opening a WebSocket connection to ws://ip:port/, it is possible to execute scripting commands and receive command results.
- arguments
- Address as a string in <IP>:<port> format. May be NULL, in which case it defaults to "localhost:3998".
- returns
- 1 if no error occurred, 0 otherwise.
int BCI_WebsocketClose( void )
Stop the WebSocket server, closing any open connections.
- returns
- 1 if no error occurred, 0 otherwise.
int BCI_ExecuteScript( const char* script )
Interprets and executes the specified script according to the Operator scripting reference.
- arguments
- Null-terminated string specifying script commands.
- returns
- 0 if a syntax error is present, 1 otherwise.
const char* BCI_ExecuteScriptWithResult( const char* script )
Interprets and executes the specified script according to the Operator scripting reference.
- arguments
- Null-terminated string specifying script commands.
- returns
- NULL if a syntax error is present, pointer to a null-terminated result string otherwise. The result string is allocated by the library, and should be released by the caller using BCI_ReleaseObject(). The result is always identical to the result of the last executed script command.
void BCI_Log( int messageType, const char* message )
Acts as if receiving the respective type of message from a module, i.e. typically calls the handler installed for that type of message.
- arguments
- Type of message, which is one of BCI_LogMessage, BCI_Warning, BCI_Error, BCI_DebugMessage; null-terminated message string.
int BCI_ReleaseObject( const char* )
Indicate that an object that has been allocated by the library is no longer needed by the library's client.
- arguments
- Object to be released, or NULL.
- returns
- 1 if successful, 0 otherwise.
See also
User Reference:Operator Module Scripting, Technical Reference:States of Operation, Programming Reference:Debug Output, Technical Reference:BCI2000Remote Library