/** * `decodeAnnotations`: TALs plus EDF+ semantics. * * Layer 3. Sole owner of timekeeping extraction and of the annotation sort. The byte grammar * lives in `grammar.ts`; everything here is about which TAL means what. * * Three rules the rest of the library depends on: * * 1. The FIRST TAL of the FIRST annotation signal of the file is that record's timekeeping TAL. * "First" is a position, not "the first one that parsed", and "first annotation signal" is * `header.annotationSignalIndices[0]` — not the first signal this call was asked for. An * additional annotation signal carries NO timekeeping TAL, and stripping its first TAL would * silently delete a real event. * 2. `recordOnsetTicks` has one entry for EVERY record in the decoded range, always. A record * whose timekeeping TAL is missing gets the derived onset `start + recordIndex * duration` * rather than a hole or a sentinel, and `TIMEKEEPING_TAL_MISSING` carries the record index so * the derivation is never invisible. Every timeline in edfcore is built from this array. * 3. Onsets are exposed under both conventions as separately named fields, never as an option: * `onsetSecondsFromHeaderStart` is the verbatim on-disk value and * `onsetSecondsFromFirstRecord` is rebased to record 0's true start. Compare on the TICKS, * never on the floats — and on `onsetTicksFromFirstRecord` whenever the other side of the * comparison is a window, a chunk or anything a read produced, because every read in the * package puts `t = 0` at the start of record 0. `onsetTicks` is the header's axis, exact and * right for comparing one annotation against another; the two differ by the sub-second offset * record 0 may declare. This said `onsetTicks` "is the only one worth comparing" until 0.6.56, * which `types.ts` calls the wrong field for a window in as many words (fixed in 0.6.56). * * Diagnostic volume is bounded on purpose, by one test: does another occurrence of this code * carry information available nowhere else? `TIMEKEEPING_TAL_MISSING` does — it names a record * whose onset was derived — so it is reported per record. `NEGATIVE_ANNOTATION_ONSET` and * `TIMEKEEPING_TAL_NONCONFORMANT` do not: the onsets are in the result and the shorthand is a * property of the writer, so they are reported once per call. The grammar's own defects are * deduplicated per region and carry an occurrence count. * * Record-onset spacing and monotonicity are deliberately NOT checked here. This module produces * `recordOnsetTicks`; `time/timeline.ts` owns enforcing what a valid timeline is, and splitting * that would give one rule two owners. */ import type { DecodeAnnotationsOptions, EdfAnnotationsResult, EdfHeader, RecordRange } from '../types.js'; /** * Decodes the TAL regions of a record range into events, and the per-record onsets alongside * them. Pure and synchronous over bytes you already hold — `readAnnotations` is this plus one * read, and is what most callers want. */ export declare function decodeAnnotations(header: EdfHeader, recordBytes: Uint8Array, records: RecordRange, options?: DecodeAnnotationsOptions): EdfAnnotationsResult; //# sourceMappingURL=annotations.d.ts.map