Coder Social home page Coder Social logo

lsl.jl's Introduction

LSL.jl

Build Status Build Status

A Julia interface to the lab streaming layer library.

Installation & platform support

LSL is a registered package. Install using the package manager:

]add LSL
Platform Architecture Notes
Linux (x86) 32-bit and 64-bit CI active
MacOS 64-bit CI active
Windows 64-bit CI active

For Julia > 1.3, the library is cross-compiled for Windows (x64), Linux (x86, x64, ARMv7, ARMv8), MacOS, and FreeBSD using the BinaryBuilder package, with CI builds undertaken on the Yggdrasil platform. Binaries are packaged and supplied through the JuliaBinaryWrappers organisation. Platforms for which the library are built, but not listed as supported, are untested or known to fail.

Usage

LSL.jl provides an interface similar to the official Python bindings, with some changes to ensure the wrapper follows idiomatic Julia.

Specifying a stream

A new stream is specified by building a SteamInfo structure:

info = StreamInfo(name = "streamname",
                  type = "streamtype",
                  channel_count = 16,
                  channel_format = Float64,
                  source_id = "streamuuid")

A stream information structure can be quieried using methods such as name(info), type(info), channel_count(info), nominal_srate(info), channel_format(info), source_id(info), version(info), created_at(info), session_id(info), uid(info), hostname(info). Get help on these and all other methods provided by the library using the Julia help system.

Creating a stream outlet, and pushing data

To advertise the stream on the network, and allow data to be sent, create a StreamOutlet structure:

outlet = StreamOutlet(info)

You may push a vector of channel_count(info) samples of type channel_format(info) by using the push_sample method:

sample = rand(Float64, 16)
push_sample(outlet, sample)

Push a massive chunk of data consisting of many such samples with a matrix of appropriate dimension:

chunk = rand(Float64, 16, 1024)
push_chunk(outlet, sample)

Check if anyone is listening to the outlet by calling have_consumers(info), or block on a connection using wait_for_consumers(info). Note that the latter function is a blocking C call, and this will prevent Julia from switching between Tasks if you choose to use this function in an asynchronous operation. It may be preferable to simple poll the former function.

Finding streams on the network

Find all streams on the network, waiting two seconds for discovery:

streams = resolve_streams(timeout = 2.0)

This function returns a vector of StreamInfo structures, each of which can be queried or read from. Alternatively, you may wish to resolve a stream by property:

streams = resolve_byprop("source_id", "streamname", timeout = 2.0)

Or using a predicate:

streams = resolve_bypred("type=streamtype", timeout = 2.0)

Creating a stream inlet, and reading data

To get some data, given a StreamInfo structure, create a StreamInlet structure:

inlet = StreamInlet(streams[1])

You can open_stream(inlet), close_stream(inlet), set_postprocessing(inlet), and check if samples_available(inlet), etc. But probably you're more intersted in getting samples:

sample, timestamp = pull_sample(inlet, timeout = 10.0)

Be careful, the default timeout will wait forever (timeout = LSL.LSL_FOREVER). For high performance code you may want to reuse an existing vector:

timestamp = pull_sample!(sample, inlet, timeout = 10.0)

To grab a chunk of data:

chunk, timestamps = pull_chunk(inlet, timeout = 10.0, max_samples = 512)

Since the size of the available chunk is not known until the library returns, a large allocation (equal to a chunk size of max_samples) is made by this function, and resized accordingly. This may not offer the best performance in a hot loop.

Adding extended metadata to stream information

Streams can be annotated using structured metadata as described in the XDF format. For example, an EEG recording may employ the meta-data in the associated specification.

info = StreamInfo(name="BioSemi",
                  type="EEG",
                  channel_count=8,
                  nominal_srate=100,
                  channel_format=Float32,
                  source_id="sub_ae852")

channels = append_child(desc(info), "channels")
for label in ["C3", "C4", "Cz", "FPz", "POz", "CPz", "O1", "O2"]
  ch = append_child(channels, "channel")
  append_child_value(ch, "label", label)
  append_child_value(ch, "unit", "microvolts")
  append_child_value(ch, "type", "EEG")
end
append_child_value(desc(info), "manufacturer", "SCCN")
cap = append_child(desc(info), "cap")
append_child_value(cap, "name", "EasyCap")
append_child_value(cap, "size", "54")
append_child_value(cap, "labelscheme", "10-20")

Full stream metadata can be rendered as XML:

XML(info)

Low level library access

The full C API of liblsl is wrapped by the package, and the functions can be accessed by their usual names, in the lib submodule, e.g. LSL.lib.lsl_get_name(info). Julia structures such as StreamInfos, StreamOutlets, and StreamInlets will automatically convert to their C handle when used as arguments to the C library. Alternatively you may get a pointer by accesing the .handle property of each.

lsl.jl's People

Contributors

juliatagbot avatar samuelpowell avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

abcsds

lsl.jl's Issues

Inclusion in the main repository

The main repository has all the official language bindings as submodules.
I've looked over the code and if you think it's ready I think it'd be a good idea to have it in there (even though no one has asked for Julia bindings yet :-).

The semi-official policy is that the repository would have to be transferred to the labstreaminglayer organization (with you as an admin, of course) or have the labstreaminglayer organization as administrator in the repository.

Fix Windows x64 CI / library

Windows x64 target is failing CI - the library build could be bad or this could just be a CI configuration issue

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.