Guide
Framework examples
A section-by-section walk through examples/mora-framework-intro.mora, a file of small framework demonstrations.
The example file examples/mora-framework-intro.mora contains small, generic demonstrations of patterns, transformations, layers, shader construction, ordered image processing, and inspection. This page walks through each section of the file and explains what each form does.
Open the file in Mora Studio and evaluate one form at a time. The file begins by stating its prerequisites and selecting the mora package:
;;; MORA: SMALL FRAMEWORK EXAMPLES
;;; Evaluate one form at a time in normal Mora Studio.
;;; Sound requires SuperDirt and its bd/sn/hh banks. Shader examples require
;;; Studio's native renderer.
(in-package :mora)The forms deliberately replace the contents of channel 1 as you go. Evaluate them in order and listen or look after each one.
;;; Tempo, mini notation, transformation, and explicit stopping.
(bpm 140)bpm sets the tempo directly. Mora’s time is measured in cycles, a musical coordinate that the transport maps to physical time using tempo and beats per cycle. With four beats per cycle, 140 BPM corresponds to 7/12 cycles per second; Mora exposes BPM so that musicians do not need to make that conversion. See Patterns and time.
(d1! (s "bd [hh hh] sn hh"))d1! immediately assigns live channel 1. s builds a sample pattern from a mini notation string: space-separated elements form a sequence within the current cycle, and [hh hh] subdivides its containing slot. See Mini notation.
(d1! (>> (s "bd [hh hh] sn hh")
(every 4 #'rev)
(gain 0.9)))Re-evaluating d1! replaces the channel’s composition. >> threads a pattern through transformations and clauses from left to right. every is a conditional-application transform; here it conditionally applies rev, which reverses the score in time. (gain 0.9) is a parameter annotation: each existing event keeps its multiplicity while receiving the parameter. See Pipelines and composition and Transformations and groove.
(d1! (silence))Assigning (silence) stops the channel. (d1!) with no pattern is not a stop command, and hush is the session-wide tool when you intend to silence the whole session.
;;; Independent voices, using ordinary sample patterns.
(d1! (stack
(s "bd ~ bd ~")
(s "~ sn ~ sn")
(>> (s "hh*8")
(gain 0.45))))stack plays its patterns as simultaneous voices. In the strings, ~ is a rest and * marks repetition, a faster local occurrence. Only the hh layer passes through >> to receive a gain annotation, so the annotation applies to that layer alone.
stack polyphony is distinct from parameter merging. A parameter annotation joins values onto existing events; stack adds voices. Pipelines and composition explains the difference.
;;; Generic shader construction and ordered image processing.
(d1! :viz (>> (osc :freq 36)
(kaleid 6))
:post (>> (mora.visual:pixelate :px 128
:py 72)
(mora.visual:ascii :characters " .:-=+*#%@")
(mora.visual:edge-glow :amount .6
:radius 1.5)))This channel form has two facets:
:vizselects visual material for the channel form. The visual DSL constructs CLOS operator objects:oscis a generator, andkaleidcomposes with it through>>. Emission produces GLSL with cached compiled programs. A visual operator is also a pattern, so temporal transforms can act on it.:postsupplies an ordered image post-processing chain. Post effects operate on the preceding image in the written order: here pixelation, then ASCII rendering, then edge glow. ASCII after pixelation is different from pixelation after ASCII.
The form has no :audio facet. An omitted facet is left alone, so a visual or post-only edit need not replace an audio pattern already running on the channel.
Supplying an explicit :post chain replaces the renderer’s legacy built-in post effects. It does not replace the underlying visual object or geometry. See Shader composition and Ordered post-processing.
;;; Bypass post-processing without replacing the visual source.
(d1! :post (mora.visual:post-chain))An explicit empty chain deliberately bypasses post-processing, including the renderer’s legacy effects, while the :viz source keeps running. Three cases are distinct:
Form of :post | Meaning |
|---|---|
| Omitted | Preserves the installed post policy. |
nil | Restores the renderer’s legacy treatment. |
An empty chain, (mora.visual:post-chain) | Bypasses post effects, including legacy effects. |
;;; Inspect an ordinary temporal pattern without dispatching sound.
(defparameter *example-pattern*
(>> (s "bd sn")
(fast 2)))This stores a pattern in an ordinary Lisp variable without assigning it to a channel, so nothing is dispatched. (fast 2) changes the pattern’s rate.
(query-cycle *example-pattern* 0)
(mora.core:pattern-summary *example-pattern*)
(mora.core:pattern-children *example-pattern*)query-cycle asks for the events in cycle 0. pattern-summary and pattern-children are structural observation operations: they expose the retained pattern objects and their structure for inspection and tools. A query does not send audio; the object remains available for later queries. See What remains after evaluation.
Source references
Repository-relative paths in the Mora source where these mechanisms are implemented.
-
examples/mora-framework-intro.mora -
src/mini/d-bang-bangs.lisp -
src/visual/emitter.lisp -
src/visual/post-model.lisp -
src/visual/post-backend.lisp -
src/core/pattern.lisp