You are on page 1of 47

First MIT Press paperback edition, 2001

© 1998 Massachusetts Institute of Technology

All rights reserved. No part of this book may be reproduced in any form by any electronic
or mechanical means (including photocopying, recording, or information storage and
retrieval) without permission in writing from the publisher.

This book was set in Stone Serif and Stone Sans by Graphic Composition, Inc. and was
printed and bound in the United States of America.

Library of Congress Cataloging-in-Publication Data

Winkler, Todd, 1 958-


Composing interactive music : techniques and ideas using Max /
Todd Winkler.
p, cm.
Includes bibliographical references and index.
ISBN 0-262-231 93-X (hc alk. paper), 0-262-73139-8 (pb)
1. Computer composition. 2. Max (Computer program language)
I. Title.
MT56.W5 1998
781 .3'45268dc2l 97-34535
CIP
109876 MN

Material
7 Composer Objects

Composer objects represent musical processes, known in computer


music as compositional algorithms. Algorithms are plans (methods)
for performing actions, operations, or procedures on musical material
or other data. Programmers break down procedures into sequences of
simple operations, with each step clearly defined. For hundreds of years
composers have used processes to create musical material and musical
structures. A canon (round) is a very old compositional algorithm; the
plan is for one person to begin singing a melody, and after a set amount
of time (or beats), a second person comes in singing the same melody
while the first one continues. The method for action is to delay the
second voice. The material (data) to be processed is the original melody.
Transposition is another example of a simple algorithm. Transposition
modifies notes by adding or subtracting a specified number of semi-
tones. The plan is to add. The data are the notes.
Many musical processes, especially those used in twentieth century
acoustic music, lend themselves well to computer implementation.
Perhaps even more interesting are the complex and sometimes unique
processes that would be difficult or impossible to create without the
use of a computer. Many composers have, in fact, used the computer as
a tool to generate algorithmic music that is then scored for traditional
ensembles. Pioneering work, such as Lej aren Hiller's I/hoc Suite for String
Quartet, began to appear in the late 1950s with the birth of computer
music (Hiller 1959). In general, compositional algorithms are the meth-
ods computers use to create music.
Composer objects serve a double role in creating interactive works;
not only are they the response mechanism to a performer's actions, but

Copyrighted Material
174 Core Components

they also serve as a computer-aided sketchpad for the composer to cre-


ate a new work. Composer objects provide an intuitive platform for
real-time exploration of musical processes, with selected variables con-
trolled by the composer from the computer keyboard or by a performer.
This immediacy in generating and manipulating musical materials pro-
vides the composer with an interactive laboratory where musical ideas
and time-varying compositional algorithms are quickly realized and
refined. The benefits of receiving immediate aural feedback from this
kind of experimentation cannot be overemphasized. Complex pro-
cesses, which at first seem confusing, can be mastered and understood
with practice and rehearsal. Compositional algorithms, coupled with
a well-designed user interface, allow composers to generate scores for
acoustic works, improvise with other musicians, perform solo pieces
from the computer, or shape interactive pieces on-the-spot during re-
hearsals or performances.
Other music programs, running concurrently with Max, create a
powerful working environment for composers. Music generated with
Max can be recorded with seq or routed directly to many sequencer or
notation programs through Opcode's Inter-Application Communica-
tion Bus (TAC). From there, the music can be viewed and edited. This
is helpful in understanding the musical capabilities inherent in each
process. It also makes it possible to produce a score for musicians using
Max, perhaps based on similar music that would be played by the com-
puter during a performance.
The study of compositional algorithms is so large that existing litera-
ture comprises hundreds of volumes. These are rich resources for com-
posers wishing to expand their musical technique using the computer.
This chapter discusses some general concepts about algorithms and
describes various types of composer objects common to interactive
composition.

Creative Response to Listener Date

Composer objects create music directly or indirectly by responding to


performance data. Composer objects are algorithms that embody the
thought processes, taste, and skill of a composer. They represent a pro-
gram's entire range and potential for musical production. Possibilities
for composer objects are endless; it is in their design that the composer
can be most imaginative.
Copyrighted Material
175 Composer Objects

Listener objects, on the other hand, only need to be factual to pro-


vide accurate and dependable data about a performance. They answer
a limited number of questions, such as what note, how loud, how fast,
and how parameters change over time. Listener objects, in and of
themselves, may not be artistically interesting; they simply need to
work. The real work for composers begins by interpreting listener data
so that it can influence musical production, showing a mutual cause
and effect relationship between performers and computers. The basic
principles of object and program design are applicable to composi-
tional algorithms. They should be consistent in how they work, have
a clear function, be generalized for expanded use, and be foolproof to
prevent unwanted side effects. Compositional ideas need to be repre-
sented as a step-by-step process, with each step having exact limits and
a precise purpose essential to the outcome.
The logic involved in creating an algorithm does not imply that a
composer's talents, which involve craft, imagination, and refined artis-
tic judgment, are secondary. Such strict "rules" are the limitations that
shape form and create musical style. Music history is full of examples
of music predicated on a strict adherence to rules (that are at times
intentionally but tastefully broken). Taste, artistic values, and even
"breaking the rules" are all aspects of composition that can be pro-
grammed into an interactive piece. The beauty of interactive composi-
tion is that a thoroughly logical and even uninteresting algorithmic
process can be made to sound quite expressive when a performer
'messes it up" by manipulating variables according to his or her own
interpretation.
Which variables should the performer alter? The ability to alter or
change a variable in real time is precisely what makes an algorithm
interactive. With the potential to have numerous composer objects si-
multaneously producing music, it is important to make a few signifi-
cant variables available for manipulation.

Composer Object Design

Performers may affect computer output in one of two ways. The com-
puter may look for a specific note, a condition, or other listener data
to trigger a prerecorded sequence or to begin a compositional process.
When a specified conditional is met, playback or processing will com-
mence. Performers may also have continuous control over specific
Copyrighted Material
176 Core Components

parameters of a process, such as controlling the dynamic level or the


tempo, which continually shapes the musical outcome. The composer
determines the range, scale and time frame for a performer to influence
a musical process. Performer actions may not always be so obvious as
a one-to-one correspondence with composer objects; performer actions
may be stored, delayed, accumulated, or interpreted in other ways that
produce compelling musical results. Triggers may even cause a chain
reaction of automated actions.

Data Sources

Composer objects may receive data from a variety of sources. Listener


objects provide real-time data via MIDI, or from the computer keyboard
and mouse. They also provide captured data, useful musical material
and analysis information that has been stored during a performance
via one of Max's data storage objects. Storage objects may also hold
predetennined data, musical material or potential material that is loaded
into a program prior to a performance. Predetermined data could be
anything from a complete musical score, waiting for playback, to raw
material, such as a few intervals used to create new melodies or chords.
Seq, table, coil, and detonate are used in most cases for this purpose,
since they can retrieve large amounts of information in real time, and
in an organized fashion. Generated data is produced by algorithms that
create data from a small subset of stored or real-time data. The com-
puter may use a mathematical formula or statement to internally gen-
erate numbers used for musical input, without needing outside input
or stored data. Such an example has already been shown using the
random object to generate melodies using random numbers within a
given range. Other, more complex formulas have been used by com-
posers to generate pitches and timbres based on fractals, the golden-
mean ratio, and other such phenomena. Finally, processed data results
when data from any source is modified by an algorithm. Several com-
poser objects may be linked so that processed data is passed out one
object and into another object for further processing.
RandomMelody provides a straightforward interface for a random-
melody generator (fig. 7.1). The simple algorithm within Random-
PitchRange is used throughout this text to create random notes within
a given range (fig. 7.2). The random object generates values from O to
the maximum, which are offset to reside within a reasonable range for
Copyrighted Materia!
177 Composer Objects

RandomPitchRange uses metro to start/stop and set


the tempo. The range size is set with the second inlet,
and the range minimum is set with the third inlet.

on/oft tempo
range range
250 size minimum

etro 25 50 46

p RandomPitchRange
makenote88 20

noteout

Figure 7.1
Random melody

Generates a range of random notes. The lowest note is set by the + object;
the range size is set by the random object.

bang out range lowest


next number size note

default - generate random values


random 50 between O and 49 (a range of 50 values)
offset range to start on the
lowest note (default 46 = Bb)

random notes out

Figure 7.2
RandomPitchRange (subpatch of fig. 7.1)

