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.

Reading and running examples

Examples throughout these docs use the public package:

Common Lisp
(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, and cp.
  • 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.

Explore a pattern without audio

Start with make repl. The make repl launcher loads the lower-level SuperDirt system, so load the language explicitly before using its DSL:

Common Lisp
(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 >>:

Common Lisp
(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.

Open Mora Studio

Shell
make studio

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

Play and change a channel

Evaluate these forms one at a time:

Common Lisp
(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-evaluation replaces

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.

Stop a channel or the session

(d1!) is not a stop command. Assign (silence) to stop that channel:

Common Lisp
(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.

Layer independent voices

stack plays patterns simultaneously. Each layer can carry its own parameters:

Common Lisp
(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.

Add visual material

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.

Add your own samples and stems

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:

Common Lisp
(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:

Common Lisp
(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.

Where to go next

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

Documentation

Search the documentation

Results update as you type. Use the up and down arrow keys to choose a result and Enter to open it.