Algorithmic Composition: A Gentle Introduction to Music Composition Using Common LISP and Common Music
Skip other details (including permanent urls, DOI, citation information) :This work is protected by copyright and may be linked to without seeking permission. Permission must be received for subsequent distribution in print or electronically. Please contact : [email protected] for more information.
For more information, read Michigan Publishing's access and usage policy.
Chapter 10: Sets and Tables
A set is a collection of objects. In Common LISP, we can think of a set as a list. Each object in a set is called an element or a member . In algorithmic composition, sets may be manipulated to achieve a compositional result.
10.1 Introduction to Set Theory
The analysis of atonal music using set theory mathematics was codified by Allen Forte in his landmark book, "The Structure of Atonal Music." [Forte, 1973] His theory of atonal music develops a comprehensive framework for the organization of collection of pitches referred to as pitch class sets . A pitch class is an integer in the range 0-11 that represents a symbolic note name. Pitch class assignment in twelve-tone equal temperament is C (or its enharmonic equivalent) is 0, C-sharp (or its enharmonic equivalent) is 1, D-flat (or its enharmonic equivalent) is 2. . . and so on. A pitch class set, or pc set, is a collection of integers representing pitch classes.
Forte grouped pc sets by cardinality . The cardinality of a set is the number of elements in that set. Within each cardinality, pc sets are assigned a unique integer identifier for the prime form of a set. The prime form of a set is the arrangement of pitch classes such that the smallest intervals are at the beginning of the set, the interval between the first and last members of the set is smaller than the interval between the last and first members of the set, and the first pitch class is 0. For example, set 4-1 is comprised of pitch classes (0 1 2 3). The 4 in the pc set name represents the cardinality of the set. The 1 is the unique integer identifier associated with that set. Only pc set 4-1 is comprised of a succession of three minor seconds.
10.2 Set Operations
Common LISP provides a number of functions that perform operations on lists or sets. These primitives are helpful in analyzing or composing music that is based on sets.APPEND, which was first discussed in Chapter 3, is very helpful in manipulating sets.
In the following example, we assign pitch class sets to two global variables 6-1 and 5-2. We use APPEND to create a list of the two pc sets in succession.
In Example 10.2.2, we use major triads on C, F and G as sets. A major triad corresponds to set 3-11 (0 3 7). You may look at the pitch classes and see a c-minor triad or C E-flat G. In set theory, the major and minor triads are equivalent because they reduce to the same prime form. The Common Music declaration vars assigns the lists of symbolic note names to variables that are local to the container. The variables that represent the lists are appended and converted into a cyclic item stream using make-item-stream.
Example 10.2.2: append.lisp
What's the difference between the Common LISP primitive REVERSE and the Common Music macro retrograde ?REVERSE expects a list as input whereas retrograde expects an item stream.
In Example 10.2.4, we use the Common Music function make-item stream to create an item stream of the pitch classes in set 6-1. The Common Music macro retrograde reverses the order of elements in the item stream. The Common Music function read-items shows the result of the retrograded item stream.
Example 10.2.4
Example 10.2.5 uses REVERSE and retrograde in a Common Music generator.
(setf amplitude (item (crescendo from pp to ff in 9))))
In Example 10.2.7, we use NTH to randomly access elements in a set.LET* is used to assign the local variables INDEX, 6-Z36, and OCTAVE. These variables are used to determine the value of the note slot.
The Common LISP predicate MEMBER checks to see if an element is included in a list. If the element is not found in the list, MEMBER returns NIL. If the element is found, MEMBER returns a subset beginning with the found member.
Why is MEMBER considered a predicate if it returns a sublist? Recall that in Common LISP, any non-NIL value evaluates to T.
Example 10.2.9 creates a merge container of generators melody, accompaniment, and final-chord.
The Common LISP primitive INTERSECTION takes two lists as input and returns the intersection of the two sets, that is, a list of the elements common to both sets.
In Example 10.2.10, we take the INTERSECTION of pc sets 6-Z3 and 6-Z36.
Example 10.2.10
The Common LISP primitive UNION takes two lists as input and returns the elements that are found in either set.
Example 10.2.12 demonstrates how the Common LISP set operations INTERSECTION and UNION may be used in algorithmic composition. We use vars to assign pc sets to their set names. Within the vars, we take the INTERSECTION and UNION of set combinations, convert the list to an item stream using make-item-stream, and assign the result to a variable. We use the item stream accessor item to select an item from the item streams and assign that item to a slot.
The Common LISP primitive SET-DIFFERENCE performs set subtraction.SET-DIFFERENCE takes two lists as input and subtracts all of the elements in the first list from those that are in common with the second list.SET-DIFFERENCE returns a list.
The Common LISP predicate SUBSETP accepts two lists a input and returns T if the first list is a subset of the second and NIL if not.
Example 10.2.14
10.3 Tables
Tables are built in Common LISP by making lists of lists. In fact, a table can be thought of as a nested indexed list. In Common LISP, sometimes tables are referred to as association lists or simply a-lists. Consider the table in Figure 10.3.1 that makes a correspondence between pitch class and note name.
Figure 10.3.1: A Simple Table
Pitch Class | Note Name |
0 | C |
1 | C-sharp |
2 | D |
3 | D-sharp |
4 | E |
In Figure 10.3.1, we refer to the pitch class as the key to the table and the note name as its value. For example, key 1 has a value of C-sharp.
The way we represent tables or a-lists in Common LISP are as nested lists. Example 10.3.1 converts the table representation of Figure 10.3.1 to a nested list and assigns it to the global variable *SIMPLE-TABLE*.
Example 10.3.2 demonstrates that Common LISP has stored our table as a nested list.
Example 10.3.2
Now that we have a table stored in memory, we can look-up things in the table. Common LISP performs table look-up using the function ASSOC. When ASSOC is given a key in a table, it returns a list comprised of the key and its corresponding value(s). It may be helpful to think of ASSOC as returning a specified row in a table as a list.
If we want to find the value associated with a particular key, we simply use list functions to point to the element of interest.
Performing table look-up is such a common occurrence, we define a Common LISP function TABLE-LOOK-UP in Example 10.3.4 to simplify the procedure.
We call the function to perform the look-up.
Example 10.3.5
Example 10.3.6 demonstrates how you can use tables into Common Music. We assign a table named table using vars. Notice the syntactical difference between assigning a table using SETF and vars. Like LET and LET*,vars requires the variable value pairs be enclosed in parentheses. After table is assigned using vars, we enter a LET* that randomly generates a pitch class in the range 0-11. The randomly-generated pitch class serves as the key for table look-up. We assign the result of the table look-up to the note slot in the body of the LET* .
Example 10.3.7 integrates many of the concepts we have learned in this chapter and applies them to Common Music.
10.4 Suggested Listening
Late August by Paul Lansky is one in a series of his pieces that explores the conversations of everyday life. In this composition, Paul Lansky recorded a conversation between two Chinese students sometime in late August, 1989. Their processed speech, in conjunction with pitch material motivated by set theory, became the foundation for this composition. [Lansky, 1990], [Simoni, 1999]