MIDI melodies. Other types of random-number generators in Max will


produce different melodic results, such as urn, which outputs random
numbers without duplicates, and drunk, which outputs numbers
within a moving range, a "random walk" with a specified step size.

Types of Composition Algorithms

In Interactive Music Systems, Robert Rowe defines three basic methods


by which composer objects respond to data input: generative, se-
quenced, and transformative. Generative algorithms use elementary or

Copyrighted Material
178 Core Components

fragmentary source material, such as a set of intervals for producing


chords and melodies. The music may be generated from musical frag-
ments captured from a live performance, from fragments stored before
a performance begins, or from equations or formulae that generate
numbers, such as a random-number generator. Rowe (1993) writes:

Generative methods use sets of rules to produce complete musical output from
the stored fundamental material.

Sequenced techniques use prerecorded music fragments in response to some


real-time input. Some aspects of these fragments may be varied in performance,
such as tempo playback, dynamic shape, slight rhythmic variations, etc.

Transformative methods take some existing musical material and apply trans-
formation to it to produce variants. According to the technique, these variants
may or may not be recognizably related to the original. For transformative algo-
rithms, the source material is complete musical input.

Transforming Musical Material

Source material may come from one of several sources: a live perfor-
mance, a stored sequence, or a generative algorithm. Transformative
methods may be used to alter musical material from any source. They
are represented as musical processors, taking existing material as input,
and shaping it to produce new versions based on some aspect of the
original. Thus, they are the primary means for creating variations. The
transformation may alter a single parameter, such as pitch transposi-
tion, or may alter several parameters so drastically as to produce results
that are unrecognizable, yet formally related, to the original. Processors
are analogous to MIDI effects boxes (signal processors): the input signal
is warped, distorted, colored, or otherwise altered according to the se-
lected algorithm. In fact, previous examples have shown that it is pos-
sible to create Max objects that mimic some functions of a signal
processor, such as delay, pitch shift, arpeggios, and panning. A few ba-
sic categories of processor types are discussed below.

Filtering

Filters take in a performance or sequence, and alter the data by reduc-


ing, distorting, or eliminating some aspect of the performance. Simple
filters can throw out certain pitches or registers, thin data, or set up

Copyrighted Material
179 Composer Objects

restrictive conditions for data to be able to pass through. Select and


split are Max objects useful for setting up simple filters by select-
ing data to accept or reject. A counter or timer, coupled with a gate,
may also be used as a filter by allowing one out of every x number of
events to pass through, for instance, playing every third note, or
allowing events to pass during specific time frames (also known as
"windowing").

Limiting

Limiters are types of filters that modify or eliminate values outside of a


specified range. The split object is the most obvious limiter, specifying
allowable high and low values. Split may be used to reject velocity
values that are too loud, ignore tempo changes that are too slow, or
accept only short duration values. A limiter may be used in conjunction
with a formula to alter the rejected values. In figure 7.3, Range-Loop

This example uses RandomPitchRange to create pitches that are then further
limited by split. The allowable range of values is set with the low and high split
inlets. When the GSwitch is sending to the left outlet, it chooses new random notes
until it gets one within that range. When the GSwitch is sending to the right outlet,
notes outside the range will not sound.
on/off tempo
range range
>250 size minimum
L
metro 250
L
r 50 6

p RandomPitchRange

Range: Low High

8 O

split 48 60
J-
pitches outside range
makenote 88 200
Click here to correct
noteout pitches out of range.

Note: each loop will use up processor time on the computer;


use this method with caution!

Figure 7.3
Range ioop

Copyrighted Material
180 Core Components

plays notes only within a predefined range using a single split object.
Each bang from metro produces a random value from Random-
PitchRange, with pitches out of split being ignored. This makes the
object fairly limited, but it does create interesting rhythms because val-
ues outside of the split range will produce rests (they do not go to
makenote). Fine tuning the range of random values from Random-
PitchRange and the range of notes to play from split will produce
continuous rhythmic variations that are somewhat predictable, since
the values are highly constrained. Many algorithms that improvise and
produce constant variations use constrained random values. In this
example, a simple correction algorithm may be added by clicking on
the GSwitch, which creates a feedback loop by sending a bang back to
RandomPitchRange for each out-of-range value. Such feedback loops
should be used with caution, since indeterminately endless looping
can use up processor time on the computer. However, this should not
be a problem if an appropriate value is generated within a short time.
Figure 7.4 shows the output of an arpeggio-generating algorithm,
AddArpeggio, being processed by a more generalized algorithm,
RangeMod, to place values within a predefined range. RangeMod
takes in melodies (or any other data) in the first inlet and alters pitches
that fall outside the selectable minimum and maximum range using

flip
on/off speed time interval (-12 to 12)

i331

AddArpeggio
1250 positive for up
negative for down

pitch duration velocity

range range
minimum maximum
40 60

; RangMod
makenote 100 20

noteout
-

Figure 7.4
Constrained arpeggio

Copyrighted Material
181 Composer Objects

