SuperCollider projects
SuperCollider is a programming language for audio synthesis and
computer-aided composition, created in 1996 by James McCartney and now in
its third major version. It’s especially good at interactive music,
including the use of computers onstage as musical instruments. In this,
it’s in the same category as Max/MSP, but SuperCollider is a
text-based, object-oriented programming language with a wide array of
conveniences for audio and musical work:
A lightweight, fast audio synthesis server, controlled by a minimalist
Open Sound Control network interface;
Hundreds of predefined unit generator plug-ins for audio processing;
A rich framework of Patterns and Events for algorithmic composition;
Support for external devices and software via MIDI, OSC, HID and Arduino.
I have been an active user and developer since late 2002. Since then, I have created a number of pieces for myself to perform (with and without other instruments), pieces with other performers on acoustic instruments, and a large project with dancers and video projection (Affectations, whose SuperCollider code runs for 45 minutes without interruption). In addition, I’ve built some extensions that simplify some common tasks.
Some representative SuperCollider music is on my Works page.
Projects
These are a couple of my recent larger projects, which don’t fit into the
categories of compositions or quarks extension libraries (below).
cl-livecode
A live-coding dialect that controls ddwChucklib processes. A compact
language, feasible to type in front of an audience, represents rhythms and
note parameters in a visually expressive way that is then translated into
SC patterns, according to a translation table in the target process. The
performer builds up a library of phrases, which are chosen in turn by a
partially-randomizable sequence. My personal setup uses TouchOSC running on
an Android tablet to make it easier to start and stop processes quickly and
adjust the mix interactively.
Video demo: On Youtube, On Youku (for mainland China)
JITModular
JITModular is an approach to synthesis pedagogy, using SuperCollider’s Just-In-Time Library as a monophonic modular synthesizer. Each “module” (oscillator, filter, envelope generator, LFO etc.) becomes a JITLib NodeProxy, defined by a very short code block whose purpose is instantly clear. JITLib allows NodeProxies to be patched and repatched at will, using simple syntax, and it can display parameters for graphical manipulation automatically. Students can experiment with different arrangements of modules interactively, learning both synthesis and audio programming through a process that feels more like play. A new event type \psSet
and proxy type of the same name make it easy to run SC patterns as if they were analog-style step sequencers.
Example
s.boot;
p = ProxySpace.new.push;
// a stable output location,
// connected (by .play) to the hardware output
~out = { \in.ar(0!2) }; ~out.play;
// a sawtooth oscillator
~osc = { |freq = 60, amp = 0.1|
Saw.ar(freq, amp).dup
};
// connect to output
~osc <>> ~out;
// detune it
~osc = { |freq = 60, amp = 0.1, detun = 1.006|
Mix(Saw.ar(freq * [1, detun], amp)).dup
};
// a filter -- \in.ar(0!2) defines an audio input
~lpf = { |ffreq = 800, rq = 1|
RLPF.ar(\in.ar(0!2), ffreq, rq)
};
// repatch
~osc <>> ~lpf <>> ~out;
// amp envelope
~eg = { |gt = 1|
\in.ar(0!2) * EnvGen.kr(
Env.adsr(0.01, 0.1, 0.6, 0.1),
gt
)
};
~lpf <>> ~eg <>> ~out;
// now too quiet
~osc.set(\amp, 0.2);
// run some notes
TempoClock.tempo = 124/60;
~player = \psSet -> Pbind(
\skipArgs, [\amp],
\midinote, Pseq([Pn(36, { rrand(3, 8) }), 39], inf),
\dur, Pwrand([0.25, 0.5], [0.9, 0.1], inf)
);
// filter eg
~ffreq = 400;
~feg = { |t_trig = 1, freqMul = 25|
var eg = EnvGen.kr(
Env.perc(0.01, 0.1, level: freqMul),
t_trig, levelBias: 1
);
(~ffreq.kr(1) * eg).clip(20, 20000)
};
// patch the filter envelope to the filter's frequency input
~lpf.set(\ffreq, ~feg);
~feg.set(\freqMul, 40);
~lpf.set(\rq, 0.1);
// change the pattern to accent only some notes
~player = \psSet -> Pbind(
\skipArgs, [\amp],
\midinote, Pseq([Pn(36, { rrand(3, 8) }), 39], inf),
\dur, Pwrand([0.25, 0.5], [0.9, 0.1], inf),
\t_trig, Pwrand([0, 1], [0.7, 0.3], inf)
);
// we're done, remove everything
p.clear;
p.pop;
SuperCollider extensions
SuperCollider packages extensions as quarks. I’ve written several.
Note that you can install the lot by executing, in SuperCollider, the
statement Quarks.install("dewdrop_lib");
Large quarks
ddwChucklib: Simplifies performance by bundling complex musical
processes and synth instruments into objects that you can manipulate
with simple commands. All processes effectively have their own local
namespaces, reducing the chance of bugs resulting from the overuse of
global storage. I’ve used this for all my compositions since 2005 and
I’ve had no need to change the basic design since then. See my chapter
in The SuperCollider Book, “Composition for Live Performance
with dewdrop_lib and chucklib,” for details.
ddwCommon: Several small features here, but many of my quarks
use them. One of the most important is GenericGlobalControl
, which
represents a number that is kept in sync between the language and
server. Easy to plug into SynthDefs, patterns, and GUIs.
ddwEQ: A fully-parametric EQ, with an editor panel, that integrates
easily into MixerChannel.
ddwMIDI: A MIDI-input framework that represents message handlers by
function, rather than message type. Recommended for MIDI control of
MixerChannels and Voicers.
ddwMixerChannel: A general-purpose mixing and signal-routing
framework, based loosely on the signal flow in Digital Audio Workstations.
Features include automation, effect inserts, pre- and post-fader sends,
submixes, disk recording, and graphical and MIDI control. (Order of
execution is a common point of confusion in SuperCollider. MixerChannel
handles the majority of scenarios automatically and transparently.)
ddwPatterns: Miscellaneous additions to the library of pattern
classes for generative composition.
ddwPrototype: Implements prototype-based programming to support
object-oriented designs using objects defined (and redefined) at runtime,
without having to reset the interpreter for every change. Musical processes
in ddwChucklib use Proto
for local namespaces. (The base SC class
Environment
supports rudimentary object prototyping, but with some
restrictions. ddwPrototype eases some of those restrictions.)
ddwTimeline: A sequencing framework for large-scale form. A timeline
consists of commands which control some action that should occupy some
time: running a note sequencer, automating a parameter, or any custom
action. Actions may be strictly timed, or wait for a signal from the
performer, supporting interactive musical form. (Unfortunately,
documentation is pending as yet, but it’s a powerful framework that’s
driven my pieces You are already on the far shore, Fantasia on “Liu
Sanjie,” Meditations on “Myu Mhaung Wai Kin” and all 45 minutes of
Affectations.)
ddwVoicer: A voice-stealing note player, suitable for direct MIDI
performance (including MIDI-connected parameter control). Apart from its
MIDI capabilities, it’s useful for controlling the number of synths in
thick chords, and automatically mapping parameters to global controls. A
variant, MonoPortaVoicer
, supports fingered portamento for leads and basslines.
Minor quarks
ddwGUIEnhancements: Primarily recursiveResize for windows and
container views, to shrink to fit the contents. Largely unnecessary now
because of Qt layouts.
ddwPeakMonitor: A graphical monitor for audio signals that watches
the peak value rather than RMS. Useful to check levels for recording.
ddwSensitivity: Modeled after the sensitivity controls in Yamaha
hardware synths, it maps a 0..1 value onto x..1, where x = 1 at 0
sensitivity, and 0 at full sensitivity (1). It’s just a convenient name for
the formula (value - 1) * sensitivity + 1.
ddwStatusBox: Captures SC-language output to the post window and
inserts it into a graphical TextView
, which you can embed into any GUI window.
ddwTemperament: An alternate way of defining tuning systems,
including EqualTemperament
, TuningOffsets
(tuning specified in semitone
deviation from equal temperament), and TuningRatios
(each scale division is
given as a ratio above the root, which is 1:1).