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.

    Sign in to follow this  

  • 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

    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

    Tutorial Guide 0
  • Create New...