the % object (the modulo operator), which divides two numbers and
outputs the remainder. The size of the range is determined by sub-
tracting the maximum from the minimum. (1 is added to include the
specified end points.) The number received in the right inlet of % (the
divisor) determines the maximum value of the range; the middle inlet
determines the minimum value (fig. 7.5). Values sent to % will result
in numbers between O and the range size. A previous example showed
the use of [% 121 (mod 12) to analyze incoming notes as pitch classes,
reducing all values to fall within a range of O to 11 (fig. 6.14).
RangeMod first checks to see if values are in range using split; if they
are, the values are sent out without further processing (fig. 7.5). The
expr object calculates the size of the range. To be fail-safe, an abs object
(absolute value) is used to convert any possible negative numbers to
positive. Next, the modulo operator creates new values within the
specified range, starting at 0. To get the new values in the proper regis-
ter, the minimum value (Range Ìvfinirnurn) is added to offset the results.
(See figures 7.30 and 7.31 for a third range method.)
Each notein to AddArpeggio begins a new arpeggio from the last
note played (fig. 7.6). Speed controls the arpeggio speed and is sent out
to the duration inlet of makenote to assure that the duration and the

RangeMod will take any value and place it within a


predescribed range using % (the modulo operator).

range range
input minimum maximum

lIt expr gets the size of the range - the


pr $2 - $il + i
difference (+1 for inclusive range)
bypass abs I abs outputs the absolute value of the input value

within modulo operator (%) places values within range,


°/ 24
range cycles between O and the size of the range

+ 60 range minimum is added back to the results

output within range

Figure 7.5
RangeMod (subpatch of fig. 7.4)

Copyrighted Material
182 Core Components

AddArpeggio takes a note played on the keyboard as a starting point and adds or
subtracts a specified interval repeatedly, creating an arpeggio. The addition/subtraction
will restart each time a note is played on the keyboard. In regutar time intervals (flip
time), the arpeggio direction will be reversed by multiplying the original interval by -1.

flip time
on/off speed

/ 40 250

met ro 1000

interval
metro 50 note i n
\/ 4
st rip n ote
Positive intervals will create
inI 60 starting ascending arpeggios;
note negative numbers will create
descending arpeggios.

pitch uration vel


mt 3
reverse
continually add or
direction
subtract interval

Figure 7.6
AddArepeggio (subpatch of figure 7.4)

speed are equal (legato). Arpeggios in this example are created by con-
tinuously adding or subtracting a single interval, as specified in the
right inlet, producing ascending and descending lines. An mt is used
to hold the starting keyboard pitch, which gets replaced each time an
interval is added or subtracted. Flip time, in milliseconds, determines
how often the direction of the arpeggio will change using a second
metro. With each bang from the metro, the direction of the arpeggio
is reversed by multiplying the arpeggio interval by 1.

Scaling

Another approach to Range would be to use a compression algorithm


to scale data outside of the range. Such a process would generate a
larger scalar factor for numbers farthest away, pulling them within the
range, with smaller corrections made to numbers just outside the
range. Scaling can be used to increase or decrease a range of values,
:terial
183 Composer Objects

usually by multiplying or dividing the values, sometimes with an


added offset. (See Scaling Parameters in fig. 8.22.)
To build and operate many composer objects, it is essential to know
the allowable input value range and to be able to scale data to accom-
modate that range. Scaling is an important technique for interpreting
listener data and processed data for composer objects because incom-
ing MIDI data is often scaled or offset before it is used. O to 127 is a
perfect range for MIDI velocity values, but what happens if those values
are intended to control another parameter, such as the speed of a
metro? With time in milliseconds, O to 127 would make for a truly
exhilarating experience! With a loud note, the slowest tempo would be
around mm = 480, and playing quietly could result in the computer
playing at impossibly fast speeds (with the increased risk of crashing
the computer). By adding an offset (plus 10), and scaling the velocity
(multiplying by 10), the numbers are transformed from O to 127 to
usable metronome speeds between 100 and 1370 (fig. 7.7). In this way,
the range of incoming performance data can grow or shrink to accom-
modate each situation.
On the other hand, linking velocity numbers to pitch may result in
too many extreme highs and (mostly inaudible) lows, so the scale fac-
tor would be needed to condense the range. Adding 60 to the velocity
number and multiplying by 0.5 would yield more usable pitches in a
range between 30 and 93.

Selecting

The select object is a very useful tool for matching and obtaining a
bang for desirable numbers specified as arguments. However, it can also

notein
¶27
st rip note

+ 10

metro 2 370

Figure 7.7
Scaling

Copyrighted Material
184 Core Components

be used in reverse, to remove numbers from a data stream, since all


nonmatching values are output through the right outlet. Figure 7.8
shows a self-operating version of the RanMinorMel subpatch from
figure 6.13. Random 24 creates values representing a two-octave range.
All pitches entering the select object will pass out the right outlet ex-
cept for the note numbers outside the C minor scale: 1, 4, 6, 9, 11, 13,
16, 18, 21, 23. The results are then transposed to place them in a cho-
sen tonic and register. Any type of scale, even one that changes in each
octave, could be produced in this way.
The gate below select causes pitches outside C minor to output a
new note, until a note in the scale is found. The feedback loop ensures
that all beats will be played. Like the previous RangeLoop example,
unhooking the feedback loop produces more interesting rhythms.

Timing Processes

Objects dealing with timing processes use techniques such as thinning,


speed change, delaying, gating, and switching to create variations in
rhythm, texture, and speed. Thinning, gating, and switching are re-
lated, cutting out part of a signal for a specified amount of time. In

metro 200

random 24
choose tonic/register
select 1 4 6 9 11 13 16 18 21 23 46
in the minor
60
scale are sent to
makenote to be played.
gate

noteout

If the gate is open, notes outside the minor scale re-bang' the random
number generator until an acceptable value is found. When the gate is
closed, notes outside the minor scale will not sound, creating rests."

Note: care should be taken when using this method since the computer
could spend much of its time looping if a desired value is not found.

Figure 7.8
Select scale

Copyrighted Material
185 Composer Objects

thinning, this is usually done at regular intervals; gating and switching


let data pass through at variable times. Delay techniques create canons,
echoes, and other structures with delay lines.

Thinning
Speedlim (chap. 6) is the data-thinner of choice for many composition
functions, especially when a continuous controller from the keyboard
is used to control compositional processes, since the rate of data
change sent from controllers is faster than many algorithms require.
Speedlim keeps data streams to a minimum, which improves efficiency
for the overall program. Speedlim allows only one value output every
X milliseconds. For example, if the modulation wheel is used to deter-
mine the register of a melody, looking at its position once every 40
milliseconds might be just as effective as looking at it every millisec-
ond, with forty times less information to process. In figure 7.9, Mod-
WheelMelody scales modulation-wheel values to fall between 60 and
85, and sends them to select to create a melody. (The tonic is not vari-
able in this example; select will reject any notes outside a C minor
scale.) The right inlet is a variable that controls the maximum speed
of the melody by thinning the data-transfer rate with speedlim. Slid-
ers can generate a thinned data stream by using an offset and a multi-
plier in GET INFo. Here the slider values go from 50 to 1000
(millisecond speed for melody), in increments of 10. This makes the

Use mod wheel data to generate values between 60 and 85,


outputting a note every X milliseconds according to speedlim,

mod wheel input on


ctlin i i melody speed
MIDI channel i
+ 300
scales values of 0 127
to values of 60 - 85 lii
2

190 duration
speedlim loo
select 61 64 66 69 71 73 76 78 81 83
Notes outside of C makenote88 20
minor are filtered out.
noteout

Figure 7.9
Modulation wheel melody

Copyrighted Material
186 Core Components

slider smoother to operate since the data stream has been reduced. In
this case, speed changes of less than 10 milliseconds offer more detail
than is needed.

Gating
In figure 7.10, the subpatch Rest is an elaborate switching filter that
takes in steady metronome beats and creates varied rhythm and phras-
ing (fig. 7.10). Two variables control the operation of Rest. Both num-
bers represent constrained random values between 1 and the specified
maximum number (i.e., a value of six means random values between
one and six). The middle inlet represents the rest phrase length, the
maximum number of notes that will be played continuously before a
rest. The right inlet determines the rest size, the maximum duration of
a rest. As soon a phrase is completed, a new rest size number is issued,
and the melody waits that number of metro beats. Then, the algorithm
gets a new number for the phrase length and plays that number of
beats, and so on. A GSwitch alternately switches back and forth be-
tween the two (fig. 7.11). When it switches to phrases, bangs are out-
put, when it switches to rests, the signal is blocked. (A similar effect
could be achieved usìng a gate to open for X number of beats for the
phrase, and close for Y number of beats for the rest.) For example, long

Rest generates rhythm in a melody or other


functions involving a steady metronome.

100
metro 200
phrase rest
length Size

p Rest
E
random 3
T
+ 40
-
makenote 110 200
E
noteout

Figure 7.10
Rest example

'eriaI
187 Composer Objects

Rest takes metro bangs in and outputs a variable subset of them.

RestSize sets the maximum number


of beats to rest, from i to RestSize.
Si metro in

-9 RestPhraseLen RestSize
RestPhraseLen sets the maximum
When RestSize number of beats to play before a rest.
is O, there
are no rests -
all bangs are
sent directly
through.

Figure 7.11
Rest (subpatch of fig. 7.10)

phrases with infrequent rests of one or two beats would result from
choosing 25 for the phrase length and 2 for the rest size, whereas
choppy, pointillistic rhythms would result from a phrase length of 4
and a rest size of 8. When the rest size is O, the beat is continuous and
bangs from metro will bypass the entire algorithm to prevent unneces-
sary computer calculations. (Note: Remote sends in fig. 7.11 are used
to improve the readability of the example.)

Automated and Delayed Functions


Delay may be used to postpone a reaction to performance data or to
automate actions. Chaining delay lines together, or using one delay
line with a variable delay time, can set up a time frame for specific

Copyrighted Material
188 Core Components

actions. The line object can also be used to automate the increase or
decrease of variable values in a composer object, and to create "ramp"
values that interpolate between two end points.
Line takes four variables: a starting value, an ending value, the time
it takes to get from the starting value to the ending value, and the time
"grain," the number of milliseconds it takes to output an updated value
(a thinning value). A single number to the left inlet is the starting
value; a pair of numbers to the left inlet [0 500] represents the starting
value (0) and the time (500). The middle inlet is the destination value,
and the right inlet is the time grain. Perhaps the easiest way to use line
is to send a message of three variables in the form of 10, 200 5000],
where O is the starting point, 200 is the destination value, and 5000 is
the time in milliseconds to output values between O and 200. Option-
ally, line takes two typed-in arguments that represent the starting value
and the time grain.

Line creates a continuously changing function using velocity and duration.


The resulting values are applied to pitchbend and modulation wheel.

on/off
note i n message lists for line
27 1000 Go to 127 in one second.
g ate
10 2000 Begin at 88, go to
ti i
10 in two seconds.
stripnote p GetDur
velocity = new duration = time to
>86 >2226
target value target value
line 1 10

bendout ctlout 1

Duration and velocity control


pitchbend and modulation.
I86
line output
Beginning value is previous velocity;
ending value is new velocity.

Figure 7.12
Interpolator

Copyrighted Material
189 Composer Objects

An example called Interpolator uses line to map discrete velocity


