An Introduction to Collective Algorithmic Music Composition

IN C

Essentially my contribution was to introduce repetition into Western music as the main ingredient without any melody over it, without anything just repeated patterns, musical patterns. - Terry Riley

In C is a semi-aleatoric music composition written by American composer Terry Riley in 1964. It's considered by many as the first minimalist piece of music. In C, consists of 53 numbered musical patterns that are played sequentially an arbitrary number of times by an arbitrary number of performers.

We will now create a script both in JavaScript and Scheme to perform the piece.

JavaScript

First, we will create a Score and Track objects. Each Track will be assigned a name, a channel, a MIDI instrument number and a tempo.

var s = createScore();
var t1 = createTrack("",1,0,160);
var t2 = createTrack("",2,4,160);
var t3 = createTrack("",3,46,160);
var t4 = createTrack("",4,13,160);
var t5 = createTrack("",5,24,160);
var t6 = createTrack("",6,32,160);

Now we will create a new variable that will hold the pitches and note durations in an array of arrays.

var x = [["C4 E4 C4 E4 C4 E4","E E E E E E"],["C4 E4 F4 E4","E E E Q"],["R E4 F4 E4","E E E E"],["R E4 F4 G4","E E E E"],["E4 F4 G4 R","E E E E"],["C5","DW"],["R R R R C4 C4 C4 R R R R R","Q Q Q E S S E E Q Q Q Q"],["G4 F4","W. DW"],["B4 G4 R R R R","S S E Q Q Q"],["B4 G4","S S"],["F4 G4 B4 G4 B4 G4","S S S S S S"],["F4 G4 B4 C5","E E W Q"],["B4 G4 G4 F4 G4 R G4","S E. S S E E. S+H."],["C5 B4 G4 F#4","W W W W"],["G4 R R R R","S E. Q Q Q"],["G4 B4 C5 B4","S S S S"],["B4 C5 B4 C5 B4 R","S S S S S S"],["E4 F#4 E4 F#4 E4 E4","S S S S E. S"],["R G5","Q. Q."],["E4 F#4 E4 F#4 G3 E4 F#4 E4 F#4 E4","S S S S E. S S S S S"],["F#4","H."],["E4 E4 E4 E4 E4 F#4 G4 A4 B4","Q. Q. Q. Q. Q. Q. Q. Q. E"],["E4 F#4 F#4 F#4 F#4 F#4 G4 A4 B4","E Q. Q. Q. Q. Q. Q. Q. Q"],["E4 F#4 G4 G4 G4 G4 G4 A4 B4","E E Q. Q. Q. Q. Q. Q. E"],["E4 F#4 G4 A4 A4 A4 A4 A4 B4","E E E Q. Q. Q. Q. Q. Q."],["E4 F#4 G4 A4 B4 B4 B4 B4 B4","E E E E Q. Q. Q. Q. Q."],["E4 F#4 E4 F#4 G4 E4 G4 F#4 E4 F#4 E4","S S S S E S S S S S S"],["E4 F#4 E4 F#4 E4 E4","S S S S E. S"],["E4 G4 C5","H. H. H."],["C5","W."],["G4 F4 G4 B4 G4 B4","S S S S S S"],["F4 G4 F4 G4 B4 F4 G4","S S S S S S+H. Q."],["G4 F4 R","S S E"],["G4 F4","S S"],["F4 G4 B4 G4 B4 G4 B4 G4 B4 G4 R R R R Bb4 G5 A5 G5 B5 A5 G5 E5 G5 F#5 R R R E5 F5","S S S S S S S S S S E Q Q Q Q H. E Q E Q. E H. E E+H. Q Q E E+H W."],["F4 G4 B4 G4 B4 G4","S S S S S S"],["F4 G4","S S"],["F4 G4 B4","S S S"],["B4 G4 F4 G4 B4 C5","S S S S S S"],["B4 F4","S S"],["B4 G4","S S"],["C5 B4 A4 C5","W W W W"],["F5 E5 F5 E5 E5 E5 E5 F5 E5","S S S S E E E S S"],["F5 E5 E5 C5","E Q E Q"],["D5 D5 G4","Q Q Q"],["G4 D5 E5 D5 R G4 R G4 R G4 G4 D5 E5 D5","S S S S E E E E E E S S S S"],["D5 E5 D5","S S E"],["G4 G4 F4","W. W W+Q"],["F4 G4 Bb4 G4 Bb4 G4","S S S S S S"],["F4 G4","S S"],["F4 G4 Bb4","S S S"],["G4 Bb4","S S"],["Bb4 G4","S S"]];

