Sound, visuals, and listening

One timeline for sound, samples, and shaders.

Mora's scheduler sends sound events to SuperDirt, its shader operators render in Studio's native canvas, and optional listening tools work from measured audio. A composition uses only the facilities it needs, and each section names what that facility requires.

Needed for that capability Optional component

Sound through SuperDirt

  • Needed: SuperCollider and SuperDirt
  • Needed: The sample banks you name

Mora separates the temporal score from the system that renders its events. d1! through d8! install patterns in session channels; a SuperDirt backend lowers the resulting events and sends OSC bundles with future playback timetags. The default backend targets loopback UDP port 57120.

Common Lisp
(bpm 140)

(d1! (>> (s "bd ~ sn [hh hh]")
         (gain .8)))

d1! channel 1 owns one composition

  • (s "bd ~ sn ~")
  • (notes "f2 ~ ab2 c3")
  • (notes "f4 ab4 c5 eb5")

SuperDirt orbits

  • (orbit 0)
  • (orbit 1)
  • (orbit 2)
Channels are not orbits. A Mora channel owns a source pattern; a SuperDirt orbit is an audio output and effect bus. One stack can keep drums, bass, and melody together in the score while routing each to its own orbit. Naming an orbit does not create a hardware output or a DAW track.
Common Lisp
(d1! (stack
       (>> (s "bd ~ sn ~")
           (orbit 0))
       (>> (notes "f2 ~ ab2 c3")
           (s "psin")
           (orbit 1))
       (>> (notes "f4 ab4 c5 eb5")
           (s "psin")
           (orbit 2))))

The mixer provides continuous channel levels and xfade transitions that affect running streams and their tails, while pattern-crossfade shapes newly triggered events. level and xfade act on each channel's configured target orbit; they do not automatically fade every explicit orbit override inside a routed stack like the one above.

From pattern to audio

The SuperDirtMora companion

  • Optional: SuperDirtMora package
  • Optional: Separate plugins for some components

The packaged SuperDirtMora extension groups Mora's SuperCollider-side capabilities: managed voices, ordered insert effects, sample-loop readers, shared modulation, instrument and control profiles, and orbit-level ducking and taps. Ordinary sample playback remains the ordinary path. prepare-audio does preparation before assignment, outside temporal querying and the frame renderer.

Common Lisp
(defparameter *movement*
  (>> (notes "f3 ab3 c4 eb4")
      (synth :pulse
             :width (range .2 .8 (lfo 1/4
                                      :unit :cycles))
             :level .12)
      (fx-chain
       (fx-low-pass (range 500 4000
                           (adsr :attack .02
                                 :decay .15
                                 :sustain .3
                                 :release .2))))))

(d1! (prepare-audio *movement*))
Typed instruments
Stock sources include sine, saw, square, triangle, pulse, supersaw, additive, and FM instruments, plus noise sources. stock-instruments lists them, and :details t reports controls, units, and bounds.
Ordered insert effects
fx-chain applies native processors in written order: filtering before distortion is not the same as after it. This is an audio chain, distinct from the image chain :post.
Continuous modulation
lfo and adsr can be voice-local or explicitly named and shared. Named shared LFOs retain phase across code and tempo edits.
Ducking and submixes
duck attaches event-triggered sidechain behavior. bus-send, bus-route, bus-receive, and bus-signal make up the named submix interface.

Managed features need the SuperDirtMora companion. Live stretch and neural instruments also need their native plugins.

Samples and stems, by role

  • Needed: A user-owned, imported library
  • Needed: Matching banks in SuperDirt

Sample Explorer (Cmd+P in Studio) is a modal search that indexes configured sample roots and cached metadata, so compositions need not carry filenames. Structured queries combine fields such as BPM, duration, kind, and tags, and insertion is context-aware.

Studio's persistent Samples tab, in the inspector pane, shows original names, metadata, tags, and a waveform, and previews a recording at its native tempo and key only when asked. Inserting a registered loop from the current selection writes a keyword stem form, or changes the stem or part call at the cursor in place, without evaluating it.

Sample Explorer queries
bpm:120-140 kind:drum
dur:0.1-2 tag:vocals

loops describes an eligible pool; part and stem construct ordinary temporal patterns from it. A range is not a hidden exact clamp, and each loops call is a complete query: omitted filters are unrestricted, not inherited.

