hypertools.io.synthetic_outlet

hypertools.io.synthetic_outlet(name='HypertoolsSyntheticStream', n_channels=6, rate=100.0, stream_type='EEG', push_interval=0.01, noise=0.05, seed=None)[source]

Start a REAL pylsl.StreamOutlet on a background daemon thread, continuously pushing synthetic samples – for exercising lsl_stream() (or any other LSL consumer) without real acquisition hardware. This is the same generator the LSL tutorial (docs/tutorials/lsl_streaming.ipynb) and the LSL test suite (tests/test_lsl_streaming.py) each used to hand-roll; both now call this instead.

Signal definition. Sample i of channel c (c in range(n_channels)) is:

sin(2*pi*(0.5 + 0.1*c) * i/rate) + noise * N(0, 1)

i.e. channel c oscillates at (0.5 + 0.1*c) Hz – distinct but related frequencies, easy to tell apart in a plot – plus Gaussian noise with standard deviation noise.

Parameters:
namestr

The LSL stream’s name property (what hyp.io.lsl_stream(name= …) matches against). Must be unique on the network to avoid resolving someone else’s outlet.

n_channelsint

Number of channels to push per sample (default: 6).

ratefloat

Nominal sampling rate in Hz, both the LSL stream’s declared rate and the one used in the signal formula above (default: 100.0).

stream_typestr

The LSL stream’s type property (default: 'EEG').

push_intervalfloat

Seconds to sleep between pushes on the background thread (default: 0.01). Independent of rate: it is what actually paces the thread, while rate only feeds the signal formula and the stream’s declared nominal rate.

noisefloat

Standard deviation of the Gaussian noise added to each channel (default: 0.05). 0 disables noise.

seedint, optional

Seed for the noise generator, for reproducible samples. None (default) uses fresh, non-reproducible randomness.

Returns:
outletSyntheticOutlet

A handle with .stop() (stop the background thread; idempotent), .thread (the threading.Thread pushing samples), .info (the pylsl.StreamInfo the outlet was created with), and .closed. Also usable as a context manager – with hyp.io.lsl.synthetic_outlet(...) as outlet: – which calls .stop() on exit.

Raises:
ImportError

If pylsl is not installed and could not be installed on demand.

TypeError

If name or stream_type is not a non-empty string.

ValueError

If n_channels is not a positive integer, or rate, push_interval is not a positive number, or noise is negative.

Examples

>>> import hypertools as hyp
>>> outlet = hyp.io.lsl.synthetic_outlet('Demo')
>>> stream = hyp.io.lsl_stream(name='Demo', timeout=5.0)
>>> hyp.plot(stream, stream_init=200, stream_chunk=20)
>>> stream.close()
>>> outlet.stop()

or, equivalently, scoped to a block:

>>> with hyp.io.lsl.synthetic_outlet('Demo') as outlet:
...     with hyp.io.lsl_stream(name='Demo') as stream:
...         hyp.plot(stream, stream_init=200, stream_chunk=20)