GeoMaestro & Csound:
An introduction to the Compositor tool
GeoMaestro is an experimental system for MIDI and Csound composition, based on the multiplatform environment KeyKit. It is released under the GPL.
In this paper, I would like to introduce the basic features of its Compositor tool, and how to use them in a strict Csound perspective.
For an overall description of the whole system, see the documentation. It includes a Csound chapter with a specific tutorial. Reading all this is not required here, though. The following will not be technical, it is just here to give you an insight of what is possible. Links to corresponding topics in the documentation are provided between parenthesis, like this: (*)
Note that in the following, no mention is made of the GeoMaestro customization. This is fully covered in the manual. Customization, basically involving setting the value for a couple of environment variables, is necessary so that the system knows where to read and write files, and how to interact with programs like Csound or a text editor.
The Compositor philosophy
This tool is simply a mixer. It can help you compose a large and complex score by symbolically linking smaller scores. It is also able to write temporary files and call Csound, so that the composition can be processed and heared from the Compositor itself. Several orchestra can be used at the same time, along with different Csound command line settings.
In its full extend, the tool also makes it possible to mix MIDI parts and audio files along with Csound score, but this is off-topic here. See the Compositor documentation for a comprehensive description.
What the tool can not do is generate scores from scratch (well, actually it can, but let's forget about it at this point). So in the following we will suppose that we want to create a larger composition out of already existing orc/sco pairs.
The idea is to represent each initial score as a box. Linking together boxes defines how their content will be arranged and mixed.
Basic box management is handled by mouse operations, while more elaborated operations can be interactively programmed, thanks to the powerful KeyKit interpreted langage.
Let's start with very simple things. Importing (*) a score box from a file is done with the command "sco" (which opens a browser window) or "sco name".
This creates a string variable storing the file name, and reference the new box with a command reading this file and processing it so that its symbols ".", "+", "<" or ">" are replaced by numerical values; the score is also stripped from all comments and non i-statement lines. Other commands for other processings are possible (*).
We will use as an example tibetan.orc and tibetan.sco, from the Amsterdam catalog (their real references there are 02_43_1.ORC and 02_43_1.SCO)
With the import command "sco tibetan", we get a box like this:
Clicking on [EVAL] (*) then on [Score] (*) opens your favorite text editor so that you can see the evaluated score:
i1 0 35 8000 110 .03 .07 21
i2 5 20 9600 55 .02 .04 12
i2 20 15 8000 220 .05 1.5 3
i1 20 20 9600 110 .04 2 4
i1 28 30 8000 220 .04 3 6
i2 32 26 9600 110 .025 2.6 5.2
i1 32.1 23 8000 110 .03 2.3 4.6
i2 36 22 8000 55 .01 .04 13
... it is simply tibetan.sco reduced to its i-statements.
In order to render this score from GeoMaestro, we need to create the file tibhead.sco: it contains the necessary table declaration, and also, in its first line, the name of the orchestra to be used.
Then we import a score header box (*) referencing this file, and link it to the previous box like this:
Now [EVAL]-uating box 2 associates the header with the score and dumps the whole as a temporary score. Then clicking [Audio] calls Csound and creates the audio file. At this point you can optionally have a sound file editor open and display the result.
Now consider the following set-up:
Here, evaluating box 2 leads to the temporary score tibhead_.sco: the previous score lines have been duplicated, with a time offset so that the music is repeated twice.
This is the resulting score: tibhead_2.sco. This time, the second part (box 3) is repeated 10 seconds after the first one (box 1), thanks to the new silent (*) framework (box 4)
Instead of using such a box, we can directly have anchoring marks in the score boxes: there are different ways (*) to create a mark inside a box, so that we get this kind of set-up:
... which is exactly equivalent to the previous one (the mark place sets its time value to 10 seconds from the beginning of box 1). Marks can also be automatically derived from comments within the score itself (*).
The black arrow lines we used so far to connect boxes are called "links" (*). They state how boxes are connected time-wise, and also logically. For example, in the following set-up:
... evaluating box 5 will lead to the mixing of scores in boxes 1 and 3, both starting at time 10 seconds, the first one being associated to the orchestra tibetan.orc, while the second one will be associated to the orchestra referenced in box 5.
Now there is another kind of connection, called "time stamp" (*). It is used to synchronize different boxes:
Here the two stamps (blue lines) on box 1 mean that its duration has to be 6 seconds, while the single stamp on box 3 means that box 3 has to terminate at time 20 seconds. If we scale the display (*), it becomes this:
... where it is clear that box 1 and box 3 have been stretched or compressed in order to fit the time constraints. Here is the temporary score we get when evaluating box 2: tibhead_3.sco.
If you listen to it, you will notice a problem: the sound is abruptly cut at times. This is because scaling a score is done by simply scaling its p2 and p3 fields. This is the default procedure. In our case, however, it is not a good approach, because p7 and p8 are used to define an envelope which should be scaled also.
So this is a good point to stop with the basics and see what can be done on the programming side...
Customizing and developping
The KeyKit langage is very easy to use: it is a kind of simplified C, without need for memory management or type declarations.
GeoMaestro implements a library of functions handling Csound scores (*). In our example, replacing the default scaling function by a custom one is as simple as writing this in a text editor (without the comments, of course !):
function ScaleTibetan(score, lf) # multiply p2, p3, p7 and p8 by lf for all lines in score
if ((lf == 1) || score == 0) # nothing to do if no score or no scaling
if (score > 0) # score is the number of lines in score
for (l=1; l<=score; l++) # ... a loop going through all lines
p = SCgetallp(score[l]) # ... reads the parameter in line l
p *= lf # ... scales p2
p *= lf
p *= lf
p *= lf
score[l] = SCsetallp(p) # ... rewrite the line with the new parameters
Once the replacement done (*) in boxes 1 and 3, here is the new score got from evaluating box 2: tibhead_4.sco . This time, the envelopes are fine.
Let's see another usage of custom functions: echo boxes (*). The following set-up is equivalent to the one we saw earlier, where box 3 starts 10 seconds after box 1:
The difference is that the initial score appears only once here, in box 1. Box 3 is an echo box, that is: a box echoing the result of the evaluation of another one.
An interesting point is that the echo box can also perform operations on its source. It has a reference field, which by default is:
This can be replaced by any function taking a score as argument, like
... which would remove all lines not related to instrument 1
Writing your own functions allows for all kinds of algorithmic operations on the score you're echoing, from simple manipulations like scaling parameters or reversing the score to full algorithmic composition. In the previous example the echo box had one source; it can actually have two sources and perform arbitrary operations on them to define its "echo".
The point I would like to emphasize in this paper is the flexibility of the boxes relationships; while others elements of the system may not bring new perspectives to someone already dealing with scripting langages, the links & time stamps approach is quite unique and powerful. It's also very intuitive after a short while... well at least I do find it intuitive.
So here is a detailed example of a more complex box structure:
There are some novelties here:
Consider box 5: it is a silent box of duration 10 seconds. Box 1 was, when first created, a silent box of duration 20 seconds: but a time stamp now goes from the end of box 5 to the first large mark in box 1. As a consequence, the duration of box 1 is extended to 20x10 = 200 seconds.
- The blue circles indicate that box 6 is the composition trigger, or starting point: it is the box that will be evaluated, all the other ones being its children.
- The boxes look differently from before: this is because this image illustrates the time-line mode, where boxes are moved and scaled relatively to one of them (which you can choose arbitrarily). Since it is still possible to move them or modify their content, special displays make it easy to check if a given box is correctly scaled and positioned. Here box 6 escapes the time-line mode because its duration is 0: it does not embed any musical data.
The three score boxes are anchored in box 1. Look at the right one (box 4): the link is broken, with the arrow at the beginning of the box, while the line points to its end. This mean that box 4 must end when box 1 ends.
Box 2 must simply begin when box 1 starts. And box 3 must start at the 7/20th of box 1 duration. So far, so good.
Now let's add a time stamp going from box 1 to box 3, such that it doesn't have any effect in the current configuration, like this:
We can now play with the time stamp from box 5. Since box 5 is not subject to any constraint, its duration is always 10 seconds. By choosing where the time stamps goes in box 1, we can scale it as we want, and the three (C) boxes will follow according to their relationship with box 1.
For example, if we move the time stamp to the left, here is what we get (after scaling):
Box 1 has now a longer duration. As a consequence, the three scores are separated by longer silences. Note that box 2 still starts with box1, and box 4 still ends with it. What happened to box 3? Its duration has been extended because of the time stamp we created earlier.
Now, doing the opposite operation:
Here box 1 is much shorter. Box 3 has been drastically compressed and boxes 2 and 4 overlap. There is no more silence in the composition. Indeed, all three scores overlap in the middle of the piece !
What we just saw is the kind of effect that a single time stamp can have.
By carefully setting up the boxes network of links and time stamps, it is thus possible to define very complex and precise dependencies between boxes.
Of course we have the possibilty to copy and paste whole subsets of the composition, so that we can for example easily merge into one the three previous scaling variations:
At this point I should add that while all manipulations introduced here have been done solely with the mouse, it is possible to operate the Compositor from the KeyKit console or from programs. For a average programmer it is also very easy to extend the tool by writing plug-ins, so that the mouse actions themselves are customizable. The GeoMaestro system is fundamentally a programming environment; its GUIs are intended to be as transparent and open as possible.
There is much more, but I think this paper is already long enough... I hope this introduction gave you a hint of the Compositor tool.
This tutorial demonstrates more of it. The examples are MIDI compositions, but this does not make any difference.
Whole parts of the GeoMaestro system have been ignored here; the main one being its composition paradigm based on two-dimensional projections, which is briefly introduced in this paper. A Csound example can be found in this tutorial.
Also of interest to Csound composers is the possibility to create a score by mapping MIDI data (GeoMaestro is primarily a MIDI system, remember) either by using functions in the existing library or by writing your own. This means that the whole collection of algorithmic tools in KeyKit can be used for score generation in a straighforward way.
All of this, and more, is detailed in the GeoMaesto documentation.
Hopefully this paper will awake the interest of some composers; as the GeoMaestro system is still growing and developping, I am very much interested in any feedback: bug reports, of course, but also ideas for new features and critics about the current approach, its scope and its limitations.
GeoMaestro is developped and tested on Win98, but it definitely should run on Linux and Mac systems. Please let me know of any installation problem.
KeyKit, the langage/environment required by GeoMaestro
GeoMaestro home page: comprehensive manual, tutorials and download