• # Lesson 24. Tonality 1

## Annotation

Composers are keen to do novel and interesting things with tonality, and Opusmodus has three powerful tonality functions to realise mapping to chords and scales. The Opusmodus system carries within it an extensive list of pre-defined tonalities, but in this piece we're going to create tonalities from the pitch-class-set PCS 4-9 and its complementary form:

```(pcs '4-9 :pitch)
=> (c4 cs4 fs4 g4)

(pcs-complement (pcs '4-9) :pitch)
=> (d4 ds4 e4 f4 gs4 a4 as4 b4)```

First, let's use CREATE-TONALITY to make two scales made from the intervals of PCS 4-9 and its complement.

```(create-tonality scale-1 '(0 1 6 7 12))
(create-tonality scale-2 '(2 3 4 5 8 9 10 11))```

The aim is to map a stream of integers on to each of the tonalities (scale-1 and scale-2). Here is the integer stream:

`=> (9 4 5 11 10 5 10 5 11 10 3 7 5 6 8 1 2 4 10 5 2 7 5 10 1)`

Now we can use TONALITY-MAP to map the tonality on to the stream.

```(setf stream-1
(tonality-map '(scale-1)
(integer-to-pitch stream)))
=> (g4 cs4 cs4 g4 c5 g4 c4 g4 c5 c5 fs4 c5 c5
cs4 g4 cs4 fs4 c4 fs4 c5 cs4 g4 cs4 fs4 c5)```

Let's do the same with scale-2:

```(setf stream-2
(tonality-map '(scale-2 :root d4)
(integer-to-pitch stream)))```

To get the complementary pitches we have to fix a :root d4:

```=> (b4 eb4 e4 b4 d5 bb4 d4 b4 b4 d5 f4 d5 b4 eb4
b4 e4 gs4 d4 gs4 b4 eb4 bb4 eb4 gs4 b4)```

Now to structure the rhythm of the piece:

```(setf bar-lengths '(5 3 4 6 7 5 4 3 7 5))
(setf bar-lengths-addup (find-sum bar-lengths))```

Later we'll see why we need to know just how many beats there are in the collection of bar-lengths. But for now, we use the function FIND-SUM to find out. If we SPAN stream-1 and stream-2 with rhy-a we get a list in sequence:

```(setf str-a (span rhy-a (list stream-1 stream-2)))
=> ((g4 cs4 cs4 g4 c5) (b4 eb4 e4) (g4 cs4 cs4 g4) (b4 eb4 e4 b4 d5 bb4)
(g4 cs4 cs4 g4 c5 g4 c4) (b4 eb4 e4 b4 d5) (g4 cs4 cs4 g4) (b4 eb4 e4)
(g4 cs4 cs4 g4 c5 g4 c4) (b4 eb4 e4 b4 d5))```

Moving to Section B let's use the function HARMONIC-PATH. This is like one of those simple electronic keyboard arpeggiators (!) only written  into a software function.

```(setf sc-1
(harmonic-path scale-1
stream-p :type 'rnd-order :octave '?
:seed 121))
=> (c4 g4 cs4 c4 fs4 c4 g4 cs4 c4 fs4 c4 g4 cs4
c4 fs4 c4 g4 cs4 c4 fs4 c4 g4 cs4 c4 fs4)```

Notice the pattern repeating in the list.

This section uses the CHORD-INTERVAL-ADD function to harmonise notes in both hands, but only on selected sections:

```(setf p-group
(span rhy-1 (list sc-1 sc-2))
:section '(1 3 5 7 9)))```

In Section C the chordal material moves to the right hand. We use the third tonality function - TONALITY-SERIES. This is a little similar to what we did in Section A, sequencing one tonality after an other, only we could use any number of tonalities 'as a series'. The source for the pitch material (to be mapped to our scale tonalities) is quite complex:

```(setf v-mat (gen-accumulate
(rnd bar-lengths-addup :low -1.0 :high 1.0)))

(setf v-ptchs (gen-divide bar-lengths
(integer-to-pitch
(vector-round 0 24 v-mat))))```

The right hand makes chords whilst the left hand plays a stream of pitches in the bass, always corresponding with the changes in tonality at every bar.

Finally, something quite unusual happens at the end. Evaluate and Play and wait for the final bars of the piece to see/hear for yourself:

```(compile-score
'((lesson-24 :start 1 :end 41)
(lesson-24 :start 40 :end 41)
(lesson-24 :start 40 :end 41)))```

This :start and :end feature of COMPILE-SCORE lets the composer play with the ordering and sequencing of a score-script. And this is the tip of the iceberg, as we'll discover in Lesson 27.

## Score