values as continuous changes over time (fig. 7.12). The velocity values
act as points connected in time to create a function. The time between
points is dependent on the duration. The patch creates a continuous
function that is a mapping of dynamic level and duration (articula-
tion). Staccato notes will cause Interpolator to jump rapidly to the
next velocity value. Legato playing will cause Interpolator to move
smoothly between two velocity values. The output is a function (a con-
tour), with values between O and 127. In this example, the line object
alters pitchbend and modulation, while its changing values are "ani-
mated" by a slider for display. Using message lists in series is another
way to create ramped functions using line. Functions with multiple
break-point values can be edited and viewed graphically using the env
(envelope) object.
An excellent use of delay as a compositional technique can be seen
in Robert Gibson's Canon program, which uses delay lines and ramped
delays to create canons (fig. 7.13). The object reads a single standard
MIDI file into two seq objects and delays the playback of the second
by a user-specified amount. The following is a short description of its
features and operation, which can be seen in the carefully designed
user ìnterface.

Delay Ramped Delay


Follower Tempo Reset to Default

L till 1024

o Play
Reset Delay
o Stop
Start/Stop Delay

( Read Input Sequence )


E
Ramped delay
increased by
ims every
250 ms
( Help ) Transpose Interval
Follower begins
milliseconds behind Leader
MIDI CANON
Leader Follower
Channel K2000 Channel by Robert Gibson
K2000
ji Irecord

Figure 7.13
Canon by Robert Gibson

Copyrighted Material
190 Core Components

The Follower Tempo slider sets the tempo of the "follower" voice. The
default is 1024the same tempo as the "leader" (the original tempo
of the sequence). Values higher than 1024 create canons in diminution
(e.g., 2048 plays the follower at twice the speed of the leader); values
less than 1024 produce canons in augmentation. The Delay slider sets
the number of milliseconds between the start of the leader and the start
of the follower. The Ramped Delay slider sets the rate of an optionally
increasing time interval between the leader and the follower, triggered
by clicking ori the start/stop toggle for Ramped Delay. This can create
phasing effects, as the two versions slowly drift out of synch. The pitch
interval of the follower can be set by selecting a number (in half steps
above or below the leader) with the Transpose Interval slider. The slider
has a four-octave range (-24 to +24). The default is O (unison). The
device (or port) and channel of the leader and follower can be set in
the MIDI menu. The final result can be recorded.
Using this program, Gibson has successfully created new computer
pieces as well as renditions of several acoustic pieces, including Georg
Philip Teleman's Allegro (III) from Six Canonic Sonatas and Steve Reich's
Piano Phase.

Mapping

Mapping is one of the most effective and commonly used techniques


in interactive music. Mapping is typically used as a transformative
method to link performer actions to composer object parameters. In
this broad definition, parameter mapping usually associates one promi-
nent musical feature with another. For example, mapping velocity to
delay time so that louder notes will have a longer delay time, and
shorter notes will have a shorter delay time.
More specific data mapping techniques use mapping in the mathe-
matical sense; to take an element in one set and match it with another
element in the same set or a different set. Data mapping may take place
within the same parameter, such as mapping all pitch input to play a
specific scale, or harmonizing a melody by using pitch numbers as the
index to a coll to output stored chords. A table is also a useful data
structure for mapping, since pitch or dynamic information may be
used as the index to output other values. Output from one table may,

Copyrighted Material
191 Composer Objects

in turn, be used as the index to another table. Select and match are
often used to define an initial set of data.
After choosing the variable that will alter a process, the composer
must select the performance feature(s) that will control the variable. A
clear example of performance feature to variable mapping can be seen
in the user interface of Robert Rowe's Cypher program (fig. 7.14). Note
that the clearly marked performance features above (listener objects)
can be connected to influence any of the music-producing parameters
below (composer objects). The user simply draws a line between them
to map (connect) any listener feature to a composition method. In this
example, the first two rows of connected ovals will cause the following
to occur (from left to right): a slower performance tempo will increase
the tempo of the computer (accelerando), a soft dynamic level will

C!pher bi Robert Rowe


Cypher 2.0
F ° 1 2 3 4 5 6 ?
State Bank C:' (ö) C) C) C) i) :
ii:'
-, Timbre i) 'fi ) 'fi' fi C) C) 'fi:'
Clear J Presets E E E E E E E E
Channel: Kb Echo: 0ff EEEEEEEE
,- ---------------
fast soft f: #
hi q h

i--
si Oil irisi o
- ,,-_-',
rrifa.s
,,-' ici id s h rt i':' no C E:' Eb

r,-- (,
' ' ' .i '.
:' i, i ',
_...- --.- ---. ----
i. i

r , , I
J i ii i i

flat i nvt acci tite swng tril loup arpq st.rc chrd bass t.rris treni
U
irin i rrg rgrg i rsp i riir irpi
i
phrs
',- -.'
i.
--. i i
rqini
t i_____i
.---.-' '___I ,"i i')
'.___.'
rcisp
____
i rdu
,----,
rqdl4

___d ,.___- (ti


rqd r rq pl
p'.
i,-..
J,
phrs jigp
i i

riodn
t i_J p___',
,-, ,___.,
basi
l,)
basN tapY
i,J i
tapN accru
i._)
sa/nri t..':ib
n
I' F...i..PJL!
Figure 7.14
Cypher by Robert Rowe

Copyrighted Material
192 Core Components

produce a trill, playing loudly will invert the melody, playing any C
will produce a chord, and playing any B will produce an arpeggio. The
bottom two rows of connections handle responses based on larger
changes over time, such as phrasing features or detecting regular or
irregular skips in register. (Note: Cypher is not a Max program).
Allen Strange's MIDI reMap demonstrates a Max program with a sim-
ilar approach to mapping parameters (fig. 7.15). In this clearly designed
interface, a menu selects a MIDI performance control, such as velocity,
aftertouch, or mod wheel, and maps this controller onto specified com-
position parameters, such as panning or duration. In the description
provided with the program, Strange writes:

This instrument allows the player to remap various MIDI controls to selected
parameters of a free running instrument. Each data stream can be "inverted"
with the toggle to give reciprocal values [i.e. duration can be the inversion of
velocityl. Each parameter can also be determined by a free running random
object or controlled by a screen slider.

MIDI reMap
by Allen Strange
Start/Stop Pitch JG#3 I

Period STEP SIZE


Velocity Velocity
Invert E 48 Manual Invert
E 88 Manual

34 o

Velocity PRNNIN6
After Touch After Touch
Invert E 19 Manual Invert E 16 Manual

38 o

Duration
Key

Invert E 53 Manual

Figure 7.15
MIDI reMap by Allen Strange

Copyrighted Material
193 Composer Objects

The pitches are determined by a "Brown Noise" generator [the Max drunk
objectj accessing a table consisting of various pitches in related modes. The
possible deviation from the last sounded pitch to the next is controlled by the
STEP SIZE parameter. Any key pressed on the MIDI keyboard instantly resets
the "seed" for the selection of the next pitch.

In figure 7.15, period (tempo) is controlled by velocity, while panning


is controlled by aftertouch. Panning location, left and right, would be
reversed if invert mode was selected. On-screen controls of all the pa-
rameters makes this a very usable "instrument" for performance from
the computer keyboard.

Constrained Pitch Output: Comparative Programming Examples

Sometimes algorithmic output needs to be shaped with a filter to


achieve the desired musical results, such as altering incoming notes to
conform to a scale. Three different objects for mapping pitch informa-
tion to a "correct" scale or pitch will show the diverse structures avail-
able in Max.
Tonicize is the simplest and most limited example (figs. 7.16 and
7.17). Tonicize takes incoming notes and forces notes near a chosen
tonic to become the tonic note. This creates a "black hole" effect: the
Tonic Strength setting specifies a range of semitones, centered around
the tonic, that will be "sucked" into the tonic. The larger the range

Tonicize takes the noies immediately surrounding a selected tonic,


and moves those notes to the tonic.

200

metro 200
spews random
random 48 Tonic Tonic Strength
pitches
+ 36 lili

range around
tonic to change
Toiciz
makenote 100 200
-
noteout

Figure 7.16
Tonicize tutorial

Copyrighted Material
194 Core Components

pitch in tonic tonic strength

figure out
closest tonic
I 12

12
tonicizing range offset for odd
closest tonic tonic strength

expr $il ($i2/2) expr $il + ($i2/2)

split checks the incoming note


against the tonicizing range

tonic to be
output

same note if not within the tonicizing range,


otherwise the tonic

Figure 7.17
Tonicize (subpatch of fig. 7.16)

setting, the stronger the force of the tonic note. For example, a range
of six will map to the tonic any pitch that is three semitones above or
below the tonic so that a selected C) tonic will cause any A), B, C, D,
D), or E to be changed to a C). This creates a variable situation where
the prominence or weight of a single note can be controlled in terms of
the frequency of occurrence and its isolation from surrounding pitches.
Quantization is a technique that takes a large set of continuous val-
ues and changes them to a smaller set of discrete values. This may be
done using a rounding function, a formula, or mapping techniques.
PitchQuant (pitch quantization) is a custom object that maps incom-
ing pitches to a predetermined scale (fig. 7.18). lt may be used in the
typical sense of quantizing a scale, for example changing chromatic
scale input to major scale output, but is flexible enough to allow for
quite unusual mapping. The interface asks for the input note, the new
note to map it to, and the percentage of time that the mapping will
occur (quantization strength). The store button updates a coli that con-

