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