Common Lisp
(loops :bpm-range '(130 150)
       :mode :minor
       :genre '(:drill :trap))

Variants and slices are independent. The first argument after the type selects variants, as an integer or mini notation; the optional string that follows rearranges slices without treating slice numbers as pitches. Omit it and the full loop plays over its native length.

part slice strings follow ordinary Mora cycles by default. In stem, :p follows the recording by default: one cycle of slice notation lasts one source slice, and :timing :cycle selects cycle timing.

Common Lisp
(d1! (stack
       (>> (part :drums 0 "0 1 2 3 4 4 6 7")
           (cut 1))
       (>> (part :bass "<0 1 1>" "0 ~ 2 3 4 ~ 6 7")
           (cut 2))
       (>> (part :melody 0)
           (cut 3))))

stem-stack composes stem lanes: a lane whose recipe and recording are unchanged keeps playing, and a changed lane hands off with a fade on the running audio. Ordinary stack remains the tool for part and general layering. With (loops :group :family), :n selects a family of related recordings and :v one of its members; the default flat view keeps the original numbering.

sync-splice imports Splice content you have already downloaded, with its available metadata, repeatably and incrementally.

Stems and sample libraries

Tempo and key, matched on request

  • Needed: Live-stretch plugin, for matching
  • Needed: Verified source metadata

Global performance targets are separate from library selection. :match t follows global tempo and key; :tempo and :key select one axis, so a drum loop need not claim a tonal key. Matching uses the optional native live-stretch capability, which must be installed and ready.

Common Lisp
(bpm 140)
(key "Fm")

(d1! (stack
       (>> (part :drums 0
                 :match :tempo)
           (cut 1)
           (orbit 0))
       (>> (stem :type :bass
                 :n "<0 1 1>"
                 :match t)
           (cut 2)
           (orbit 1))
       (>> (part :melody 0
                 :filter '(:synth)
                 :match t)
           (cut 3)
           (orbit 2))))

Tempo interpretation accounts for half- and double-time: at 140 BPM, a source labeled 75 BPM can follow a 70 BPM half-time reading instead of being stretched toward 140. Pitch shifting changes tonic, not mode: known major/minor incompatibility is refused, and missing key information is not silently relabeled.

The live-stretch plugin admits a half/double rate window and pitch shifts up to two octaves in either direction. Unsupported combinations are errors, not silent clamps or a lower-quality fallback.

Tempo and key matching

Shader composition is an inspectable program

  • Needed: Mora Studio's OpenGL 4.1 canvas

The visual DSL constructs CLOS operator objects. Generators such as osc, noise, gradient, and solid compose with coordinate, color, blending, and modulation operators through >>. Emission produces GLSL with cached compiled programs and retained bindings.

A visual operator is also a pattern: temporal transforms act on it, and pattern values can drive visual parameters. One channel form separates three responsibilities, and an omitted facet is left alone, so a visual or post-only edit need not replace the running audio pattern.

Common Lisp
(d1! :audio (s "bd ~ sn [hh hh]")
     :viz (>> (osc :freq 36)
              (kaleid 6)
              (rotate :speed .03))
     :post (>> (mora.visual:pixelate :px 128
                                     :py 72)
               (mora.visual:ascii :characters " .:-=+*#%@")
               (mora.visual:edge-glow :amount .6
                                      :radius 1.5)))

Ordered post-processing

Post effects operate on the preceding image, in written order. Implemented stages include ASCII rendering, pixelation, edge glow, bloom, phosphor persistence, scanlines, and chromatic faults. Each occurrence of a history effect owns its own history, and numeric controls can be numbers, temporal patterns, or retained knobs and sliders where supported.

:post chain: pixelate, then ascii

  1. Source
  2. pixelate
  3.          ...---++++++---...                   ...---++++++---...                   ...---++++++---...                   ===%%%######%%%===                   ===%%%######%%%===                   ===%%%######%%%===                ...###+++------+++###...             ...###+++------+++###...             ...###+++------+++###...             :::%%%===++++++===%%%:::             :::%%%===++++++===%%%:::             :::%%%===++++++===%%%:::             ...###+++------+++###...             ...###+++------+++###...             ...###+++------+++###...                ===%%%######%%%===                   ===%%%######%%%===                   ===%%%######%%%===                   ...---++++++---...                   ...---++++++---...                   ...---++++++---...          then ascii

:post chain: ascii, then pixelate

  1. Source
  2.             ...::::::...                        ..:-=++++=-:..                      .:-+*##%%##*+-:.                    .:=+#%%@@@@%%#+=:.                  .:-*#%%%####%%%#*-:.                 .-+#%%#*+==+*#%%#+-.                .:=#%%#+------+#%%#=:.               .-+%@#+--------+#@%+-.               .-*%%*=--====--=*%%*-.               .=*%%*---+**+---*%%*=.               :=#%%+--=+**+=--+%%#=:               .=*%%*---+**+---*%%*=.               .-*%%*=--====--=*%%*-.               .-+%@#+--------+#@%+-.               .:=#%%#+------+#%%#=:.                .-+#%%#*+==+*#%%#+-.                 .:-*#%%%####%%%#*-:.                  .:=+#%%@@@@%%#+=:.                    .:-+*##%%##*+-:.                      ..:-=++++=-:..                        ...::::::...             ascii
  3. then pixelate
Order is part of the program. Post effects operate on the preceding image in written order, so ASCII after pixelation differs from pixelation after ASCII. This schematic is computed by the website from a simple image to show the idea; it is not a capture of Mora's renderer.
Common Lisp
(d1! :post (>> (mora.visual:phosphor :seconds .18)
               (mora.visual:bloom :amount .35
                                  :threshold .8
                                  :radius .35)
               (mora.visual:scanlines :direction :both
                                      :spacing 5
                                      :thickness 1
                                      :opacity .15)
               (mora.visual:chromatic :trigger :kick
                                      :pixels 3)))

An explicit chain replaces a renderer's legacy built-in post effects, not its visual object or geometry. Omitting :post preserves the installed policy, and removing a policy differs from deliberately bypassing it:

Common Lisp
;; Restore the renderer's legacy treatment.
(d1! :post nil)

;; Use an explicit empty chain: no post effects, including legacy effects.
(d1! :post (mora.visual:post-chain))

Follow the score, or measure the sound

  • Optional: cl-mltk
  • Needed: An audio input to analyze

Machine listening is a second direction of flow: rendered audio returns to analysis as measured PCM, FFT magnitudes, band envelopes, and energy.

Optional SuperDirt orbit taps observe dry orbit buses before orbit-global effects and the DAW. Several stems on one orbit remain mixed, so a tap is not an isolated stem.

Common Lisp
(orbit-taps :orbits '(0 1)
            :frames 1024
            :rate 30)

Listening and ML, all optional

  • Optional: Model environments and weights
  • Optional: Per-model license terms

Patterns, sound output, and many visuals need no ML model. Learned tools offer additional ways to find, rank, and generate material, each with its own installation, data, and licensing requirements.

Learned search
MuQ audio embeddings for audio-to-audio similarity, and MuQ-MuLan joint audio and text embeddings for natural-language retrieval. The model weights are licensed CC-BY-NC-4.0.
PHALAR pairing
Local source embeddings and a learned compatibility ranker. Pairing ranks candidates against an anchor recording (pairings) or a captured audible mix (suggest-stems, or inline in the editor, including zen). A shortlist keeps the best-scoring recording from each family, and its scores are model logits, not probabilities.
Generation
conjure generates samples through an explicitly configured local sidecar. Generated audio must enter the configured sound library before it can be played by name.
Neural instruments and proposals
rave and nn.ar need a valid model, plugin support, and explicit preparation. An optional performer assistant proposes score material through a configured local model server.
Explorer query with a learned description
bpm:120-140 nl:dark ambient pad
Common Lisp
(pairings :melody 0
          :with :bass
          :filter '(:synth)
          :limit 8)

(paired :bass
        :with '(:melody 0)
        :rank 0
        :match t)

MIDI and other outputs

  • Needed: A configured receiver or device

MIDI output requires an explicitly selected and configured receiver. Pitch policies make delivery explicit: :quantize rounds and clamps for ordinary MIDI, :strict declines unsupported fractional or out-of-range delivery with diagnostics, :bend uses channel pitch bend shared by simultaneous notes, and MPE allocates member channels for independent note expression.

Common Lisp
(configure-midi 1
                :device "Mora"
                :channel 0
                :pitch-policy :bend
                :bend-range 2)

Optional OSC, MIDI, speech, serial, MQTT, and Csound adapters are enabled through explicit configuration for the devices or services you use.

MIDI and other outputs

Search the documentation

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