sampleIndexAt

fun sampleIndexAt(hostTimeNs: Long = hostClockNs()): Long?

The device sample number being converted at host time hostTimeNs (System.nanoTime(), the clock of EegChunk.hostTimeNs) — the sample an annotation made at that moment belongs to — or null when no stream is running. Meant for annotations and triggers: call it when the event happens, with the default time, and store the index.

With the device's time sync (firmware 3.8.0+, see timeSyncInfo) the answer comes from the device's own clock and sample counter, fitted from pings during the stream: the sample whose conversion was under way at hostTimeNs, to within about a millisecond once a few seconds of pings are in. Without it — older firmware, impedance mode, or too few or too old pings — it is estimated from the newest packet: its counter plus one, plus the samples that fit in the time since it arrived; before the first packet of the stream, counted from the stream's start. That estimate is early, on a sample from before hostTimeNs, by the packet's whole trip over the radio (5 to 40 ms), and jitters with it.

The number is the device's own sample counter, as the packet footers count it (a Long: the counter is unsigned 32-bit and wraps at 2^32, like the counter does), so it names the same sample as EegChunk.firstSampleIndex + n within a chunk — as long as sampleCounterJumps is 0: after a counter jump the decoder's running index no longer follows the wire counter, while this keeps following it. Never negative. The rate the packet fallback counts at is the one the stream started with.