/** * Which dialect the file claims to be. * * Layer 2. Sole owner of the version-block and reserved-field grammars — the two fields that * decide sample width, EDF+ dialect and continuity, and therefore every byte offset and every * time value computed downstream. * * Two rules deserve stating because they look wrong: * * - The 8-byte version block is the ONLY reliable EDF-vs-BDF discriminator. EDF+ deliberately * keeps `'0 '` so legacy readers still open the file, so nothing in the reserved field * can be trusted to identify the family. * - BDF's version block is not ASCII: byte 0 is 0xFF, then `'BIOSEMI'`. */ import { type DiagnosticSink } from '../diagnostics/collector.js'; import type { EdfVariant } from '../types.js'; /** * The half of a variant that decides byte layout: EDF stores 16-bit samples, BDF 24-bit. It is * detected from the version byte rather than the reserved marker, because a file can be BDF * without ever claiming `BDF+`, and every offset in the record depends on getting this right. */ export type EdfFamily = 'EDF' | 'BDF'; /** The recognised reserved-field prefixes. Matched on the first five bytes, never trimmed. */ export type EdfReservedMarker = 'EDF+C' | 'EDF+D' | 'BDF+C' | 'BDF+D' | '24BIT'; /** * Everything the two identifying fields yield, kept apart rather than collapsed into `variant`. * The parts disagree on real files — a 24-bit file whose reserved field says nothing is BDF with * no marker — and each consumer needs a different one, so none of them is derived twice. */ export interface EdfVariantInfo { readonly variant: EdfVariant; /** From the version block alone. Sample width follows from this and nothing else. */ readonly family: EdfFamily; readonly bytesPerSample: 2 | 3; readonly continuity: 'continuous' | 'discontinuous'; /** True for EDF+C/EDF+D/BDF+C/BDF+D: the file claims the EDF+ dialect, so the subfield * grammars in `identification.ts` apply and an annotation signal is mandatory. */ readonly isPlus: boolean; /** The five-byte prefix that actually matched, or `undefined` when the field is blank or * unrecognised. */ readonly reservedMarker: EdfReservedMarker | undefined; /** Trimmed, case-sensitive annotation label for this family. */ readonly annotationsLabel: string; /** What the sample width can represent. Drives `DIGITAL_RANGE_EXCEEDS_FORMAT`. */ readonly digitalMinimumLimit: number; readonly digitalMaximumLimit: number; } /** * EDF's version block: ASCII `'0'` then seven spaces. * * NUL is accepted as padding alongside space. The spec says space, but a writer that pads with * NUL has produced the same value, and `NOT_AN_EDF_FILE` — the only alternative here — would * refuse a file whose every other byte is fine. */ export declare function isEdfVersionBlock(versionBytes: Uint8Array): boolean; /** BDF's version block: byte 0 = 0xFF, bytes 1..7 = `'BIOSEMI'`. Exact, no padding tolerance. */ export declare function isBdfVersionBlock(versionBytes: Uint8Array): boolean; /** * The dialect marker carried by the reserved field, matched on its five-byte PREFIX. * * The prefix rule is what makes `'EDF+D v2.1'` an EDF+D file rather than an unrecognised one. */ export declare function reservedMarkerOf(reserved: string): EdfReservedMarker | undefined; /** The container these bytes begin with, or `undefined` — which is most files. */ export declare function containerAt(bytes: Uint8Array): string | undefined; /** * Read the version block and the reserved field, and decide the variant. * * `headerBytes` must cover at least the 256-byte fixed header; the caller has already refused * anything shorter with `SOURCE_TOO_SMALL`. * * When the reserved marker names a different family than the version block does — `'BDF+C'` on * a file whose version block is EDF — the version block wins for the family, but the marker is * still honoured for continuity and EDF+ dialect, and the disagreement is reported. Dropping * the `D` would silently turn a discontinuous recording into one whose every timestamp is * wrong; keeping the wrong sample width would make every sample wrong instead. */ export declare function detectVariant(headerBytes: Uint8Array, sink: DiagnosticSink): EdfVariantInfo; //# sourceMappingURL=variant.d.ts.map