Copyrighted Material
195 Composer Objects

PitchOuant maps incoming pitches to a predetermined scale. The percentage chance that a pitch
will be mapped is specified by the user. The Note menu selects which pitch class should be
changed. The New Note menu selects the new value of that pitch class. Chance of quantization
specifies the percentage chance of the original pitch class being changed when played.

on/off chance of
>200 note in new note quantization (%)
store -->
metro 200 settings
spews random random 48
pitches
+ 36

p PitChQuant

note in 60 61 mapped note out


makenote 100 200
-J-
noteout

Figure 7.18
PitchQuant tutorial

tains all the mapping information. Each line of the coli contains pitch
class (0 - 11) as the address, followed by the new note, followed by
the percentage chance that the original has to change. Thus, (4, 5, 50)
in the coli would mean to change all Es to Fs fifty percent of the time.
A user monitor gives feedback about which pitch is entering Pitch-
Quant and which pitch is being output.
When a note enters PitchQuant, an analysis object separates pitch
class from register, a technique that allows similar processing of notes
for all octaves (fig. 7.19). Register is later added back to the final pitch
class. Pitch class goes into the coli, acting as the address to trigger the
new note and percentage change. The new note and the old note are
stored in ints The percentage algorithm chooses how often to output
an altered note. Each note input generates a random value between i
and 100. A less-than (<) operation sets the percentage range: All values
below the percentage change will trigger the new note; all values above
will trigger the old note. The < object works by sending a i if the
condition is true, or a O if the condition is false.
How could PitchQuant be improved? Although PitchQuant is set
up to work on all octaves the same way, it could be easily expanded so

Copyrighted Material
196 Core Components

PitchOuant maps incoming pitches to a predetermined scale


notes list of pitch class, new
pitch class, and %
chance of quantization

get pitch class % 12

Collection 'tonic stores map nt


of corresponding pitches and subtract pitch
quantization percentages. class from pitch
to get register...
coil tonic
Every new note
triggers a random
number between 1 and unpack
tb
100. If this number is
less than the chance of random 100
quantization, the
quantized note will be +1 new note
output. The greater the chance of
< 100
chance of quantization, q u a fltiZatio n
the better the odds sel i O
that the random
number will be less
than that value. quantized pitch mt original pitch

add register
back to pitch class

Figure 7.19
PitchQuant (subpatch of fig. 7.18)

that various octaves could have different mappings. More important is


the lack of a data structure to create and store multiple mappings. A
nice added feature would allow many different scales to be stored and
recalled with a menu or preset object.
The next example, Scale, simplifies the previous idea, providing a
menu of available scales in the interface (fig. 7.20). It is easier to use
than PitchQuant, but less flexible, since it does not have the percent-
age feature or an interface for creating custom mappings. Instead, Scale
always maps every note input to a predefined scale, available in a
menu. Variables to Scale are scale selection and pitch input. Any note
received outside the selected scale will get mapped to the nearest
scale note.

Copyrighted Material
197 Composer Objects

All notes passing through the Scale object will conform to a pre-defined
scale type, selectable from a menu. Scale uses a different algorithm than
PitchOuant to map incoming notes.
Range Range
Size Minimum

jtro
250
i i
p RandomPitchRange
46

generates random notes


in a certain range

Chromatic I
conforms entering
p Scale
--
- I notes to selected scale

makenote77 350
-
noteout

Figure 7.20
Scale tutorial

The user interface contains a list of scale names in a menu. Selecting


