Jump to content
  • Sign in to follow this  

    Lesson 21. Mapping, Substituting and Interleaving



    The score-script of this piece begins with a function. It does the same thing as GEN-CHORD, but it is very simplified and at this stage a little easier to explain and use. It's also an example of how a composer with a little knowledge of LISP can write his/her own functions. This function only uses LISP primitives, that is words that are available to everyone using Opusmodus.

    Section A

    The objective with Lesson 21 is to compose a piece using chords derived from pitches. To see how this is done let's take apart the expression called chord-sequence:

    (setf chord-seqeunce 
          (sort-asc ;3
           (gen-bundle (rnd-sum 10 '(2 3) :seed 22 ) ;2 
                       (rnd-order (flatten p-transp) ;1
                       :seed 56)))) 


    Here's the output of the line marked ;1

    => (g4 cs5 gs4 cs5 d5 fs5 cs4 g4 gs4 cs4 c5 c6 c5
         c4 fs4 d4 g5 fs4 cs5 g4 cs5 g5 g4 fs5 c5)


    We've randomised the order of p-tranpose.

    Now evaluate the lines marked ;2 and ;1:

    (gen-bundle (rnd-sum 10 '(2 3) :seed 22)  
                (rnd-order (flatten p-transp) :seed 56))
    => (g4cs5gs4 cs5d5fs5 cs4g4 gs4cs4 
        c5c6c5 c4fs4d4 g5fs4 cs5g4 cs5g5g4 fs5c5))


    Now we can see what GEN-BUNDLE does. It creates chords of 2 or 3 pitches:

     (gen-bundle (rnd-sum 10 '(2 3) :seed 22)  
                 (rnd-order (flatten p-transp) :seed 56)))


    Finally, adding SORT-ASC makes a rising progression for this chord-sequence. To help the next step the output has been placed on the score-script itself and numbered one to ten:

    (setf chd-order '(7 8 4 10 4 3 9 3 6 2 6 2 7 8 10 4))
    (setf chd-play (substitute-map
                    (gen-integer 1 12) chd-order))


    The function SUBSTITUTE-MAP enables the composer to write a progression of chords with chd-order and then substitute that list for chord-sequence:

    => (g4cs5g5 c5c5c6 fs4g5 cs5d5fs5 fs4g5 cs4gs4 . . .)


    Once the new progression is in place the rest of the composition of Section A follows the usual pattern except for the next expression chd-lengths.

    We saw in Lesson 20 the value of the LISP primitive LENGTH. With GET-COUNT we can see how many chords tones we have in each chord because we want the left hand of the piano to play melodically:

     (pitch-melodize (mclist chd-play))
    => ((g4 cs5 g5) (c5 c5 c6) (fs4 g5) (cs5 d5 fs5) . . .))


    So we map with GET-COUNT to find out the length of each list.

    (setf chd-lengths
           (pitch-melodize (mclist chd-play))))
    => (3 3 2 3 2 2 2 2 2 2 2 2 3 3 3 2)


    And with this string of numbers we can make the bass-play variable and get the list/bar length to create the correct metre grouping.

    Section B

    This section uses the INTERLEAVE-MAP function to move the melody and chords between both hands. For an easy example of how it works look up INTERLEAVE-MAP in the documents.

     i-1 '(1 2 1 2) 
     i-2 '(2 1)
     p-1 '(c4 cs4 fs4 g4 c5)
     p-2 '(c5 b4 fs4 f4 c4)
    (interleave-map (list i-1 i-2) (list p-1 p-2))
    => (c4 c5 b4 cs4 fs4 fs4 g4 f4 c4 c5)
    ;(c4       cs4 fs4     g4       c5)
    ;(   c5 b4         fs4    f4 c4   )


    Now here’s INTERLEAVE-MAP being used in Section B:

    (setf i-map
           (list i-1 i-2) 
           (list (span rhy chd-play)  
                 (pitch-transpose 12 bass-play)))))


    Now to use AMBITUS in the interleaved part for the right hand. This moves the melodic pitches of bass-play up into the treble clef:

    (setf i-rh (ambitus '(g4 c6) i-map))
    => ((g3 cs3 g3) (g3cs3g3 c4c4c4 fs3g3)
        (cs3d3fs3 fs3g3 cs3gs3) (c3 c3 c3) . . .))


    When we come to do the same for the left hand we’ll put AMBITUS together with INTERLEAVE-MAP.

    (setf j-map
          (list i-1 i-2)
          (list bass-play (span rhy chd-play))))


    In the expressions for dynamics see how the final dynamic in the list is replaced using POSITION-REPLACE by a triple forte! Remember when counting sections 0 is the starting point. Hence this expression:

    (position-replace (- (length chd-order) 1) '((fff)) . . .)
    (- (length chd-order) 1) 
    => 15


    ;; Function
    (defun gen-bundle (n-bundle pitch-list)
      (mapcar (function (lambda (x) (compress x)))
              (gen-divide n-bundle pitch-list)))
    ;; Section A
    (setf pitches '(c4 cs4 fs4 g4 c5))
    (setf p-transp 
           (pitch-to-integer pitches) 
           (gen-repeat 5 (list pitches))))
    (setf chord-sequence
          (respell (sort-asc 
            (rnd-sum 10 '(2 3) :seed 22)   
            (rnd-order (flatten p-transp) :seed 561)))))
    ;(c4d4fs4 cs4g4 cs4gs4 fs4g5 g4ab4cs5
    ; 1       2     3      4     5
    ; g4cs5 g4cs5g5 c5c5c6 c5fs5 cs5d5fs5)
    ; 6     7       8      9     10    
    (setf chd-order '(7 8 4 10 4 3 9 3 6 2 6 2 7 8 10 4))
    (setf chd-play (substitute-map
                    (gen-integer 1 10) chd-order))
    (setf chd-lengths (get-count (pitch-melodize (mclist chd-play))))
    (setf bass-play (ambitus
                     '(c2 g3) 
                     (gen-divide chd-lengths
                                  -12 (pitch-melodize chd-play)))))
    (setf rhy (span bass-play '(e)))
    (setf rhy-c (get-span rhy))
    (setq rh-1 (make-omn 
                :length rhy-c
                :pitch (span rhy chd-play)
                :velocity '(mp))) 
    (setq lh-1 (make-omn
                :length (length-weight rhy :weight '(4 1) :seed 231)
                :pitch bass-play
                :velocity '(f)))
    ;; Section B
    (setf i-1 '(1 2 1 2))
    (setf i-2 '(2 1))
    (setf i-map
           (list i-1 i-2) 
           (list (span rhy chd-play)  
                 (pitch-transpose 12 bass-play))))
    (setf i-rh (ambitus '(g4 c6) i-map))
    (setf j-map
          (list i-1 i-2)
          (list bass-play (span rhy chd-play))))
    (setf i-lh (ambitus '(g2 c4) j-map))
    (setf i-dyn-k (span rhy (interleave-map
                             (list i-1 i-2) 
                             (list (span  bass-play '(ff)) 
                                   (span rhy '(p))))))
    (setf i-dyn-l (position-replace
                   (- (length chd-order) 1)
                   '((fff)) i-dyn-k :type 'list))
    (setq rh-2 (make-omn 
                :length (length-weight rhy :weight '(4 1) :seed 231)
                :pitch i-rh
                :velocity i-dyn-l))
    (setq lh-2 (make-omn
                :length rhy
                :pitch i-lh
                :velocity i-dyn-l))
    (setq rh-AB (chord-pitch-unique (assemble-seq rh-1 rh-2)))
    (setq lh-AB (chord-pitch-unique (assemble-seq lh-1 lh-2)))
    (setf timesigs (get-time-signature lh-AB))
    (def-score lesson-21
               (:key-signature 'chromatic
                :time-signature timesigs
                :tempo 80
                :layout (piano-layout 'piano-rh 'piano-lh))
       :omn rh-AB
       :channel 1
       :sound 'gm
       :program 'acoustic-grand-piano)  
       :omn lh-AB)


    Screen Shot 2017-12-05 at 17.23.13.png


    Next page Lesson 22. Lengths and Rhythms

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