Jump to content
  • Sign in to follow this  

    Lesson 24. Tonality 1



    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
          (chord-interval-add '(5 7) 
                        (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
                               (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:

     '((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.


    ;; 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)))
    (setf p-group (chord-interval-add
                   '(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))
       :omn (respell p-rh :type :chord)
       :channel 1
       :sound 'gm
       :program 'acoustic-grand-piano)  
       :omn p-lh)
    ;; Assemble score
     '((lesson-24 :start 1 :end 41)
       (lesson-24 :start 40 :end 41)
       (lesson-24 :start 40 :end 41))



    Screen Shot 2017-12-06 at 02.20.08.png


    Next page Lesson 25. Tonality 2

    Go back to Reference page.

    Edited by opmo

    Sign in to follow this  

  • 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

    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

    CLM Examples 0
  • Create New...