Harm Visser’s examples

In Computer Music Journal 22,2 (1998) page 63, Dutch com­pos­er Visser commented:

I think that the devel­op­ment of more and more visu­al stuff cur­tails the pos­si­bil­i­ty of “think­ing in your chair.” Sometimes I devel­op gram­mars, not at the com­put­er, but sit­ting with a pen­cil and paper. With pro­grams [oth­er than BP2] this is not pos­si­ble: you must sit in front of the com­put­er. The dif­fer­ence lies in the type of atten­tion that each soft­ware envi­ron­ment demands on the part of the com­pos­er, and indeed reflects on the way s/he thinks about music.

The fol­low­ing is a pre­sen­ta­tion and dis­cus­sion of a few exam­ples com­posed on Bol Processor by Harm Visser in 1998. Versions of ‘BP2’ com­pli­ant with Macintosh sys­tem ver­sions up to MacOS 10.14 (Mojave) can be dowloaded from SourceForge. The pack­age con­tains all gram­mars men­tioned in this article.

A new ver­sion com­pli­ant with 64-bit proces­sors on var­i­ous sys­tems (MacOS, Windows, Linux…) is under development.

Period notation

In the same way it deals with super­im­posed sequences, the poly­met­ric expan­sion algo­rithm works out equal sym­bol­ic dura­tions between beat sep­a­ra­tors notat­ed ‘’ — name­ly the peri­od nota­tion.  A note sequence in peri­od nota­tion and the context-free gram­mar it orig­i­nat­ed from are shown below.  In this exam­ple, beats con­tain increas­ing num­bers of notes result­ing in an accel­er­at­ing movement.

S --> _vel(60) A B _vel(65) C D _vel(70) E F _vel(75) G _vel(77) H _vel(80) I _vel(85) J _vel(87) K _vel(90) L
A --> E2
B --> D2 A
C --> B2 B
D --> G2 C
E --> F#2 D
F --> A#2 E
G --> C2 F
H --> G#2 G
I --> A2 H
J --> D#2 I
K --> C#2 J
L --> F2 K

The “_vel” oper­a­tor is a con­trol of veloc­i­ty pro­duc­ing a step­wise increas­ing vol­ume of the piece. This gram­mar yields the fol­low­ing “score”:

_vel(60) E2 • D2 E2 •_vel(65) B2 D2 E2 • G2 B2 D2 E2 • _vel(70) F#2 G2 B2 D2 E2 • A#2 F#2 G2 B2 D2 E2 • _vel(75) C2 A#2 F#2 G2 B2 D2 E2 • _vel(77) G#2 C2 A#2 F#2 G2 B2 D2 E2 • _vel(80) A2 G#2 C2 A#2 F#2 G2 B2 D2 E2 • _vel(85) D#2 A2 G#2 C2 A#2 F#2 G2 B2 D2 E2 • _vel(87) C#2 D#2 A2 G#2 C2 A#2 F#2 G2 B2 D2 E2 • _vel(90) F2 C#2 D#2 A2 G#2 C2 A#2 F#2 G2 B2 D2 E2 •

and the fol­low­ing piano-roll rep­re­sen­ta­tion with the sound exam­ple on a Pianoteq syn­the­siz­er:

Serial tools

