Chapter Four: Synthesis

14. A Digital Synthesis Language Sampler


This section features brief overviews of several well-known and well-used digital synthesis languages, both historoical and currently in use. The languages presented are Music V (p.9) (for historic purposes), Csound (p.10), Max (p.11), SuperCollider (p.12), RTcmix (p.13), Kyma (p.14) and ChucK (p.15). The first four plus ChucK are "typing" languages whereby musical attributes and performance are proscribed by text files (or punch cards early on), while both MAX and the Kyma languages have primarily graphic visual programming interfaces. The section first focuses on common concepts and features between them all before examining short samples of each to encourage further exploration of those that fit the reader's needs and imagination. The reader may find it advantageous to skip ahead and read the following chapter on digital audio to understand all concepts discussed here.

There were myriad advantages digital synthesis languages seemingly offered over analog synthesis instruments.  Virtually unlimited numbers of component equivalents like oscillators, envelopes, filters, signal mixing, and voices were possible within memory limitations.  Exact reproducibility, editability and sharability was made famous early by composer and Max Mathews' collaborator Jean-Claude Risset (Bell Labs 1964-1969).  His collection of the various digitally-coded instruments he designed was called “An Introductory Catalog of Computer Synthesized Sounds” and was the quintessential cookbook of computer music for many years following its 1969 publication, even for more modern languages.  It featured brass, drum, gong and many more coded instrument-like templates, but required a thorough knowledge of Music V to implement.

Certain things were lost (compared to analog tape and synthesis composition) for a while as well, such as the ability to create and interactively modify sound in real time, the limitations to composers without high-level computer programming skills to participate unless they had technical assistants like the IRCAM model provided, the limited accessibility to specific mainframe computer models and converters, and the long computational times for even the shortest of examples.  But these all began to moderate if not disappear within two decades of the first 1957 MUSIC program.

Common Language Features

Orchestra-Score Structure: Beginning with the MUSIC-N series of languages developed at Bell Labs beginning in the late Fifties, software author Max V. Mathews (1926-2011) set the early paradigm for digital sound generation as a binary file structure.  The composer would define one or more instruments (what Mathews called instrument units) through lines of code to form an orchestra.  In a separate file or subsequent lines of code called the score, the composer would then play those instruments by referring to a specific instrument and supplying the necessary musical parameters for each note, such as start time, duration, amplitude, frequency and whatever other specific parameters the instrument definition required.  This binary structure continues today through Csound, RTcmix, and SuperCollider.  Even Max and Kyma-defined instruments may be played via a separate MIDI scorefile or real-time MIDI or OSC input.

Unit Generators (ugens or UGens) and arguments: Music V’s instrument units were defined with building blocks famously titled unit generators by Mathews.  These were subsequently called ugens, opcodes, or graphic or text objects in other programs.  A ugen is typically a small program or subroutine that does a specific audio or data modification task. An instrument built with these ugens could be as simple as a single oscillator unit generator and an output unit generator, or be highly complex, with outputs of certain generators feeding the inputs of other generators, for example, to create vibrato with two oscillators, with the output of one ugen feeding into the frequency input of another ugen, similar to what we saw in the analog synthesis modulation section.  Originally there were only a handful of these unit generators in Music V. In Mathew’s book, The Technology of Computer Music, he assigned each a unique symbol to draw the instrument schematics.  The original Music V ugens are listed in the table below, with their modern day Csound and Max equivalent listed as well.

Comparative chart of ugens
OSC oscil cycle simple oscillator
AD2 a1 + a2 MAX_add sum inputs
MLT a1 * a2 MAX mult multiply inputs
OUT out cycle takes an input (or inputs)
and outputs it to the program output(s)
in blocks of samples

Music V also provided:

    RAN, a random signal generator
    ENV, an envelope generator and
    FLT, a filter algorithm

Modern languages have dozens, if not hundreds, of additional ugens or their equivalents.

Ugens, opcodes or objects typically take arguments in a specific order as specified in a user manual.  For example, the Csound oscil  opcode is defined in the manual as:

    avar oscil xamp, xcps [, ifn, iphs]

This means an oscil statement should begin with the variable avar to write the oscillator’s output data to, followed by the opcode’s name (oscil), followed by its amplitude and frequency.  Optional arguments in brackets are the function table number (ifn) to use as the waveform (if omitted, uses a sine wave), and the initial phase angle offset expressed as 0-1 (if omitted, begins at 0 offset).  Previous conversion statements would make it possible to express amplitudes in dB and frequency as pitch classes.

A note about variables

Most synthesis languages allow users to name and define variables, with certain caveats. Csound variable names, for example, start with an a, k, or i depending on the computation rate the user wishes the variable to be computed at. Some names are reserved, but variables like abob, ksue, iheather are legal, though a user might want to use better pneumonics such as afreqmodsig.

At first, it takes some getting used to that a variable, such as avar above, can hold an entire audio signal, but most programs work in passes, whereby each variable value is computed once for each pass (either a sample rate pass or other slower passes) and then written to an output buffer before the next pass begins.

Variables take up memory space, and it is common practice to reassign the value of a previously used variable name in order to conserve memory. So a statement such as:

    abob = abob + 1

puts the newly calculated value of the old abob plus 1 into the new abob and reuses that same memory space.