Table of Contents

Namespace NAudio.Sequencing

Classes

EventBufferQuery

Stateless per-buffer event query — the dispatch math used by SequencedSampleProvider<T>, exposed as a standalone API for consumers that don't want to route events through a MixingSampleProvider (e.g. a VST3 instrument provider feeding events into a plugin's process() event input).

EventTimeline<T>

An ordered set of timed events with a consumer-defined payload. Events are sorted by tick; events with the same tick preserve insertion order. Internally the timeline is an immutable snapshot array published copy-on-write: mutators (Add(long, T), Clear()) serialise on an internal lock and atomically publish a new array, while queries read the current snapshot lock-free and (via EventsInRangeSpan(long, long)) allocation-free. This trade-off favours the audio thread — timelines are queried every buffer but mutated rarely (user edits) — at the cost of an O(n) copy per mutation, and it means a UI-thread edit can never block or priority-invert the audio thread's per-buffer query.

IdentityPositionTransform

The no-op position transform. Use this when no swing/quantize/humanize is needed.

LiveTempoMap

A tempo map with a single mutable "current" tempo, intended for live consumers (the drum-machine tempo knob, a real-time-input keyboard performance). Past tempo segments are frozen as they are observed; SetTempo(double, long) only changes the future. Writers serialise on an internal lock; readers are lock-free (segment array is swapped atomically).

MusicalTime

Constants and helpers for the canonical tick resolution used by the sequencing primitives. All ticks in ITempoMap, EventTimeline<T>, TimeSignatureMap, and Transport are at CanonicalPpq, regardless of the PPQ in any source file (e.g. a MIDI file). External PPQs must be rescaled at the ingestion boundary.

SequencedSampleProvider<T>

The audio bridge that ties an EventTimeline<T> to a MixingSampleProvider. On each Read(Span<float>) call it delegates to EventBufferQuery for the upcoming buffer's events, invokes the dispatcher delegate with sample-accurate frame offsets, then reads from the mixer to fill the output.

StaticTempoMap

An immutable piecewise-constant tempo curve, intended for content with a fully-known tempo map (a MIDI file, an edited DAW project). Lookups are O(log n) over the segment list.

SwingTransform

A snap-based swing transform: events that sit exactly on an odd grid line are delayed by a fraction of the grid step. Events not aligned to the grid are passed through unchanged (this matches how musicians think of swing applied to a quantised drum pattern).

TimeSignatureMap

An ordered set of time signature segments, used to convert canonical ticks to and from the human-facing bar/beat/tick view. The first segment must begin at tick 0; subsequent segment boundaries must fall on a bar line of the preceding signature.

Transport

Tracks playback position for the sequencing layer. Position is held in both audio frames (the master, since the audio device pulls a frame count) and canonical ticks (derived from the tempo map). Position-mutating methods (AdvanceByFrames(int), SeekTicks(long), SeekFrames(long)) serialise on an internal lock so a UI-thread seek can't race with the audio-thread advance. Position reads (CurrentFrames, CurrentTicks) remain lock-free.

Structs

BarBeatTick

A human-readable musical position. Bar and Beat are 1-based (matching how musicians count); TickInBeat is 0-based.

LoopRegion

A half-open musical loop region: playback wraps from EndTick back to StartTick.

SequencerEvent<T>

An event placed at a musical position (in canonical ticks) with a consumer-defined payload.

TimeSignature

A musical time signature, expressed as numerator over denominator (e.g. 4/4, 3/4, 6/8). The denominator is the actual note value (4 for quarter, 8 for eighth), not the MIDI-file power-of-two exponent.

Interfaces

IPositionTransform

Transforms a nominal event tick into an effective tick. Used to layer swing / quantize / humanize on top of a stored event timeline without rewriting the events. The transform must declare a tight bound on the magnitude of any shift it can apply, so the consumer can over-scan its timeline query (see the architecture doc for why this is essential).

ITempoMap

Maps musical position (in canonical ticks) to and from real time (in seconds). Implementations may be immutable (a static curve built from a MIDI file) or mutable (a live tempo knob that changes the future from now forward).