After defining our variable that contains the musical phrases, we will now use a \textit{for loop} to iterate over the patterns and create

for(var i = 0; i<x.length; i++){
    var section = createSection();
    section.addEvents(x[i][0],x[i][1]);
    t1.addSection(section,random(3,13));
    t2.addSection(clone(section),random(3,13));
    t3.addSection(clone(section),random(3,13));
    t4.addSection(clone(section),random(3,13));
    t5.addSection(clone(section),random(3,13));
    t6.addSection(clone(section),random(3,13));
}

We will now transpose the tracks by different octaves.

t1.transpose(-24);
t2.transpose(12);
t3.transpose(24);
t5.transpose(-12);
t6.transpose(-24);

Finally, we will add the tracks to the Score object and play the MIDI.

s.addTrack(t1);
s.addTrack(t2);
s.addTrack(t3);
s.addTrack(t4);
s.addTrack(t5);
s.addTrack(t6);

s.play();

The final result should look something like this:

// In C - Terry Riley

// create a Score
var s = createScore();

// create the Tracks
var t1 = createTrack("",1,0,160);
var t2 = createTrack("",2,4,160);
var t3 = createTrack("",3,46,160);
var t4 = createTrack("",4,13,160);
var t5 = createTrack("",5,24,160);
var t6 = createTrack("",6,32,160);

// the cells containing the musical patterns.

var x = [["C4 E4 C4 E4 C4 E4","E E E E E E"],["C4 E4 F4 E4","E E E Q"],["R E4 F4 E4","E E E E"],["R E4 F4 G4","E E E E"],["E4 F4 G4 R","E E E E"],["C5","DW"],["R R R R C4 C4 C4 R R R R R","Q Q Q E S S E E Q Q Q Q"],["G4 F4","W. DW"],["B4 G4 R R R R","S S E Q Q Q"],["B4 G4","S S"],["F4 G4 B4 G4 B4 G4","S S S S S S"],["F4 G4 B4 C5","E E W Q"],["B4 G4 G4 F4 G4 R G4","S E. S S E E. S+H."],["C5 B4 G4 F#4","W W W W"],["G4 R R R R","S E. Q Q Q"],["G4 B4 C5 B4","S S S S"],["B4 C5 B4 C5 B4 R","S S S S S S"],["E4 F#4 E4 F#4 E4 E4","S S S S E. S"],["R G5","Q. Q."],["E4 F#4 E4 F#4 G3 E4 F#4 E4 F#4 E4","S S S S E. S S S S S"],["F#4","H."],["E4 E4 E4 E4 E4 F#4 G4 A4 B4","Q. Q. Q. Q. Q. Q. Q. Q. E"],["E4 F#4 F#4 F#4 F#4 F#4 G4 A4 B4","E Q. Q. Q. Q. Q. Q. Q. Q"],["E4 F#4 G4 G4 G4 G4 G4 A4 B4","E E Q. Q. Q. Q. Q. Q. E"],["E4 F#4 G4 A4 A4 A4 A4 A4 B4","E E E Q. Q. Q. Q. Q. Q."],["E4 F#4 G4 A4 B4 B4 B4 B4 B4","E E E E Q. Q. Q. Q. Q."],["E4 F#4 E4 F#4 G4 E4 G4 F#4 E4 F#4 E4","S S S S E S S S S S S"],["E4 F#4 E4 F#4 E4 E4","S S S S E. S"],["E4 G4 C5","H. H. H."],["C5","W."],["G4 F4 G4 B4 G4 B4","S S S S S S"],["F4 G4 F4 G4 B4 F4 G4","S S S S S S+H. Q."],["G4 F4 R","S S E"],["G4 F4","S S"],["F4 G4 B4 G4 B4 G4 B4 G4 B4 G4 R R R R Bb4 G5 A5 G5 B5 A5 G5 E5 G5 F#5 R R R E5 F5","S S S S S S S S S S E Q Q Q Q H. E Q E Q. E H. E E+H. Q Q E E+H W."],["F4 G4 B4 G4 B4 G4","S S S S S S"],["F4 G4","S S"],["F4 G4 B4","S S S"],["B4 G4 F4 G4 B4 C5","S S S S S S"],["B4 F4","S S"],["B4 G4","S S"],["C5 B4 A4 C5","W W W W"],["F5 E5 F5 E5 E5 E5 E5 F5 E5","S S S S E E E S S"],["F5 E5 E5 C5","E Q E Q"],["D5 D5 G4","Q Q Q"],["G4 D5 E5 D5 R G4 R G4 R G4 G4 D5 E5 D5","S S S S E E E E E E S S S S"],["D5 E5 D5","S S E"],["G4 G4 F4","W. W W+Q"],["F4 G4 Bb4 G4 Bb4 G4","S S S S S S"],["F4 G4","S S"],["F4 G4 Bb4","S S S"],["G4 Bb4","S S"],["Bb4 G4","S S"]];

