# Harmony

Now it is not my aim to present such a theory or even a theory of harmony, nor do I possess enough ability and knowledge to do so; I am rather simply trying to present the harmonic means of music in such a way that they can be directly applied in practice. - Arnold Schoenberg, Theory of Harmony.

When we play multiple notes at once we generate a chord. Harmony is concerned with chord construction and progressions. In Scripthica, generating chords is a simple as embedding a list of the chord notes within the musical pattern. For example if we only want to create a sequence of two chords we simply would do the following:

``````(define pitches '((60 62 66)(64 66 68)))
(define durations '((2000 2000 2000) (2000 2000 2000)))
(define vels '((96 96 96)(96 96 96)))
(save-midi (create-events 0 pitches durations vels 1))
``````

We can rotate the list to get a chord inversion.

``````(rotate '(60 70 80) 1)
;; => (80 60 70)
``````

## create-chord

The create-chord procedure allows us to construct chords. We can specify a MIDI pitche number and the type of chord we want to construct and the function will return a list with the respective numbers that construct the chord.

``````(create-chord 50 "maj")
;; => (50 54 57)
(create-chord 50 "min")
;; => (50 53 57)
(create-chord 50 "aug")
;; => (50 54 58)
(create-chord 50 "dom")
;; => (50 54 57 60)
(create-chord 50 "dim")
;; => (50 53 56)
(create-chord 50 "min7")
;; => (50 53 57 60)
(create-chord 50 "maj7")
;; => (50 54 57 61)
``````

We can also specify the note and we will get a list with pitch symbols.

``````(create-chord "c4" "maj")
;; => (C4 E4 G4)
(create-chord "c4" "min")
;; => (C4 Eb4 G4)
(create-chord "c4" "dim")
;; => (C4 Eb4 Gb4)
(create-chord "c4" "min7")
;; => (C4 Eb4 G4 Bb4)
``````

## Random chord sequence generator

We are going to create a small script that generates random chord sequences.

First, lets set the tempo and set an instrument.

``````(set-tempo '((0 0 82)))
(set-instruments '((1 0 6)))
``````

Lets define lists with the types of chord and lengths we want to choose.

``````(define chord-type '("maj" "min" "aug" "dim"))
(define chord-lengths '((3000 3000 3000)
(2000 2000 2000)
(4000 4000 4000)))
``````

We can now create a function that will create a random chord n number of times.

``````(define (chord-seq n)
(if (= n 0) '()
(append (list
(list
(create-chord
(+ 60 (random-integer 15))
(list-ref chord-type (random-integer 4)))
(list-ref chord-lengths (random-integer 3))))
(chord-seq (- n 1)))))

(define seq (chord-seq 15))
``````

Every time we call chord-seq it will return a different chord.

``````(chord-seq 1)
;; => (((74 77 81) (3000 3000 3000)))
(chord-seq 1)
;; => (((70 73 76) (4000 4000 4000)))
(chord-seq 1)
;; => (((73 76 79) (4000 4000 4000)))
(chord-seq 1)
;; => (((63 67 70) (4000 4000 4000)))
(chord-seq 1)
;; => (((71 75 78) (3000 3000 3000)))
``````

We can create two new functions that will separate the list that contains the durations and the pitches. We also rotate the chord just to make it more interesting.

``````(define (p-seq seq)
(if (null? seq) '()
(append (list (rotate (caar seq) 1)) (p-seq (cdr seq)))))

(define (d-seq seq)
(if (null? seq) '()
(append (cdar seq) (d-seq (cdr seq)))))
``````

Finally, we can define our pitches, durations and velocities to create the MIDI events.

``````;pitches
(define p (p-seq seq))

;durations
(define d (d-seq seq))

;velocities
(define v (create-constant-velocities p 127))

(save-midi (create-events 0 p d v 1))
``````

The complete code:

``````(set-tempo '((0 0 82)))
(set-instruments '((1 0 6)))

(define chord-type '("maj" "min" "aug" "dim"))
(define chord-lengths '((3000 3000 3000)
(2000 2000 2000)
(4000 4000 4000)))

(define (chord-seq n)
(if (= n 0) '()
(append (list
(list
(create-chord
(+ 60 (random-integer 15))
(list-ref chord-type (random-integer 4)))
(list-ref chord-lengths (random-integer 3))))
(chord-seq (- n 1)))))

(define seq (chord-seq 15))

(define (p-seq seq)
(if (null? seq) '()
(append (list (rotate (caar seq) 1)) (p-seq (cdr seq)))))

(define (d-seq seq)
(if (null? seq) '()
(append (cdar seq) (d-seq (cdr seq)))))

;pitches
(define p (p-seq seq))

;durations
(define d (d-seq seq))

;velocities
(define v (create-constant-velocities p 127))

(save-midi (create-events 0 p d v 1))
``````