In C

Assign: Thursday, September 30

Due: Thursday, October 14

Assignment Policies

All assignments are partner assignments. Please make sure to review the policies and guidelines about discussing assignments with those other than your partner. Assignments are usually, but not always, a combination of paper and coded exercises. Please make two submissions (one for paper exercises and one for coded exercises) to Gradescope. Paper exercises are marked with HW to indicate a handwritten question and C to indicate a coded question. Paper submissions can receive an extra 2% bonus if they are typed. Please visit the tools section of the website for more information.

Overview

In this assignment you are going to create a digital implementation of Terry Riley’s piece “In C”. Terry Riley was part of a movement in music called minimalism. “In C” is one of the most famous works from the movement. The general aesthetic is one of slow-changing repetition which is why it is pertinent for an assignment on patterns. We will be using Pbindef to create the patterns in the piece and update them over time.

Step 1: Understand How “In C” Works

Take a look at the score for “In C”. Note that there is a page with melodic fragments as well as two pages of instructions about those fragments.

A typical performance of “In C” calls for roughly 35 instruments though I have played the piece in much smaller ensembles. In our implementation of the piece we are going to create 3-4 “performers”. Each performer plays through the 53 patterns in order repeating each pattern multiple times before moving onto the next pattern. For our purposes, 53 patterns is too many for the scale of this assignment. Typically performances can last up until an hour! Therefore, we will selectively choose the following patterns to implement in order: 1, 3, 4, 5, 6, 7, 8, 50, 51, 52, 53. Our performance should only last on the order of 3 - 4 minutes.

To start out, I recommend taking a listen to a recording or two of the piece: https://www.youtube.com/watch?v=DpYBhX0UH04.

If you are confused at all about how the piece works, you should stop and ask questions before moving on.

Step 2: Understanding the Starter Code

Download the starter code. Write your name and your partner’s name at the top (if applicable). Start out spending some time looking over the starter code. You’ll need to know what you are given before you can begin. It is imperative that you have an understanding of all the starter code before you even write a line of your own code.

At the top, you are given four SynthDefs:

Step 3: Getting the Pulse to Play

To get going, first create a TempoClock and select a tempo for your piece. You can listen to various recordings to get a sense for common performance tempos but I leave the creative choice to you! You will need to assign your clock to a global variable to refer to it later in your code. Please use ~clock. You’ll notice that the pattern given to you assumes that it is ~clock.

Next create a reverb synth and an audio bus to route sound to the reverb synth. The SynthDef for the reverb has been provided. You simply need to instantiate it. Please use the global variable ~reverbBus for the audio bus. You’ll notice that the pattern given to you assumes that it is ~reverbBus.

If you have done these two steps correctly, you should be able to boot the server, run the block for the SynthDefs and your tempo/reverb, and the pattern called \cPulse to get a constant stream of high C’s.

Note that the reverb has an argument for mix with a default value of 0.4. Feel free to change that value to something between 0 and 1. A value of 1 is going to be heavy reverb and 0 will be no reverb.

Under the section “CLEANUP”, write a code block to stop the \cPulse pattern and remove all Pbindef references. Refer to your notes for help with the latter.

Step 4: Adding Instruments

The next step is to understand the data held in the variables ~pat1 and ~pat3. Each melodic pattern for “In C” is defined as an array of arrays where the inner arrays represent a single note. As an example look closely at the value of ~pat3 (i.e., [[Rest(), 0.5], [3, 0.5], [4, 0.5], [3, 0.5]]) and the third pattern from the score. The first inner array [Rest(), 0.5] represents the eighth note rest where the first element is the pitch (in this case, no pitch because it is a rest) and the second element is the duration in beats. The second inner array [3, 0.5] represents the eighth note E where the first element is the degree from the C major scale and the second element is the duration.

In music, scale degrees are a way to refer to the notes in a scale irrespective of octave. Notice how in the image below that middle C (i.e., the first note picture below) has scale degree 1 and so does the C an octave above (i.e, the last note pictured below). Any major scale always has seven degrees starting from the root of the scale.

A picture of C major scale degrees

Why structure our patterns around scale degrees? The piece is designed to be played by many instruments that have different ranges. All that matters in “In C” is that each performer plays the right note from the scale. Octave is not important.

