Guide

SuperDirtMora companion

The SuperCollider companion package behind Mora's prepared audio, including typed instruments, ordered insert effects, continuous modulation, ducking, and submixes.

SuperDirtMora groups Mora’s SuperCollider-side capabilities into one package. This guide explains what it adds to ordinary SuperDirt playback and how prepared audio is described from Lisp: typed instruments, ordered effects, continuous modulation, ducking, and submixes.

What the package includes

SuperDirtMora is built from the repository’s supercollider/SuperDirtMora sources. It includes:

  • managed voice support
  • ordered insert effects
  • sample-loop readers
  • shared modulation
  • instrument and control profiles
  • orbit-level ducking and taps
  • related resource-ownership protocols

Some components, notably live stretch and neural UGens, also need their own separately compiled plugin or runtime. See the optional live-stretch engine and generation and neural instruments. Orbit taps are described under machine listening.

SuperDirtMora works alongside SuperDirt; it is not a replacement audio engine. Installing it does not boot a server, start music, load models, alter devices, or change output routing.

Installation and activation

The package is built and installed separately from Mora’s Lisp dependencies. Build it with make superdirt-package in the Mora checkout, install the printed package directory as a SuperCollider Quark, and recompile the class library during setup. The SuperDirtMora class reference covers installation, attaching the package to a running SuperDirt, optional features, and the class’s methods.

Activating a new class library can require a recompile or restart, so do it during setup rather than during a performance. An installed or updated package takes effect in a running interpreter only after its class library is recompiled.

Preparing audio

Ordinary sample playback remains the ordinary path. The more advanced constructors on this page play only when the companion advertises their capabilities and preparation succeeds; constructing their Lisp description does not prepare native resources.

prepare-audio performs that preparation before assignment, outside temporal querying and the frame renderer. An unsuccessful candidate should leave the previously installed score intact.

Explicit owned preparations return a receipt that can be inspected, released, and reconciled. A receipt identifies resources; it is not a new musical pattern syntax.

Typed instruments

stock-instruments lists the implemented instrument declarations. With :details t, it reports controls, units, bounds, defaults, and native strategies. Stock integrated sources include sine, saw, square, triangle, pulse, supersaw, additive and FM instruments, plus several noise sources.

The instrument-control protocol separates logical controls from the implementation strategy. An integrated voice and a mapped existing synth can therefore both expose typed controls without implying identical native lifetimes or supported targets. The mapped :psin profile, for example, describes an existing SuperDirt instrument rather than replacing its envelope semantics.

Common Lisp
(defparameter *phrase*
  (>> (notes "f3 ab3 c4 eb4")
      (synth :pulse
             :width .3
             :level .12)
      (fx-chain (fx-low-pass 2500)
                (fx-gain .7))))

(d1! (prepare-audio *phrase*))

This example needs the SuperDirtMora companion. The level of synth and fx-gain is linear amplitude; do not confuse it with SuperDirt’s gain control law.

Owned audio tables

Owned audio tables support wavetable and sample instruments and authored PCM. Updating a table publishes a new immutable generation for later voices; voices already sounding retain the generation they captured. Table metadata and server buffer ownership stay internal, so a score does not need raw buffer IDs.

Extended sources

Extended sources include operator FM, harmonic-wave authoring, and bounded bytebeat and ZZFX-style PCM constructors. The finite PCM constructors are not arbitrary live interpreters.

The explicit offline WAV authoring interface is not a complete offline copy of the native SuperDirt engine. Native DSP that it does not support must be supplied by an appropriate renderer or refused; it is not silently omitted.

Ordered insert effects

fx-chain applies native audio processors in the written order. Low-pass filtering before distortion is not equivalent to filtering after it. The current family covers gain, filters, distortion and waveshaping, chorus, phasing, compression, transient shaping, noise, convolution, and reverb, each with a typed parameter contract.

Impulse responses and other external audio assets must be explicitly available.

Continuous LFOs and envelopes

Temporal patterns determine events; continuous DSP modulators determine values during a voice’s life. lfo and adsr can be voice-local or explicitly named and shared:

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*))

These modulators are different from pattern signals such as sine or tri, which remain temporal data. Signals and patterned arithmetic describes those.

Voice-local and shared LFOs

Voice-local LFOs restart with the note. Named shared LFOs retain phase across code and tempo edits. Cycle-based sources freeze when the transport stops, while Hz-based sources can free-run. Rephasing is explicit.

Shared envelopes

A named shared ADSR is configured separately from being triggered or released, and editing its declaration is not itself a gate action. Its active stage and latched settings remain stable; new settings take effect at the documented trigger or note-off boundary. Releasing an envelope fades its consumers but does not stop their source patterns.

Voice and resource lifetimes

Local ADSR release can extend a managed voice’s lifetime after note-off. Shared controls require owned producer and bus lifetimes, and native voice notifications provide the evidence for cleanup. Without that evidence, a resource is kept rather than risk freeing one that is still in use.

Ducking

duck attaches cross-orbit duck triggers to successfully dispatched events. The targeted orbit has its own gain stage after effects.

Common Lisp
(d1! (prepare-audio
      (>> (s "bd*4")
          (duck 1
                :depth .81
                :onset .003
                :recovery .18))))

This is event-triggered sidechain behavior. It does not extract a kick from arbitrary audio.

Submixes

The named submix interface provides bus-send, bus-route, bus-receive, and bus-signal. A send copies audio at its exact chain position while preserving the dry path. A route removes that dry path, so it requires a return if the audio should remain audible.

Waveform modulation

bus-signal exposes the actual waveform for explicitly supported audio-rate modulation targets. It is neither an FFT feature nor an RMS envelope.

Ordering and ownership

The implementation orders producers and consumers and rejects cyclic dependencies rather than quietly inserting a feedback delay. These buses are owned by the audio preparation system; score authors do not allocate raw server bus numbers.

Source references

Repository-relative paths in the Mora source where these mechanisms are implemented.

  • supercollider/SuperDirtMora/Classes/SuperDirtMora.sc
  • supercollider/SuperDirtMora/SuperDirtMora.quark
  • supercollider/SuperDirtMora/HelpSource/Classes/SuperDirtMora.schelp
  • scd/mora-*.scd
  • scripts/build-superdirt-package.py
  • src/audio/
  • src/mini/instruments.lisp
  • src/mini/audio-modulation.lisp
  • src/mini/audio-fx.lisp
  • src/mini/audio-processors.lisp
  • src/mini/audio-ducking.lisp
  • src/mini/submixes.lisp

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.