Stream Handle#
- class nistreamer.streamer.NIStreamer.StreamHandle(streamer)#
Handle providing full stream control within
withcontext.The handle is obtained by initializing stream context (see
init_stream()):>>> strmr = NIStreamer() >>> # ... add cards/channels, add instructions, compile ... >>> >>> # This is how you initialize stream context: >>> with strmr.init_stream() as stream_handle: >>> # ... This is context body ... >>> >>> # Use handle to control stream: >>> stream_handle.launch(instream_reps=10) >>> >>> # Always wait for stream to finish: >>> stream_handle.wait_until_finished() >>> >>> # Stream will be closed automatically when leaving context
- launch(instream_reps=1)#
Launch sequence generation.
This call is non-blocking - returns immediately after generation starts. You must always call
wait_until_finished()after launching to ensure generation is complete before making any further stream actions.- Parameters:
instream_reps – number of in-stream repetitions. Plays once by default.
- Raises:
RuntimeError – if attempting to launch stream while it is already running.
Notes
In-stream looping is very different from basic repeating by re-launching (see
run()) - all iterations happen as a single continuous stream without any gaps (but it is still interruptible between repetitions).The limitation is that in-stream looping requires at least a minimal sequence duration of
chunksize_ms(). Shorter sequences can still be played withinstream_reps=1only or be repeated by re-launching. Alternatively, one can concatenate several repetitions into a single sequence to reach sufficient duration for in-stream looping to work.See also
You must always call
wait_until_finished()after launching stream.
- reps_written_count()#
Number of fully computed and transferred in-stream repetitions so far.
- Return type:
int
Notes
This value DOES NOT show the current play position and cannot serve as a reliable sync mechanism.
Samples are computed and written to cards before they are actually played. So this value - the number of fully written repetitions - can be greater than the actual number of fully played cycles. The two can differ significantly, especially for very short sequences.
Instead, this value is meant to be a coarse progress indicator for long-running in-stream loops (see example below).
Examples
>>> strmr = NIStreamer() >>> # ... add cards/channels, add instructions, compile ... >>> >>> # Timed wait + reps_written_count to implement live progress printing: >>> with strmr.init_stream() as handle: >>> handle.launch(instream_reps=1000) >>> while True: >>> finished = handle.wait_until_finished(timeout=1) >>> print(handle.reps_written_count()) >>> if finished: >>> break >>>
- request_stop()#
Request to stop in-stream loop without completing all repetitions.
Streamer will complete the current repetition in progress and then stop. You should call
wait_until_finished()after requesting stop to wait until the in-progress iteration is finished.Notes
Practically, you do not need to use this function in most cases - simply leaving
withcontext will automatically request stop and wait until stream finishes before returning:>>> import time >>> strmr = NIStreamer() >>> # ... add cards/channels, add instructions, compile ... >>> >>> # This will stop in-stream loop as well: >>> with strmr.init_stream() as handle: >>> handle.launch(instream_reps=1000000) >>> time.sleep(10) >>> >>> # This will stop the loop whenever `KeyboardInterrupt` is emitted: >>> with strmr.init_stream() as handle: >>> handle.launch(instream_reps=1000000) >>> handle.wait_until_finished()
This function is only exposed for advanced cases where you need to break out of in-stream loop (e.g. due to some external condition) and then launch the stream again without incurring re-init overhead:
>>> import time >>> strmr = NIStreamer() >>> # ... add cards/channels, add instructions, compile ... >>> >>> with strmr.init_stream() as handle: >>> handle.launch(instream_reps=1000000) >>> time.sleep(10) >>> >>> # Now have to break the loop due to some condition: >>> handle.request_stop() >>> handle.wait_until_finished() >>> >>> # Then launch again: >>> handle.launch(instream_reps=10) >>> handle.wait_until_finished() >>>
- wait_until_finished(timeout=None)#
Block to wait until generation is finished.
- Parameters:
timeout (
Optional[float]) – wait time limit in seconds.None- wait indefinitely (default).- Return type:
Optional[bool]- Returns:
In timed mode,
Turemeans generation finished,Falsemeans still running when timeout elapsed. Basic mode returnsNone.- Raises:
RuntimeError – if there is any stream error (underflow, overvoltage, sync signal loss)
Notes
There are two modes depending on
timeoutvalue:Basic (
timeout=None, default). Blocks and waits indefinitely until run is finished. Can be interrupted withKeyboardInterrupt. ReturnsNonewhen finished.Timed (
timeout: float). Blocks and returnsTrueif run is finished orFalseif timeout elapses before.
Examples
>>> strmr = NIStreamer() >>> # ... add cards/channels, add instructions, compile ... >>> >>> # Basic wait: >>> with strmr.init_stream() as handle: >>> handle.launch(instream_reps=10) >>> handle.wait_until_finished() >>> >>> # Timed wait - using to implement live progress printing: >>> with strmr.init_stream() as handle: >>> handle.launch(instream_reps=10) >>> while True: >>> finished = handle.wait_until_finished(timeout=1) >>> print(handle.reps_written_count()) >>> if finished: >>> break >>>