// lets loop over the patterns and
// add them to the tracks.
for(var i = 0; i<x.length; i++){
    var section = createSection();
    section.addEvents(x[i][0],x[i][1]);
    t1.addSection(section,random(3,13));
    t2.addSection(clone(section),random(3,13));
    t3.addSection(clone(section),random(3,13));
    t4.addSection(clone(section),random(3,13));
    t5.addSection(clone(section),random(3,13));
    t6.addSection(clone(section),random(3,13));
}

// transpose the tracks
t1.transpose(-24);
t2.transpose(12);
t3.transpose(24);
t5.transpose(-12);
t6.transpose(-24);

// add tracks to the score.
s.addTrack(t1);
s.addTrack(t2);
s.addTrack(t3);
s.addTrack(t4);
s.addTrack(t5);
s.addTrack(t6);

// save midi
s.play();

Scheme

Now lets try the same piece, but now with the Scheme programming language. First, we will set the tempo and instruments.

;;set tempo and instruments
(set-tempo '((0 0 160)))
(set-instruments '((0 0 2) (1 0 6) (2 0 46) (3 0 8) (4 0 1) (5 0 0)))

We'll now define the pitches and lengths and an index number to identify the pattern.

;;define the musical patterns in a list
(define cells '((0 (C4 E4 C4 E4 C4 E4) (E E E E E E))(1 (C4 E4 F4 E4)(E E E Q))(2 (R E4 F4 E4)(E E E E))(3 (R E4 F4 G4)(E E E E))(4 (E4 F4 G4 R)(E E E E))(5 (C5)(DW))(6 (R R R R C4 C4 C4 R R R R R)(Q Q Q E S S E E Q Q Q Q))(7 (G4 F4)(W. DW))(8 (B4 G4 R R R R)(S S E Q Q Q))(9 (B4 G4)(S S))(10 (F4 G4 B4 G4 B4 G4)(S S S S S S))(11 (F4 G4 B4 C5)(E E W Q))(12 (B4 G4 G4 F4 G4 R G4)(S E. S S E E. S+H.))(13 (C5 B4 G4 F#4)(W W W W))(14 (G4 R R R R)(S E. Q Q Q))(15 (G4 B4 C5 B4)(S S S S))(16 (B4 C5 B4 C5 B4 R)(S S S S S S))(17 (E4 F#4 E4 F#4 E4 E4)(S S S S E. S))(18 (R G5)(Q. Q.))(19 (E4 F#4 E4 F#4 G3 E4 F#4 E4 F#4 E4)(S S S S E. S S S S S))(20 (F#4)(H.))(21(E4 E4 E4 E4 E4 F#4 G4 A4 B4)(Q. Q. Q. Q. Q. Q. Q. Q. E))(22 (E4 F#4 F#4 F#4 F#4 F#4 G4 A4 B4)(E Q. Q. Q. Q. Q. Q. Q. Q))(23 (E4 F#4 G4 G4 G4 G4 G4 A4 B4)(E E Q. Q. Q. Q. Q. Q. E))(24 (E4 F#4 G4 A4 A4 A4 A4 A4 B4)(E E E Q. Q. Q. Q. Q. Q.))(25 (E4 F#4 G4 A4 B4 B4 B4 B4 B4)(E E E E Q. Q. Q. Q. Q.))(26 (E4 F#4 E4 F#4 G4 E4 G4 F#4 E4 F#4 E4)(S S S S E S S S S S S))(27 (E4 F#4 E4 F#4 E4 E4)(S S S S E. S))(28 (E4 G4 C5)(H. H. H.))(29 (C5)(W.))(30 (G4 F4 G4 B4 G4 B4)(S S S S S S))(31 (F4 G4 F4 G4 B4 F4 G4)(S S S S S S+H. Q.))(32 (G4 F4 R)(S S E))(33 (G4 F4)(S S))(34 (F4 G4 B4 G4 B4 G4 B4 G4 B4 G4 R R R R Bb4 G5 A5 G5 B5 A5 G5 E5 G5 F#5 R R R E5 F5)(S S S S S S S S S S E Q Q Q Q H. E Q E Q. E H. E E+H. Q Q E E+H W.))(35 (F4 G4 B4 G4 B4 G4)(S S S S S S))(36 (F4 G4)(S S))(37 (F4 G4 B4)(S S S))(38 (B4 G4 F4 G4 B4 C5)(S S S S S S))(39 (B4 F4)(S S))(40 (B4 G4)(S S))(41 (C5 B4 A4 C5)(W W W W))(42 (F5 E5 F5 E5 E5 E5 E5 F5 E5)(S S S S E E E S S))(43 (F5 E5 E5 C5)(E Q E Q))(44 (D5 D5 G4)(Q Q Q))(45 (G4 D5 E5 D5 R G4 R G4 R G4 G4 D5 E5 D5)(S S S S E E E E E E S S S S))(46 (D5 E5 D5)(S S E))(47 (G4 G4 F4)(W. W W+Q))(48 (F4 G4 Bb4 G4 Bb4 G4)(S S S S S S))(49 (F4 G4)(S S))(50 (F4 G4 Bb4)(S S S))(51 (G4 Bb4)(S S))(52 (Bb4 G4)(S S))))

Now we will define a function that will iterate over the patterns and repeat the pattern x number of times.

;;return a list with the pattern repeated x number of times
(define (iter l f x) 
 (let loop ((n 0)) 
  (if (> n l) '() 
    (append (repeat (f (list-ref cells n)) x) 
 (loop (+ n 1))))))

Now, lets define a function that will call the iter function and lets specify the parameters. We want to iterate 52 times and we want to repeat k number of times the pitches and the durations and add them to a single list.

;; create a list with k times the musical patterns.
(define (create-voice)
 (let ((k (+ (random-integer 4) 5)))
  (list (iter 52 (lambda (x) (cadr x)) k)
  (iter 52 (lambda (x) (caddr x)) k))))

Now, lets define a function that will loop n times, where n is the number of instruments specified as channels. We will transpose the pitches randomly.

(define (make-evs l)
 (let loop ((n 0))
  (let ((v (create-voice)))
    (if (> n l) '() 
      (append (create-events 0 
                    (transpose (pitches->numbers (car v)) 
                    (list-ref '(0 12 -12 24 36) (random-integer 4)))
                    (lengths->numbers (cadr v)) 
                    (create-constant-velocities (pitches->numbers (car v)) 96) 
                    n)
 (loop (+ n 1)))))))

Finally, we call the make-evs function, in this case with 5 different voices and then save the MIDI.

(define evs (make-evs 5))
(save-midi evs)

The final script should look something like this:

;; Terry Riley: IN C

(set-tempo '((0 0 160)))
(set-instruments '((0 0 2) (1 0 6) (2 0 46) (3 0 8) (4 0 1) (5 0 0)))

(define cells '((0 (C4 E4 C4 E4 C4 E4) (E E E E E E))(1 (C4 E4 F4 E4)(E E E Q))(2 (R E4 F4 E4)(E E E E))(3 (R E4 F4 G4)(E E E E))(4 (E4 F4 G4 R)(E E E E))(5 (C5)(DW))(6 (R R R R C4 C4 C4 R R R R R)(Q Q Q E S S E E Q Q Q Q))(7 (G4 F4)(W. DW))(8 (B4 G4 R R R R)(S S E Q Q Q))(9 (B4 G4)(S S))(10 (F4 G4 B4 G4 B4 G4)(S S S S S S))(11 (F4 G4 B4 C5)(E E W Q))(12 (B4 G4 G4 F4 G4 R G4)(S E. S S E E. S+H.))(13 (C5 B4 G4 F#4)(W W W W))(14 (G4 R R R R)(S E. Q Q Q))(15 (G4 B4 C5 B4)(S S S S))(16 (B4 C5 B4 C5 B4 R)(S S S S S S))(17 (E4 F#4 E4 F#4 E4 E4)(S S S S E. S))(18 (R G5)(Q. Q.))(19 (E4 F#4 E4 F#4 G3 E4 F#4 E4 F#4 E4)(S S S S E. S S S S S))(20 (F#4)(H.))(21(E4 E4 E4 E4 E4 F#4 G4 A4 B4)(Q. Q. Q. Q. Q. Q. Q. Q. E))(22 (E4 F#4 F#4 F#4 F#4 F#4 G4 A4 B4)(E Q. Q. Q. Q. Q. Q. Q. Q))(23 (E4 F#4 G4 G4 G4 G4 G4 A4 B4)(E E Q. Q. Q. Q. Q. Q. E))(24 (E4 F#4 G4 A4 A4 A4 A4 A4 B4)(E E E Q. Q. Q. Q. Q. Q.))(25 (E4 F#4 G4 A4 B4 B4 B4 B4 B4)(E E E E Q. Q. Q. Q. Q.))(26 (E4 F#4 E4 F#4 G4 E4 G4 F#4 E4 F#4 E4)(S S S S E S S S S S S))(27 (E4 F#4 E4 F#4 E4 E4)(S S S S E. S))(28 (E4 G4 C5)(H. H. H.))(29 (C5)(W.))(30 (G4 F4 G4 B4 G4 B4)(S S S S S S))(31 (F4 G4 F4 G4 B4 F4 G4)(S S S S S S+H. Q.))(32 (G4 F4 R)(S S E))(33 (G4 F4)(S S))(34 (F4 G4 B4 G4 B4 G4 B4 G4 B4 G4 R R R R Bb4 G5 A5 G5 B5 A5 G5 E5 G5 F#5 R R R E5 F5)(S S S S S S S S S S E Q Q Q Q H. E Q E Q. E H. E E+H. Q Q E E+H W.))(35 (F4 G4 B4 G4 B4 G4)(S S S S S S))(36 (F4 G4)(S S))(37 (F4 G4 B4)(S S S))(38 (B4 G4 F4 G4 B4 C5)(S S S S S S))(39 (B4 F4)(S S))(40 (B4 G4)(S S))(41 (C5 B4 A4 C5)(W W W W))(42 (F5 E5 F5 E5 E5 E5 E5 F5 E5)(S S S S E E E S S))(43 (F5 E5 E5 C5)(E Q E Q))(44 (D5 D5 G4)(Q Q Q))(45 (G4 D5 E5 D5 R G4 R G4 R G4 G4 D5 E5 D5)(S S S S E E E E E E S S S S))(46 (D5 E5 D5)(S S E))(47 (G4 G4 F4)(W. W W+Q))(48 (F4 G4 Bb4 G4 Bb4 G4)(S S S S S S))(49 (F4 G4)(S S))(50 (F4 G4 Bb4)(S S S))(51 (G4 Bb4)(S S))(52 (Bb4 G4)(S S))))

(define (iter l f x) 
 (let loop ((n 0)) 
  (if (> n l) '() 
    (append (repeat (f (list-ref cells n)) x) 
 (loop (+ n 1))))))

(define (create-voice)
 (let ((k (+ (random-integer 4) 5)))
  (list (iter 52 (lambda (x) (cadr x)) k)
  (iter 52 (lambda (x) (caddr x)) k))))

(define (make-evs l)
 (let loop ((n 0))
  (let ((v (create-voice)))
    (if (> n l) '() 
      (append (create-events 0 
                    (transpose (pitches->numbers (car v)) 
                    (list-ref '(0 12 -12 24 36) (random-integer 4)))
                    (lengths->numbers (cadr v)) 
                    (create-constant-velocities (pitches->numbers (car v)) 96) 
                    n)
 (loop (+ n 1)))))))

(define evs (make-evs 5))

(save-midi evs)