Fortunately, SuperCollider is well adept at working with scale degrees. The careful student will recognize that \degree is one of the default keys from events that can be used to set the frequency of a SynthDef. Below shows how a Pbindef could use one of our array of arrays to produce the correct frequency and duration. Notice how we create a key called \melody that we can use to cycle through our array of arrays to get each inner array. We can refer to that inner array assigned to the key \melody using Pkey and extract the degree and duration through .collect. When .collect is used on a pattern, it applies a function to the value in the pattern. In the example below, we use the function in .collect to extract each value from the array. The subtracting by one is used in \degree simply because degrees are 0 indexed in SuperCollider as opposed to 1 indexed as is the convention in music theory.

Pbindef(
  \test, // name of the pbindef

  // Other key/value pairs like the instrument, amplitude, etc.

  \melody, Pseq(~pat3, inf), // Will extract an array of two items [degree, duration] from the pattern ~pat3
  \degree, Pkey(\melody).collect({|pair| pair[0] - 1}),
  \dur, Pkey(\melody).collect({|pair| pair[1]}),
)

Your next step is to start three or more patterns to create “performers” for your piece. Each performer should begin by playing the pattern defined in the variable ~pat1.
Ensure that all sounds are directed to the reverb synth. Give appropriate names to each of the performers. Give each performer a distinct octave so notes do not overlap.

Stop and test to make sure this works. Do all three or more performers work? Can each of them play ~pat1?

Finally, in your code block for “CLEANUP”, make sure to stop the patterns you created.

IMPORTANT DEBUGGING TIP: Pbindefs are registered in a global variable that persists even after doing a hard audio quit using CMD + “.”. When you are getting ready to retest, make sure to run Pbindef.clear so that you have a fresh slate. If not, there may be instances, depending upon what you do, where certain patterns do not play or use older values.

Step 5: Creating Additional Patterns and Updating Patterns

After you have successfully created all of your performers, fill out the rest of the patterns for the piece using the array of arrays notation as exemplified by ~pat1 and ~pat3. The patterns should go underneath ~pat1 and ~pat3.

The bulk of the work for this assignment is to use Pbindefs to update each performer to the next pattern. You will also want to adjust arguments to the synths produced to create interest in your piece. Seeing the Grading criteria below for more details.

This is your first opportunity to execute music dynamically. Each Pbindef is meant to be executed one at a time at the discretion of the SuperCollider user. Linger on a pattern for a while or move through a series of pattern updates quickly. There’s a lot of room for creativity here. Have fun!

One final note: you will notice that the scale for the piece changes in the later patterns (note the presence of Bb!). To change the scale, you can update the \scale key in the Pbindef and set it to a new scale using the Scale class.

Step 6: Perform the Piece

Once you have implemented all the patterns, spend some time practicing executing each pattern in order. When you have a feel for the piece in SuperCollider and you have settled on the musical choices you have made, record the piece.

To record, run the two code blocks under the header “RECORDING”. This will capture the sound as you execute the piece in SuperCollider. When you are done recording, execute the code block under “STOP RECORDING”. You should have a file called “inC.wav”. Send that file to me by email. I want to hear your musical vision in action!

IMPORTANT: You should record a performance of the piece and send it to me at adavis15@wellesley.edu. You must submit a performance in order to receive full credit for the problem set.

Grading

The grading of your piece will be judged on several different criteria. Your piece should satisfy the following implementation requirements:

Additionally, you should endeavor to make your implementation of “In C” as musical as possible. Your code should also satisfy the following musical requirements:

Finally, a small portion of the grade will be used to assess the style and readability of your code. Add comments to state important musical moments.

Submission

Feedback

When you are finished with the problem set, please fill out the form linked here to provide feedback on how long the problem set took you and how difficult you found it. Note that you must fill out this form to receive credit for the problem set.

Submission Guidelines

All assignments in this course are submitted through Gradescope. There are two kinds of assignments in this course: paper assignments and code assignments. Both are submitted to Gradescope. Most assignments are a mix of code and paper assignments. Each question or question part will be marked either “code” or “paper” to indicate which kind of question it is. For paper assignments, note that typed answers will receive a small additional bonus of 2%.