- NB: Document updated for OpenViBE 1.2.0 (27.May.2016)
OpenViBE and LabStreamingLayer
LabStreamingLayer (LSL) is a protocol for exchanging streaming data between applications. We’ve developed some prototype components to enable OpenViBE to pass data between other LSL-aware applications. For example, LSL can be used to bring signals from various currently unsupported devices into OpenViBE. You just need an application that forwards data from a device to an LSL stream. Alternative, you can send data from OpenViBE into an LSL-aware application.
Feedback about your experiences regarding the LSL components in OpenViBE (e.g. timing accuracy, usability, …) are very welcome.
LSL -> Acquisition Server
To read data from LSL to OpenViBE, you can use the LabStreamingLayer (LSL) driver in acquisition server.
After selecting the driver, you can select the signal sources by configuring the driver by clicking the Driver Properties button.
When configuring the driver, the driver detects the compatible LSL streams available in the network and lets you select one signal and one (optional) marker stream. Both streams must be already opened by the source application by the time you configure the driver. The stream choices will be remembered across runs when you close the Acquisition Server normally. The signal stream must be of type cf_float32
and the marker stream cf_int32
. The sampling rate is obtained from the stream. The markers will be passed on as OpenViBE stimulations without conversion. Note that since OpenViBE stimulations are 64 bit integers, not all stimulations can be represented by LabStreamingLayer’s 32 bit integer stream.
Acquisition Server -> LSL
It is possible to pass data from Acquisition Server directly to LSL without passing it through Designer. This way, you can easily use Acquisition Server as a data acquisition component for your LSL-aware application.
You can do this by opening the Acquisition Server preferences, and enabling the LSL Output plugin. You can choose a name for each of the outgoing streams. Both streams will additionally have a randomized integer identifier (as a string) to differentiate them with other streams potentially having the same names. These identifiers are different each time the Acquisition Server is started.
The types of the two opened streams will be ‘signal’ and ‘Markers’ (note the difference in case).
Designer -> LSL
You can send processed or unprocessed data and stimulations out from Designer using either the LSL Export or LSL Export (Gipsa) boxes. The difference is that the LSL Export box uses the same two-stream convention as the LSL components in the Acquisition Server, whereas the Gipsa box passes the stimulations out as an additional float signal channel (the last one).
In the case of the non-Gipsa box, the types of the two opened streams will be ‘signal’ and ‘Markers’ (note the difference in case).
The Gipsa-lab version of the export box lets you specify the type as a box parameter.
Other notes
LSL -> Designer. It is currently not possible to receive data directly from LSL into Designer. You must use the driver in the Acquisition Server.
Timing: Note that sampling rates in LabStreamingLayer are nominal: the signal source is not actually required to conform to this rate, nor does LSL try to enforce it. In practice, the LSL stream can give you more or less samples per second than expected from the sampling rate. Also, in LSL each sample is essentially separate with its own timestamp. Data in OpenViBE, on the other hand, is continuous and should exactly conform to the declared sampling rate. For example, 512 samples with a sampling rate of 512hz equals exactly 1 second of simulated time in Designer. No gaps, missing samples, or extra samples are supported in the OpenViBE signal stream. To attain this with imprecise signal sources, the Acquisition Server can alter the signal stream when it notices it deviating from the declared sampling rate. To change how Acquisition Server does this, see the Drift Correction settings in Acquisition Server preferences (more information here and in this tutorial). It is recommended to experiment with the settings until you find one suitable for your conditions.
Its also good to remember that OpenViBE operates by handling chunks of samples (i.e. the amount of samples handled per iteration is fixed, typically 32). So when OpenViBE pushes samples into an LSL stream, it will call the LSL sample push for all samples in the current chunk — so the pushes will occur in bursts. This has the consequence that if you feed LSL Export output in Designer to LSL Driver in the Acquisition Server, you will often notice some constant drift. The reason is that the LSL Export will write the whole chunk regardless how many samples the server expects to be ready at that time, and the LSL Driver just picks up the chunk without looking at the timestamps. So at time 0, if LSL Export has already managed to write a chunk after the driver connected to the stream, the driver will get a full chunk of samples immediately (instead of expected 0).
Conventions of stream identification: LSL Streams are supposed to be uniquely identified by a (name, id)
pair. User can select the name
part of the stream. Currently, the LSL Output plugin in the server randomizes the id
on each startup of the server, and the LSL Export box in Designer randomizes it when the user presses Play (in some use-cases its imaginable the identifier should stay the same — let us know). The LSL Driver in the server remembers the (name,id) pair across the runs (if you close it normally), and when the server is started again, the LSL Driver always tries to match (name,id) exactly. If this is not possible, it automatically accepts one of the ‘name’ only matches. If this is wrong, you can select the correct pair in the driver configuration.
Bug reports and feedback are welcome.