The fol­low­ing gram­mar pro­duces a 10-minute musi­cal piece with only 12 rules and 3 notes (C3, D4, F#3). It is an illus­tra­tion of Visser’s mot­to: “com­pos­ing with a pen­cil and paper”.

The rhyth­mic intri­ca­cy is the result of using poly­met­ric expres­sions: super­im­po­si­tion of sequences list­ed between curled brack­ets {} and resiz­ing “beats” thanks to the peri­od mark­er ‘’.

The length and com­plex­i­ty of the piece is achieved by the use of recur­sive rules. For instance, rule gram#2[2] pro­duces “Mel1” that will be rewrit­ten again by rule gram#2[1].

Three “ser­i­al tools” are used:

  • _transpose(n) shifts up the fol­low­ing sequence by n semitones
  • _rotate(x) rotates the fol­low­ing sequence by x units
  • _keyxpand(basenote, ratio) mul­ti­plies melod­ic inter­vals with ratio rel­a­tive to basenote. For instance, after _keyxpand(C4, 2), sequence D4 E4 F4 would be replaced with E4 G#4 Bb4. This tool is applied recur­sive­ly to the fields of a poly­met­ric expres­sion.

The gram­mar follows:

ORD
gram#1[1] S --> _vel(80) _rndvel(20) Melos1 Melos2 Melos3
gram#1[2] Melos1 --> Mel1 Mel2 Mel3
gram#1[3] Melos2 --> _transpose(11) Melos1
gram#1[4] Melos3 --> _transpose(5) Melos1 - Melos2

ORD
gram#2[1] Mel1 --> M1 - - - - - M2 - - M3 M4 - - M5
gram#2[2] Mel2 --> _transpose(-11) Mel1
gram#2[3] Mel3 --> _transpose(6) _rotate(-1) {Mel1 - Mel2}

ORD
gram#3[1] M1 --> C3 - • D4 F#3 _keyxpand(B3,-1) C3 - D3 F#2
gram#3[2] M2 --> _transpose(2) M1
gram#3[3] M3 --> _transpose(-6) _rotate(-2) {M1 M2, _keyxpand(C3,-1) M1}
gram#3[4] M4 --> C3 D4 F#3 _keyxpand(B3,-1) C3 D3 F#2
gram#3[5] M5 --> _keyxpand(B4,-1) {M4, _vel(100) M1} {M2, M3}

Note that all sub­gram­mars are head­ed with “ORD”, mean­ing that rules will be applied in order instead of being ran­dom­ly select­ed. Thus, this gram­mar pro­duces a unique musi­cal piece, which is the case with all exam­ples com­posed by Harm Visser. The only sto­chas­tic ele­ment of this piece is the veloc­i­ty that may vary between 60 and 100 due to per­for­mance con­trols _vel(80) _rndvel(20).

The sound out­put was played on a Pianoteq synthesizer: 

Trills

The fol­low­ing gram­mar pro­duces trills tak­ing advan­tage of tem­po vari­a­tions and con­tin­u­ous vari­a­tions of velocities:

ORD
gram#1[1] S --> _script(Wait for space) _staccato(50) Shapes
gram#1[2] Shapes --> Part1 {_rotate(20) _transpose(2) Part1} Part2 Part3 {_tempo(0.7) Part3} Part4

ORD
gram#2[1] Part1 --> {M1 Trill1 M2 Trill2 Int1 Int2 Trill3 Int3 1/4}
gram#2[2] Part2 --> {M3 M4 M5 1/4 Trill4 1/4 Trill4 Trill4 1/4 Trill5 M6 1/4 Trill6 Trill7 Trill8 1/4 Trill9 Trill10 1/4 M5 M4 M3 M6 {_rotate(6) _transpose(23) M6} 1/4 Int3 Int2 Int1 _rotate(23) Part1} Trill3
gram#2[3] Part3 --> {1 {M3, M4} 2, _transpose(12) Trill1} _transpose(-11) {1 {M3, M4} 2, _transpose(12) Trill1}
gram#2[4] Part4 --> {Trill12, Trill11} {Trill10, Trill1} {Trill9 Trill10, Trill2} {_transpose(11) {M3, Trill2}} {M3, _transpose(12) Trill3} {Trill10, Trill1} {Trill9 Trill10, Trill2} {_tempo(2/3) Trill10} {M3, M4} {_tempo(1/2) Trill10} 1/4 _transpose(12) Trill9

ORD
gram#3[1] M1 --> {_velcont _vel(40) _transpose(12) _tempo(7) C0 C2 C4 C6 _vel(60) _tempo(6) Bb4 G3 F2 B2 G3 _vel(80) _tempo(8) A2 B1 F#1 G2 A3 C#4 E3 G2 _vel(40) _tempo(6) Bb1 C#1 G0 _tempo(5) G#1 A2 A3 Bb4 _vel(90)}
gram#3[2] M2 --> {_keyxpand(C4,-1) M1}
gram#3[3] M3 --> {_velcont _vel(40) _transpose(12) _tempo(7) C0 C2 {C4, C6} _vel(100) _tempo(6) Bb4 G3 F2 {B2, G3} _vel(80) _tempo(8) A2 B1 F#1 G2 A3 C#4 {E3, G2} _vel(50) _tempo(6) Bb1 C#1 G0 _tempo(5) G#1 A2 {A3, Bb4} _vel(70)}
gram#3[4] M4 --> {_tempo(0.7) _rotate(5) _transpose(3) M3}
gram#3[5] M5 --> {_tempo(0.7) _rotate(12) _transpose(6) M4}
gram#3[6] M6 --> {_tempo(2) M1}
gram#3[7] Int1 --> {_tempo(12) _vel(40) _transpose(3) D2 C#3 _transpose(6) D2 C#3 _transpose(9) D2 C#3}
gram#3[8] Int2 --> {_transpose(11) Int1}
gram#3[9] Int3 --> {_transpose(11) Int2}
gram#3[10] Trill1 --> {_tempo(12) _velcont _vel(10) Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 _vel(80) Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 Bb4 A5 _vel(10)}

Waves

Harm Visser had been invit­ed to com­pose a piece à la Debussy with ruba­to rhythms cre­at­ing the impres­sion of wav­ing move­ments. We had expect­ed him to use the “_tempo()” tool with floating-point val­ues (or inte­ger ratios) as arguments.

In fact he did not… In the fol­low­ing gram­mar, only mark­ers “1/2”, “1/4” indi­cate reg­u­lar speed changes applied to an entire sec­tion. The wav­ing effect is pro­duced by a clever use of (self-imbedded) poly­met­ric expres­sions. As indi­cat­ed by the com­pos­er: “It is build on the idea of imbed­ding: {5, A B {3, A B {2, A B C D} C D} C D}.”

ORD
_mm(48) _striated
S --> Frase1 1 Frase1 Frase2 1/2 {_retro _transpose(12) Frase1} {_rotate(2) _transpose(1) Frase2} {_transpose(-13) Frase3} 1/4 {_transpose(-1) Frase1} Frase4 {_retro _transpose(-1) Frase1} {_rotate(3) _transpose(-11) Frase4} 1 Frase1 {_keyxpand(C4,-1) Frase1} 1/2 {2, _keyxpand(B3,-1) _vel(40) M19, M24} 1/2 {2, _keyxpand(A#3,-1) _vel(40) M19, M24} 1/4 Frase5 {_keyxpand(B3,-1) _transpose(-1) Frase5} {_keyxpand(C4,-1) Frase1} 1/2 {2, _keyxpand(B3,-1) _vel(40) M19, M24} 1/2 {2, _keyxpand(A#3,-1) _vel(40) M19, M24} 1 Frase6 1 Frase6 F1 B3 1 {_vel(50) F1 B3} 2 {6, _vel(40) F1}

Frase1 --> _legato(100) {_velcont _vel(50) M1 M2 M3 M4 _vel(60) M5 M6 _vel(50)}
Frase2 --> _legato(100) {_velcont _vel(50) _transpose(2) M7 M8 _vel(60) M9 M10 M11 M12 _vel(50)}
Frase3 --> _legato(100) {_velcont _vel(50) _transpose(2) M13 M14 M15 _vel(60) M16 M17 M18 _vel(50)}
Frase4 --> _legato(100) {_velcont _vel(50) _transpose(2) M19 M20 M21 M22 _vel(60) M23 M24 _vel(50)}
Frase5 --> _legato(100) {_velcont _vel(50) _transpose(2) M25 _vel(60) M26 M27 M28 M29 M30 _vel(50)}
Frase6 --> _legato(100) {_velcont _vel(50) _transpose(2) M31 _vel(60) M32 M33 M34 M35 M36 M37 M38 _vel(50)}

M1 --> {5, C3 F#3
M2 --> {3, _transpose(13) C3 F#3
M3 --> {3, _transpose(1) C3 F#3
M4 --> F2 B3}
M5 --> F2 B3}
M6 --> F1 B3}
M7 --> {5, _vel(60) C3 F#3
M8 --> {3, _transpose(13) C3 F#3
M9 --> {3, _transpose(1) C3 {M8 M10} F#3
M10 --> F2 B3}
M11 --> F2 B3}
M12 --> F1 B3}
M13 --> {5, _vel(60) C3 F#3
M14 --> {5, _transpose(13) C3 {_transpose(1) M13 M17} F#3
M15 --> {5, _transpose(1) C3 {M14 M16} F#3
M16 --> F2 B3}
M17 --> F2 B3}
M18 --> F4 B3}
M19 --> {9, C3 F#3
M20 --> {9, _transpose(13) C3 {_transpose(1) M13 M17} F#3
M21 --> {9, _transpose(1) C3 {M14 M16} F#3
M22 --> F2 {18, _transpose(-11) M1 M2 M3 M4 M5 M6} B3}
M23 --> F2 B3}
M24 --> F1 B3}
M25 --> {15, _vel(60) C3 F#3
M26 --> {15, _transpose(13) C3 {_transpose(1) M1 M5} F#3
M27 --> {15, _transpose(1) C3 {M2 M4} F#3
M28 --> F2 {30, _transpose(-11) M1 {30, _transpose(-11) M1 M5 M1 M5 M3 M6} M2 M3 M4 M5 M6} B3}
M29 --> F2 B3}
M30 --> F1 B3}
M31 --> {6, C3 F#3
M32 --> {5, _transpose(13) C3 F#3
M33 --> {5, _transpose(1) C3 F#3
M34 --> {5, _transpose(1) C3 F#3
M35 --> F2 B3}
M36 --> F2 B3}
M37 --> F1 B3}
M38 --> F1 B3}

The fol­low­ing is a ren­der­ing of the piece for piano solo on a Pianoteq synthesizer:

In an oth­er ver­sion, the com­pos­er assigned parts to a dif­fer­ent MIDI chan­nel con­trol­ling a physical-model syn­the­sized sax­o­phone (which he had designed on his own): 

Fractals

Harm Visser sent this gram­mar with the fol­low­ing comment:

It is com­plete­ly based on a func­tion that I have made in PatchWork. Take 3 notes and take their inter­vals to trans­pose. The result is a kind of ‘auto­trans­pose’. You get a ‘frac­tal’ - the idea of the famous Von Koch-curve. The next step is mak­ing a recur­sive loop, so that you can set the lev­el of recur­sion. The num­ber of notes grows expo­nen­tial: 3 9 27 81 243 etc. Of course you can do the same with rhythm-values.
This gram­mar is a BP2-version of exact­ly the same idea. It has 4 recur­sion lev­els. (You might also say ‘depth’. It is in fact a ‘copy’ of the PW-function). That’s why S --> L4 (lev­el 4) (num­ber of notes 243).

The dif­fer­ence between BP2 and PW is that the func­tion in PW is fixed, which is not the case in BP2. I can easy make sub­tle changes (devi­a­tions) in the process. I can ‘break in’, so to speak. In his gram­mar I have set a com­ma between M10 and M11 and set M11 on the sax. The result is a poly­met­ric canon!

S --> L4
L1 --> M1 M2 M3
L2 --> M4 M5 M6
L3 --> M7 M8 M9
L4 --> _rndvel(20) _vel(80) {_tempo(1/2) _chan(9) M10, _chan(1) M11 M12}
M1 --> _tempo(1) _transpose(0) C3 B3 F3
M2 --> _tempo(2) _transpose(11) M1
M3 --> _tempo(3) _transpose(5) M1
M4 --> _tempo(1) _transpose(0) M1 M2 M3
M5 --> _tempo(2)_transpose(11) M1 M2 M3
M6 --> _tempo(3) _transpose(5) M1 M2 M3
M7 --> _tempo(1) _transpose(0) M4 M5 M6
M8 --> _tempo(2) _transpose(11) M4 M5 M6
M9 --> _tempo(3) _transpose(5) M4 M5 M6
M10 --> _tempo(1) _transpose(0) M7 M8 M9
M11 --> _tempo(2) _transpose(11) M7 M8 M9
M12 --> _tempo(3) _transpose(5) M7 M8 M9

The fol­low­ing sound ren­der­ing is with piano solo on a Pianoteq syn­the­siz­er. The ver­sion with sax­o­phone is unfor­tu­nate­ly miss­ing. It could be gen­er­at­ed play­ing the (type-1) MIDI file Visser8.mid on a syn­the­siz­er assign­ing MIDI chan­nel 9 to a sax­o­phone sound.

References

Leave a Reply

Your email address will not be published. Required fields are marked *