The complete reference manual for version 2 of the Bol Processor
Computing ‘ideas’
A composition in Carnatic musical style by Srikumar K. Subramanian, June 1995. Name: "-gr.trial.mohanam".
This is a non-stop improvisation of variations in a style similar to Carnatic music. The compositional approach here is to decide that each variation should contain 32 notes and can use up to 20 "ideas". To do this, a flag called Ideas is set to 20 at the beginning, and it is decreased by 1 unit in certain rules (such as GRAM#2[2]) or 2 units in others (such as GRAM#2[3]). See the Flags in grammars for more details.
Rules in subgrammar #3 can only be candidates if there are few ideas left, but they do not reduce ideas.
Rules in subgrammar #6 use wildcards to create patterns.
Rules in subgrammar #9 create "effects" by changing velocities.
In the ‘Improvize’ mode, the values of flags and rule weights can be carried over from one variation to the next. This allows them to be used to trigger/inhibit events at any distance from those that created/modified them.
The following output was recorded on a Roland D-50 synthesiser.
Undetermined rests in dance performance
The polyrhythmic piece "765432" composed by Andréine Bel for her CRONOS dance production (1994) illustrates the use of undetermined rests. Six dancers were on stage: Suresh Shetty, Smriti Mishra, Olivier Rivoirard, Vijayshree Chaudhary, Arindam Dasgupta and Andréine Bel.
In this grammar, "SUB1" indicates a substitution that only needs to be performed once. Using it to replace "SUB" saves computation time.
Glyphs "…" are undetermined rests, i.e. silences whose duration is a priori unknown and will be precisely calculated by the polymetric expansion algorithm.
The whole structure is based on regular arithmetic divisions. For example, Suresh moves at "speed 7", Smriti at "speed 6" and Olivier at "speed 5".
"CR47" and "C46" are patches from the Roland D-50 synthesiser.
The following output was recorded on a Roland D-50 synthesiser.
This performance was part of the choreographic work CRONOS performed at the National Centre for the Performing Arts (Mumbai, India) and the Shri Ram Center (Delhi) in October 1994. An excerpt is shown from 4mn 50s to 5mn 10s:
References
Tutorials
Time patterns (smooth time)
The following is a simple grammar illustrating the use of time patterns in smooth time. Whereas striated time is filled with (regular or irregular) pulses, smooth time does not involve counting.
_mm(120.0000) _smooth
GRAM#1[1] S --> {10 , t1 t2 , Part1 Part2}
GRAM#1[2] Part1 --> {t1 t3 t4 , C4 D4 E4 F4 - A4}
GRAM#1[3] Part2 --> {t3 t1 , B4 C5 _ E5}
TIMEPATTERNS:
t1 = 1/1 t2 = 3/2 t3 = 4/3 t4 = 1/2
In this grammar, "t1", "t2" etc. are the time patterns arranged in such a way that they define a structure of (irregular) "beats" on which notes "C4", "D4" etc. will be located.
The final arrangement is as follows:
{10, t1 t2, {t1 t3 t4, C4 D4 E4 F4 - A4} {t3 t1, B4 C5 _ E5}}
Time flexibility in Bol Processor is not the effect of arbitrary numerical functions. This flexibility stems from a time structure — Xenakis’ (1963) structure temporelle — that is deeply interwoven with the syntactic description of music.
If striated time is selected, the same structure will be displayed as shown below:
Some time patterns were used in Andréine Bel's choreographic work: Shapes in Rhythm.
Reference
- Bel, Bernard. Migrating Musical Concepts: An Overview of the Bol Processor. Computer Music Journal, Massachusetts Institute of Technology Press, 1998, 22 (2): 56-64.
Interactive improvisation with sound-objects
This grammar (namely “-gr.koto3") is an improvisation model running on the Bol Processor BP2 connected to a Roland D-50 synthesiser. The choice of synthesiser was crucial for a good reproduction of the sound imitating a Japanese koto.
The underlying model (SUB grammar) is a one-dimensional cellular automaton using substitution rules: at each step of the computation, a set of randomly selected rules is applied to the work string. Conversely, in a RND grammar, a new rule would be selected each time the previous one was applied. For more details, see a presentation of "-gr.koto3" on the Bol Processor ‘BP3’ and its PHP interface page.
In subgrammar #2 we see a competition between constructive rules, such as gram#2[8] and gram#2[11] which increase the length of the work string, and destructive rules, such as gram#2[10] and gram#2[15] which decrease its length.
The weight of gram#2[12], initially set to 100, decreases by 10 each time it is applied, until the rule is invalidated.
SUB gram#1[1] <100> S --> _vel(127) _volume(40) X X X X Y X X X X Y X X X X gram#1[2] <K9> X --> a [Weight is controlled by K9, see Interaction] gram#1[3] X --> b ----- SUB gram#2[1] Y --> Y gram#2[2] #? ?1 --> #? ?1 [Keep leftmost symbol] gram#2[3] ?1 #? --> ?1 #? [Keep rightmost symbol] gram#2[4] } --> } gram#2[5] , --> , gram#2[6] <5> a --> a gram#2[7] <30> a b a --> a a gram#2[8] <100> #({) a b a --> {5,a c b,f f f - f} gram#2[9] <5> b --> b gram#2[10] <30> #({) b a b #(}) --> b b gram#2[11] <100> #({) b a b --> {3,b a b c b a,f a f} gram#2[12] <100-10> #({) #a b #(}) --> #a c b gram#2[13] c c c --> c a c gram#2[14] c a c --> b a b gram#2[15] <50> ?1 ?1 ?2 ?3 ?4 ?4 --> ?2 ?3 gram#2[16] <K9> ?1 ?1 ?1 --> ?1 gram#2[17] <K9> ?1 ?1 --> ?1 ----- SUB gram#3[1] <40> Y --> <<f>> gram#3[2] <50> Y --> <<chik>> gram#3[3] <1-1> ? #? --> ? Silence _script(MIDI send Continue) #? gram#3[4] <50> Silence --> - - - - - gram#3[5] <15> Silence --> - - - - gram#3[6] <8> Silence --> - - - gram#3[7] <8> Silence --> - -
Rules in subgrammar #2 are applied until none of them can be a candidate. Then the rules in subgrammar #3 are applied, producing the out-time sound-objects <<f>> (a bass note) and <<chick>> (a chord).
The sound objects "a", "b", "c", "f", "chick" are defined in a sound-object prototype file called "-so.koto3". Some of them have specific properties that force a relocation to satisfy topological constraints. For example, "a" must maintain continuity with the preceding object (as shown in the image), which may cause it to be moved into the past.
The time-setting algorithm takes into account all the constraints to create a piece that may not fit exactly into the metronomic beat pattern. Below is an example of the final piece created using this grammar (played 3 times):
In this grammar, parameter K9 is set to follow the position of a controller (e.g. the pitchbend or a pedal on the D-50), assigning a value from 0 to 100. This value is the weight of the rules gram#1[2], gram#2[16] and gram#2[17]. The higher the weight, the more "a" and the less "b" in the string; in addition, the final string becomes smaller due to the higher weight of the destructive rules gram#2[16] and gram#2[17].
During the improvisation, the work string is played at each step of its transformation. The end of the transformation is indicated by the <<f>> and <<chick>> sound-objects.
Below is an example of improvisation played in real time MIDI:
The following video illustrates the grammar at work on BP2.9.8 — unfortunately with a GeneralMIDI "koto" sound:
References
- Two Algorithms for the Instantiation of Musical Structures (1994) on polymetric structures and the time-setting algorithm of sound objects
- Migrating Musical Concepts: An Overview of the Bol Processor (1998)
A beginner's tutorial
By Harm Visser, 2007
Let us take a look to the ideas and historical background of BP2. At the end of the fifties the linguistic scientist Noam Chomsky wrote his famous book 'Syntactic Structures'. It was an attempt to generalize the structure of language in a system of rewrite-rules, so called 'grammars':
Sentence --> NP + VP
NP --> T + N
VP --> Verb + NP
T --> The
N --> man, ball..
Verb -> hit, took…
When we computerize such a grammar and we give the command 'derive' we should see that Sentence became NP + VP, NP became T + N, VP became Verb + NP etc. At the end we see that N became 'man' and Verb became 'hit'. No further derivation is possible. The words 'man', 'hit' are therefore called 'terminal symbols'.
After derivation of Sentence we should read: the man hit… (or whatever). Such a Chomsky 'grammar' can be seen as a set of rules to generate well-formed English sentences.
You can read a rule as 'X --> Y'. It gives the 'instruction' to rewrite X as Y (X becomes Y). Maybe you can imagine already that such a grammar-system can also apply to musical syntax.
Let us therefore compare the Chomsky-example with this BP2-example:
S(entence) --> X Y
X --> Motif1
Y --> Motif2
Motif1 --> C3
Motif2 --> D3
After derivation we should hear the terminal symbols C3 D3.
The main difference between the 'Chomsky-grammar' and a BP2-grammar is that a BP2-grammar is exclusive. It is a formalisation of one particular piece of music. Chomsky-grammars try to generalize language as a whole.
At the other hand you can in BP2 'formalize' the sonata-form:
S --> Sonata
Sonata --> Theme1 Theme2 Development Coda
Theme1 --> Notes1
Theme2 --> Notes2
Development VariateNotes1 VariateNotes2
Coda --> HalfTheme1 HalfTheme2
When we derive the Sonata, we shall hear nothing, because there are no terminal symbols i.c. 'real notes', like C3, D2, etc. So let's finish the Sonata:
S --> Sonata
Sonata --> Theme1 Theme2 Development Coda
Theme1 --> Notes1
Theme2 --> Notes2
Development --> VariateNotes1 VariateNotes2
Coda --> HalfTheme1 HalfTheme2
Notes1 --> A3 B3 A3 G3
Notes2 --> D3 E3 F3 A3
VariateNotes1 --> _transpose(2) Notes1
VariateNotes2 --> _retro Notes2
HalfTheme1 --> A3 B3
HalfTheme2 --> D3 E3
Note that we use for VariateNotes1 and VariateNotes2 the tools _transpose(2) and _retro.
_transpose(x) transposes up or down at a given interval: _transpose(2) (two semitone up), _transpose(6) (six semitones up) _transpose(-7) (seven semitones down). You can also use values like _transpose(0.2).
The _retro tool stands of course for 'retrograde'. It turns the symbols backwards. You can read commands like _transpose and _retro as 'transformers'.
Well, let's listen to this Sonata! Select S and 'Play selection':
A3 B3 A3 G3 D3 E3 F3 A3 _transpose(2) A3 B3 A3 G3 E3 D3 B3 A3 A3 F3 E3 D3
There are two important things to remember
- When you write a variable like Theme1 or VariateNotes2 or Sonata (yes, these are variables until you give them a 'content'), start the variable with a capital and don't use empty spaces between symbols. So Not 'sonata', but 'Sonata'. Not 'n1', but 'N1', not 'my piece', but 'Mypiece'.
- You can listen to every stage or level of your piece at every moment. So, instead selecting S, you can select Notes1 or Development, or G3… In other words, you can listen to every compositorial detail! Try to make your own Sonata now!
Note that the example-Sonata is also a description of the actual piece. That is to say that the first half is the description, the second half is the 'realisation' of the description. This approach means that a description can also have a 'subdescription', while the subdescription can have… indeed, a subsubdecription. So BP2 is the perfect tool for hierarchical descriptions of musical structures.
Random selection of an item in a fixed-cardinal set
Typical application
Select candidate rules in a generative grammar randomly and apply them to the workstring until there is no more candidate rule.
Problem
To stop the process it is necessary to scan the entire grammar and make sure that there is no more candidate rule. Each time the workstring has changed, the "candidate / non candidate" status of each rule in the grammar may vary. Since scanning "N" rules in the grammar is time consuming, it is preferable to do it only after "maxtry" unsuccessful attempts to find a candidate. The problem investigated here is to find a minimum "maxtry" making it almost sure that there is no more candidate.
Related problem
Sometimes a selected rule must be applied repeatedly until it is no more candidate. If the position of derivation in the workstring is random then the problem amounts to selecting one amongst "candidate" or "non candidate" positions in a set whose cardinal "N" is the length of the workstring.
To summarize…
The two examples above may be abstracted to the repeated random selection of an item in a set containg N items. The algorithm of a general procedure is given below. The problem is to evaluate "maxtry" so that in the worst case the probability of heuristic [2] being true is greater than a given probability "p".
ScanSet() Return number of candidate items; FoundItem() Select an item; Return "yes" if item is candidate, "no" otherwise; Procedure() Evaluate maxtry; Start: nb_candidates = ScanSet(); if (nb_candidates = 0) exit; if (nb_candidates = 1) Use candidate item found; Go to Start; [Heuristic 1: if there was a unique candidate item then next time there should be less than two.] Again: repeat with try = 1 to maxtry if (FoundItem()) then Use candidate item found; Go to Again; [Heuristic 2: if try < maxtry there may still be candidate items.] Go to Start;
Solution
Let "k" be the number of candidate items. The probability to find a candidate item after (maxtry-1) unsuccessful attempts is:
1 - (1 - k/N)^maxtry
If k = 1 then the Scan() procedure will find the unique candidate item. Therefeore the worst case is k = 2 and the condition is:
1 - (1 - 2/N)^maxtry > p
yielding:
maxtry > Log(1 - p) / Log(1 - 2/N)
i.e., if 2/N is much smaller than 1,
maxtry > - N/2 Log(1 - p)
In Bol Processor, we imposed p = 0.64 so that maxtry > N/2.
Indeed, this method is only valid if items have equal weights.
Examples
Harm Visser's examples
In Computer Music Journal 22,2 (1998) page 63, Dutch composer Visser commented:
I think that the development of more and more visual stuff curtails the possibility of "thinking in your chair." Sometimes I develop grammars, not at the computer, but sitting with a pencil and paper. With programs [other than BP2] this is not possible: you must sit in front of the computer. The difference lies in the type of attention that each software environment demands on the part of the composer, and indeed reflects on the way s/he thinks about music.
The following is a presentation and discussion of some examples written on the Bol Processor by Harm Visser in 1998. All examples shown on this page are available in the sample set bp3-ctests-main.zip shared on GitHub. Follow the instructions on the Bol Processor ‘BP3’ and its PHP interface page to install BP3 and learn its basic operation. Download and install Csound from its distribution page.
Period notation
In the same way as it deals with superimposed sequences, the polymetric expansion algorithm computes equal symbolic durations between beat separators notated ‘•’ — namely, the period notation. A note sequence in period notation and the context-free grammar from which it is derived are shown below. In this example, the beats contain an increasing number of notes, resulting in an accelerating movement.
S --> _vel(60) A B _vel(65) C D _vel(70) E F _vel(75) G _vel(77) H _vel(80) I _vel(85) J _vel(87) K _vel(90) L
A --> E2 •
B --> D2 A
C --> B2 B
D --> G2 C
E --> F#2 D
F --> A#2 E
G --> C2 F
H --> G#2 G
I --> A2 H
J --> D#2 I
K --> C#2 J
L --> F2 K
The "_vel" operator is a velocity control that produces a gradually increasing volume of the piece. This grammar produces the following "score":
_vel(60) E2 • D2 E2 •_vel(65) B2 D2 E2 • G2 B2 D2 E2 • _vel(70) F#2 G2 B2 D2 E2 • A#2 F#2 G2 B2 D2 E2 • _vel(75) C2 A#2 F#2 G2 B2 D2 E2 • _vel(77) G#2 C2 A#2 F#2 G2 B2 D2 E2 • _vel(80) A2 G#2 C2 A#2 F#2 G2 B2 D2 E2 • _vel(85) D#2 A2 G#2 C2 A#2 F#2 G2 B2 D2 E2 • _vel(87) C#2 D#2 A2 G#2 C2 A#2 F#2 G2 B2 D2 E2 • _vel(90) F2 C#2 D#2 A2 G#2 C2 A#2 F#2 G2 B2 D2 E2 •
and the following piano-roll representation with the sound example on a Pianoteq synthesiser:
Serial tools
The following grammar produces a 10-minute piece of music with only 12 rules and 3 notes (C3, D4, F#3). It is an illustration of Visser's motto: "composing with a pencil and paper".
The rhythmic complexity is the result of the use of polymetric expressions: the superimposition of sequences listed between curly brackets {} and the resizing of "beats" thanks to the period marker '•'.
The length and complexity of the piece is achieved by using mutually recursive rules. For example, rule gram#2[2] produces "Mel1" which is rewritten by rule gram#2[1].
Three "serial tools" are used:
- _transpose(n) shifts the following sequence up by n semitones
- _rotate(x) rotates the following sequence by x units
- _keyxpand(basenote, ratio) multiplies melodic intervals by ratio relative to the basenote. For example, _keyxpand(C4, 2) would replace the sequence D4 E4 F4 with E4 G#4 Bb4. This tool is applied recursively to the fields of a polymetric expression.
Note that all the subgrammars are headed with "ORD", which means that the rules are applied in order rather than randomly. Thus, this grammar produces a unique piece of music, as is the case with all examples composed by Harm Visser. The only stochastic element in this piece is the velocity, which can vary between 60 and 100 due to the performance controls _vel(80) _rndvel(20).
The sound output was played on a Pianoteq synthesiser:
Trills
The following grammar produces trills that take advantage of tempo variations and continuous velocity variations:
Waves
Harm Visser had been asked to compose a piece à la Debussy with rubato rhythms giving the impression of waving movements. We had expected him to use the "_tempo()" tool with floating point values (or integer ratios) as arguments.
In fact he did not… In the following grammar, only the markers "1/2", "1/4" indicate regular speed changes applied to an entire section. The waving effect is produced by a clever use of (self-embedded) polymetric expressions. As the composer indicated: "It builds on the idea of embedding: {5, A B {3, A B {2, A B C D} C D} C D}."
The following is a rendering of the piece for solo piano on a Pianoteq synthesiser:
In the final version, the composer assigned parts to a different MIDI channel that controlled a physically modelled synthesised saxophone (which he had designed himself):
Fractals
Harm Visser sent this grammar with the following comment (1998):
It is completely based on a function that I have made in PatchWork. Take 3 notes and take their intervals to transpose. The result is a kind of 'autotranspose'. You get a 'fractal' - the idea of the famous Von Koch-curve. The next step is making a recursive loop, so that you can set the level of recursion. The number of notes grows exponential: 3 9 27 81 243 etc. Of course you can do the same with rhythm-values.
This grammar is a BP2-version of exactly the same idea. It has 4 recursion levels. (You might also say 'depth'. It is in fact a 'copy' of the PW-function). That's why S --> L4 (level 4) (number of notes 243).
The difference between BP2 and PW is that the function in PW is fixed, which is not the case in BP2. I can easy make subtle changes (deviations) in the process. I can 'break in', so to speak. In his grammar I have set a comma between M10 and M11 and set M11 on the sax. The result is a polymetric canon!
The following version is with piano solo on a Pianoteq synthesiser. The version with saxophone is unfortunately missing. It could be generated by playing the (type-1) MIDI file Visser8.mid on a synthesiser and assigning MIDI channel 9 to a saxophone sound.