On July 12th 2018, Portuguese saxophonist Henrique Portovedo premiered HOTPO, my new piece for alto saxophone, ensemble, and electronics. The performance was part of the World Saxophone Congress and was given in Blagoje Bersa in Zagreb, Croatia. The Cantus Ensemble was conducted by new music saxophonist extraordinaire Lars Mlekusch. Here’s the programme note:

Hinting at something a little more coarse, the title HOTPO is in fact a completely innocent reference to the Collatz Conjecture. This mathematical proposition, also known by other names, refers to a succession of numbers called the hailstone sequence (or wondrous numbers), because their values usually ascend and descend like hailstones in a cloud.

Though the mathematical proof of the conjecture is complex, the proposition is very simple: Take any positive whole number; if it is even, divide it by two; if it is odd, multiply it by three and add one (hence the acronym Half Or Three Plus One: HOTPO); repeat the process with the result and you will find that no matter which number begins the process, you will always, given enough iterations, reach one.

The algorithm is easy to programme and experiment with plus it produces rather nice images when given different starting numbers and plotted over various iterations. I used the algorithm in this piece to generate section lengths and repeated structures from nine basic rhythm sequences, hence my sequence was 9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1. The piece alternates sections opposing mixed materials (odd section numbers) with obsessively repeated material (even). The numbers are also used for the generation of the sound files triggered during the performance. Despite the rather abstract nature of the generative procedure, the results of the algorithms were developed intuitively and the piece as a whole arises out of and proceeds through a maelstrom of events fitting to the imagery of a hailstorm.

The premiere was prefaced by a rather dramatic and almost catastrophic accident. Poor Henrique had the misfortune of having his saxophone fall off a table and hit the floor just minutes before he was due to go on-stage. In another context that could have been game over but given that there were hundreds of saxophonists milling around the congress, Henrique was able to borrow someone else’s instrument and give it his best shot. Talk about nerves of steel! I don’t think anyone in the audience could have noticed that he had anything but his own prized instrument in his hands. I was performing sound diffusion at the back of the hall and so had no idea that anything untoward had happened. During the performance I had the feeling that Henrique was a little less forceful and dramatic than usual, but I put that down to nerves.

The performance on someone else’s instrument was not made any easier by the fact that the saxophone part consists of an enormous amount of multiphonics, so many in fact that in this piece we have the feeling that the multiphonic is almost the basic sound of the instrument.

In order to blend with the electronics the whole ensemble and soloist are amplified. The electronics themselves consist of stereo sound files triggered during the performance using custom software developed in MaxMSP. A keyboard player does the triggering because each sound, no matter how short or long, is mapped to a specific key over four octaves on a MIDI keyboard. This makes it easier than using single key/pedal triggers when jumping to specific bars during rehearsal. There are however 233 individual sound files so we have to work with ‘sound banks’. These are changed by pressing low C# (C#2) to ascend and low C to descend. Changing banks does not affect sounds already playing and it doesn’t matter how long the notes are held for as ‘note off’ MIDI messages are ignored.

The score can be downloaded but sadly the quality of the recording made during the premiere leaves a lot to be desired so I am not offering it online.

The Hailstone / Collatz Conjecture

The definition of the hailstone algorithm is part of my slippery chicken algorithmic composition software. It’s a very simple procedure that returns a list of the ‘wondrous numbers’ along with their sum. Here’s the Common Lisp code:

(defun hailstone (n)
  (let ((result (loop collect n while (> n 1) 
                   do (setf n (if (oddp n)
                                  (1+ (* 3 n))
                                  (/ n 2))))))
    (values result (apply #'+ result))))

To see the radically different results we get by applying the algorithm to
adjacent numbers, look at the following simple examples:

(hailstone 26)
(26 13 40 20 10 5 16 8 4 2 1)
145
(hailstone 27)
(27 82 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137
 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445
 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438
 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154
 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184
 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1)
101440
(hailstone 28)
(28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1)
330

For more details, see the wikipedia entry on the Collatz Conjecture. You’ll also see there some nice images generated by the algorithm or for now be content with this beauty:

Collatz Conjecture

Wikipedia: “The x axis represents starting number, the y axis represents the highest number reached during the chain to 1.”

The Collatz Conjecture in HOTPO

For HOTPO I settled on 9 as the hailstone argument as this gave me results I could work with both in terms of section durations and repeat structures:

(hailstone 9)
(9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1)
339

There are also only nine single-bar rhythmic phrases (or rthm-seqs in slippery-chicken parlance) in the whole piece, most of which have one or two slight variants. The selection of which rthm-seq to use is a two-forked process. The details are in the code and code comments below but essentially odd-numbered sequences use the procession algorithm to alternate sequences and move gradually from rthm-seq 1 to 9, whereas the even-numbered sequences ‘stick’ on a single sequence, to rather dramatic effect.

Once the structure and score was generated algorithmically, I read it through, as usual, in order to make sense of the piece. I decided some things had to be changed ‘by hand’, hence the use of ‘eingriff functions’ to accomplish this in the code below (Eingriff = intervention in German):

 
;;; The eingriff functions modify quasi-'by hand' data generated by the
;;; hailstone algorithm.
;;;
;;; section is a list of numbers;  is something like '(x 7 x x)
;;; where x means accept the next unused element in the section and a number
;;; refers to the requisite  rthm-seq in the rsp below
(defun eingriff (section model)
  (loop for el in model collect
       (if (numberp el)
           (list 'rests el)
           (pop section))))

;;;  is something like ((1 2 1 2 ...) (2 2 2 2....) ...)
(defun hailstone-rsm-eingriffe (sections &optional verbose)
  ;; letter F
  (setf (seventh sections)
        (eingriff (seventh sections)
                  ;; determined 'by ear' when reading score
                  '(x 7 x x 3 x x x 7 x 3 x 6 x x x x x 8 x x x x 3 x x x x x x
                    x x x 7 x x x 3 x x x x x)))
  (when verbose
    (format t "~%hailstone-rsm-eingriffe: ~a" sections))
  sections)

(defun hailstone-rsm (num-rthm-seqs &optional verbose)
  (multiple-value-bind
        (hs hs-total)
      (hailstone num-rthm-seqs)
    ;; we'll use the first hailstone number to move through a procession (oddsp,
    ;; below) and the second number to repeat a rthm-seq which should be
    ;; different from the last number we just saw from the procession; similarly
    ;; the new move through the procession should not start with the element we
    ;; just repeated
    (let* ((odds (loop for n in hs by #'cddr collect n))
           (odds-total (apply #'+ odds))
           ;; so we going to alternative odd-numbered sections that use the
           ;; procession algorithm to select adjacent rthm-seqs, and even
           ;; sections that merely repeat a rthm-seq
           (oddsp (remix-in (procession odds-total num-rthm-seqs)
                                   :replace t))
           stickers evens
           (result
            (loop for odd in hs by #'cddr
               for even in (cdr hs) by #'cddr
               with o with e
               collect (loop with i1 = t
                          repeat odd collect
                            (if i1
                                (progn (setf i1 nil) (setq o (popnew oddsp e)))
                                (setq o (pop oddsp))))
               do (unless stickers
                    ;; the stickers are the rthm-seqs that we'll 'stick' on
                    ;; i.e. that we'll repeat during the event sections.  NB if
                    ;; hs-total is an odd number we willl have to start over,
                    ;; hence this unless clause (we might exhaust it with popnew
                    ;; below) 
                    (setq stickers (loop for i from 1 to num-rthm-seqs
                                      collect i)))
                 ;; don't repeat the last odd rthm-seq i.e. the repeated seq in
                 ;; the even sections is always a new one
                 (setq e (popnew stickers o))
                 (push even evens)
               collect (loop repeat even collect e)))
           (len-result (length (flatten result))))
      (when verbose
        (format t "~&hailstone: ~a~%odds (procession): ~a,~%  length-odds: ~a, ~
                    odds total: ~a, ~%evens (repeats): ~a, ~
                   ~%length result (num seqs): ~a, sections: ~a"
                hs odds (length odds) odds-total (reverse evens) len-result
                (length result))
        (format t "~&leftover stickers: ~a~%result: ~a" stickers result))
      (when oddsp (warn "hailstone-rsm: odd elements remaining: ~a" oddsp))
      (unless (= hs-total len-result)
        (warn "hailstone-rsm: unequal lengths: ~a ~a" hs-total len-result))
      (hailstone-rsm-eingriffe result verbose))))

The verbose output of the call to (hailstone-rsm 9 t) is given below. This shows the mapping of the numbered rhythm sequences across the whole piece:

hailstone: (9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1)
odds (procession): (9 14 22 34 52 13 20 5 8 2),
  length-odds: 10, odds total: 179, 
evens (repeats): (28 7 11 17 26 40 10 16 4 1), 
length result (num seqs): 339, sections: 20
leftover stickers: (2 3 4 5 6 7 8 9)
result: ((1 2 1 2 3 1 3 1 1)
         (2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2)
         (4 2 1 2 2 2 1 2 3 4 1 3 1 1) (3 3 3 3 3 3 3)
         (5 1 4 4 5 2 3 2 4 4 2 3 3 3 2 1 3 1 4 1 4 2) (1 1 1 1 1 1 1 1 1 1 1)
         (5 1 1 5 1 3 6 4 5 3 5 2 5 4 2 4 2 5 5 2 3 5 4 3 3 3 5 1 2 7 4 1 4 5)
         (4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4)
         (7 2 4 2 7 4 5 1 7 8 5 7 1 6 1 6 3 5 5 3 6 2 7 4 7 5 7 4 5 6 8 2 5 2 8
          3 2 9 6 8 5 6 5 1 7 3 6 4 8 3 8 6)
         (5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5)
         (7 5 4 6 9 4 4 7 9 2 1 2 6)
         (7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
          7 7 7 7 7)
         (9 1 7 6 3 7 6 7 1 9 8 7 6 7 7 6 6 2 8 5) (6 6 6 6 6 6 6 6 6 6)
         (7 5 4 5 1) (8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8) (1 8 2 7 2 5 7 8)
         (9 9 9 9) (7 6) (1))
hailstone-rsm-eingriffe: ((1 2 1 2 3 1 3 1 1)
                          (2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
                           2 2)
                          (4 2 1 2 2 2 1 2 3 4 1 3 1 1) (3 3 3 3 3 3 3)
                          (5 1 4 4 5 2 3 2 4 4 2 3 3 3 2 1 3 1 4 1 4 2)
                          (1 1 1 1 1 1 1 1 1 1 1)
                          (5 (RESTS 7) 1 1 (RESTS 3) 5 1 3 (RESTS 7) 6
                           (RESTS 3) 4 (RESTS 6) 5 3 5 2 5 (RESTS 8) 4 2 4 2
                           (RESTS 3) 5 5 2 3 5 4 3 3 3 (RESTS 7) 5 1 2
                           (RESTS 3) 7 4 1 4 5)
                          (4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4)
                          (7 2 4 2 7 4 5 1 7 8 5 7 1 6 1 6 3 5 5 3 6 2 7 4 7 5
                           7 4 5 6 8 2 5 2 8 3 2 9 6 8 5 6 5 1 7 3 6 4 8 3 8 6)
                          (5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5)
                          (7 5 4 6 9 4 4 7 9 2 1 2 6)
                          (7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
                           7 7 7 7 7 7 7 7 7 7 7 7 7 7)
                          (9 1 7 6 3 7 6 7 1 9 8 7 6 7 7 6 6 2 8 5)
                          (6 6 6 6 6 6 6 6 6 6) (7 5 4 5 1)
                          (8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8) (1 8 2 7 2 5 7 8)
                          (9 9 9 9) (7 6) (1))
((1 2 1 2 3 1 3 1 1) (2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2)
 (4 2 1 2 2 2 1 2 3 4 1 3 1 1) (3 3 3 3 3 3 3)
 (5 1 4 4 5 2 3 2 4 4 2 3 3 3 2 1 3 1 4 1 4 2) (1 1 1 1 1 1 1 1 1 1 1)
 (5 (RESTS 7) 1 1 (RESTS 3) 5 1 3 (RESTS 7) 6 (RESTS 3) 4 (RESTS 6) 5 3 5 2 5
  (RESTS 8) 4 2 4 2 (RESTS 3) 5 5 2 3 5 4 3 3 3 (RESTS 7) 5 1 2 (RESTS 3) 7 4 1
  4 5)
 (4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4)
 (7 2 4 2 7 4 5 1 7 8 5 7 1 6 1 6 3 5 5 3 6 2 7 4 7 5 7 4 5 6 8 2 5 2 8 3 2 9 6
  8 5 6 5 1 7 3 6 4 8 3 8 6)
 (5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5)
 (7 5 4 6 9 4 4 7 9 2 1 2 6)
 (7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
  7)
 (9 1 7 6 3 7 6 7 1 9 8 7 6 7 7 6 6 2 8 5) (6 6 6 6 6 6 6 6 6 6) (7 5 4 5 1)
 (8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8) (1 8 2 7 2 5 7 8) (9 9 9 9) (7 6) (1))

My section-by-section notes on what to accomplish and how to do it are also given below. These ideas drove the development of materials both during the development of the algorithms and the editing of the score. The latter was done via MusicXML output from slippery-chicken imported into Steinberg’s Dorico notation software.

- so the structure is
  - opening: 9: ff, mixed
  - A: 28: ff repeated triplets
  - B: 14: ff, mixed
  - C: 7: ff repeated slap
  - D: 22: p sub. sparse
  - E: 11: ff repeated, opening triplets
  - F: 34: ff: explosions with tails; long rests inserted (so sparse, really)
  - G: 17: ff repeated, only explosions with tails
  - H: 52: ff, phrases: join bars to make slurred connections
    - b 319 and sim.: repeated note/mphonic slaps
  - I: 26: p sub repeated, sparse, cresc (16 phrases) then dim (10 phrases)
  - J: 13: p key clicks, semiq runs for first time (inject some tone)
  - K: 40: p repeated, key click (use (7 3)? occasionaly?)
    - C4 Bf3 C Df Bf: first 4 key clicks with cs5 grace down to note; last Bf
      is a toneless slap
    - or slap mphonic moving to its trill neighbour on next 16th (see sketch)
      - or even transition from lick to slap mp
    - cresc / dim / p sub cresc
    - accel
    - becoming more held
  - L: 20: 1st 16th run; low Bf slaps
    - continuous but with rests after 5plets
  - M: 10: repeated: Bf3 C4 Bf3 pitched slaps
    - or two mphonic slaps
  - N: 5: mphonic slaps followed by trill neighbour (as in sketch for 7)
    - b548 (last bar before O) is in fact the opening notes.
  - O: 16: repeated: just Bf-C mphonic slaps (Weiss #1)
  - P: 8: reinterpration of opening materials but on higher notes/mphonics
  - Q: 4: repeated 16th runs (4x)
  - R: 2: slapped mphonic moving to trill neighbour (as in sketch for 7)
    - followed by 3x 5plet slapped low Bf
  - S: 1: not bar 1 but rising fluttered triplets as in running 16ths, just
    skipping notes to end high
Share Button