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).