OpenMusic Tutorial Edited by Karim Haddad
Published Date: 2003/11/05 13:10:44
This manual can not be copied, in whole or part, without the written consent of IRCAM.
This manual was produced under the editorial responsibility of Karim Haddad, Marketing and Communication Dept. , IRCAM. OpenMusic was conceived and programmed by Gérard Assayag and Carlos Agon.
Patchwork was conceived and programmed by Mikael Laurson, Camilo Rueda, Jacques Duthen, Gérard Assayag and Carlos Agon.
This documentation corresponds to version 4.6 or higher of OpenMusic. OpenMusic™ is a trademark of IRCAM.
Patchwork™ is a trademark of IRCAM. MidiShare™ is a trademark of GRAME.
Macintosh Common Lisp™ is a trademark of DIGITOOL, Inc. Apple Macintosh™ is a trademark of Apple Computer, Inc.
Acknowledgments: Markus Buser.
Copyright © 2003 by IRCAM. All rights reserved.
The use of this software and its documentation is restricted to members of the IRCAM software users’ group. For any supplementary information, contact:
Marketing and Communication Dept., IRCAM 1 place Igor-Stravinsky F-75004,Paris FRANCE Phone:(33) (1) 44 78 49 62 Fax: (33) (1) 42 77 29 47 Email: [email protected]
Send comments or suggestions to the editor: Karim Haddad
For more information: http://www.forumnet.ircam.fr
I. Tutorials ... xi
1. Using Musical Objects I ... 1
Tutorial 1: Transposing pitches... 1
Topics ... 1
Key Modules Used ... 1
The Concept:... 1
The Patch: ... 1
Tutorial 2: Inverting an interval ... 6
Topics ... 6
Key Modules Used ... 6
The Concept:... 6
The Patch: ... 6
Tutorial 3: Building a scale ... 8
Topics ... 8
Key Modules Used ... 8
The Concept:... 8
The Patch: ... 8
Tutorial 4: Inverting an interval II ... 9
Topics ... 9
Key Modules Used ... 9
The Concept:... 10
The Patch: ... 10
Tutorial 5: Retrograde ... 12
Topics ... 12
Key Modules Used ... 12
The Concept:... 12
The Patch: ... 12
Tutorial 6: Four basic operations on a 12-tone row ... 13
Topics ... 14
Key Modules Used ... 14
The Concept:... 14
The Patch: ... 14
Tutorial 7: Changing melodic contour... 17
Topics ... 17
Key Modules Used ... 17
The Concept:... 17
The Patch: ... 17
Tutorial 8: Construction of a harmonic series... 19
Topics ... 20
Key Modules Used ... 20
The Concept:... 20
The Patch: ... 20
Tutorial 9: Dealing with data types ... 25
Topics ... 26
Key Modules Used ... 26
The Concept:... 26
The Patch: ... 26
2. Playing MIDI I ... 29
Key Modules Used ... 29
The Concept:... 29
The Patch: ... 29
Changing MIDI instruments ... 29
Playing microtones using MIDI ... 31
3. Using Aleatoric Elements ... 33
Tutorial 11: Constructing a Chord with random notes from a harmonic spectrum 33 Topics ... 33
Key Modules Used ... 33
The Concept:... 33
The Patch: ... 33
Tutorial 12: Building a sequence of random notes:om-random... 35
Topics ... 35
Key Modules Used ... 35
The Concept:... 35
The Patch: ... 35
Tutorial 13: Another random sequence ... 38
Topics ... 38
Key Modules Used ... 38
The Concept:... 38
The Patch: ... 38
4. Flow Control I: Predicates ... 45
Tutorial 14: Random construction of a sequence... 45
Topics ... 45
Key Modules Used ... 45
The Concept:... 45
The Patch: ... 45
5. Flow Control II: Loops... 49
Tutorial 15: Introduction toomloopI ... 49
Topics ... 49
Key Modules Used ... 49
The Concept:... 49
The Patch: ... 49
Tutorial 16: Introduction toomloopII ... 53
Topics ... 53
Key Modules Used ... 53
The Concept:... 53
The Patch: ... 53
6. Using Musical Objects II ... 59
Tutorial 17: Generation of a melodic sequence from harmonic reservoirs... 59
Topics ... 59
Key Modules Used ... 59
7. Breakpoint Functions... 65
Tutorial 19: Using BPFs I; Graphic representation of a series of notes ... 65
Topics ... 65
Key Modules Used ... 65
The Concept:... 65
The Patch: ... 65
Tutorial 20: Using BPFs II: Sampling a sequence of notes... 66
Topics ... 67
Key Modules Used ... 67
The Concept:... 67
The Patch: ... 67
Tutorial 21: Using BPFs III: Scaling a melodic contour ... 69
Topics ... 69
Key Modules Used ... 69
The Concept:... 70
The Patch: ... 70
8. OM Music objects Chord-seq and Voice... 75
Tutorial 22: Chord-seq: Onsets and durations I ... 75
Topics ... 75
Key Modules Used ... 75
The Concept:... 75
The Patch: ... 75
Tutorial 23: Chord-seq: Onsets and durations II ... 77
Topics ... 77
Key Modules Used ... 77
The Concept:... 78
The Patch: ... 78
Tutorial 24: Voice I ... 80
Topics ... 80
Key Modules Used ... 80
The Concept:... 80
The rhythmic structure ... 81
Rests... 82 Ties ... 82 Irrationals (tuplets) ... 83 The Patch: ... 83 Tutorial 25: Voice II ... 85 Topics ... 85
Key Modules Used ... 85
The Concept:... 85
The Patch: ... 86
Tutorial 26: Editing rhythm with the Voice graphic editor ... 90
Topics ... 91
Key Modules Used ... 91
The Concept:... 91
The Patch: ... 91
The time signature ... 93
Adding new measures ... 94
Creating the basic rhythmic structure ... 95
Subdividing the structure ... 99
Entering pitches ... 100
Tutorial 27: Introduction to rhythm quantification ... 101
Topics ... 101
Key Modules Used ... 101
The Concept:... 102
The Patch: ... 102
9. Playing MIDI II ... 107
Tutorial 28: Working with MIDI files I... 107
Topics ... 107
Key Modules Used ... 107
The Concept:... 107
The Patch: ... 107
Tutorial 29: Working with MIDI files II... 111
Topics ... 111
Key Modules Used ... 111
The Concept:... 111
The Patch: ... 111
10. Using Musical Objects I ... 119
Tutorial 30: Working with lists I... 119
Topics ... 119
Key Modules Used ... 119
The Concept:... 119
The Patch: ... 119
Tutorial 31: Working with lists II... 121
Topics ... 121
Key Modules Used ... 121
The Concept:... 122
The Patch: ... 122
11. The Maquette ... 125
Tutorial 32: Introduction to the Maquette I... 125
Topics ... 125
Key Modules Used ... 125
The Concept:... 125
The Patch: ... 128
Tutorial 33: Introduction to the Maquette II... 130
Topics ... 130
Key Modules Used ... 130
The Concept:... 130
The Patch: ... 131
12. Lambda Functions ... 137
Tutorial 34: Introduction to Lambda Functions ... 137
Topics ... 137
The Concept:... 144
The Patch: ... 144
13. Flow Control III: More Loops! ... 149
Tutorial 36: Accumulation... 149
Topics ... 149
Key Modules Used ... 149
The Concept:... 149
The Patch: ... 149
Tutorial 37: Accumulation with musical objects ... 151
Topics ... 152
Key Modules Used ... 152
The Concept:... 152
The Patch: ... 152
14. Flow Control IV: Recursive Functions... 157
Tutorial 38: Recursive patch I... 157
Topics ... 157
Key Modules Used ... 157
The Concept:... 157
The Patch: ... 158
Tutorial 39: Recursive patch II... 159
Topics ... 159
Key Modules Used ... 159
The Concept:... 159
The Patch: ... 160
15. The Maquette II ... 165
Tutorial 40: More Advanced Maquettes and MIDI ... 165
Topics ... 165
Key Modules Used ... 165
The Concept:... 165
The Patch: ... 166
The onsets ... 168
Evaluating Maquettes ... 168
Tutorial 41 ... 170
16. Classes and Inheritance ... 171
Tutorial 42: Creating a Generic Function I ... 171
Topics ... 171
Key Modules Used ... 171
The Concept:... 171
Creating the Function ... 171
Tutorial 43: Creating a Generic Function II ... 181
Topics ... 181
Key Modules Used ... 181
The Concept:... 182
Adding New Methods ... 182
17. Classes and Inheritance ... 189
Tutorial 44 ... 189
Tutorial 1: Transposing pitches
Topics
Using an arithmetic function to transpose pitches
Key Modules Used
Chord,om+The Concept:
Pitches in OM are expressed in , or midics. Midics are values (60 corresponding to middle C on the piano) multiplied by 100. 100 midicents = 1 semitone.
Transposing a note is thus equivalent to adding or subtracting from its midic value. We’ll do this with a simple arithmetic operatorom+.
The notes to transpose are found in a Chord object but we could take any midic output for the operation.
The Patch:
This patch transposes the notes in Chord box (A) by adding (C) the value you have entered at the second input to om+(B) to every note. The midics are then reentered into a Chord object so we can see the results.
Double-click the first Chord box (A) to open the graphic editor. The chord is displayed on four staves, as indicated by the pulldown menu reading ’GGFF’. The top treble and bottom bass clef are an octave below and above sounding pitch. This is convenient if your musical object has lots of ledger lines.
The mini-view: These Chords are already in mini-view, allowing you to see their contents.
The chord changes to display its notes in the order they were entered (which is not neces-sarily an ascending arpeggio, although this happens to be the case here:
To add notes in the Chord editor, hold option and click where you’d like to insert the new note. Then close the chord box.
When you evaluate the Chord box, it takes data from its inputs. If nothing is connected, this will effectively reset the Chord to its default state since it will read the default settings of the inputs. In order to preserve the notes we add, as well as the notes already present, we must lock the Chord, if it is not locked already. Here is an unlocked Chord:
A locked box retains its value(s) and always outputs them when evaluated. It does not take data from its inputs. Make sure your upper Chord box is locked. Also make sure the lower Chord box is not locked or else you won’t see the transposed notes.
Now evalute the patch by clicking once on the lower Chord object and hitting v. You’ll see the newly transposed notes.
Now, enter another transposition value in the box connected to the right input of the om+ box. To transpose by a semitone you have to enter the value 100. A quarter-tone corresponds to a value of 50 and a eighth of a tone to 25. (Notice that both quarter- and eighth-tone pitches can be expressed in whole numbers- the advantage of midics.) If you enter a positive number, the original notes will be transposed up, otherwise they will be transposed down.
The OM music object editors automatically ’round off’ pitches for display. By default, they display pitches in a twelve-tone octave, even if the midics are not multiples of 100. To confirm this, set the input ofom+to 50, which will transpose the notes up by a quarter tone. Evaluate the lower Chord box. You won’t see and quarter tones. In order to turn on quarter-tone visualization, use the pull-down menu in the Chord editor:
Now you should see quarter tones.
Tutorial 2: Inverting an interval
Topics
Changing the direction of an interval using arithmetic functions.
Key Modules Used
om+,om-,x-appendThe Patch:
First, open the two Note box editors, and change the note, if you want. You can do this either by dragging the note with the mouse, or by clicking on it with the mouse so it is selected and using the cursor keys. Holding shift while using the cursor keys moves the object by octaves. Deleting notes is done by selecting them and hitting delete. Whatever notes you choose, don’t forget to make sure the boxes are locked (with the b key) before continuing. Here are the notes by default:
With these values,
Note (A) outputs 6000 as its midic. Note (B) outputs 7100. The om- function (C) takes the difference of the two: -1100. This is the number that must be added to the first Note to reverse the direction of the interval, withom+(D).
We need to combine these notes into a Chord object. The online documentation (see Quick Tour) tells us that the second input on a Chord object takes a list of midics. So, we combine the original first Note’s pitch, 6000, and the result of our calculation, 4900, into a list with thex-appendfunction, which takes any inputs and combines them into a single list. The resulting pitch is displayed below.
Tutorial 3: Building a scale
Topics
Constructing a scale using thedx->xfunction.
Key Modules Used
Note, Chord-seq,dx->xThe Concept:
Here we usedx->xto build a scale.dx->xtakes a list of relative quantities and changes them into absolute quantities starting from a point we define. In this case, we’ll use it to define a scale (which is, after all, a set of relative intervals) which we can then build on any note.
The Patch:
Open the NOTE box (A) and pick the note from which you would like your scale to begin. Then lock it.
Enter a list of intervals in this box in order to construct a scale. Remember that an interval of 100 is equal to a semitone. In the example we’ve entered a major scale.
In the example, the Note outputs 6000 as its midic. Thedx->x function starts with 6000 and adds, sequentially, the elements at its second input. This list of midics is put into the
lmidicinput of the Chord-seq object. Remember, you can see the names of the inputs by command-clicking on the inputs themselves.
Evaluate the Chord-seq box to see your scale starting on your note.
Tutorial 4: Inverting an interval II
Topics
Key Modules Used
Chord,x->dx,dx->x,om*,first
The Concept:
Here we revisit tutorial 2 with an alternate solution. We will invert the interval, this time by converting it into a relative interval with thex->dx function, and by multiplying this relative interval by -1 to reverse its direction. We use the complementary functiondx->xto convert back to absolute pitch.x->dxfinds the distances between elements of a series, and its sister functiondx->xconverts relative values to absolute values, given some starting point.
The Patch:
OK, so we start with our Chord-seq object. We take thelmidicoutput, which produces (6000 4900) in our example. On the right, we send that list of values tox->dx, which converts them into a a relative distance. The output ofx->dxwill always have one less element than the list, since it measures distances between elements.
con-sidered to be the first value and the interval is thus downward. Remember that the order of notes in a Chord object is determined by the order they were entered in. Had the other note been entered first, it would be taken as the starting point instead of 6000. We multiply this by -1 withom*. Which gives us 1100, the inversion of the interval. Now, we need to make that 1100 relative to the first note, 6000.
To do this, we use the lisp functionfirst, which, you guessed it, takes the first element of a list, to extract 6000 from the list (6000 4900). That value is passed to the first input of dx->x, which uses it as a ’jumpin off’ point for the interval 1100 and arrives at the next note, 7100. These two notes are passed to the Chord object, which renders the inverted interval.
Tutorial 5: Retrograde
Topics
Here we perform the basic musical operation of retrograde on a group of notes. We’ll transpose it in the process.
Key Modules Used
Chord, Chord-seq,om+,reverse
The Concept:
Here, we’ll take the lmidic output of the Chord factory. You can check to see what’s coming out of the factory at this output by option-clicking this output. If you haven’t changed the notes, you’ll see this in the Listener window:
? OM->(6000 5600 6400 7800 7200 7100)
Remember that the order of notes here just represents the order they were entered in. This list of midics will be passed toom+for a transposition and then retrograded withreverse.
The Patch:
The midics are passed toom+. Notice thatom+can accept both a list and a single number as inputs. In this case, it adds the single number to all the elements of the list.
The resulting transposed list is reversed withreverse, which does just what it says it does. The new sequence of notes is plugged into the second input of a Chord-seq object. We could have plugged it into a Chord object, but the retrograde would not have been visible since the notes would have been stacked one on top of the other. (Unless we went into the editor and used the order selection from the pull-down menu)
Tutorial 6: Four basic operations on a 12-tone row
Topics
This tutorial applies what we’ve learned in the previous four to transformations of a 12-tone row.
Key Modules Used
Chord dx->x,first,om*,om+,reverse,x->dx
The Concept:
Here we perform the operations of the preceding four tutorials on a single bit of mate-rial, in this case from Boulez’s Structures. They are: transposition, retrograde, inversion and retrograde of the inversion.
The Patch:
The original row from Structures is in the Chord box at the top. You may keep these or change them around in the editor. Select the order option for the view (it’s less cluttered than a big fat chord).
The four Chord objects will also need to be viewed in order mode. They can be evaluated individually.
Evaluate Chord (C) and the notes are transposed:
intervals. Multiplying these by -1 (G) changes their direction. Withdx->x, (I) we will rebuild the list starting from the first element, which we extract withfirst(H). The result (L):
And finally, it’s easy to take the retrograde of this last row with thereversefunction:
Tutorial 7: Changing melodic contour
Topics
A melody form is compressed or expanded vertically by a set amount.
Key Modules Used
Chord, Chord-seq,dx->x,x->dx,first,om*,om-round
The Concept:
Here we’ll take a group of notes ordered in time as a melodic contour that we want to play around with. The midic values of the notes are taken from the Chord object, converted into relative intervals withx->dx, and multiplied by a scaling factor. The result is converted back into absolute values and passed back to a Chord-seq module.
greater than zero will make the intervals smaller. Entering numbers larger than 1 will make the intervals larger. Entering values smaller than zero will, as we saw in the last tutorials, invert the interval sequence.
Thefirstbox takes the midic of the first note of the Chord, which is not necessarily the lowest- remember, the Chord returns notes in the order they were entered, not the order in which they occur in the chord.
The om-roundfunction rounds any number to the nearest whole number. To check this, change the multiplier at (C) to something with lots of decimals, .7654321 for example. The midics that it returns will have lots of decimals.om-roundchanges them into integers (whole numbers) before transmission to the Chord-seq object. This is unecessary. As mentioned earlier, the music object editors have an automatic ’rounding function’ for display purposes. Try this: Drag a connection from the output of thedx->xfunction directly to the second input of the Chord-seq. Evaluate (by option-clicking) the output ofdx->xto make sure the results have lots of decimals. Evaluate the second output of the Chord-seq object. The decimals are still there, right? Even though your midics were not multiples of 100, the Chord-seq object displays notes as if they were rounded off- this is only for display and does not affect the data itself.
Now, open the Chord-seq editor. From the pull-down menu, select 1/4 from the list:
You’ll notice some of the notes changing because their original midics were closer to quarter-tones than to semi-tones. Change it to 1/8 and you’ll probably see some more notes change to the more exact 8th-tone temperament.
Tutorial 8: Construction of a harmonic series
Topics
We’ll use the functions arithm-serandom* to generate a harmonic series based on a fundamental we supply. This patch is built for you in this tutorial but try building it yourself from scratch.
Key Modules Used
Note,mc->f,f->mc,arithm-ser.
The Concept:
As many of you will remember from high school physics, (if you’re not yet in high school, bless your precocious little heart) the integer multiples of a given frequency (the fundamen-tal) represent a harmonic series present in all pitched tones. We can construct a musical object with the same structure.
To do this, we first need to establish the frequency of our fundamental. Then we need to multiply it by a series of increasing integers. Then the results need to be converted from frequencies into notes (midics).
The Patch:
The default note is a low C, two ledger lines below the staff. For very low notes such as this, the mini-visualization may change to an octava clef (the bass octava clef in this view displays notes two octaves above their true pitch):
In this patch, we’re going to use an what’s called an abtraction, better known as a red patch. The fact that this patch is red indicates that it exists only within this patch. You can drag it to another patch or make copies of it, but those copies exist separately and making changes in one does not affect the other.
within the current patch. The blue patches, in contrast, represent a master copy of that patch-when you drag a blue patch from the workspace into a patch window, you create a reference to that patch. This means that the same patch can be used over and over in various contexts, but if you make any changes to the patch, those changes also occur wherever else the patch is referenced. Sometimes this is great; if you don’t want this, however, you must abstract a patch from the blue patch- creating a local copy that you can manipulate with impunity.
We, on the other hand, are interested in a second, more mundane advantage of the red patch. It’s a handy housekeeping device. You can put a bunch of functions which accomplish a certain task within your function in an abstraction and give it an evocative name- it helps a lot once your patches get big, and can save loads of time when troubleshooting.
So, let’s create the abstraction first, to hold the part of our patch which calculates the series. Command-click somewhere in the patch window. the usual box appears:
Typepatch.
The abstraction apppears.
We can now rename the patch ’harmonic series’ by double-clicking on the name ’mypatch’. Open the patch by double-clicking on its icon. You will notice in the upper left corner two buttons just like the two in the upper left of the patch window. They represent outputs and inputs which can be added to the patch to allow it to communicate with the outside world. Clicking the left-hand button adds an output, and clicking the right-hand button adds an input. Once added, you can rename an output or an input just like you did the red patch.
Click to add four inputs and one output. If you add too many select them and hit delete.
The inputs we’ve added are gateways to the outside world. We’ll pass data to these inputs from outside the patch box.
To generate a harmonic spectrum we must multiply the frequency of the fundame ntal note by the its place in the harmonic series (for example, we must multiply a fundamental at 60 Hz, by 1,2,3 etc...)
First, we need to convert the fundamental pitch from a midic into a frequency, which will be done with the mc->f function. We’ll also need a list of integers representing the pitch ratios of the series. For this we’ll usearithm-ser, which will generate an arithmetic series beginning atbegin, and addingstepeach time untilendis reached. These amounts, like the fundamental, will be set from outside the patch. Using 1 as step will return a list of consecutive numbers (1 2 3...) and will thus return the entire harmonic series. If we wanted
ser don’t know what to do with that value. They are expecting numbers. We must change the inputs so that they return a different value by default.
Default Values at Inputs: When you’re building a patch, you’ll usually need to test it before you’re finished. When you’re inside a patch, the inputs produce their default values, even when connected to other stuff outside the patch. This can cause problems when evaluating your work halfway through. Luckily, you can set the default value produced by an input. Choosing a goood default value allows you to test the patch before you close the window. On the outside, this default value is replaced by whatever you connect to the input. If you connect nothing, however, the patch behaves as if you used this default input. In this way you can set the ’default behavior’ for a patch.
Let’s change the default values for our inputs by double-clicking the arrow icons inside the patch window. For each one, a window like this comes up:
Here you can set the default value of the inputs, as well as add a bit of information about what they do. Naming them is done by clicking on their names in the patch window.
Input and Output Names: Remeber the pop-up help you get Command-clicking on inputs and outputs? That pop-up help also appears for your own custom-built patches, and the names that you give your inputs and ouputs within the patch are the names that pop up in the bubbles when command-clicked from the outside.
Giving your inputs and outputs names is a good habit to get into, it’s easy to forget what’s what when your screen is filled with icons.
If you’ve been using the pre-made patch in theTutorialsfolder, the default values have already been set. Try rebuilding the patch from scratch to see what we mean.
Tutorial 9: Dealing with data types
Topics
Introduces the concept of data type.
Key Modules Used
Note,first,om*, ChordThe Concept:
This postlude will demonstrate what is meant by data type.
Now, drag a connection from the list of integers to this second input of Note and evaluate. You’ll get an error like this:
This is because a list is a different data type than a real. real is LISP’s term for any kind of number.
first, on the other hand, only accepts lists as input, since it takes the first element of a list. Give the float tofirst as input and you’ll get a similar error. float is LISP’s term for a number with decimals.
Now, plug the list of integers into first. first has what it wants; evaluating gives the answer 6900. You can take this 6900 at the output offirstand plug it into the second input midicof the Note object. It too, now has what it wants. You can find out the data types accepted by any function by looking it up in the Function Reference.
Take the list of integers and plug it into the second inputlmidicof the Chord object. This input expects a list, and you’ll see the notes in the mini-view.
Now, take the first output of the top Note object,self.selfexists for many classes, and outputs the entire object. Evaluate self and you’ll see something like#<note #x9327B36>
in the Listener. This is the Note object, and it is a data type like list and float. Plug this into the first input of the lower Note object. Evaluating effectively duplicates the Note because it passes itself to theselfinput of the other note.
Plug theselfoutput of the Note into one of the inputs ofom*. Error. This is because the Note object is not just a midic- it’s the collection of attributes of that Note, including volume, duration, and MIDI channel. Theselfoutput of the Note contains all the information from the other inputs. As seen earlier, if you want to take just the midic of the Note, you must take it from themidicoutput. Do this now and plug it intoom*. At the second input you may use either a integer or a list or a float. None of these cause errors. Why not?
OM functions are what is called a generic or polymorphic function. This means that they can be programmed to perfom differently depending on the data type they are given as input. This will be discussed in more detail later.
object. The note appears in the Chord. What gives?
You’ve just witnessed a concept called . Inheritance will be explained in more detail later, but for now, you should know that all classes in LISP, but particularly the music objects, can ’inherit’ information from simpler objects. A Chord is collection of Notes; it can therefore inherit from the Note class.
Play around with the functions and objects in this patch to get your mind around the concept of data type.
Tutorial 10: Playing MIDI
Topics
MIDI output with OM via Midishare and the QuickTime GM Synth
Key Modules Used
pitchwheel,pgmout,repeat-n, Chord-seq
The Concept:
This tutorial covers how to output MIDI from OM via Midishare. It assumes you’ve installed and configured Midishare- if you haven’t see the chapter on Installing Midishare Even if you have no MIDI equipment, you can still use Apple’s built-in QuickTime Musical Instruments synthesizer (which responds to MIDI messages just like any other MIDI instrument) to listen to your work. If you’re working in 24- or 48-tone octaves, you’ll need to reconfigure QuickTime to play quarter and eighth tones. This is covered in the second half of this Tutorial.
The Patch:
Changing MIDI instruments
In the top half of this patch we’ll send the notes of a Chord-seq out over 12 difference MIDI channels:
We’ll use the two lists, (A) and (B) as program changes and MIDI channels, respecively. Notice we’ve left out channel 10 as that channel is reserved for percussion instruments on the General MIDI standard.
Evaluating pgmout will send these program changes on the MIDI port designated at its third input (D). This function always returns nil in the Listener- the MIDI messages are sent anyway. Evaluate this box now.
Now enter some midicents in the list (E). Keep the list limited to 12 elements. Connect list (B) to the seventh inputlchanof the Chord-seq (F). The numbers in this list represent MIDI channels to which consecutive notes will be assigned, and is why we wanted the lists to be the same length. Evaluate the Chord-seq object and open its editor.
Set the display options pop-up to channel. A color-coded numebr representing the MIDI channel appears next to each note. If you play it, each note will sound on a different channel, with a different timbre as a result of thepgmoutcommand we issued.
To reassign a piano sound to all the channels, use thepgmoutmodule at (G), which issues a program change back to 1 on all channels.
Playing microtones using MIDI
Now let us build a simple patch that will play microtones using Chord-seq.
of 25, representing eighth-tones.
We add 600 to each element usingom+so that the list starts on 6000. The result is (6000 6025 6050 6075 6100 6125 6150 6175 6200) Evaluate the Chord-seq.
In the editor, you must select 1/8 from the temperament pop-up menu in order to see the eighth-tones displayed. However, they don’t play back correctly. This is because the MIDI standard does not directly incorporate intervals smaller than a semitone. To get around this, we take advantage of the fact that OM automatically sends microtones on other MIDI channels. Normal semitones are sent on channel 1. Microtones are sent on other channels based on how much higher they are:
Sharp by Sent on MIDI channel
One eighth-tone 2
One quarter-tone 3
Three eighth-tones 4
We’ll send a pitchwheel message to each of channels 2, 3, and 4, detuning the entire chan-nel so that its notes will play back corectly. The upperpitchwheelbox sends the following messages:
• 0 to channel 1 which stands for no pitch bend
• 1024 to channel 2 which stands for one eighth-tone up • 2048 to channel 3 which stands for one quarter-tone up • 3072 to channel 4 which stands for three-quarters of a tone up.
8190 is the highest possible value forpitchwheel. It represents a full tone on most MIDI instruments. This can be changed, however, and some MIDI instruments map the pitch-wheel differently, taking 8190 to be only a semitone. In this case you need to evaluate the secondpitchwheelfunction.
Once you evaluatepitchwheel, the eighth-tones play back correctly. The lowest pitch-wheelresets the other channels to normal tuning.
Tutorial 11: Constructing a Chord with random notes from a
harmonic spectrum
Topics
Using a random functions to choose elements from a harmonic series which are then built into Chords
Key Modules Used
pitchwheel,x-append,om-random,nth-random,repeat-n,om+, Chord-seq
The Concept:
The repeat-nbox evaluates the function at its first input a number of times (indicated at the second input) and returns the result as a list. Theom-randombox returns a random number between its two inputs. We start with the harmonic spectrum chord generated in Tutorial 8. We’ll build 5 groups of random chords from its elements, then transpose the second of the groups up by a fourth and the fourth of the groups up by a fifth, creating a sort of demented I-IV-I-V-I progression.
If you built a different harmonic series in Tutorial 8 and want to use it here, hold option and drag it into the Tutorial 11 window- this will create a copy of your original object. Note that this works with any object or group of objects.
The Patch:
called a tree.
The second and fourth inputs tox-appendare passed throughom+(H & I) for a transposi-tion. The others are untouched. Note thatx-appendhas 5 inputs here- each of those inputs causes repeat-nto be evaluated anew. This means that each group of 5 chords will be different, randomly generated.
The result ofx-appendis a list of lists. Remember the discussion of data type in Tutorial 9? Well, thelmidicinput of the Chord-seq object can take either a list of integers, in which case it assumes they are individual notes to be taken in order, or a list of lists, a tree, in which case it assumes each sublist represents a chord. That is what happens here.
When you are done, you can play the Chord-seq. You may need to evaluate the pitch-wheelfunction in the upper-right in order that the microtones play back correctly. (See Tuto-rial 10 for more info).
Tutorial 12: Building a sequence of random notes:
om-random
Topics
Usingom-randomandrepeat-nto build sequences of repeated notes. The ’eval-once’ mode for modules.
Key Modules Used
om-random,repeat-n, Chord-seq,x-append
The Concept:
This example shows the use of om-random for generating random repeated notes. We will use this function in two different ways: generating pitch and generating the number of repeated notes.om-randomwill be used in both normal and ’eval-once’ modes.
First of all we will generate midicent notes by using om-random. This function takes as arguments two numbers (integer or float). The two arguments represent the range of num-bers that om-randomwill produce, inclusive. For our example, we will use MIDI notes and then multiply the output by 100 to obtain midics. On the right, we’ve connected these to repeat-n, allowing us to obtain a series of 5 random midics in a list:
Now let’s compare the outputs of (B) and (C). The output of the B patch is a list of five different values each time it is evaluated, while the ouput of C patch is a list of five identical values. Why? The difference is the state of the om-random patch. Notice the little "1" in the upper-left corner of the om-randomon the right? That means the function is in ’eval-once’ mode, and will only evaluate once for each time the flowchart is evaluated. This means that it will return the same value each subsequent time it is called byrepeat-n. In contrast, the otherom-randomgenerates a new random midic each time.
To put a patch into ’eval-once’ mode, select it and hit b this brings up the little "X", which means the function is locked. The lock is one of four special modes which can be applied to boxes. Clicking one on the "X" changes it into a 1, which indicates ’eval-once’ mode. You can return the box to normal by hitting b a second time.
On the left, we’ve copied B and C, replacing the input 5 with anotherom-randomto generate the integers for the number of repeated notes. Notice that we have used one om-random module instead of three. That is because (D) is in normal mode, and will be evaluated three
times because its output is connected to three other inputs.
Connecting the outputs of the three repeat-nmodules tox-append(E) will result in one big list.
We will use aChord-seqeditor to collect our resulting notes. The first input of the Chord-seq editor is self, the object itself, as with all editors and classes. The second input is the midic input. Remember the idea of inheritance from Tutorial 9? The Chord-seq class inherits from the Chord object.. This means that you can pass a list of Chord objects to the first inputselfof a Chord-seq to obtain a sequence of chords.
Alternatively, as described in the last tutorial, thelmidicinput can accept a tree of midics, where each sublist is interpreted as a chord. However, we’ve entered a flat list with no sub-lists, so Chord-seq will interpret this to mean a series of notes- a series of one-note chords, actually. Try evaluating the second output of the Chord-seq and compare with the output of x-append(E).
The third input of the Chord-seq object is a list of onsets times, i.e. chord positions in the sequence in elapsed milliseconds. The elements of this list are paired up with the elements of lmidic to determine where the chords are. By the same token, the fourth is a list of durations, also in milliseconds. In the example above we have changed the default values (0 1000) and (1000) to shorter durations so that the thing will play faster. If we enter just two values for the onsets then Chord-seq assumes that these two values define the interval between chords. This is what happens here; Chord-seq puts the notes 100ms apart.
The same is true of the duration input,ldur. A single value causes Chord-seq to assume that the duration is global and applies to all notes. If you enter more than one duration but not enough to pair off with every chord, the last value entered is used for all remaining chords. The same is true of the onsets.
Tutorial 13: Another random sequence
Topics
The inputsldur,lvel, andlegato.
Key Modules Used
om-random, Chord-seq,repeat-n,dx->x
The Concept:
We use a similar structure here, extending our random procedure to the onsets and dura-tions of the notes.
The Patch:
We will use the same patch as in tutorial 10.om-randomwill be back in its normal mode, because here we don’t need repeated notes.
At (B), we will use patch we used for durations with slightly different parameters to produce lists of numbers appropriate to onsets and durations. om-randomwill generate values be-tween 100ms to 500ms. (Durations and onsets in OM music editors are always expressed in milliseconds.)
We want to create a sequence with no gaps between the notes. This means that the onsets and the durations have to match up. We make sure that the same sequence is used by settingrepeat-nto ’eval-once’ mode.
Off-sets, on the other hand, are measured from the beginning of the sequence. This means we can’t use the same list for both lonsetandldur inputs. Usingdx->x, we turn the list of durations (the time between notes) into a list of onsets relative to the starting time, 0.
As we just learned, notes in a Chord-seq can overlap. The Chord-seq object can thus accept polyphonic input. For example, place a Midifile class in the patch and evaluate it. A dialog window comes up. Look for the file INV6.MID in the exampleFiles/Midi folder, in the main OM folder. This is a MIDI file of the 6th two-part invention by J.S. Bach. Once evaluated, lock the box.
Opening the Midifile brings up a piano-roll style editor where you can see the two channels of the MIDI file, color coded for clarity:
The Chord-seq class can take a MIDI file as input to its self input, and it will be tran-scribed:
Opening the resulting Chord-seq and selecting dur from the view options pop-up menu will show the durations of the notes represented as colored bars:
Returning to our patch, giving a single number to all 3 second inputs of therepeat-nbox causes each element to be evaluated 3 times, producing lists of the same length for our midics, onsets, durations, and note velocities.
Note velocity is MIDI’s way of indicating how hard a note is struck. You can visualize the velocity by selecting dyn from the view options pop-up in the editor. Here is an example in page mode, which is turned on using the page view button, circled in red.
OM turns the velocities into traditional dynamic marks using a table you set up in the Prefer-ences panel. Now look at the far right-hand input,legato. Setting this to 0 leaves durations as they are. Any other number, however, will override theldurinput, and set the durations to a percentage based on 100 being perfect legato- each note lasting exactly as long as it needs to. Smaller numbers will result in gaps in the sequence, longer numbers in overlaps (you need to set the view to dur).
Tutorial 14: Random construction of a sequence
Topics
The idea of flow control; introduction to conditional functions and predicates.
Key Modules Used
omifandom=The Concept:
This patch uses theomifmodule to choose between two possible evaluations based on the outcome of the predicate moduleom=. The structure for generating the random notes is otherwise similar to the previous two tutorials’.
The Patch:
OM patches are flowcharts which graphically represent this flow. Mastering flow control is an important part of learning to program because without it patches will always act the same way.
om=(B) tests the output ofom-randomagainst its second argument, 0. Ifom-randomoutputs a zero, the test will be true and will return the truth value t. If the output of om-randomis 1, om=will return nil for false.
omif is a module used to control program flow. It is modeled on the simple if then -else syntax you may be familiar with from other programming languages. Its function can be summarized:
If it receives t at its first input, it evaluates whatever is connected to its second input. If not, it outputs nil. There is a third, optional input which can be added by selecting the function and hitting option-→. If this third input is present,omif evaluates it instead of returning nil when the predicate at thetestinput is false.
So,repeat-n(E) callsomif(C) 20 times. Each time, the predicateom=is evaluated against the random result ofom-random. If the test is true,omifpasses 6000. If it is false, the other branch of the patch is evaluated producing a random middic between 4200 and 8200. The results are collected in a Chord-seq.
Tutorial 15: Introduction to
omloop
I
Topics
Basic enumeration of a list withomloop
Key Modules Used
pgmout,omloop,om<The Concept:
In this example notes are generated and are filtered onto two midi channels depending on their pitch. All notes above 6000 midicents (inclusive) will be played on channel one. Other notes falling under 6000 midics will be played on channel 2, which will have a different instrument sound. In this way the melody will be split between two instruments in the Chord-seq module.
This patch contains two different sections: Section A, whose task is to send MIDI mes-sages, and sections B-C-D which generate the notes.
pgmout is a MIDI function which sends program change messages to internal or external MIDI devices, such as the Quicktime synthesizer. As you know, this function always returns nil value in the listener. x-appendis used as a "trick" to evaluate both pgmouts simulta-neously. The first sends the program change 56 to channel one, while the second module sends program change 1 to channel two.
At (B), we’ve created an abtraction (red patch). Remember these? Look back to Tutorial 8 if you don’t remember. Here’s what it looks like on the inside:
In this patch we have reproduced the random pitch generation patch (A) found from tutorial 13. You could just option-drag the elements you need from that Tutorial into this one. Notice that we have added an input for the times argument of repeat-nin order to be able to control this parameter from within the main patch. Notice that note generator (B) is in eval-once mode. This is because its output is connected to two modules (Chord-seq andomloop) . If our patch note generator was in its normal mode it would have yielded different results in the Chord-seq module and the omloop resulting in a mismatching of elements (notes and channels).
We need to create a list of channel assignments based on the pitches of the generated notes. We will useomloopin one of its most common roles- to go through the elements of a
By default, it has no inputs. Inputs are added to the function by clicking on it outside in the patch window and using option-→, just like forx-append.
Opening it, we distinguish three groups of modules: the iterators, the accumulators and the outputs. (For further information about these, please consult the Function Reference.) .These modules are specific toomloopand can only be accessed within this module. When omloopis in its editing mode (i.e opened), nothing connected to these special functions can be evaluated. This is because these special functions will have different values each time the loop is evaluated. One must first close the module and evaluate its output as with any other function.
Let us now examine our loop patch. We will use omloop to test each member of the list output from our note generator patch. As we can see, the patch is divided into four functional parts:
First we will use thelistloopiterator (B), which will ’ticks off’ each member of a list. On each repetition of the loop, the next member of the list is passed by listloopto (C). At (C), the enumerated element could be processed in any way. Here a midicent will be tested usingomifusing the predicateom<. If the midicent is smaller than 6000, omif will output 2, and if not, it outputs 1, our channel assignments. This result will be collected by thecollect module. The collect module simply accumulates the results from each repetition of the
Now let’s verify our result in the Chord-seq editor, choosing in channel from the view options menu:
Tutorial 16: Introduction to
omloop
II
Topics
Another example of usingomloopwithlistloop
Key Modules Used
omloop,list,om+,om-The Concept:
Using theomloopmodule, we will add an upper and a lower harmony note to each note of a melody at a set interval.
The Patch:
Choose an interval to use for the harmonizing. 1100 midics represents a major seventh. Add two inputs to omloop before opening its editing window (with option-→. Thenomloop and name these inputs as shown below. (Again, naming inputs is not necessary, but it is practical, especially when using complicated patches with many variables. Documenting your patches by naming inputs and adding documentation in the input boxes is a good way to keep track of data and patch functionality).
In order to enumerate each element of the list coming from the Chord, we uselistloop (A). Now create a red patch (B). Notice that whenever a patch is created within a patch, this patch appears as a red patch. Open it, add inputs and an output:
Coming into pivot, we will have an different enumerated note from the melody at each repetition of the loop, while ’interval’ is the interval we chose, in midicents (in our example we chose 1100 midics). Thelistfunction creates a new list by grouping its inputs together and slapping on a new pair of parentheses. This is different thanx-append, which merges two lists into one. Compare the two.listwill create a list with three midics, the first and last being a major seventh above and below the middle.
The results will be collected usingcollectand sent to the outputfinally(D). The output of omloopwill thus be a list of chords (a list of lists of midics, i.e. a tree of midics) You can listen to the result in the Chord-seq which is connected toomloop’s output.
Tutorial 17: Generation of a melodic sequence from harmonic
reservoirs
Topics
Generating a melodic sequence with elements of predetermined chords. The idea of .
Key Modules Used
nth-random,x-append,flatThe Concept:
We will generate a note sequence using four Chord objects as harmonic reservoirs. Each Chord contain a traditional harmonic chord structure. We will usenth-randomto randomly choose notes from each reservoir, sequentially. We will concatenate (put together!) the result withx-append, preserving the harmonic order of the reservoirs (I-IV-V-I).
x-append (D) will concatenate these results in harmonic order (i.e first we will have 4 randomly choosen notes from the first reservoir, then 4 from the second one etc...).
In order to have this whole harmonic sequence repeat twice, we will again use the repeat-nfunction (E). Notice that all these iterations yield different results due to the fact that we are usingnth-randomfunction which is evaluated anew at each iteration (on the C and D levels) and therefore returns different results each time.
Try this: evaluate the output of therepeat-nat (E). You should get something like: ? OM->((6400 6700 6700 6700 7200 6000 6500 6500 5900 5900 6500 6700 6000 6000 7200 6000) (6700 6400 6700 7200 6900 7200 6000 6900 6500 5900 6500 5900 6000 6000 7200 7200))
Notice that this is a list of two lists. Plug this directly into thelmidicinput of the Chord-seq object. You’ll get two huge chords. This is because the list has multiple levels. When a list has other lists as its elements, we say it is nested. A tree is a nested list. When Chord-seq encounters a nested list, it assumes the sublists are chords. In order to display this as a string of ordered notes, we must ’flatten’ the list. This is accomplished with the LISP function flat, which removes nesting. Reconnect the output offlatto the Chord-seq and evaluate.
A note from Mikhail Malt: The old version of this patch (in a patchwork version) was a gift to Camilo Rueda when he was at Ircam as a Patchwork developper. Just in order not to break the Colombian tradition, this OM version is dedicated to Carlos Augusto Agon, another nice Colom-bian guy working on Computer aided composition environments.
Tutorial 18: Generation of a note sequence by interpolation
between two chords
Topics
Using random elements and interpolation to generate a sequence of notes between two harmonic areas.
Key Modules Used
interpolation,omloop,repeat-n,flat, Chord, Chord-seq
The Concept:
In this tutorial as in previous ones, we will use randomly generated notes from particular chords to construct a sequence. This time, however, these chords are the result of an inter-polation between two seed chords we choose. The first chord is in the lower register, and the second is in the upper register. The result of the interpolation will be an ascending sequence of chords and so will be the general tendancy of our generated note sequence.
The moduleinterpolation(C) will interpolate between these two chords using n steps. In our example above we have chosen to create 12 steps (chords A and B included). The last argument of interpolation defines a curve for the calculation. A curve of 1 is linear, meaning that the arithmetic midpoint of the interpolation will fall exactly 50% of the way through the steps. In a non-linear interpolation specified by values smaller than 1 (but greater than 0) or greater than 1, that midpoint will be displaced towards the front or back of the sequence. This is easier to understand if you can see it. Open the Chord-seq at (D) and check out the interpolation withcurveof 1.0:
Now, replace the curve argument of interpolation with .3 and evaluate. Notice that the intervals between chords are greater at the beginning of the sequence. Now replace
curvewith 1.7 and reevaluate. Notice how the large intervals are now towards the end of the sequence. Resetcurveto 1.0.
In order to apply the same process as in Tutorial 16, (picking n random samples from each chord of the interpolation) we will useomloop(E):
Inlistloopwill enumerate the elements of our interpolation one by one for each repetition of the loop.nth-randomwill randomly choose one note of each of these chords. Connecting nth-random’s output to arepeat-nmodule will repeat this n times on each chord. Notice that repeat-n’s second input is getting data from an additional input that we namedn-samples
in order to choose the number of times we want to sample each chord from outside omloop’s editor window (in our example it is 4 notes per chord, see the general patch). All results will be collected bycollectand ouput byfinally.
Tutorial 19: Using BPFs I; Graphic representation of a series of
notes
Topics
Using a BPF (Breakpoint function) to analyze melodic contour.
Key Modules Used
BPF, Chord, Chord-seqThe Concept:
In this patch a series of values is used to produce a graphic representation of a melody and a melody itself. The list of midics is passed to thelmidicinput of a Chord-seq object to view it as a melody, as usual, but also to they-pointsinput of a BPF object, where it is converted into a graph (a contour).
The Patch:
Enter some values in midicents here at (A). Remember that in midicent-notation C3 is equal to 6000, C]3 is equal to 6100, and so forth.
The Chord box can visualise these values either as a chord or as a sequence ("order" mode). Evaluate the box and see the different types of musical notation.
The Chord-seq box receives these midicent-values and translates them into musical nota-tion. Evaluate this box to see the musical result.
The BPF box translates the midicents into a break-point function. On a grid with x and y axes, the graph of a break-point function is a continuous line. (A break-point function can
Tutorial 20: Using BPFs II: Sampling a sequence of notes
Topics
Sampling a melodic contour to produce a sequence of notes.
Key Modules Used
Chord, Chord-seq, BPF,bpf-sample,list-max
The Concept:
Here we sort of reverse the last tutorial: we take a melody, turn it into a graphic melodic contour, then use bpf-sampleto take that shape and turn it back into values. When con-verting it back to values, we can take more or fewer samples than the original sequence, creating a "smoother" melody.
The Patch:
The BPF box converts the midicents coming out of the Chord box (A) into a break-point function, a melodic contour.
Thebpf-sampletakes a number of ’pictures’ of the height of the graph between the x-axis values specified at the inputs xminandxmax and returns them as a list. In our example, there are 13 elements in the chord. We tellbpf-sampleto sample theBPF13 times, so the values we get back will be the same ones we put in. However, we are sampling the height of the graph. If we enter a number other than 13, we will take that many samples of the graph, and they’ll no longer line up with the original elements. This will create a new melody starting in the same place and having the same shape but with a different number of elements. Try replacing the 13 with 26.
Tutorial 21: Using BPFs III: Scaling a melodic contour
Topics
Key Modules Used
BPF,bpf-sample,first,om-scale,om-round
The Concept:
Here we start with a BPF object. We sample it at as many points as we like with the bpf-sampleto create a contour with n elements (in this case, 13). These points are then scaled withom-scaleto occur within the interval specified at itsminoutandmaxoutoutputs. We set these numbers using midic outputs of Chord objects; the result is that the melodic form occurs between the two extremes.
The Patch:
Here’s a graphic editor for BPF objects. You add new points to the graph by using the Add Points Tool:
...and clicking on the graph. If you make a mistake, use the Select Points Tool (first on palette) and select the points by clicking or dragging, then hit delete.
Open the Chord box (D) and enter one note. The note you enter will be the lowest note of your melodic profile.
Open the Chord box (F) and enter one note. The note you enter will be the highest note of your melodic profile.
The midic outputs of the Chord objects give a list of midics. Even though they only contain one note, they still return that midic in parentheses, a list of one element. To isolate this (single element) of the list, we usefirst, which takes the first (and only) element of these lists. These midic values are passed to om-scale, which adjusts the list at its first input
Voice
Tutorial 22: Chord-seq: Onsets and durations I
Topics
Managing durations in the Chord-seq editor
Key Modules Used
Chord-seq,dx->x,x->dxThe Concept:
In traditional music notation rhythm is represented as a single value (quarter note, eighth note, etc...). These values don’t tell the whole story, however. The duration alone is not sufficient information when trying to place notes in time. One also needs to know when in time these values happen. Metric information consists then of two quantities:
Onsets are the ’time addresses’ of events. An onset represents the absolute location of the beginning of a note measured from a fixed point, the beginning of the sequence. In OM, onsets are always measured in milliseconds.
Durations are the lengths of these events. A duration represents the absolute length of note measured from the onset. In OM, durations are always measured in milliseconds.
The Patch:
(1000 2000 500 500 500 250 250 1000)
Which, if transcribed, could be represented by the following:
We will take this list of durations and connect it to theldurinput of a Chord-seq. These durations have to be converted into onsets relative to the beginning of the sequence be-fore they are given to thelonsetinput. For this we usedx->x, which requires us to tell it the absolute starting point, which in this case is 0ms, the beginning of the sequence. This produces
(0 1000 3000 3500 4000 4500 4750 5000 6000) which we pass to the Chord-seq.
In example 2,
we will use this same list of onsets (C) as produced bydx->x. We will not specify anything at the duration input. This will result in ’wrong’ duration values, i.e all notes defaulting to a
Rather than calculate the durations, we can fix this by using thelegatoinput. The legato input overrides the default durations. It is a value representing a percentage of the perfect legato, with every note ending exactly as the next note starts. If we enter 100 here we fix all the durations of the sequence, as we’ve done in example 3:
Alternately, we could use the functionx->dxto turn the list of onsets into a list of durations.
Tutorial 23: Chord-seq: Onsets and durations II
Topics
Key Modules Used
Chord-seq,omloop,omif,dx->x,remove
The Concept:
In the last tutorial we learned more about the use of onset and duration lists. These con-cerned only actual note durations. What if we wanted to use rests or offset our entire rhythmic sequence by a certain amount? In this tutorial we will demonstrate a practical way to deal with rest and note durations in milliseconds, and this by using only one list of consecutive durations and rests. All the programing will be done inside an omloop method which will return correct onsets and durations for use in a Chord-seq
Chord-seq does not recognize negative numbers as rest. Theomloopwill turn all the dura-tions into offsets (including the negative ones), and then remove the elements corresponding to the negative durations so that only real notes will remain in the lists.
The Patch:
We take a list of durations with negative numbers, which we will take to represent rests. They are processed in anomloopmodule which will output two lists for use at theldurand
lonsetinputs of the Chord-seq object.
Here’s whats going on. This loop has two outputs (you add an output toomloopby adding an input to theeachTimeandfinallyfunctions. Stuff on the left is processing onsets, stuff on the right is processing durations.
At (A), we use listloopto enumerate the elements of the list of durations we gave the loop.
Theom-absfunction at (B) returns the absolute value of a number or list. It basically strips negative signs from numbers if they have them. We put the list through this module before
passing it to dx->xso that the rests can be incorporated correctly (they still last a positive amount of milliseconds).
We will use twoomifboxes (D), one for onsets, the other for durations. These will be used as filters: If an element of our list is less than 0 (meaning it is a rest), bothomifs will return nil. If not, the firstomifwill return the onset time, the other the duration.
All that’s left to do is post-process both lists in order to remove the nil elements, otherwise we cause an error. We do this with theremovefunction, which simply deletes all occurences of something from a list. We tell it to delete all the nil elements.
The results are plugged into the ldursand lonsetinputs of the Chord-seq. We have two 2000ms notes separated by rests of 1000ms:
Tutorial 24: Voice I
Topics
Introduces the concept of the rhythm tree.
Key Modules Used
Voice(? (((4 8) ((4 (1 1 1 1)))) ((4 8) ((4 (1 1 1 1)))) ((4 8) ((4 (1 1 1 1))))))
While difficult to look at, the structure is actually quite logical: The rhythmic structure
• The first element of the tree is a question mark ’?’, which is a placeholder for a certain number of measures. Rhythm trees get very complicated. The question mark tells OM to calculate the number of measures from the rest of the tree and replace the question mark with this value. It’s a timesaver.
• The second element of the tree is the rhythmic structure, in the form of a list of measures.
• Each measure is itself a list containing two elements, a time signature and a list of pro-portions, representing the way the duration represented by that time signature is divided.
• The first list, the time signature, can be represented in two different ways:
• As a list (4 4) (meaning standard 4/4 time) • Or as a double-slashed fraction: 4//4
• The second list, the list of proportions, determines the rythmic structure within the time signature.
The structure is again a list of lists where the first element is the number of pulses contained in the measure followed by its subdivision. In the example above, we have four equal pulses. We could have written
(4 (3 1))
which represents a dotted half-note followed by a quarter note in a 4//4 measure.
Rests
In the lists representing the subdivisions of the pulses, rests are represented by negative numbers. For example,
(? ( ((4 8) ((4 ( 1 -2 1)))) ) ) will output:
Ties
By the same token, ties are represented by floats (decimals) as follows: (? ( ((4 8) ((4 ( 1 -2 1)))) ((3 4) ((3 (1.0 2)))) ) ) represents:
Irrationals (tuplets)
Irrationals such as triplets, quintiplets etc. are quite easilt represented by subdividing a pulse by an odd number. For instance, if we subdivide a pulse into five beats (instead of four) we will obtain a quintuplet. Here is a pulse divided into 4: the result is sixteenths: (?(((1 4) ((1 (1 1 1 1)))) ))
And the same pulse, this time divided into 5: (?(((1 4) ((1 (1 1 1 1 1)))) ))