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.
(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)
(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.
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.
(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-instrumentslists them, and:details treports controls, units, and bounds. - Ordered insert effects
-
fx-chainapplies 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
-
lfoandadsrcan be voice-local or explicitly named and shared. Named shared LFOs retain phase across code and tempo edits. - Ducking and submixes
-
duckattaches event-triggered sidechain behavior.bus-send,bus-route,bus-receive, andbus-signalmake 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.
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.
(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.
(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.
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.
(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.
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.
(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
- Source
- pixelate
- then ascii
:post chain: ascii, then pixelate
- Source
- ascii
- then pixelate
(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:
;; 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
- Pattern
- Scheduled events and shared metadata
- Visuals (co-emit, event envelopes)
A kick event supplies an exact scheduled moment; shared metadata, event envelopes, and co-emit can preserve the relation through temporal transformation.
- Pattern
- SuperDirt renders audio
- Captured input or orbit tap
- cl-mltk analysis
- Visuals (scope, spectrum)
The rendered spectrum contains information that was not in the source event. It needs a real, configured signal.
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.
(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
-
conjuregenerates 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
-
raveandnn.arneed a valid model, plugin support, and explicit preparation. An optional performer assistant proposes score material through a configured local model server.
bpm:120-140 nl:dark ambient pad
(pairings :melody 0
:with :bass
:filter '(:synth)
:limit 8)
(paired :bass
:with '(:melody 0)
:rank 0
:match t)
Learned search PHALAR stem pairing Samples inspector Generation
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.
(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.