Photo by A. Ariza
In the fall of 1999, Christopher Ariza enrolled in a computer music course at NYU taught by Dr. Elizabeth Hoffman. The primary objective of the course was for the students to become familiar with two common computer music programs: Csound and Max. Ariza focused his time on developing algorithmic compositional systems in Max, eventually realizing that he needed a “more robust” programming language to take his explorations further.
[Two examples of Ariza’s work in Max can be downloaded from his web page. Guido’s Windchime requires MIDI to play interactively (although mp3s of two of Ariza’s own renditions are available); Ignota’s BeatBox uses MSP for real-time synthesis.]
Ariza decided that the answer to his problem was to write a new algorithmic “front end” for Csound. A “front-end” is a program that makes life easier for the user. One function of most front ends for Csound, for instance, is to provide a graphic interface that allows you (the user) to click on buttons to generate code that otherwise you would have to type in by hand.
Writing a Csound file from scratch is both difficult and time-consuming, and so over the years composers and programmers have developed a number of front ends. Csound has been around for a while – it was created by Barry Vercoe in 1985 – and, as its name implies, it was written in the C language. Csound’s advantages lie in the complexity it can handle. Composers can program incredibly elaborate chunks of music, and they can also design their own incredibly elaborate instruments. The disadvantage to Csound is that it does not function particularly well in “real-time.” This is because the program sucks up a large amount of processor power in proportion to the complexity of the code it is handling.
Csound is generally split into two parts: a “score” file and an “orchestra” file. The score file supplies information necessary to schedule sound “events,” while the orchestra file contains the “instrument” data necessary to coax actual sound out of an output device. Front ends exist for both the score and the orchestra files. Athena functions as an algorithmic front end for the score file. By “algorithmic,” Ariza means that his program provides “shortcuts” specifically for composers who think of their music in terms of algorithms. Athena handles surface details such as rhythms, note choices, and dynamics, while still allowing the composer to make large-scale compositional decisions.
Ariza started out writing his front end in C, but quickly abandoned it for the newer Python programming language. Python is actually written in C, but it is a “higher level” language. A “higher-level” language is essentially a powerful short-hand (and, of course, any computer language that uses letters rather than ‘0’s and ‘1’s is already a short-hand of sorts.) Ariza likes Python because it is easy to learn, has a compact and intuitive syntax (Python code is generally one-tenth the length of the equivalent C code), and it includes some built-in features that take care of such important tasks as automatic memory management and garbage collection. Python is an open source language that is free and highly portable, meaning that a program written in this language will be accessible to a large number of people.
Perhaps the most important difference between C and Python, however, is that in Python, programmers can easily write programs that are “object oriented.” Object orientation is an approach to programming that combines “data” and “functions” into “objects” that are deployed in hierarchies. From a single object (or “class”) definition, you can create numerous independent, modifiable, fully functional copies (or “class instances”). Ariza compares an object to a “mini-machine inside the machine.” The advantage to such an approach is that it provides an efficient way to organize larger, more complex programs, and such programs are also easily modified and extended.
Athena is the first object-oriented algorithmic front-end to Csound written in Python. Cmask is an older algorithmic front end, and it has been ported to Python in a version called Pmask. Neither Cmask nor Pmask is object-oriented, however.
Athena also stands out from its colleagues in its dual function as front-end and powerful set class utility. Athena users can easily take advantage of a huge set class (SC) database, a Python “module” (same as a “class” in C++ or Java) containing 342 set classes (all dyads through nonachords) that can be toggled between their non-inverted (Tn) and inverted (Tn/I) forms. Each set class can reference its respective normal form, Forte index, Forte vector, Morris invariance vector, and all n-class subset vectors. (This module can actually be used in any Python program, and can be downloaded from Ariza’s website.)
Ariza has written functions to accomplish standard set class transformations such as retrograding, rotating, and slicing, as well as twenty additional functions to calculate the degree of similarity between two set classes. Seven of these similarity-measuring functions can be used to analyze user-entered strings of set classes, called SinglePaths. These “Path Engines” can be used to analyze SinglePaths either in terms of adjacent SCs or in terms of a “reference” SC to every SC in a Path. Analysis results can be viewed as a SC similarity contour graph.
Below is an example of an SC similarity contour graph showing the results of an analysis of a SinglePath (4-23, 7-12, 3-6, 3-11A, 6-33A, 5-8) using David Lewin’s REL function to compare each of the set classes to a reference set class, 4-23.
Path path: Lewin REL analysis
reference SC: 4-23
sim range |0(min) (max)1|
1.00 4-23 |……………….*|
0.47 7-12 |………*……….|
0.32 3-6 |……*………….|
0.43 3-11A |……..*………..|
0.64 6-33A |…………*…….|
0.23 5-8 |….*……………|
Ariza is working on a way to incorporate information on voice leading into Paths, as well, in collaboration with City University of New York Professor Joseph Straus. This capability would allow you to create a Path that would “pull towards” a final set class not only in terms of pitch-class motion (i.e. a C is a C no matter what octave it is in) but also in terms of actual pitch space, for example. Conversely, of course, you would also be able to analyze a user-entered Path in terms of its voice leading.
The seven Path Engines can also be used to generate MultiPaths. A MultiPath represents a more complicated nest of relationships than a mere Path. To create a MultiPath, you select a Path Engine, enter beginning and ending set classes (either as Forte numbers or as pitch-class sets), and specify a “similarity range,” expressed as a number between 0 and 1. The resulting collection of Paths will all have in common the same beginning and ending set class. Within each Path, adjacent set classes will be related, and every set class will be related to the common final set class. Such a collection of interrelated set classes could form a “network” of pitches for a complex composition, or provide you with a choice of Paths that meet certain criteria.
An Athena Texture requires three pieces of information: a Path, a start time, and an end time. Each Texture represents a chunk of music, be it short or long, which is algorithmically constructed. Generic information on the Texture class is contained in a Python module called “texture_class.py.” Each new Texture module, whether it is “pre-fab” or programmed by the user, is considered a “subclass” because it “inherits” its basic ability to function from “texture_class.py.”
You don’t have to write new Texture modules every day, of course (unless you want to!). Thanks to the wonders of object-oriented programming, you can modify each new “instance” of a Texture module without altering the code of the source module. Each class instance can be specialized, allowing for the greatest possible mileage from both the sub-class (for example, LineGrooves.py) and the class definition (texture_class.py).
With each new Texture class instance, you can enter new values not only for the Path, but also for such attributes as register, rhythm, transposition, and such acoustic properties as stereo panning position and amplitude. You also have control over parameter fields for particular Csound instruments, allowing you to adjust timbre and other instrument-specific features
Running two instances of the same texture with the parameters set to the same exact values can result on different musical realizations, depending on the degree of variability incorporated into those parameters. Running two different instances of the same texture, in which the values of certain parameters have been changed, can result in wildly different music – all without having to write any new Python code. You can even execute multiple texture instances at the same time, by themselves or in conjunction with instances of different textures.
Ariza’s mercuryB is an excellent example of a composition constructed entirely from different instances (31 to be exact) of a single texture, called LineGroove.py. LineGroove is a simple, monophonic texture that works with two user-supplied rhythms. Ariza emphasizes the fact that mercuryB, like any composition in Athena, is not a fixed entity, but rather an “open-work,” a set of potentialities that changes every time the program creates a new score. Click here to be linked to the RealAudio version of one such realization of mercuryB; click here to be linked to a higher fidelity mp3 download.
Why would you ever want to write a new Texture module? With a brand-spanking-new module, you could change the number of parameters available to yourself and other users for modification. You could also add special functions unique to the texture, or incorporate a special database – a translation table for mean-tone tuning, for example, or an Indian tala that would act as a rhythmic constant. These unique features would be present each time you created a new “instance” of that texture.
Each instance (or layered instances) of a Texture can be executed in Athena using a variety of Csound instruments. (As the project develops, users familiar with Csound code will be able to add their own instruments to the Athena Orchestra.) In creating a Texture instance, Athena generates a standard Csound score file, then renders an aiff file using the Csound “Perf” engine and the necessary orchestra file. The resulting sound file can stand alone as a complete piece, or it can be exported into a program like Max/MSP where it you can manipulate it further (in real time, even) within the context of a larger piece.
Ariza’s software is remarkably open and flexible on several levels. To begin with, Athena is free and open-source. “I certainly understand the need for commercial software,” he stressed, “but the interchange of ideas and software [in academia] has allowed for a lot of growth.” Ariza is calling on the computer-savvy public to alert him to bugs in the program, and to contribute Texture modules and Csound instruments.
Ariza states that “Athena allows every user to customize the software to their needs.” Making such “customizability” possible is no mean feat, but it has been made considerably easier by an object-oriented programming language like Python. “What is most important [in Athena] is the breadth of possible musical realizations of the fundamental organizing parameter: the Path, or the succession of set classes.”
An extreme example of this breadth would be the interpretation of a Path solely as rhythm. “You could fix a Texture to produce only one frequency, and you could use the Path the partition the duration,” Ariza explained. A 4-element path would partition a 40-second duration into four 10-second partitions, for instance. Aspects of the set class could even be used to create the rhythm itself; for instance, the Texture could be designed to interpret the set class integers as portions of an established “beat.” If “0” were set to equal one-sixteenth of a “beat,” then the set class (0,2,4) would sound as one sixteenth followed by an eighth followed by a quarter.
Ariza didn’t particularly set out with such flexibility in mind, however. Like Didkovsky with JMSL, Ariza has written Athena primarily with his own compositional work in mind. In the late 1990s, he was “spending a lot of time trying to get interesting ‘vertical’ harmonies from 4-part 12-tone combinatorial groups.” He was preoccupied with finding set class successions that would complete the aggregate through inversion and transposition, but was unhappy with the results. “The [resulting harmonies] were often redundant or Z-related,” Ariza stated.
Problems of twelve-tone harmony led Ariza to the idea of the Path, but in implementing it he “abandoned the twelve-tone mandate.” “Rather than serial or motive-based constructions, I’ve become interested in content groups (set classes).” Ariza describes a Path as a “set of changes.” This set of changes was “the broadest frame” that he could think of that would apply to a wide variety of music. “A Path could be used within the context of functional harmony, but since it is based on the whole gamut of set classes, there is no a priori dependency on [any harmonic system],” he explained.
Python, as an object-oriented language, encourages thoughts of generality first, specialty second. It is a far cry from an older computer language like LISP. LISP is also an object-oriented language (CLOS is the Common Lisp Object System), but there is a noticeable difference in the opacity of the programming syntax. “The syntax of LISP is cumbersome, hard to learn, and not too user friendly,” Ariza laughed. Of course, as difficult as it may be to learn, LISP is correspondingly powerful – it is often the language of choice for artificial intelligence research.
The advantage to newer languages like Java and Python is not that they are necessarily all-powerful, but rather that they are easy to learn, thus making it possible for a wider spectrum of composers to write “computer music” (or write acoustic music with the aid of a computer) without devoting their lives to it. Python, after all, allowed a composer with limited programming skills to write a complex and detailed program in less than a year’s time. The “ease” factor could also have the side effect of inspiring the non-composer – someone like me – to try his or her hand at creating fantastic sound worlds.
The current version of Athena runs on the Macintosh and includes a user interface and editor created with the Tk GUI toolkit. It can be downloaded from Ariza’s site. A helpful “Read Me” file that accompanies the program files provides instructions on how to download Csound, which is necessary to run Athena. Currently, it comes with two modules “LineGroove.py” and “ChordHits.py.”
Over the summer, Ariza will be hard at work on a command-line version that will be portable to any platform that runs Python. He is also planning three new Texture modules: one that creates four-part choral voice-leading; one that creates regular aggregates; and one that uses specific stochastic or chaotic equations to generate musical properties.