```;; Section A
#|
(pcs '4-9)
=> (0 1 6 7)

(pcs-complement (pcs '4-9))
=> (2 3 4 5 8 9 10 11)

(pcs '4-9 :type :pitch)
=> (c4 cs4 fs4 g4)

(pcs-complement (pcs '4-9) :pitch)
=> (d4 ds4 e4 f4 gs4 a4 as4 b4)
|#
(create-tonality scale-1 '(0 1 6 7 12))
(create-tonality scale-2 '(2 3 4 5 8 9 10 11))

(setf stream (rnd-number 25 0 12 :seed 341))
(setf stream-p (integer-to-pitch stream))
(setf stream-1 (tonality-map '(scale-1) (integer-to-pitch stream)))
(setf stream-2 (tonality-map '(scale-2 :root d4) (integer-to-pitch stream)))

(setf bar-lengths '(5 3 4 6 7 5 4 3 7 5))
(setf bar-lengths-addup (find-sum bar-lengths))
(setf rhy-a (gen-repeat bar-lengths (gen-repeat (length bar-lengths) '((s)))))
(setf rhy-b (mclist (get-span rhy-a)))

(setf str-a (span rhy-a (list stream-1 stream-2)))
(setf str-b (pitch-transpose -24 (mclist (rnd-pick str-a :seed 5676))))

(setf rh-1 (make-omn :length rhy-a :pitch str-a))
(setf lh-1 (make-omn :length rhy-b :pitch str-b))

;; Section B
(setf sc-1 (harmonic-path scale-1 stream-p
:type 'rnd-order :octave '? :seed 121))

(setf sc-2 (pitch-transpose
2 (harmonic-path
scale-2 stream-p
:type 'desc :octave '? :seed 12)))

(setf rhy-1 (gen-repeat bar-lengths (gen-repeat (length bar-lengths) '((s)))))
(setf rhy-2 (mclist (get-span rhy-1)))

'(5 7)
(span rhy-1 (list sc-1 sc-2))
:section '(1 3 5 7 9)))

(setf b-group (pitch-transpose -24 (mclist (rnd-pick p-group :seed 56))))
(setf rh-2 (make-omn :length rhy-1 :pitch p-group))
(setf lh-2 (make-omn :length rhy-2 :pitch b-group))

;; Section C
(setf path (tonality-series (list scale-1 scale-2) :root '(c4 d4)))
(setf v-mat (gen-accumulate (rnd bar-lengths-addup :low -1.0 :high 1.0)))
(setf v-ptchs (gen-divide bar-lengths (integer-to-pitch (vector-round 0 24 v-mat))))

#| Graph
(list-plot v-mat :point-radius 0 :style :fill)
|#
(setf ptchs (filter-repeat 3 (tonality-map path v-ptchs)))
(setf rh-ch (chord-pitch-unique (chordize ptchs)))
(setf lh-bass (pitch-transpose -12 ptchs))
(setf rhy-3 (span lh-bass '((s))))
(setf rhy-4 (mclist (get-span rhy-3)))
(setf rh-3 (make-omn :length rhy-4 :pitch rh-ch))
(setf lh-3 (make-omn :length rhy-3 :pitch lh-bass))
(setf p-rh (assemble-seq rh-1 rh-2 rh-3 rh-1))
(setf p-lh (assemble-seq lh-1 lh-2 lh-3 lh-1))

(setf timesigs (get-time-signature p-rh :group '((5) (7))))

(def-score lesson-24
(:key-signature 'chromatic
:time-signature timesigs
:tempo '(e 140)
:flexible-clef t
:layout (piano-layout 'piano-rh 'piano-lh))

(piano-rh
:omn (respell p-rh :type :chord)
:channel 1
:sound 'gm
:program 'acoustic-grand-piano)

(piano-lh
:omn p-lh)
)

;; Assemble score
(compile-score
'((lesson-24 :start 1 :end 41)
(lesson-24 :start 40 :end 41)
(lesson-24 :start 40 :end 41))
)```

## Notation

Next page Lesson 25. Tonality 2

Go back to Reference page.

Edited by opmo

• ### Introduction to OMN the language

OMN is designed as a scripting language for musical events. It’s not about sounds themselves, it is about their control and organisation in a musical composition. As a linear script rather than a graphic stave, musical events can be transformed, extended, reorganised by powerful computer algorithms. Some sequencers and score writers provide basic algorithms, but they do not represent the way composers now think about the process of music composition. Composing has become such a multi-faceted pro

opmo
OMN The Language 0
• ### Introduction to Opusmodus

Contents A Contemporary Language for Making Music The Parametric World of Music The Parametric Instrument Learning Opusmodus : A Strategy Important Questions: Necessary Answers

opmo
Tutorial Guide 0
• ### CLM Installation

Contents CLM Installation Command Line Tools Load and Compile Instruments CLM Installation Common Lisp Music, by William Schottstaedt is a powerful sound synthesis language implemented in Lisp and C. CLM is essentiall

opmo
CLM Examples 0
×

• Lessons