GET INFO on the menu reveals the contents: [Chromatic, Pentatonic, C
major, C minori.
When selected, each item is output as an index to a previously stored
coli. Inside the coll, the list following the address represents the map-
ping of each pitch class, in order (fig. 7.21). Adding more scale types
would entail adding a name to the menu, then specifying the mapping
to coli. The definition of the scales are typed in directly and stored
with the program. The inside of the coli looks like figure 7.21.
Although not very user-friendly, the coil mappings are quite flexible.
For example adding Wild Scale to the menu (item 4) and adding a new
line to the coil: [Wild Scale, 24 1110 9 8 7 6 5 4 3 2 11 would cause all
Cs to play two octaves higher, and would invert each octave of the
keyboard for the other pitches, so that Dk = B, D = Bk, B = A, and
so forth.
The first coll is convenient for storing and retrieving multiple scales,
but it is not in a form usable for mapping. To make it usable, the con-
tents of each scale is sent out and reformatted into a second coli, where
the index number is an incoming pitch class, and the data is the
mapped pitch class. Figure 7.22 shows the mapping of a chromatic
scale to a major scale. In figure 7.23, unpack separates the list of items

Copyrighted Material
198 Core Components

Chromatic, 0 1 2 3 4 5 6 7 8 9 10 11;
Pentatonic, 1 1 1 336688 10 10 10;
C_major, 00244557799 11;
C_minor, 0 02 335 577 88 10;
Figure 7.21
Scales stored in first coil, raw storage

0, 0;
0;
2;
4;
4,
5,
5;
7;
7,
9,
9;
11;

Figure 7.22
Scales stored in second coli, usable for mapping

Coli Scales contains the pitch classes of various


pitch scale scales. The unpack object outputs to number boxes,
giving a graphic display of which pitch class
corresponds to which note in the scale. Notes in the
PitchAnalyze coli Scales selected scale are then funneled into another coIl.
divides entering
notes into pitch unpack 0 1 2 3456 789 10 11
class and register.
C C# D D# E F F# G G# A A# B

PitchAnalyze o o o O O o o o

funnel 12

The pitch classes entering this coIl from PitchAnalyse


add back are used as addresses. An entering pitch class will cause
register coli the output of the mapped pitch class in the chosen scale.
L1
>0
1to
mapped original
pitch pitch

final pitch

Figure 7.23
Scale (subpatch of fig. 7.20)

Copyrighted Material
199 Composer Objects

in the first coil, giving a graphic display to the user who can check the
mapping for each pitch class and easily experiment with different
scales. Funnel takes single values in and creates ordered pairs, supply-
ing the address numbers for the next coli. As in the previous example,
this coli uses the pitch class as the index to output the mapped note,
adding back the register at the end. PitchAnalyze is simply an encap-
suiated version of an algorithm that separates pitch class from register.
The second coil below is reformatted, as in figure 7.22.
Scale is straightforward and easy to use. It could easily be expanded
to include the features found in the previous two examples. However,
beware of "feature creep." Feature creep refers to commercial software
companies' constant addition of new features to old software, even
though the old software is perfect for the job. The new features may
add confusion or be rarely used. Composer objects may have so many
capabilities that they lose their single purpose, or offer so many options
that their operation becomes confusing.

MelodicContour: A Progressive Study in Generative Methods

Generative algorithms create complete musical statements from


"scratch" using basic musical elements or mathematical formulas. A
random-number generator, for instance, is a generative algorithm that
is the mainstay of most computer-music systems. Other formulas or
numbers, such as those derived from fractal geometry, chaos theory, or
even a phone number, may be used to generate pitch, velocity, dura-
tion, and rhythm.
Generative algorithms can be thought of in a traditional composi-
tional sense as creating larger musical structures from basic musical
motives or cells. This could be a short melodic fragment, a rhythmic
idea, or even a small set of intervals. Many traditional techniques for
motivic development can be coded as algorithms to produce complex
structures and variations based on a single musical idea. Computer mu-
sic, in general, lends itself weil to this type of organic thinking, where
a single cell spawns and mutates to grow into a larger form.
Generative algorithms may be mapped to a performer's incoming
pitches or other triggers to cause augmentation and elaboration of mu-
sical material. For example, specific pitches may produce trills, grace
notes, or arpeggios, using a portion of the current input.

Copyrighted Material
200 Core Components

A table is a useful structure for storing such raw material, since it


stores single items and can be viewed graphically. Tables can be used
to store aspects of a performance and then to play them back in a dif-
ferent order, or to use portions to create ostinatos or other variations.
Coli also is an obvious choice for holding raw material that will be
used to generate variations for a piece.
Several versions of a patch, MelodicContour, will show how a gener-
ative algorithm can be further developed with additional transforma-
tive processes.
MelodicContour: the Easy Version is a small program that gener-
ates melodies based on a set of three intervals (fig. 7.24). The intervals
are analyzed from a keyboard performance; the last three intervals
played will be the raw material used to create a melody. A pause of one
second or more will cause the interval recorder to reset and wait to
count the next three intervals. The performer controls the interval con-
tent, dynamic level, and starting note (register) of the melody.

Takes flotes played from the keyboard and generates a melody based on the intervals played.

Max number of beats


between changes of
300 melodic direction.

metro 300 I6
otein J

Direction J

Addlnterval gets ±ri pnot


the next interval
RandDir
Direction from a table of
counts random stored intervals. Getlnterval
number beats stores intervals.
between i and p RandDir p Add Interval
Direction, and Getinterval
bangs at max. T
UpDown adds or p UpDown
subtracts interval
from current pitch. ti i

makenote 77 300

noteout

Figure 7.24
Melodic contour: the easy version

Copyrighted Material
201 Composer Objects

The four subpatches operate as follows: Getlnterval records inter-


vals, Addlnterval plays back those intervals, RandDir (Random Direc-
tion) determines how often the direction of the melody will change,
and UpDown adds or subtracts intervals from the last pitch to create
a melody.
Getlnterval is the analysis and recording object (fig. 7.25). It simply
stores the last three intervals played into a table called "intervals."
After a pause of approximately one second, the counter is reset so that
the next four notes will store three intervals in the first three addresses
of the table. In this way, harmony can be changed "on the fly" either
by playing continuously or by pausing to record a complete set of new
intervals. Addlnterval plays back those intervals using a copy of the
same table (fig. 7.26). Each bang from metro goes to a counter that
continuously cycles through the table. The starting note to create the
melody is always the last note played, which could be from the perfor-
mer or the computer. In other words, while a performer is playing, the
computer creates a response in the same register as the performer. Once
a performer pauses, the computer continues to play, taking its last note
as a starting point. To generate the melody, a number is sent by the
user, s Direction, to the object RandDir (random direction), which
determines the maximum number of intervals that can go consecu-
tively in any one direction (fig. 7.27). The direction value represents
the maximum of a randomly generated number. With each bang, the

Gets intervals from incoming pitches, and stores them in table intervals.

pitch

Sends current pitch first to left minus


Bangs input to cycle
inlet, then to right as previous pitch.
the counter and move
the table location. rigger i i

ocker 1O counter -1 2 Gets the interval


between current
aos pitch and previous.

table intervals Stores last three intervals.

Resets counter after i second.

Figure 7.25
Getlnterval (subpatch of fig. 7.24)

Copyrighted Material
202 Core Components

Outputs intervals ¡n table when banged.

counter 0 2

table intervals

Figure 7.26
Addlnterval (subpatch of fig. 7.24)

Counts a random number between i and Direction (maximum range);


bangs highest number reached and chooses new number.

counter bang direction (maximum)

random 4
Selects a number between
1 and Direction.

counter i lo Counts to last random value;


bangs when reached and gets
new random value.

new range flag

Figure 7.27
RandDir (subpatch of fig. 7,24)

melody ascends or descends a certain number of times, by adding or


subtracting the intervals in the table beginning with the starting pitch.
After the end of each ascent or descent, a new number is issued by
RandDir that represents the number of intervals to go in the opposite
direction, and the toggle changes a GSwitch inside UpDown so that
it adds or subtracts (fig. 7.28). This process continues over and over
again, with RandDir sending new random numbers, and UpDown al-
ternately adding and subtracting the numbers. Eventually, numbers
generated outside the MIDI notenumber range will cause playback
problems.

Copyrighted Material
203 Composer Objects

Interval is added to or subtracted from old pitch.

interval old pitch number


D for up,
i for down

change
direction

new note out, to MakeNote


(also sent to old pitch input)

Figure 7.28
UpDown (subpatch of fig. 7.24)

In MelodicContour: the medium version (fig. 7.29), notes out of


range are corrected with RangeFlip, which alters pitches to fit within
a user-definable range. RangeFlip uses an approach different from the
previously mentioned RangeLoop and RangeMod (figs. 7.2 to 7.5).
User controls to set RangeFlip are provided to the right of the screen;
they set minimum and maximum values for the range, and specify
exact intervals (in semitones) to add or subtract to numbers falling out-
side the range to make the correction. In this way, a pitch outside a
range can be transposed up or down by an exact interval.
RangeFlip is particularly useful for processes sensitive to pitch (fig.
7.30). For example, a value of 24 or 36 to RangeLowAdd or RaugeHighSub
would transpose out of range pitches by two or three octaves, preserv-
ing the original pitch class. Parameter RcrngeMin sets the minimum
value and RangeMcix sets the maximum value. RangeLowAdd specifies
the number to add to values below RangeMin. RangeHighSub specifies
the number to subtract from values above RangeMax. If one addition
or subtraction does not "correct" the value, RangeFlip will continue to
add or subtract numbers until it is within range. With LowAdd and
HiSub set to 12, the object would always transpose melodies up or
down by one or more octaves until they fit inside the specified range.
In figure 7.29, melodies will go up or down between one and five
notes before changing direction. Larger direction values would create
broader, more sweeping melodic contours, whereas smaller values

Copyrighted Material
204 Core Components

Takes notes played from the keyboard and generates a melody based on
the intervals played. The melody is kept within a user-specified range.

K
Maximum number of beats between
300 notein
V5 changes of melodic direction.

metro 300 Direcbon


trip note
j36
minimum and
RangeMin s RangeMax
Getlnterval maximum ranges
24 24
amount added to or
r Direction RangeLowAdd s RangeHighSub subtracted from pitch
if outside range
(Caution, these values must not be
p RandDir greater than the range (above).)
Add Interval

p UpDown

RangeFlip constrains pitches between RangeMin and


p RangeFlip RangeMax. The note is looped back to UpDown as old note.

makenote 77 300

noleout

Figure 729
Melodic contour: the medium version

Places pitches within a specified range by adding to a low number or subtracting from a high number.

RangeMin RangeMax
input lower limit upper limit below add above subtract
RangeMin RangeMax RangeLowAdd RangeHighSub
Dont let the Dont let the If input is lower If input is higher
input fall input exceed than RangeMin, than RangeMax,
below this this amount. then add this then subtract this
amount. amount. amount.
selects input
less than 30 or split -127 30
RangeMin

adds 24 or + 24
LowAdd selects input greater than
split 110 256
110 or RangeMax

subtracts 24 or 24
HighSub pitches within range

output

Figure 7.30
RangeFlip (subpatcPKIÍQq Material
205 Composer Objects

would create "creeping" melodies that constantly change direction.


The range is set between 36 and 74, excluding the highest and lowest
notes on a keyboard. All values outside the range will be 'corrected"
by adding or subtracting 24 (two octaves). If the number 70 is sent, it
will pass through unchanged. If the number 30 is sent it will be
changed to 54 (30 + 24). If the number 300 is sent, 24 will be sub-
tracted ten times until the number is within range (300 - (24 * 10) =
60). Sending the object data that is closer to the desired range will
improve efficiency. Also, this object is a bit dangerous to use, since if
the values to add or subtract are not smaller than the entire range, a
note could be flipped back and forth, continuously falling outside the
chosen range.
In the "tricky" version of MelodicContour, (fig. 7.31) a simple ob-
ject, VoiceNum, adds a tremendous amount of variety to the previous

VoiceNum sends out a number of bangs specified by the VoiceNum


variable or a random number of bangs from i to VoiceNum.

300
number of voices
L
metro 300
notein
J

JVoiceNum
ripnote
random on/off
s RanVoice

k how often melodic


Direction
p VoiceNum V5 direction will change
p RandDir Direction
p Addinterval

G et Interval
range controls
p UpDown t36 I

RangeMin RangeMax
p RangeFlip
24 24

RangeLowAdd RangeHighSub
makenote 77 300

noteout

Figure 7.31
Melodic contour: the tricky version

Copyrighted Material
206 Core Components

number of voices per beat, either by VoiceNum or randomly.

bangs in Ran Voice Random number of voices per beat on or off.

r VoiceNum

random

+1

gate

r VoiceNum

store VoiceNum and


send when random is
turned off

An mt in the right inlet sets number of


zi
times to bang, and a bang in the left inlet
starts it.

bangs out

Figure 7.32
VoiceNum (subpatcti of fig. 7.31)

version. VoiceNum sends out one or more bangs for each one received
using Uzi (fig. 7.32). A single number to the left inlet of Uzi sends out
that many bangs immediately. A bang to the left inlet will continue to
send out multiple bangs. The number may also be set by the right inlet
(as in this example) or as an argument. In this way, it is possible to
make chords of two, three, four, or more notes with each metro bang,
all based on the same interval set. Another option, [s RanVoicel, uses
constrained random numbers to create a mixture of single notes and
chords, with the maximum number of notes per chord specified by
[s VoiceNumj. Thus, setting [s VoiceNumi to 3 and [s RanVoice] to on
will generate music with a mixture of single notes, dyads (two-note
chords), and triads (three-note chords).

Param Coil: Parameter Analysis and Playback

ParamColl (parameter collection) is a complex program that shows an


integration of listener and composer objects (fig. 7.33). ParamColl has
two main components: a recording section and a playback section. It
Copyrighted Material
207 Composer Objects

start/stop recording notein

stripnote

Record p GetDur p GetDelta


Note: last note played
is not recorded! ParamCollRecorder
ParamCollRecorder records the pitches, velocities,
durations, and rhythm of the melody played.

start/stop playback
set tempo
loo (defaults to tempo of recording)

EI
p ParamCollPlay

makenote
ParamCollplay plays the recorded melody.

noteout

Figure 7.33
ParamColl example

takes in a live performance, analyzing a single melody for four perfor-


mance features: pitch, velocity, duration, and rhythm (using algo-
rithms from chapter 5). It stores each parameter in a separate coil.
In example 7.33, all four colis play back together, using the same
counter to recreate the original performance. However, since all the
parameters are stored separately, a number of processes may be used
to generate variations. For example, by giving each coil a separate
counter with a different length, the various parameters could be con-
stantly cycled through, generating a kaleidoscopic mixture of the four
parameters. The counters could be set to cycle through the first ten
pitches, the first nine velocities, the first eight durations, and the
first seven rhythms. Irregular cycling of pitch and rhythmic values
can reproduce isorhythmic techniques similar to those common in
fourteenth-century music. Further variations could be generated using
the features found in counter. Counters could be set up to play por-
tions of the coil beginning at a given spot, loop up and down, or al-
ways play in reverse. Messages sent directly to coil can also manipulate
the stored data, such as goto, delete, sort, or insert. Finally, one or more
parameters could be replaced with a different source. Rhythm, for

Copyrighted Material
208 Core Components

ParamCoiiRecorder uses four coils to store pitch, velocity, duration, and rhythm. All
subpatches use counters to pack the current event number (used as the index) with the data.

PackPitch Pack Velocity GetRhythm


records the rhythm
r Record of the melody

sei O i

clears colis before


length clear beginning recording

coil PCPitch.c coil PCVelocity.c coli PCDuration.c

Length number of notes in melody

Figure 7.34
ParamCollRecorder (subpatch of fig. 7.33)

example, could be supplied by another algorithm or a human perfor-


mer, with the remaining recorded parameters playing back in response.
ParamColl Recorder uses listener objects to analyze pitch, velocity,
duration, and rhythm (fig. 7.34). Before recording, a tempo is set by
tapping the beat with the foot pedal or the spacebar of the keyboard.
Rhythms are limited in this example to sixteenth-note values. A further
variation could store delta times in a coli, rather than sixteenth-note
rhythms, and use the delta times to play back the other parameters
with the original rhythm or a scaled version of the original. In this
way, the rhythm would not be limited to sixteenth notes.
The algorithm for playing the colis is very simple. In ParamCollPlay
(fig. 7.35), three coils share a counter that can be set to any length by
sending a remote message to [r Lengthl (which defaults to the number
of notes originally recorded). Any bang into the counter will output
the next item in each coli. (Again, separate counters for each coil
would offer further possibilities for variation.) PiayRhythm can output
all the original rhythmic values, or, since it has its own counter, could
be set to cycle through portions of the collection. (See figures 6.16 to
6.18 for rhythmic analysis.) If the metro bangs bypassed PlayRhythm,
it would send constant beats to the other three coils below. With a few
modifications, a performer could control the whole timing mechanism
for playback, using the rhythm or tempo of a new melody to trigger
the parameters based on previously played material.
Copyrighted Material
209 Composer Objects

start/stop tempo

Tempo

primes the counter sel O


when stopped Imetro 250

p PiayRhythm
PlayRhythm turns the metronome
beat into the rhythms recorded.
r Length

counter Length is received from


ParamColl Recorder

coils share information


coil PCPitch.c coil PCVeiocity.c coli PCDuration.c
with recorder

Figure 7.35
ParamCollPlayer (subpatch of fig. 7.33)

Sequencer Methods

The previous example showed how whole sequences or performances


can be broken down to create raw material for generating new melo-
dies. Sequencer fragments or large sections can be recorded live, pre-
recorded, or imported as a standard MIDI file from another MIDI
application. Although coil may be used to record entire performances,
seq and detonate are specifically designed for that purpose. Seq files
record and play back the entire MIDI stream. Since their primary func-
tion is playback via a trigger, they have limited possibilities for varia-
tion. What they do well is to provide quick and easy playback of
numerous files, from short melodic fragments to long multichannel
arrangements. The primary variable control is playback speed. Short
seq files may be mapped to notein input to create ornamentation and
decoration around chosen notes. Longer files may be started to provide
a tape-style accompaniment for a section of a performance. (See fig. 9.6
for more information.)
Seq is ideal for playing music that a composer has carefully crafted
with a commercial sequencer, and will be played back the same way
each time. It is also useful for capturing generated material or a live
performance for playback. Virtually any performance condition or fea-
ture is capable of triggering a seq. Seq may also be used to feed listener
objects, replacing a live performer. In fact, an interesting working

Copyrighted Material
210 Core Components

method for a live interactive piece is for the composer to record the
performer's part using a seq, and then work with that file as a virtual
performer to do much of the programming and rehearsing without
the performer being there physically. That way, any problems that arise
within the program or the music can be discovered and ironed out
without wasting the performer's time. Analysis can be done on seq
using midiparse to separate the various parameters, but this is a job
more easily handled by detonate.
While ParamColl is a good study of how several analysis objects can
be coordinated with colls to generate musical variations, it is not a
very practical example since the detonate object already exists to re-
cord, edit, and playback most of the same information. In addition,
detonate records on multiple tracks, reads and writes MIDI files, and
displays all the data in a full-featured graphical editing window. In fact,
detonate uses delta time in the way suggested above for ParamColl,
Since it does not have an automatic timing mechanism, as does seq, it
usually gets its timing data from an analysis of the performed delta
times, stored in its left inlet. Other inlets are used to record pitch, ve-
locity, track number, MIDI channel, and there are two extra unspecified
inlets for any type of data (which could store the sixteenth-note rhyth-
mic values, for instance, or data from a modulation wheel or foot
pedal). All these parameters can then be viewed and edited in a graphic
score, or altered for playback with a variety of messages. Upon play-
back, detonate sends analysis data out separate outlets representing
delta time, velocity, pitch, duration, MIDI channel, track number, and
the two unspecified data tracks. Detonate is also very useful for under-
standing how complex and unpredictable composer objects work, by
capturing and displaying the musical output that shows the variations
that result from parameter changes.

Humanizing Algorithms: The Computer as Performer

Composition variables can be used with absolute values or constrained


random values to determine how much variation will occur from per-
formance to performance. Constrained random values define a range
of possible outcomes. These techniques allow a computer to "impro-
vise," producing music that is constantly changing and unpredictable
yet within a given style.

Copyrighted Material
211 Composer Objects

Similar techniques can be used to simulate interesting and expressive


performance qualities in computer-generated music. Humans cannot
possibly play with the accuracy of a computer, yet many musicians
strive in vain for such perfection in their technique. Ironically, it turns
out that listeners often find composer algorithms too perfect; the lack
of constant small imperfections creates music that is missing some of
the richness and complexity produced by real musicians. With many
algorithms, adding slight errors and the "jitter" associated with human
performance creates a more musically satisfying result. Jitter is the con-
tinuous, small fluctuating movement in many parameters that charac-
terizes all human performances and adds life to computer-music
performances. Pitch in wind instruments, for instance, is never steady,
but continuously fluctuates around the idealized target pitch. Some
algorithms add subtle and constant variation to pitch, velocity, dura-
tion, or tempo, which gives a more human-sounding performance. Con-
trolling a parameter like tempo with constrained random values, for
example, gives a wide continuum, from subtle fluctuations to wild,
irregularly spaced rhythms. Other humanizing algorithms attempt
to impart expressive phrasing and timing information to computer
music.

Using Constrained Random Numbers

The custom object, Randomize, is an example of a very useful all-


purpose object that adds random fluctuations to selected parameters.
In figure 7.36, the user selects the range of random fluctuations for
velocity using the Randomize object. The right inlet is the original
value to randomize, the middle inlet is the maximum percentage of
change allowed above or below that value, and a bang to the left inlet
sends out the new, randomized value. With each metro pulse, Ran-
domize takes the last played velocity value and changes it by adding
or subtracting a random percentage between O and n. Small random
values almost always improve the performance of dynamics; it is virtu-
ally impossible for any performer to maintain a constant dynamic
level, The same object could also be used to randomize tempo, dur-
ation, or any type of musical data. Randomizing the tempo by 4%,
for example, would make the pulse more human by adding slight un-
steadiness to the beat. Randomizing the tempo at 50% would produce

Copyrighted Material
212 Core Components

Randomize changes a given number by up to a certain percent around


it. In this example, the velocity of the melody is being randomized.

notein

93 strip not

metro 200
% to Value to
tbb randomize randomize

random 30 15 11>89

+ 40 p Randomize

makenote 100 200

flotea ut

Figure 7.36
Randomize example

melodies with the disjunct rhythms associated with certain styles of


twentieth century music, but with the overall speed still tied to the
metro. Randomizing duration adds variety to the articulation of music.
Small changes add subtle interest to all these parameters, while larger
fluctuations seem to make the computer's performance more passion-
ate (or even wildly out of control).
In figure 7.37, a percentage of the current value is determined by
multiplying the percentage number (percentage number * .01) times
the current value. The percentage number is sent to random, repre-
senting a range of new numbers, and thus, how wide the possible fluc-
tuation will be from the original. Rather than simply add this number
to the original, the entire range of random values is shifted downward
by half so that half of the values are positive and half are negative,
and therefore the randomization will take place above and below the
original value.
In the final version of MelodicContour: the hard version, several
humanizing and improvising features have been added that use con-
strained random values (fig. 7.38). Randomize has been inserted to
process duration, dynamics, and tempo. Also, two variable controls
work together to alter UpDown by influencing the longer term me-

Copyrighted Material
213 Composer Objects

bang out percent (0 to 100) to value to be


new value be added or subtracted randomized

15 tb
converts input
to percentage 0.01

tb
*
calculates range of 0.5
± this amount
randomness

range doubled to allow '13.35


b for + and values
26.7

random

converts doubled range into 20


positive and negative values

random amount
adds a positive or
+ negative random amount
to the original value
output 96

Figure 7.37
Randomize (subpatch of fig. 7.36)

lodic drift. UpOrDown is a variable that determines if the melody will


generally drift higher or lower over time. UpDown, by itself, drifts ran-
domly; it has no preference for direction. DirectionPull determines how
quickly the melody will reach the end points of the range. A zero may
be sent to bypass its effect. The strongest DirectionPull value is 1, creat-
ing arpeggios that go only in a single direction; the weakest value is
20. Over a large span of time, the melody will tend to go higher or
lower. In between there is more or less influence on the overall me-
lodic direction.
This series of examples show how subpatches are added to the pro-
cessing chain to generate complex variations and explore musical
material. Additional performance controls would create further interac-
tion, such as using a performer's Delta time to control tempo or using
continuous controllers to alter one or more of these compositional
parameters.

Copyrighted Material
214 Core Components

Takes flotes played from the keyboard and generates melodies based on the intervals played. These
melodies are kept within a user-specified range and may tend toward one end or the other of that range.

40 300

p Randomize notein

metro 300 st rip n o


Selects whether melody
tends toward up or down.
on = down, off = up
stores intervals
Getlnterval s UpOrDown

Changes how hard melody is


VoiceNum pulled up or down.
r Direction
off = 0, 1 = max, 20 = min
: RandD Add Interval
s DirectionPull H
Direction
random
p UpDown2 velocity H
5
p RangeFlip VoiceNum an Voice J

J- j33 I

random set
p Randomize
duration duration RangeMin RangeMax
>60 300

p Randomize RangeLowAdd RangeHighSub

makenote 77 300
J-
n oteo ut

Figure 7.38
Melodic contour: the hard version

CaptureG esture: Applying Human Phrasing to Computer Processes

Rather than simply simulate the irregularities of a human performer,


actual phrasing, timing, and dynamic information can be captured
from a performer and applied as input to compositional algorithms.
CaptureGesture is an example of a complex object that captures and
plays back gestural information regarding a performance (fig. 7.39).
CaptureGesture records and plays back musical gestures representing
the "expressive" information of a live performance: tempo, rhythm,
articulation, and dynamics. The playback module, PlayGesture, has
been separated from the recording module to facilitate ease of pro-

Copyrighted Material
215 Composer Objects

These patches capture and play back musical gestures -


the rhythm, articulation, and dynamics of a musical phrase.
CaptureGesture uses both a seq and a coil to store the data it needs -
the coli is for durations, and the seq is for rhythm and velocity.

Recording on/off Play Scale Tempo


OO

p CaptureGesture p PlayGesture

Figure 7.39
CaptureGesture example

sel i O

s RecStart RecStop

notein

Borax clear

pack1
J
coil CGDuration.c

stores durations

Figure 7.40
CaptureGesture (subpatch of fig. 7.39)

gramming. CaptureGesture uses both a seq and a coli to store the data
it needs; the coil stores durations and the seq stores rhythm and veloc-
ity (fig. 7.40). CaptureGesture can use a seq to record a portion of a
performance or a prerecorded seq. On playback, it is parsed for delta
time, velocity, and duration (fig. 7.41). In this way, it stores a tempo
map in a very compact form. It can then use this timing and dynamic
information, based on phrasing and other expressive playing tech-
niques, to impart those qualities to composer algorithms. In figure
7.41, the bang outputs are used to drive a random pitch-generating
algorithm, accompanied by the original "feel" of the performance. In
this way, a phrase from a performer can be captured, and that musical
gesture applied to a different computer melody or other parameters.

eriaI
216 Core Components

tbb idiin

percentage of RecStop
original tempo 0.01
op
converts to seq scale 1* 1024.

number box removes float Q r RecStart


mt
co rd
start $

stores rhythm (pitches) seq CG


and velocity
extracts Note-On data midiparse
unpack

st ri p note
pitches are converted
to bangs for playback
counter
random 3

+ 36 coli CGDuration.c

makenote 75 200
1
noteout

Figure 7.41
PlayGesture (subpatch of fig. 7.39)

The phrase can be played back slower or faster using tempo scale. This is
an interesting abstraction of a performance, since timing and dynamic
information do not have a life of their own separated from sound (De-
sain and Honing 1991). Composers will then find inventive ways to
apply these uniquely human properties to influence computer music
output.
CaptureGesture can also generate time-varying functions in con-
junction with Interpolator, which uses the line object to continuously
represent dynamic changes over time (fig. 7.12). These functions can
be used to control any parameters over time anywhere in the program,
imparting a live performance quality to the variable changes. These
continuous changes are especially effective for the continuous control
of timbre, vibrato, and signal-processing parameters.

Copyrighted Material
217 Composer Objects

These composer objects have shown just some of the diverse ap-
proaches to creating computer music using performer input based on
transformative, generative, and sequenced methods. These algorithms,
which represent a composer's tools and techniques, produce the mate-
rials and musical processes for a composition. In some cases, a few
simple algorithms may be very effective in producing short works. How
larger collections of objects are connected and how their events are
synchronized will be the focus of chapter 9. Resources for further study
are numerous, and additional examples are provided on the accompa-
flying CD-Rom. Of special note are several Internet sites where Max
programs are available for downloading.

Copyrighted Material

You might also like