Tutorial
First patterns
Query a first pattern without audio, then play, change, and stop a channel in Mora Studio.
This tutorial constructs and queries a first pattern from a plain REPL, then opens Mora Studio to play, change, and stop a channel. It assumes Mora is installed; see Installation and setup.
Examples throughout these docs use the public package:
(in-package :mora)Evaluate one top-level form at a time. Many examples deliberately replace channel contents, so a page of examples is not a startup file to load wholesale.
Examples have different prerequisites:
- Sound-bearing examples need an attached output backend and a working receiver.
- The basic sample examples use the familiar SuperDirt banks
bd,sn,hh, andcp. - Pitched examples need an available instrument named
psin. - Stem examples additionally require a registered local library.
- Managed DSP examples need the corresponding current SuperDirtMora components.
Pure pattern queries can be performed without producing sound. Forms that touch hardware, services, or installation are explicit actions; read them before running them.
Start with make repl. The make repl launcher loads the lower-level SuperDirt system, so load the language explicitly before using its DSL:
(asdf:load-system "mora")
(in-package :mora)
(defparameter *first-pattern*
(s "bd [hh hh] sn hh"))
(query-cycle *first-pattern* 0)
(mora.core:pattern-summary *first-pattern*)
(mora.core:pattern-children *first-pattern*)The result is a pattern object and its events, not an audio file. Time is expressed in cycles. A query asks for events in a span; the object remains available for subsequent queries and inspection.
The string notation is embedded in Lisp rather than replacing it. A pattern held in an ordinary Lisp variable can be threaded through transformations with >>:
(defparameter *changed-pattern*
(>> *first-pattern*
(fast 2)
(every 4 #'rev)))
(query-cycle *changed-pattern* 0)For arbitrary spans, use the lower-level events-in protocol described in Patterns and time.
make studioThe launcher attempts the configured services and opens the native editor.
Evaluate a form with Cmd+Return on macOS or its configured Control equivalent. F10 toggles desktop fullscreen; F11 toggles zen/performance presentation. The Studio keybinding help lists the current shortcuts; see also Keybindings and presentation.
Evaluate these forms one at a time:
(bpm 140)
(d1! (s "bd hh sn hh"))
(d1! (>> (s "bd [hh hh] sn hh")
(gain 0.9)))
(d1! (silence))bpm sets the tempo. d1! immediately assigns live channel 1. The second d1! form replaces the first one’s composition with a subdivided rhythm and a gain annotation. The last form stops the channel.
Re-evaluating a form replaces the addressed material according to its assignment policy. Re-evaluating a channel replaces that channel’s composition; assigning another channel adds another active part.
Editing text alone does not generally install the change. Interactive controls have an explicit, separate policy for performing versus writing code; Inline controls explains it.
(d1!) is not a stop command. Assign (silence) to stop that channel:
(d1! (silence))hush is the session-wide tool when you intend to silence the session rather than one part. MIDI has its own cleanup functions, separate from sound-channel silence. Inspect the transport and backend controls before using stronger panic or recovery operations.
stack plays patterns simultaneously. Each layer can carry its own parameters:
(d1! (stack
(>> (s "bd ~ bd ~")
(gain 0.9))
(>> (s "~ sn ~ sn")
(gain 0.8))
(>> (s "hh*8")
(gain 0.45))))In the mini notation strings, ~ is a rest and * marks repetition, a faster local occurrence, as in "hh*8". Mini notation and Pipelines and composition cover the full notation and layering forms.
Studio supplies the canvas and native GL context. Visual operators and shaders can be described without starting an audio receiver, but measured waveform and spectrum views need an audio input or capture source. If the analysis integration is unavailable, patterns and visuals that do not use measured audio can still be used. See Measured-analysis capture.
Start with complete visual examples: the Framework examples include a shader with an ordered post-processing chain, and Multimodal channel forms explains how :viz and :post behave. Score/event coupling and measured-audio coupling are distinct.
The sample system indexes and imports your own audio. loops selects eligible pools; part and stem construct patterns that read those pools. The repeatable Splice sync workflow and tagging semantics are covered in Stems and sample libraries.
Selection is not pitch or time processing. A broad collection might be selected as:
(loops :bpm-range '(130 150)
:mode :minor)An exact :key or :bpm would narrow the eligible collection. Leave a restriction out when you do not want it. Explicit global tempo and key matching is then requested on the player, rather than built into discovery by filtering everything to one original tempo and key; see Tempo and key matching.
No sample filenames need to appear in the performance form:
(d1! (stack
(>> (part :drums 0)
(cut 1))
(>> (part :bass 0)
(cut 2))
(>> (stem :type :melody
:n "<0 1 1>"
:p "0 ~ 2 3 4 ~ 6 7")
(cut 3))))Variant selection and slicing are separate: :n selects which loop; :p selects its slices. Omitting a slice pattern plays the full loop.
This needs enough eligible variants for each requested type. Missing metadata, an empty filtered pool, and a sound bank absent from SuperDirt are different conditions; When something is silent or blank covers each one.
- Framework examples walks through the public example file, including shaders and ordered image processing.
- Patterns and time explains spans, cycles, and queries.
- Channels, tempo, and transport covers channel ownership and tempo.
- Mini notation and Transformations and groove cover the pattern vocabulary.
- When something is silent or blank gives an ordered checklist for problems.
Source references
Repository-relative paths in the Mora source where these mechanisms are implemented.
-
src/core/pattern.lisp -
src/runtime/transport.lisp -
src/runtime/channel.lisp -
examples/mora-framework-intro.mora