Concept
Patterns and time
How a Mora pattern answers questions about spans of cycle time, and how that model relates to tempo, events, and playback.
In Mora, a pattern is a question about time: given an interval, which events appear in it? This page explains that model, the cycle time it is measured in, and why asking a pattern for its events is a different act from hearing it.
Mora follows the span-query approach associated with TidalCycles: a pattern describes the events that appear in a requested interval. A pattern answers a question about a time interval rather than stepping through one permanently consumed list. A short expression can describe a repeating pattern without enumerating every future event.
A pattern is an object that can answer:
What events are visible in this interval?
Mora calls that operation events-in. Rhythms, melodies, parameters, and visual behavior can be built by composing answers to that question. Layering, subdivision, reversal, variation, and harmony all build on the same temporal model.
Common Lisp supplies the surrounding language. Functions, variables, macros, exact ratios, objects, and generic functions are available in the same running image as the patterns. See Common Lisp and CLOS.
An interval, or span, is half-open: it includes its beginning and excludes its end. Time is expressed in cycles, and fractions such as 1/3 and 7/8 can remain exact Common Lisp ratios. Mora’s temporal model is built from these rational, half-open spans and the event queries asked of them.
A cycle is a musical coordinate, not intrinsically a second or a bar. The transport maps cycles to physical time using tempo and beats per cycle.
With four beats per cycle, 140 BPM corresponds to 7/12 cycles per second: 140 beats per minute is 35 cycles per minute, or 7/12 of a cycle each second. Mora exposes BPM directly because musicians should not need to make that conversion to set the tempo. The tempo and transport forms are described in Channels, tempo, and transport.
The basic relationship between what you write and what an output receives is:
source expression
→ evaluated pattern objects
→ a query over a cycle-time span
→ events with values, spans and provenance
→ interpretation by a configured output backendEvaluating a source expression produces pattern objects. A query over a span of cycle time asks those objects for events, and each event carries values, spans, and provenance. Only the last step involves an output backend, which interprets the events. Selected objects from the second step remain available after evaluation; see What remains after evaluation.
An event has both its currently visible span and its whole span. A scheduler may query only a fragment of a note or loop. That query should not turn the fragment into a new full event, change the recording’s pitch, or create another attack by accident.
An onset belongs to the event’s temporal identity. Operators that crop or repeat phrases make explicit decisions about retaining that attack or clipping and retriggering it. This is why score-time looping, audio-file looping, and changing a sample’s playback speed are separate operations. See Arrangement and transitions for phrase-level looping and Samples and slicing for operations on recordings.
Inspecting a pattern or requesting its events does not itself send audio. Playback additionally needs:
- a running transport,
- a channel assignment,
- a backend, and
- a functioning receiver.
For the normal sample and synthesis path, Mora sends timestamped OSC to SuperDirt in SuperCollider. From pattern to audio describes that path, and When something is silent or blank helps when one of these pieces is missing.
Mora’s supplied stochastic combinators derive their choices from stable temporal inputs and seeds. The variation operators themselves are covered in Transformations and groove.
The pattern protocol is open, however. An arbitrary user method can be nondeterministic or violate a provenance convention.
To define your own pattern classes and methods, see Extending Mora.
Source references
Repository-relative paths in the Mora source where these mechanisms are implemented.
-
src/core/pattern.lisp -
src/core/time.lisp -
src/core/event.lisp -
src/runtime/transport.lisp -
src/runtime/channel.lisp