Skip to content

Commit 11e2ff1

Browse files
committed
Update README
1 parent 1f54300 commit 11e2ff1

1 file changed

Lines changed: 71 additions & 29 deletions

File tree

README.md

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,87 @@
11
# C# bindings
22

33
The is the C# interface to the lab streaming layer. To use it, you need to include the file LSL.cs in
4-
your project, and make sure that the lsl library (e.g. liblsl32.dll) is found (e.g., in your application's
4+
your project, and make sure that the appropriate lsl library (e.g. lsl.dll) is findable (e.g., in your application's
55
root directory or in a system path).
66

7-
If you are deploying for something other than Unity, and on a platform that requires a different binary
8-
than liblsl32.dll (e.g., liblsl64.so on 64-bit Linux, or liblsl64.dylib on Mac OS)
9-
then you need to replace the libname constant in LSL.cs by the corresponding file name.
7+
If LSL.cs fails to find the lsl shared library for your target platform, edit LSL.cs and update the following line with the name for your system: `const string libname = "lsl";`
108

11-
These example applications can be debugged from within the IDE (i.e. Visual Studio). However, the built
12-
products are DLL files, not EXE files. The DLL files can be run at console with `dotnet my_application`
13-
(from within same folder as my_application.DLL). This will work anywhere the .NET Core Runtime works.
14-
To make a more portable but platform-dependent product, use `dotnet publish -C Debug -r win10-x64`
15-
(or Release instead of Debug) and this will generate an EXE file.
9+
# C# Example Programs
1610

11+
The examples folder contains example C# code for sending and receiving data streams. The examples are described in the [online documentation](https://labstreaminglayer.readthedocs.io/dev/examples.html#id2).
1712

18-
## C# Example Programs
13+
These example applications can be debugged from within the IDE (i.e. Visual Studio). However, the built products are DLL files, not EXE files. The DLL files can be run at console with `dotnet my_application` (from within same folder as my_application.DLL). This will work anywhere the .NET Core Runtime works. To make a more portable but platform-dependent product, use `dotnet publish -C Debug -r win10-x64` (or Release instead of Debug) and this will generate an EXE file.
1914

20-
These examples show how to transmit a numeric multi-channel time series through LSL:
15+
# Unity
2116

22-
- [Sending a multi-channel time series into LSL.](https://github.com/labstreaminglayer/liblsl-Csharp/blob/master/examples/SendData)
23-
- [Receiving a multi-channel time series from LSL.](https://github.com/labstreaminglayer/liblsl-Csharp/blob/master/examples/ReceiveData)
17+
The [LSL4Unity repository](https://github.com/labstreaminglayer/LSL4Unity) provides a more featureful integration of LSL into Unity. However, it is not as well-maintained as this repository. The recommended approach to integrating LSL into a Unity project is to use this repository's LSL.cs, and use LSL4Unity as a reference for more advanced use of LSL in Unity.
2418

25-
The following examples show how to transmit data in form of chunks instead of samples, which can be
26-
more convenient.
19+
## Getting Started in Unity
2720

28-
- [Sending a multi-channel time series in chunks.](https://github.com/labstreaminglayer/liblsl-Csharp/blob/master/examples/SendDataInChunks)
29-
- [Receiving a multi-channel time series in chunks.](https://github.com/labstreaminglayer/liblsl-Csharp/blob/master/examples/ReceiveDataInChunks)
21+
These instructions were written while using Unity 2020.1.0f1.
3022

31-
These examples show a special-purpose use case that is mostly relevant for stimulus-presentation
32-
programs or other applications that want to emit 'event' markers or other application state.
23+
1. Drag and drop LSL.cs into the project Assets folder.
24+
1. Download the latest [liblsl release](https://github.com/sccn/liblsl/releases) for your platform and extract the library (e.g. liblsl64.dll) into the project root folder.
25+
1. In Unity, use the menu to place a cube in the scene: GameObject > 3D Object > Cube
26+
1. When the cube is selected, in the Inspector click on "Add Component", and create a new script called LSLInput.
27+
1. In the Project viewer, double click on LSLInput.cs. This should launch Visual Studio or another IDE.
28+
1. Fill in the script. Use [LSL4Unity AInlet](https://github.com/labstreaminglayer/LSL4Unity/blob/master/Scripts/AInlet.cs) for inspiration.
29+
```
30+
using System.Collections;
31+
using System.Collections.Generic;
32+
using UnityEngine;
33+
using LSL;
3334
34-
The stream here is single-channel and has irregular sampling rate, but the value per channel is a string:
35-
- [Sending string-formatted irregular streams.](https://github.com/labstreaminglayer/liblsl-Csharp/blob/master/examples/SendStringMarkers)
36-
- [Receiving string-formatted irregular streams.](https://github.com/labstreaminglayer/liblsl-Csharp/blob/master/examples/ReceiveStringMarkers)
35+
public class LSLInput : MonoBehaviour
36+
{
37+
public string StreamType = "EEG";
38+
public float scaleInput = 0.1f;
39+
liblsl.StreamInfo[] streamInfos;
40+
liblsl.StreamInlet streamInlet;
41+
liblsl.ContinuousResolver resolver;
42+
float[] sample;
43+
private int channelCount = 0;
3744
38-
The last example shows how to attach properly formatted meta-data to a stream, and how to read it
39-
out again at the receiving end.
40-
While meta-data is strictly optional, it is very useful to make streams self-describing.
41-
LSL has adopted the convention to name meta-data fields according to the XDF file format
42-
specification whenever the content type matches (for example EEG, Gaze, MoCap, VideoRaw, etc);
43-
the spec is [here](https://github.com/sccn/xdf/wiki/Meta-Data).
45+
// Start is called before the first frame update
46+
void Start()
47+
{
48+
resolver = new liblsl.ContinuousResolver("type", StreamType);
49+
StartCoroutine(ResolveExpectedStream());
50+
}
4451
45-
- [Handling stream meta-data.](https://github.com/labstreaminglayer/liblsl-Csharp/blob/master/examples/HandleMetaData)
52+
IEnumerator ResolveExpectedStream()
53+
{
54+
var streamInfos = resolver.results();
55+
yield return new WaitUntil(() => streamInfos.Length > 0);
56+
streamInlet = new liblsl.StreamInlet(streamInfos[0]);
57+
channelCount = streamInlet.info().channel_count();
58+
streamInlet.open_stream();
59+
yield return null;
60+
}
61+
62+
// Update is called once per frame
63+
void Update()
64+
{
65+
if (streamInlet != null)
66+
{
67+
sample = new float[channelCount];
68+
double lastTimeStamp = streamInlet.pull_sample(sample, 0.0f);
69+
if (lastTimeStamp != 0.0)
70+
{
71+
Process(sample, lastTimeStamp);
72+
while ((lastTimeStamp = streamInlet.pull_sample(sample, 0.0f)) != 0)
73+
{
74+
Process(sample, lastTimeStamp);
75+
}
76+
}
77+
}
78+
}
79+
void Process(float[] newSample, double timeStamp)
80+
{
81+
var inputVelocity = new Vector3(scaleInput * (newSample[0] - 0.5f), scaleInput * (newSample[1] - 0.5f), scaleInput * (newSample[2] -0.5f));
82+
gameObject.transform.position = gameObject.transform.position + inputVelocity;
83+
}
84+
}
85+
```
86+
1. Elsewhere, run one of the LSL outlet examples. For example, from a conda environment with pylsl installed: `python -m pylsl.examples.SendData`
87+
1. Run the Unity game.

0 commit comments

Comments
 (0)