labstreaminglayer / pylsl

Python bindings (pylsl) for liblsl
MIT License
142 stars 58 forks source link

LSL buffer issue #57

Closed CalebUAz closed 2 years ago

CalebUAz commented 2 years ago

I am using LSL to stream EEG, fNIRS, and Eye tracker data. I'm using PyQT5 to plot those data streams. The issue I am having is initially there isn't a delay in plots but over some period of time (say an hour), there is a huge delay in the plots. One thing I observed is my EEG is streaming at 500hz so after I stop the streams, for like 2 hours my program will continue to plot the streams. Does LSL have a built-in buffer?

If so how do I control the buffer?

cboulay commented 2 years ago

LSL does have a built-in buffer. By default it's 6 minutes.

When creating an inlet, use the max_buflen parameter: https://github.com/labstreaminglayer/liblsl-Python/blob/master/pylsl/pylsl.py#L646-L651

But shortening the buffer will only mean that you'll drop samples. The real issue is that you aren't consuming data fast enough. If you're still plotting for 2 hours that means that your code is only plotting at 1/20th the data rate.

  1. Make sure you're using pull_chunk instead of pull_sample. You might have to rewrite your plotting code to accommodate variable sized chunks.
  2. In your application, you can preallocate a numpy array and pass that in as the dest_obj. This can speed up your data retrieval significantly.
  3. Please check out https://labstreaminglayer.readthedocs.io/info/viewers.html

I'm going to close this issue because it isn't really an issue with LSL. I'm happy to continue the conversation though.

agricolab commented 2 years ago

I totally second @cboulay, your problem most likely is caused by too slow consumption. As an alternative, you can decimate the received data, and e.g. only plot every 10th sample.

Just for taking notes, reading the source code how dest_obj is handled: The speedup stems from not cutting and converting the received data (https://github.com/labstreaminglayer/liblsl-Python/blob/master/pylsl/pylsl.py#L865-L870), and skipping a dictionary lookup instead of creating a buffer interface https://github.com/labstreaminglayer/liblsl-Python/blob/master/pylsl/pylsl.py#L865-L870 (am not sure whether the latter is really faster, though)