namespace DeepDrftContent.Processors.Opus; /// /// Wire-format constants for the Ogg-Opus derived artifacts. Centralised so the seek-index codec, /// the page walker, and the tests agree on one set of magic numbers. /// public static class OggOpusConstants { /// Opus granule positions are always sample counts at 48 kHz, regardless of input rate. public const double OpusSampleRate = 48000.0; /// One seek-index entry per this many seconds of audio (OQ7 — 0.5 s buckets). public const double SeekBucketSeconds = 0.5; /// The Ogg page capture pattern "OggS" — every page starts with these four bytes. public static ReadOnlySpan CapturePattern => "OggS"u8; /// Magic signature opening an OpusHead identification header packet. public static ReadOnlySpan OpusHeadSignature => "OpusHead"u8; /// Magic signature opening an OpusTags comment header packet. public static ReadOnlySpan OpusTagsSignature => "OpusTags"u8; /// /// Fixed size of an Ogg page header before the segment table: capture(4) + version(1) + /// header-type(1) + granulepos(8) + serial(4) + sequence(4) + checksum(4) + page-segments(1). /// public const int OggPageHeaderSize = 27; /// Byte offset of the 64-bit granule position within an Ogg page header. public const int GranulePositionOffset = 6; /// Byte offset of the page-segment count (the segment-table length) within the header. public const int PageSegmentCountOffset = 26; /// Sentinel granule position for a page that ends mid-packet (no usable timestamp). public const ulong NoGranulePosition = 0xFFFFFFFFFFFFFFFFUL; /// /// Minimum byte length of an OpusHead packet payload to safely read pre_skip. /// RFC 7845 §5.1: "OpusHead"(8) + version(1) + channels(1) + pre_skip(2) = 12 bytes minimum. /// public const int OpusHeadMinSize = 12; /// /// Byte offset of pre_skip within the full OpusHead packet payload (including the /// magic). RFC 7845 §5.1: "OpusHead"(8) + version(1) + channels(1) = 10 bytes before pre_skip. /// public const int OpusHeadPreSkipOffset = 10; /// /// Header size of the serialized seek-index blob: /// totalBytes(8) + duration(8) + count(4) + preSkip(2) + reserved(2) = 24 bytes. /// public const int SeekIndexHeaderSize = 24; /// Size of one serialized seek point: granulepos(8) + byteOffset(8). public const int SeekPointSize = 16; /// Vault-resource extension for the Opus audio bytes. public const string OpusExtension = ".opus"; /// Vault-resource extension for the combined setup-header + seek-index sidecar. public const string SidecarExtension = ".opusidx"; }