Csound objects
This article is a continuation of Csound check in which we introduced the creation of Csound parameters monitored by performance controls. Musical phrases were created from simple notes translated into Csound events in a straightforward manner. We now consider the creation of Csound scores based on sound-objects containing Csound instructions — which may be called "Csound objects".

Csound objects contain a Csound score with a specific tempo and duration. For example, in object "e" shown above, the tempo (line "t" of the score) is 120 beats/min. The total duration is 2 beats, or 1000 ms. Note that to calculate the total duration of this sound-object, the durations of 'E3' and 'G3' (0.667 sec) shouldn't be added to those of 'C3' and 'D3', because of the start dates.
The duration of a Csound object is independent of the duration set by MIDI events that may coexist in the sound-object prototype. In most situations, note sequences and durations are identical in the MIDI stream and the Csound score. This makes it possible to play almost the same items via MIDI and Csound. However, as we will see, Csound is open to controls that are not available in MIDI.
Calculations can be easily verified against the C-sound instrument file "‑cs.tryCsoundObjects" provided in the example set bp3-ctests-main.zip — downloadable from GitHub along with the Bol Processor BP3 interface: php-frontend-master.zip. Items can be created with the grammar "‑gr.tryCsoundObjects" using the alphabet "‑ho.tryCsoundObjects" associated with the sound-object prototype file "‑mi.tryCsoundObjects".

Let us start with sound-object "a" whose score is shown in the picture. The score is given for a tempo of 120 beats per minute, giving a total duration of 2 beats ( = 1.5 + 0.5) or 1000 ms.
The first event (note 'F0') is repeated 2 times with identical timing, a meaningless detail to check that Csound can handle this abnormal case.
Events i1 and i2, calling instruments 1 and 2, describe tonal positions in the octave point pitch-class format: octave number + semitones above C. We notice that "5.05" has been mislabelled as 'G5'. This will have no effect on the computation, as the Bol Processor will automatically correct it to 'F1'. It will also rename notes according to the convention set in the settings: English, French or Indian.

Event i3, calling instrument 3, defines pitch as frequency (in Hz). It is assumed that 643.5 Hz is 'D#5' because the diapason is 'A4' = 440 Hz. This tuning is defined in the settings (page "-se.tryCsoundObjects"). Bol Processor can change the name of this note according to the diapason.
Changes of the diapason are taken into account by BP3 when generating Csound scores, but this was not yet the case with BP2. The following examples have been produced with the default 'A4' = 440 Hz, giving identical results with BP2 and BP3. See the page Csound tuning in BP3 page to examine different cases.
Producing object "a" at a tempo of 60 beats per minute results in the following Csound score:
a

t 0.000 60.000
i1 0.000 0.250 4.05 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i1 0.000 0.250 4.05 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i2 0.750 0.250 5.05 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; F1
i3 0.750 0.100 643.50 1.000 ; D#5
Note that this score is more complete than the one contained in sound-object "a". This is because the sound-object prototype file "-so.tryCsoundObjects" is linked to a Csound instrument file "-cs.tryCsoundObjects" (see figure below).

Instrument 1 of the Csound instrument file is designed to handle 10 arguments while the score of "i1" events in "a" only contains 4. The 6 missing arguments are filled with default values of the parameters they represent. Here, for example, '90' is the default volume. Zeros represent default pitchbend or function table indexes.
Note that "5.05" has been correctly fixed to "F1". This is only relevant to human readers, as Csound ignores any text following a semicolon.
You cannot convert this and other examples to sound with the supplied Csound orchestra "default.orc", because it only handles instrument 1. The examples on this page are for visual inspection only.

In the following example, we need to look at the graph to understand why the events of "a" are delayed by 160ms compared to "b". Object "b" has a pivot set at 20% of its duration from the start date. This can be checked in "-so.tryCsoundObjects".
Although the object graphic and the pianoroll for this item indicate that "b" should start on a negative date (-160ms), the Csound score is shifted to show only positive or zero dates.
{a, b} c

i3 0.000 0.800 461.34 1.000 ; A4
i4 0.100 0.200 6.03 1.050 ; C2
i1 0.160 0.250 4.05 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i1 0.160 0.250 4.05 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i2 0.910 0.250 5.05 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; F1
i3 0.910 0.100 643.50 1.000 ; D#5
i2 1.160 0.125 9.00 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; C5
i2 1.285 0.125 9.02 0.000 0.000 62.000 62.000 0.000 0.000 0.000 ; D5
i2 1.410 0.125 9.04 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; E5
i2 1.535 0.125 9.05 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; F5
Note on pivots and relocation: sound-object "b" has its pivot shown as a full arrow, unlike other sound-objects in this set which only have a red triangle. This means that it is not relocatable. Relocation would be performed if these sound-objects had topological properties such as prohibiting the covering of their beginning/end, allowing truncation of beginning/end to a certain degree, breaking the tempo etc. A constraint-satisfaction algorithm is run on each production to produce a solution that minimises the number of constraints violated. This is best illustrated by "-gr.koto3" (read the article).

Let us now look at a phrase containing "midiobject", a sound-object with both a MIDI stream and a Csound score. The MIDI stream is ignored when constructing the score. The time resolution (10 ms) also has no effect on the accuracy of timings in the Csound score.
b midiobject
i3 0.000 0.800 461.34 1.000 ; A4
i4 0.100 0.200 6.03 1.050 ; C2
i1 1.160 0.666 7.04 90.000 90.000 0.000 0.000 0.000 0.000 ; E3
i1 1.160 1.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 ; C3
i1 2.160 1.000 7.02 90.000 90.000 0.000 0.000 0.000 0.000 ; D3
i1 2.493 0.667 7.07 90.000 90.000 0.000 0.000 0.000 0.000 ; G3
Since the score of "midiobject" has been defined with a tempo of 60 beats/min for a duration of 2 beats, the durations of the notes E3, C3, D3, G3 are unchanged.

Now consider a polymetric structure in which the first line contains 3 sound-objects and the second line contains 2 sound-objects. The structure will be forced to a symbolic duration of 3 beats — the duration of "a b a" — and the second line will arrange the objects as "two in three" with symbolic durations of 1.5 beats.
This is clear on the picture, looking at the pivots of sound-objects, if one does not get confused by the physical duration of the sound-objects. The sound-object prototype "b" has a duration of 0.8 beats, resulting in a physical duration of 800 ms.

On the second line, the symbolic duration of each object is 1.5 beats. Consequently, the sound-object "c", whose prototype has a physical duration of 500 ms, is set to physical duration = 500 * 1.5 = 750 ms. The object "c" appears as sequence "C5 D5 E5 F5" with total physical duration of 4 * 188 ms = 752 ms. These durations are reflected in the Csound score below.
{a b a, c midiobject}
i1 0.000 0.250 4.05 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i1 0.000 0.250 4.05 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i2 0.000 0.188 9.00 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; C5
i2 0.187 0.188 9.02 0.000 0.000 62.000 62.000 0.000 0.000 0.000 ; D5
i2 0.374 0.188 9.04 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; E5
i2 0.561 0.188 9.05 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; F5
i2 0.750 0.250 5.05 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; F1
i3 0.750 0.100 643.50 1.000 ; D#5
i3 0.840 0.800 461.34 1.000 ; A4
i4 0.940 0.200 6.03 1.050 ; C2
i1 1.500 0.999 7.04 90.000 90.000 0.000 0.000 0.000 0.000 ; E3
i1 1.500 1.500 7.00 90.000 90.000 0.000 0.000 0.000 0.000 ; C3
i1 2.000 0.250 4.05 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i1 2.000 0.250 4.05 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i2 2.750 0.250 5.05 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; F1
i3 2.750 0.100 643.50 1.000 ; D#5
i1 3.000 1.500 7.02 90.000 90.000 0.000 0.000 0.000 0.000 ; D3
i1 3.499 1.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 ; G3

In the following example, we combine sound-objects (containing Csound scores) with simple notes that are converted to Csound events. These notes are played on (default) MIDI channel 1, which is assigned to instrument 1.
a C4 D4 b c

i1 0.000 0.250 4.05 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i1 0.000 0.250 4.05 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i2 0.750 0.250 5.05 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; F1
i3 0.750 0.100 643.50 1.000 ; D#5
i1 1.000 1.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 ; C4
i3 2.840 0.800 461.34 1.000 ; A4
i4 2.940 0.200 6.03 1.050 ; C2
i1 2.000 1.000 8.02 90.000 90.000 0.000 0.000 0.000 0.000 ; D4
i2 4.000 0.125 9.00 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; C5
i2 4.125 0.125 9.02 0.000 0.000 62.000 62.000 0.000 0.000 0.000 ; D5
i2 4.250 0.125 9.04 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; E5
i2 4.375 0.125 9.05 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; F5
This combination is highlighted in the pianoroll. Notes that are present in both the MIDI stream and the Csound score are displayed in brown, while notes that are present only in the Csound output are displayed in green.

Let us apply a continuous pitchbend control to a sound-object containing four Csound instructions, using instrument 2, which maps the MIDI pitchbend range [0..16384] to a range of [-200..+200], both on logarithmic scales. (This mapping is therefore linear.)
In the Bol Processor score, the use of mapped values in _pitchbend() controls is possible, thanks to a _pitchrange(200) instruction at the beginning of the sequence.
The resulting Csound score makes it clear that the pitchbend should vary continuously over each Csound event : 0 to 24.997, 24.997 to 49.994 etc. Csound will further interpolate the values using its GEN 07 (linear interpolation) generator.
_pitchrange(200) _pitchcont _pitchbend(0) c _pitchbend(100)
i2 0.000 0.125 9.00 0.000 24.997 90.000 90.000 0.000 0.000 0.000 ; C5
i2 0.125 0.125 9.02 24.997 49.994 62.000 62.000 0.000 0.000 0.000 ; D5
i2 0.250 0.125 9.04 49.994 74.991 90.000 90.000 0.000 0.000 0.000 ; E5
i2 0.375 0.125 9.05 74.991 99.988 90.000 90.000 0.000 0.000 0.000 ; F5
Volume control is possible on instruments 1 and 2, but not on instrument 3. Therefore its effect is only applied to certain events of sound-object "a":
_volumecont _volume(30) a _volume(127)
i1 0.000 0.250 4.05 30.000 54.250 0.000 0.000 0.000 0.000 ; F0
i1 0.000 0.250 4.05 30.000 54.250 0.000 0.000 0.000 0.000 ; F0
i2 0.750 0.250 5.05 0.000 0.000 102.750 127.000 0.000 0.000 0.000 ; F1
i3 0.750 0.100 643.50 1.000 ; D#5

In the following example, a continuous pitchbend correction cannot be applied because instrument 5, called by "d", does not have a pitchbend parameter. However, the value of +100 cents is applied to the pitch parameter itself.
The Csound score of sound-object "d" is limited to 1 note at 440 Hz (with reference to instrument 5). This note was labelled 'A4' on the prototype, but we should remember that with a diapason of 435 Hz it will be slightly higher than 'A4'. The increase is 1200 * log2(440/435) = 24 cents. So, in the performance it will be set to 124 cents above 435 Hz, giving 435 * 2^(124/1200) = 467 Hz. As shown below:
_pitchrange(200) _pitchcont _pitchbend(100) d _pitchbend(0)
i5 0.000 0.500 466.16 ; A4

In the following example, a continuous pitchbend correction results in different adjustments of the pitchbend parameters of the instruments called by sound-objects "a", "b" and "c". Simple notes 'C4' and 'D4' call instrument 1 because it is the one assigned to the (default) channel 1. The volume is also adjusted continuously.
Note that we also apply negative values to the pitchbend parameter, expecting the Csound orchestra to do the extrapolation.
_pitchrange(200) _pitchcont _volumecont _volume(30) _pitchbend(-10) a C4 D4 b c _pitchbend(100) _volume(127)
i1 0.000 0.250 4.05 30.000 34.850 0.000 -10.000 -4.500 0.000 ; F0
i1 0.000 0.250 4.05 30.000 34.850 0.000 -10.000 -4.500 0.000 ; F0
i2 0.750 0.250 5.05 6.499 11.999 44.550 49.400 0.000 0.000 0.000 ; F1
i3 0.750 0.100 643.50 1.005 ; D#5
i1 1.000 1.000 8.00 49.400 68.800 0.000 12.000 34.000 0.000 ; C4
i3 2.840 0.800 461.34 1.069 ; A4
i4 2.940 0.200 6.03 1.151 ; C2
i1 2.000 1.000 8.02 68.800 88.200 0.000 34.000 56.000 0.000 ; D4
i2 4.000 0.125 9.00 77.990 83.490 107.600 112.450 0.000 0.000 0.000 ; C5
i2 4.125 0.125 9.02 83.490 88.989 77.466 80.807 0.000 0.000 0.000 ; D5
i2 4.250 0.125 9.04 88.989 94.488 117.300 122.150 0.000 0.000 0.000 ; E5
i2 4.375 0.125 9.05 94.488 99.988 122.150 127.000 0.000 0.000 0.000 ; F5

Let us check an arbitrary parameter "burb" which affects arguments 9, 10 and 11 of instrument 2.
This parameter is designed as additive in its combinations. The default value is '0'.
In sound-object "e", the third event 'D3' is required to set 'blurb' to a start value of 10 and to an end value of 30.

These values are added to those interpolated over the continuous 'blurb' variation: 25.6 + (100 - 25.6) * 0.5 = 62.8 and 100 at dates 0.5 and 1 sec. This gives an initial value of 62.8 + 10 = 72.8 and a final value of 100 + 30 = 130.
_cont(blurb) _value(blurb,25.6) e _value(blurb,100)
i2 0.000 0.333 7.04 8191.500 8191.500 64.000 64.000 25.600 50.375 0.000 ; E3
i2 0.000 0.500 7.00 8191.500 8191.500 64.000 64.000 25.600 62.800 0.000 ; C3
i2 0.500 0.500 7.02 8191.500 8191.500 64.000 64.000 72.800 130.000 0.000 ; D3
i2 0.666 0.334 7.07 8191.500 8191.500 64.000 64.000 75.150 99.963 0.000 ; G3
If the variation of "blurb" becomes more complex, the Bol Processor will handle it
through function tables.
_cont(blurb) _value(blurb,12) e _value(blurb,110)_ _value(blurb,130)__ _value(blurb,80)__ _value(blurb,-20)_ _value(blurb,-10)___ _value(blurb,40)
f101 0.000 256 -7 12.000 76 110.000 76 130.000 104 96.750
i2 0.000 3.330 7.04 8191.500 8191.500 64.000 64.000 12.000 96.750 101.000 ; E3
f102 0.000 256 -7 12.000 51 110.000 51 130.000 102 80.000 52 30.000
i2 0.000 5.000 7.00 8191.500 8191.500 64.000 64.000 12.000 30.000 102.000 ; C3
f103 5.000 256 -7 40.000 51 -6.000 51 8.000 154 70.000
i2 5.000 5.000 7.02 8191.500 8191.500 64.000 64.000 40.000 70.000 103.000 ; D3
f104 6.660 256 -7 -13.400 26 -10.000 230 39.917
i2 6.660 3.335 7.07 8191.500 8191.500 64.000 64.000 -13.400 39.917 104.000 ; G3
In the Csound score of "e", event 'D3' has non-zero initial values on arguments 9 and 10. These values are added to those determined by variations of the "blurb" parameter, thereby giving 40 for argument 9 (the initial value of "blurb") and 70 for argument 10 (the final value). The same calculation is applied to the attached table f103. Consequently, the first and last values of a function table always reflect the initial and final values of the parameter. This allows Csound instruments to operate in a consistent manner, either interpolating the initial and final values, or picking up (and interpolating) the values in the attached function table.

The Bol Processor combines Csound parameters either additively or multiplicatively. For predefined MIDI-mapped parameters, the combination mode is preset: all parameters, except volume, are combined additively. For additional (non-MIDI) parameters, the composer can choose both the default value and the combination mode.
For example, instrument 6 deals with an "oops" parameter that combines multiplicatively. Sound-object "f" contains calls to this instrument with values of "oops" other than the default.
f
i6 0.000 0.500 7.00 0.000 0.000 90.000 90.000 0.000 0.000 0.000 0.500 1.500 0.000 0.000 0.000 0.000 ; C3
i6 0.500 0.500 7.02 0.000 0.000 90.000 90.000 0.000 0.000 0.000 0.000 4.700 0.000 0.000 0.000 0.000 ; D3
i6 1.000 0.500 7.04 0.000 0.000 90.000 90.000 0.000 0.000 0.000 0.250 2.500 0.000 0.000 0.000 0.000 ; E3
_cont(oops) _value(oops,0) f _value(oops,4)
i6 0.000 0.500 7.00 0.000 0.000 90.000 90.000 0.000 0.000 0.000 0.000 2.000 0.000 0.000 0.000 0.000 ; C3
i6 0.500 0.500 7.02 0.000 0.000 90.000 90.000 0.000 0.000 0.000 0.000 12.533 0.000 0.000 0.000 0.000 ; D3
i6 1.000 0.500 7.04 0.000 0.000 90.000 90.000 0.000 0.000 0.000 0.667 10.000 0.000 0.000 0.000 0.000 ; E3

The "oops" parameter varies from 0 to 4 over 1500 ms. At the start of 'D3' and 'E3', its values are 4 * (500 / 1500) = 1.33 and 4 * (1000 / 1500) = 2.66 respectively.
The initial value of "oops" in 'C3' is 0 * 0.5 = 0, and its final value 1.5 * 1.33 = 2, as shown on the score.
The initial value for 'D3' will be O, and for 'E3' it will be 0.25 * 2.66 = 0.665. The value at the end of D3 is 4.7 * 2.66 = 12.5. The value at the end of D3 is 2.5 * 4 = 10.
These examples have been designed to test all the features of the Csound interface as it is implemented in Bol Processor. We expect more to come as both environments continue to explore new concepts and build tools for musicians.
We apologise for the lack of a corpus of real musical pieces created with Bol Processor and Csound. A first example of high musical quality was composed in 1996: read and listen to Sarasvati vina!
Csound checkup

This article and the next one on Csound objects are reserved for Csound geeks interested in creating Csound scores with Bol Processor. They are complementary but they can be studied independently.
The examples in this section are not intended to be auditory. Rather, the idea was to produce short Csound scores that could be used to illustrate the treatment of parameters in a variety of contexts.
The calculations in this article can be easily checked against the Csound instrument file "‑cs.chekAllCsound" included in the bp3-ctests-main.zip example set, which can be downloaded from GitHub along with the Bol Processor BP3's interface: php-frontend-master.zip. See the Bol Processor ‘BP3’ and its PHP interface page for the installation and testing.
All items can be produced with the grammar "‑gr.checkAllCsound".
Let us start with a simple example:
A4 G4 C5 A4
This produces the following Csound score:
t 0.000 60.000
i2 0.000 1.000 440.00 90.000 0.000 0.000 0.000 ; A4
i2 1.000 1.000 392.00 90.000 0.000 0.000 0.000 ; G4
i2 2.000 1.000 523.25 90.000 0.000 0.000 0.000 ; C5
i2 3.000 1.000 440.00 90.000 0.000 0.000 0.000 ; A4
s
Instrument 2 is used because it's the one assigned to channel 1 by default in the Csound instrument file "-cs.checkAllCsound".
This score will not produce any sound with the default orchestra file "default.orc" because it does not contain a definition for instrument 2.
Argument 4 is the pitch (in Herz) related to the diapason (frequency of A4) set in "-se.checkAllCsound".
Argument 5 is the MIDI value of the volume, default 90 according to the settings.
Arguments 6 and 7 can be used for the 'blurb' parameter (see infra).
Argument 8 is not not used, its value remains 0.

Instrument 2 does not use the pitchbend value as a parameter, but changes the pitch parameter (in Hz) accordingly. In the following example, G4, which is 200 cents higher, will be played 2 semitones higher, at the same pitch as A4 (440 Hz).
_pitchrange(200) A4 _pitchbend(200) G4 _pitchbend(0) C5 A5
i2 0.000 1.000 440.00 90.000 0.000 0.000 0.000 ; A4
i2 1.000 1.000 440.00 90.000 0.000 0.000 0.000 ; G4
i2 2.000 1.000 523.25 90.000 0.000 0.000 0.000 ; C5
i2 3.000 1.000 880.00 90.000 0.000 0.000 0.000 ; A5

Now we will force the instrument to 3. Note that many new parameters are displayed.
The default volume is 90 on the MIDI scale. This is converted to 16.98 (log scale) using the volume mapping defined in instrument 3.
As instrument 3 accepts pitchbend corrections (arguments 5 and 6), pitchbend = 16383 (+2 semitones) is applied to G4 instead of changing its frequency.
_ins(3) _pitchrange(200) A4 _pitchbend(200) G4 _pitchbend(0) C5 A5
i3 0.000 1.000 440.00 8191.500 8191.500 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; A4
i3 1.000 1.000 392.00 16383.000 16383.000 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; G4
i3 2.000 1.000 523.25 8191.500 8191.500 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; C5
i3 3.000 1.000 880.00 8191.500 8191.500 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; A5
Arguments 5 and 6 represent the start and end values of the pitchbend. This makes it possible to tell Csound to calculate a portamento (see infra).

Playing simple notes on channel 2 calls up instrument 3, which has volume and modulation control parameters. Here the modulation range (0 to 12431) is mapped to 0 to 3035.097 (arguments 11 and 12).
chan(2) _modcont _mod(0) C4 D4__ E4 _mod(12431)
i3 0.000 1.000 261.63 8191.500 8191.500 16.981 16.981 0.000 0.000 0.000 607.019 0.000 ; C4
i3 1.000 3.000 293.66 8191.500 8191.500 16.981 16.981 0.000 0.000 607.019 2428.078 0.000 ; D4
i3 4.000 1.000 329.63 8191.500 8191.500 16.981 16.981 0.000 0.000 2428.078 3035.097 0.000 ; E4
Another way to do the same without tempering with channels is to use instrument 3.
ins(3) _modcont _mod(0) C4 D4__ E4 _mod(12431)
Note that instrument specifications override the assignments of The_default instrument, which are made on the basis of the MIDI channel. For instance, in the following example, because of the _ins(1) statement, _chan(2) does not set the instrument index to 3, so _mod() is ignored:
ins(1) _chan(2) _modcont _mod(0) C4 D4__ E4 _mod(12431)
i1 0.000 1.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 ; C4
i1 1.000 3.000 8.02 90.000 90.000 0.000 0.000 0.000 0.000 ; D4
i1 4.000 1.000 8.04 90.000 90.000 0.000 0.000 0.000 0.000 ; E4

Let us consider a polymetric structure in which the same note (D5) has two consecutive NoteOn's.
In MIDI, a NoteOff is inserted before the second NoteOn of "D5". In Csound the same
instrument is called twice. In both versions the break between successive occurrences of "D5" is audible.

_ins(The_default) {_volume(30) C5 D5 E5 F5,_volume(20) G5 D5 C6}
i1 0.000 1.000 9.00 30.000 30.000 0.000 0.000 0.000 0.000 ; C5
i1 0.000 1.333 9.07 20.000 20.000 0.000 0.000 0.000 0.000 ; G5
i1 1.000 1.000 9.02 30.000 30.000 0.000 0.000 0.000 0.000 ; D5
i1 1.333 1.333 9.02 20.000 20.000 0.000 0.000 0.000 0.000 ; D5 striked again
i1 2.000 1.000 9.04 30.000 30.000 0.000 0.000 0.000 0.000 ; E5
i1 3.000 1.000 9.05 30.000 30.000 0.000 0.000 0.000 0.000 ; F5
i1 2.666 1.334 10.00 20.000 20.000 0.000 0.000 0.000 0.000 ; C6
Note that this example would sound strange without the volume controls: we would get a silence during the time the two D5' are superimposed, simply because they are sine waves with equal amplitudes and opposite phases!
Let us look at the same note played at different volumes in stepwise variations. Notice that instrument 3 is now specified by its name "Harpsichord". (Don't look for it in an orchestra file!)
_ins(Harpsichord) _volume(0) A4 _volume(32) A4 _volume(64) A4 _volume(80) A4_volume(127) A4
i3 0.000 1.000 440.00 8191.500 8191.500 -24.000 -24.000 0.000 0.000 0.000 0.000 0.000 ; A4
i3 1.000 1.000 440.00 8191.500 8191.500 -2.763 -2.763 0.000 0.000 0.000 0.000 0.000 ; A4
i3 2.000 1.000 440.00 8191.500 8191.500 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; A4
i3 3.000 1.000 440.00 8191.500 8191.500 13.204 13.204 0.000 0.000 0.000 0.000 0.000 ; A4
i3 4.000 1.000 440.00 8191.500 8191.500 24.000 24.000 0.000 0.000 0.000 0.000 0.000 ; A4

The following illustration shows the volume decreasing continuously from 127 (i.e. +24 after mapping) to 0 (i.e. -24 after mapping). Instrument 3 has two parameters (7 and 8) that take the start and end volumes respectively, and these values are interpolated by Csound (using scheme GEN07) to produce a continuous change.
_ins(Harpsichord) _volumecont _volume(127) A4 _volume(0)
i3 0.000 1.000 440.00 8191.500 8191.500 24.000 -24.000 0.000 0.000 0.000 0.000 0.000 ; A4
Now we will look at similar continuous changes over several notes invoking the same instrument.
_ins(Harpsichord) _volumecont _volume(127) A4 G4 C5 A5 A4 G4 C5 A5 _volume(0)
i3 0.000 1.000 440.00 8191.500 8191.500 24.000 21.688 0.000 0.000 0.000 0.000 0.000 ; A4
i3 1.000 1.000 392.00 8191.500 8191.500 21.688 18.431 0.000 0.000 0.000 0.000 0.000 ; G4
i3 2.000 1.000 523.25 8191.500 8191.500 18.431 12.899 0.000 0.000 0.000 0.000 0.000 ; C5
i3 3.000 1.000 880.00 8191.500 8191.500 12.899 -0.031 0.000 0.000 0.000 0.000 0.000 ; A5
i3 4.000 1.000 440.00 8191.500 8191.500 -0.031 -1.179 0.000 0.000 0.000 0.000 0.000 ; A4
i3 5.000 1.000 392.00 8191.500 8191.500 -1.179 -2.794 0.000 0.000 0.000 0.000 0.000 ; G4
i3 6.000 1.000 523.25 8191.500 8191.500 -2.794 -5.547 0.000 0.000 0.000 0.000 0.000 ; C5
i3 7.000 1.000 880.00 8191.500 8191.500 -5.547 -24.000 0.000 0.000 0.000 0.000 0.000 ; A5
The same, but step by step:
_ins(Harpsichord) _volumestep _volume(127) A4 G4 C5 A5 A4 G4 C5 A5 _volume(0)
i3 0.000 1.000 440.00 8191.500 8191.500 24.000 24.000 0.000 0.000 0.000 0.000 0.000 ; A4
i3 1.000 1.000 392.00 8191.500 8191.500 21.688 21.688 0.000 0.000 0.000 0.000 0.000 ; G4
i3 2.000 1.000 523.25 8191.500 8191.500 18.431 18.431 0.000 0.000 0.000 0.000 0.000 ; C5
i3 3.000 1.000 880.00 8191.500 8191.500 12.899 12.899 0.000 0.000 0.000 0.000 0.000 ; A5
i3 4.000 1.000 440.00 8191.500 8191.500 -0.031 -0.031 0.000 0.000 0.000 0.000 0.000 ; A4
i3 5.000 1.000 392.00 8191.500 8191.500 -1.179 -1.179 0.000 0.000 0.000 0.000 0.000 ; G4
i3 6.000 1.000 523.25 8191.500 8191.500 -2.794 -2.794 0.000 0.000 0.000 0.000 0.000 ; C5
i3 7.000 1.000 880.00 8191.500 8191.500 -5.547 -5.547 0.000 0.000 0.000 0.000 0.000 ; A5
Changing the volume continuously on the first two notes, then the volume stays unchanged:
_ins(Harpsichord) _volumecont _volume(127) A4 G4 _volume(10) C5 A5
i3 0.000 1.000 440.00 8191.500 8191.500 24.000 4.549 0.000 0.000 0.000 0.000 0.000 ; A4
i3 1.000 1.000 392.00 8191.500 8191.500 4.549 -7.372 0.000 0.000 0.000 0.000 0.000 ; G4
i3 2.000 1.000 523.25 8191.500 8191.500 -7.372 -7.372 0.000 0.000 0.000 0.000 0.000 ; C5
i3 3.000 1.000 880.00 8191.500 8191.500 -7.372 -7.372 0.000 0.000 0.000 0.000 0.000 ; A5
Continuous pitchbend variation over an entire phrase:
_ins(Harpsichord) _pitchcont _pitchbend(16383) A4 G4 C5 A5 A4 G4 C5 A5 _pitchbend(0)
i3 0.000 1.000 440.00 16383.000 14335.125 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; A4
i3 1.000 1.000 392.00 14335.125 12287.250 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; G4
i3 2.000 1.000 523.25 12287.250 10239.375 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; C5
i3 3.000 1.000 880.00 10239.375 8191.500 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; A5
i3 4.000 1.000 440.00 8191.500 6143.625 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; A4
i3 5.000 1.000 392.00 6143.625 4095.750 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; G4
i3 6.000 1.000 523.25 4095.750 2047.875 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; C5
i3 7.000 1.000 880.00 2047.875 0.000 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; A5
Here, pitchbend and volume vary simultaneously:
_ins(Harpsichord) _volumecont _volume(0) _pitchcont _pitchrange(200) _pitchbend(200) A4 G4 C5 A5 A4 G4 C5 A5 _pitchbend(-200) _volume(127)
i3 0.000 1.000 440.00 16383.000 14335.125 -24.000 -5.547 0.000 0.000 0.000 0.000 0.000 ; A4
i3 1.000 1.000 392.00 14335.125 12287.250 -5.547 -2.794 0.000 0.000 0.000 0.000 0.000 ; G4
i3 2.000 1.000 523.25 12287.250 10239.375 -2.794 -1.179 0.000 0.000 0.000 0.000 0.000 ; C5
i3 3.000 1.000 880.00 10239.375 8191.500 -1.179 -0.031 0.000 0.000 0.000 0.000 0.000 ; A5
i3 4.000 1.000 440.00 8191.500 6143.625 -0.031 12.899 0.000 0.000 0.000 0.000 0.000 ; A4
i3 5.000 1.000 392.00 6143.625 4095.750 12.899 18.431 0.000 0.000 0.000 0.000 0.000 ; G4
i3 6.000 1.000 523.25 4095.750 2047.875 18.431 21.688 0.000 0.000 0.000 0.000 0.000 ; C5
i3 7.000 1.000 880.00 2047.875 0.000 21.688 24.000 0.000 0.000 0.000 0.000 0.000 ; A5
So far we have seen how instruments interpolate between single start and end values.
Instrument 1, here called "The_default", i.e. the one defined in "default.orc", is able to vary pitchbend and volume in a more sophisticated way, using a function table.
BP3 automatically creates function tables when required and when the instrument specification (here "-cs.checkAllCsound") provides slots (arguments) for entering function table indexes.
Let us look at a simple example with pitchbend. Both of the following notations result in the same score.
You will hear the production of this score with the demo orchestra "default.orc". (Doesn't sound great!)
ins(The_default) _pitchcont _pitchbend(0) D4__ _pitchbend(16383) E4_ _pitchbend(0)__
ins(The_default) _pitchrange(200) _pitchcont _pitchbend(-200) D4__ pitchbend(+200) E4_ pitchbend(-200)__
i1 0.000 3.000 8.02 90.000 90.000 0.000 -200.000 200.000 0.000 ; D4
f101 3.000 256 -7 200.000 102 -200.000 154 -200.000
i1 3.000 5.000 8.04 90.000 90.000 0.000 200.000 -200.000 101.000 ; E4
Note that GENO7 is used. GENO8 (cubic spline interpolation) could be considered, but it has the disadvantage of forcing the first derivative to zero at the start and end points. GEN07 is also much faster.
Here, C4 needs a 4-point table, because of _pitchcont whereas D4 only needs linear interpolation?
ins(1) _pitchrange(200) _pitchbend(0) _pitchcont C4_ _pitchbend(20) __ _pitchbend(165) __ D4 _ _ _ _pitchbend(150)
f101 0.000 256 -7 0.000 85 20.000 85 165.000 86 160.000
i1 0.000 6.000 8.00 90.000 90.000 0.000 0.000 160.000 101.000 ; C4
i1 6.000 4.000 8.02 90.000 90.000 0.000 160.000 150.000 0.000 ; D4
Here, the initial portamento on a silence '-' is only provided by the
MIDI output. Csound ignores silence:
ins(1) _pitchrange(200) _pitchbend(0) _pitchcont - ___ C4 ___ _pitchbend(200) __ D4 ___ _pitchbend(150)
f101 4.000 256 -7 100.000 170 200.000 86 183.333
i1 4.000 6.000 8.00 90.000 90.000 0.000 100.000 183.333 101.000 ; C4
i1 10.000 4.000 8.02 90.000 90.000 0.000 183.333 150.000 0.000 ; D4
ins(1) _pitchrange(200) _pitchbend(0) _pitchcont - _ _pitchbend(20) __ C4 ___ _pitchbend(200) __ D4 ___ _pitchbend(150)
f101 4.000 256 -7 80.000 170 200.000 86 183.333
i1 4.000 6.000 8.00 90.000 90.000 0.000 80.000 183.333 101.000 ; C4
i1 10.000 4.000 8.02 90.000 90.000 0.000 183.333 150.000 0.000 ; D4
ins(1) _pitchcont _pitchrange(200) _pitchbend(0) - ___ C4 ___ _pitchbend(200) __ D4 ___ _pitchbend(150
f101 4.000 256 -7 100.000 170 200.000 86 183.333
i1 4.000 6.000 8.00 90.000 90.000 0.000 100.000 183.333 101.000 ; C4
i1 10.000 4.000 8.02 90.000 90.000 0.000 183.333 150.000 0.000 ; D4
Here the section between brackets { } follows an independent portamento
ins(1) _pitchcont _pitchrange(200) _pitchbend(0) - ___ {C4 ___ _pitchbend(200) __ } D4 ___ _pitchbend(150)
f101 4.000 256 -7 42.857 170 200.000 86 200.000
i1 4.000 6.000 8.00 90.000 90.000 0.000 42.857 200.000 101.000 ; C4
i1 10.000 4.000 8.02 90.000 90.000 0.000 107.143 150.000 0.000 ; D4
A polymetric structure. E4 retains the initial pitchbend value of C4.
ins(1) _pitchcont _pitchrange(200) _pitchbend(0) - ___ {C4 ___ _ pitchbend(200) __ , E4} D4 ___ _pitchbend(150)
f101 4.000 256 -7 42.857 170 200.000 86 200.000
i1 4.000 6.000 8.00 90.000 90.000 0.000 42.857 200.000 101.000 ; C4
i1 4.000 6.000 8.04 90.000 90.000 0.000 42.857 107.143 0.000 ; E4
i1 10.000 4.000 8.02 90.000 90.000 0.000 107.143 150.000 0.000 ; D4
Here, E4 has its own independent movement, which would be impossible with MIDI.
ins(1) _pitchcont _pitchrange(200) _pitchbend(0) - ___ {C4 ___ _ pitchbend(200) __ ,E4_ _pitchbend(180) _ _pitchbend(60) _ } D4 ____ _pitchbend(150)
f101 4.000 256 -7 42.857 170 200.000 86 200.000
i1 4.000 6.000 8.00 90.000 90.000 0.000 42.857 200.000 101.000 ; C4
f102 4.000 256 -7 42.857 128 180.000 64 60.000 64 60.000
i1 4.000 6.000 8.04 90.000 90.000 0.000 42.857 60.000 102.000 ; E4
i1 10.000 4.000 8.02 90.000 90.000 0.000 107.143 150.000 0.000 ; D4
Don't forget to set _pitchrange(200) on channel 2, otherwise _pitchbend(180) will be used as the MIDI value (range 0..16383). Note again that channel 2 will not call instrument 3 because instrument 1 has already been specified.
ins(1) _pitchcont _pitchrange(200) _pitchbend(0) - ___ {C4 ___ _ pitchbend(200) __ , _chan(2) _pitchrange(200) E4_ _pitchbend(180) __ } D4 ___ _pitchbend(150)
f101 4.000 256 -7 42.857 170 200.000 86 200.000
i1 4.000 6.000 8.00 90.000 90.000 0.000 42.857 200.000 101.000 ; C4
f102 4.000 256 -7 42.857 128 180.000 128 180.000
i1 4.000 6.000 8.04 90.000 90.000 0.000 42.857 180.000 102.000 ; E4
i1 10.000 4.000 8.02 90.000 90.000 0.000 107.143 150.000 0.000 ; D4
In the above example, if you forget to set the instrument to 1, instruments will be assigned based on MIDI channels. This results in:
pitchcont _pitchrange(200) _pitchbend(0) - ___ {C4 ___ _ pitchbend(200) __ , _chan(2) _pitchrange(200) E4_ _pitchbend(180) __ } D4 ___ _pitchbend(150)
i2 4.000 6.000 268.18 90.000 0.000 0.000 0.000 ; C4
i3 4.000 6.000 329.63 9946.821 15563.850 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; E4
i2 10.000 4.000 312.41 90.000 0.000 0.000 0.000 ; D4
Let us now try an arbitrary parameter 'blurb' (which has no MIDI equivalent)
on the two instruments 'Harpsichord' and 'Flute'.
_ins(Harpsichord) _cont(blurb) _value(blurb,123.42) C4 D4 _ins(Flute) E4 F4 _value(blurb,-211) _step(blurb) G4 A4 _value(blurb,-34) _fixed(blurb) B4 C5
i3 0.000 1.000 261.63 8191.500 8191.500 16.981 16.981 123.420 39.815 0.000 0.000 0.000 ; C4
i3 1.000 1.000 293.66 8191.500 8191.500 16.981 16.981 39.815 -43.790 0.000 0.000 0.000 ; D4
i2 2.000 1.000 329.63 90.000 -43.790 -127.395 0.000 ; E4
i2 3.000 1.000 349.23 90.000 -127.395 -211.000 0.000 ; F4
i2 4.000 1.000 392.00 90.000 -211.000 -211.000 0.000 ; G4
i2 5.000 1.000 440.00 90.000 -122.500 -122.500 0.000 ; A4
i2 6.000 1.000 493.88 90.000 -34.000 -34.000 0.000 ; B4
i2 7.000 1.000 523.25 90.000 -34.000 -34.000 0.000 ; C5
Instrument "Flute" can handle function tables for 'blurb'.
ins(Flute) _cont(blurb) _value(blurb,544.5) C4__ _value(blurb,120) __ _value(blurb,-37)___ _value(blurb,0)
f101 0.000 256 -7 544.500 96 120.000 64 -37.000 96 0.000
i2 0.000 8.000 261.63 90.000 544.500 0.000 101.000 ; C4
Note that if the 'arbitrary' parameter is called 'volume', it will be MIDI volume, here remapped to the range -24..+24
_ins(Harpsichord) _cont(volume) _value(volume,127) A4 B4 _value(volume,0)
i3 0.000 1.000 440.00 8191.500 8191.500 24.000 -0.031 0.000 0.000 0.000 0.000 0.000 ; A4
i3 1.000 1.000 493.88 8191.500 8191.500 -0.031 -24.000 0.000 0.000 0.000 0.000 0.000 ; B4
The same applies to 'pitchbend', 'pressure', 'panoramic' and 'modulation' (all case sensitive). In instrument 3, MIDI modulation is remapped to the range 0..4000.
_ins(Harpsichord) _cont(modulation) _value(modulation,0) A4 B4 C5 D5 _value(modulation,16383)
i3 0.000 1.000 440.00 8191.500 8191.500 16.981 16.981 0.000 0.000 0.000 1000.000 0.000 ; A4
i3 1.000 1.000 493.88 8191.500 8191.500 16.981 16.981 0.000 0.000 1000.000 2000.000 0.000 ; B4
i3 2.000 1.000 523.25 8191.500 8191.500 16.981 16.981 0.000 0.000 2000.000 3000.000 0.000 ; C5
i3 3.000 1.000 587.33 8191.500 8191.500 16.981 16.981 0.000 0.000 3000.000 4000.000 0.000 ; D5
Now the two have been combined:
_ins(Harpsichord) _cont(volume) _cont(modulation) _value(volume,127) _value(modulation,0) A4 B4 C5 D5 _value(volume,0) _value(modulation,16383)
i3 0.000 1.000 440.00 8191.500 8191.500 24.000 18.431 0.000 0.000 0.000 1000.000 0.000 ; A4
i3 1.000 1.000 493.88 8191.500 8191.500 18.431 -0.031 0.000 0.000 1000.000 2000.000 0.000 ; B4
i3 2.000 1.000 523.25 8191.500 8191.500 -0.031 -2.794 0.000 0.000 2000.000 3000.000 0.000 ; C5
i3 3.000 1.000 587.33 8191.500 8191.500 -2.794 -24.000 0.000 0.000 3000.000 4000.000 0.000 ; D5
Note that if the additional parameter is unknown to the instrument, it will simply be ignored. No warning will be given. For example:
_ins(Harpsichord) _cont(gasp) _value(gasp,0) A4 B4 _value(gasp,1000)
i3 0.000 1.000 440.00 8191.500 8191.500 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; A4
i3 1.000 1.000 493.88 8191.500 8191.500 16.981 16.981 0.000 0.000 0.000 0.000 0.000 ; B4
The 'Splashmachine' instrument handles the 'splash' parameter which is instructed to create function tables with GEN08 (cubic spline) instead of GEN07.
ins(Splashmachine) _cont(splash) _value(splash,544.5) C4__ _value(splash,120) __ _value(splash,-37)___ _value(splash,130)
f101 0.000 256 -8 544.500 96 120.000 64 -37.000 96 130.000
i4 0.000 8.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 544.500 130.000 101.000 ; C4
The same instrument also uses GENO8 for the pitchbend.
_ins(Splashmachine) _cont(pitchbend) _pitchrange(200) _value(pitchbend,120) C4__ _value(pitchbend,34) __ _value(pitchbend,55)___ _value(pitchbend,-160)
This can be written more simply:
_ins(Splashmachine) _cont(pitchbend) _pitchrange(200) _pitchbend(120) C4__ _pitchbend(34) __ _pitchbend(55)___ _pitchbend(-160)
f101 0.000 256 -8 120.000 96 34.000 64 55.000 96 -160.000
i4 0.000 8.000 8.00 90.000 90.000 0.000 120.000 -160.000 101.000 0.000 0.000 0.000 ; C4
All these examples produce identical results with BP2.9.8 and its current version BP3.
Want to know more? Read the page Csound objects!
Sarasvati vina

The following is an example of successful combination of Bol Processor and Csound. Both music creation software packages are still in development after four decades… Csound was originally written by Barry Vercoe at MIT in 1985, while Bol Processor dates back to 1981.
Short musical phrases were composed in 1995 by Srikumar Karaikudi Subramanian, an accomplished practitioner of Carnatic music with deep understanding of mathematics and physics — read his blog, PhD thesis (2013) and list of patents.
Listen to the result:
The making of this example requires a 33-millisecond waveform sample of Sarasvati vīna (vina-wave-table.aif) and a grammar (-gr.vina3) associated with a Csound instrument description (-cs.Vina). All this is handled by the Bol Processor in both BP2 and BP3 versions. This process produces a Csound score which Csound converts into a sound file using a Csound orchestra file (new-vina.orc).
The demo was initially developed on Bol Processor BP2, the standalone application still available for Mac computers. In October 2020, it was repeated on BP3, the multi-platform version, to check the validity of Csound procedures in the new environment.
The grammar
The grammar "-gr.vina3" is available with all the necessary ingredients in the example 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 as instructed.
The grammar "-gr.vina3" is shown below.
This grammar is exemplary for its use of variables that represent "musical gestures" before their sound representation. For example, "Pull0", "Pull1" and "Pulll2" are different ways of pulling the string to raise its pitch. This is reflected by changing the value of a pitchbender, which is a MIDI standard and has been reproduced in the Csound orchestra.
Another gesture is named "slide", which is the movement from one fret to the next one. It also affects the frequency of the note, but in a discontinuous way, because the movement is a rapid change.
A more sophisticated model might include the strength of the plucking of a note, which could be mapped to a parameter similar to the velocity parameter in MIDI.
The Csound score
Once the grammar is open in the BP3/PHP interface environment, clicking on "Produce item(s)" will (by default) create a Csound score named "vina3.sco", as shown below.

Note that the first line of this score — table "f1" — contains the link to the sampled waveform "vina-wave-table.aiff" and the Csound orchestra file "new-vina.orc" located in the same folder. The value "1" in the fourth argument indicates that data from a sound file will be transferred into a function table (see documentation).
Lines starting with "i1" are note instructions submitted to the instrument "vina" to produce notes 'C3', 'G3', 'F4' etc. The second and third arguments are the start time and duration respectively (see documentation). The fourth argument is the pitch, expressed as "octave.note": for example, "7.05" means the 7th note of octave 7, which is F3. The pitch could also be given in Herz with respect to 'A4' = 440Hz — see Csound tuning in BP3.
Instructions "f102", "f103" etc. describe tables used for the interpolation of pitchbend and "slide" parameters associated with the "vina" instrument. In the "slide" parameter settings, the table index is the 13th argument. In fact, the 13th parameter of the "i1" instructions contains "101", "103" etc. In each of these tables, the fourth argument indicates the GEN routine that Csound will use for its interpolation. The value "-7" means "GENO7" (linear interpolation) with no post-normalization (see documentation).

Instructions "f102", "f104" etc. are tables for interpolating pitchbender values. These are referenced in the 10th argument of "i1" events, as shown in the picture. We see that the range of MIDI values [0 .. 16383] is mapped to the [-500 .. +500] interval used by the Csound instrument, both being logarithmic scales. The central mapping of 8191.50 to 0 is used to construct this interpolation with a quadratic regression. See the Csound argument mapping page for a detailed explanation.
For example, in this event:
i1 4.750 0.656 7.07 90.000 90.000 0.000 0.000 100.000 104.000 0.000 0.000 105.000 ; G3
the table "f104" (10th argument) is invoked to interpolate pitchbend values between 0.000 and 100.000 (the 8th and 9th arguments). In event:
i1 21.000 1.000 7.05 90.000 90.000 0.000 0.000 0.000 0.000 0.000 201.000 117.000 ; F3
the table "f117" (13th argument) is used to interpolate the "slide" parameter between 0.000 and 201.000 (the 11th and 13th arguments). However, in the orchestra file "new-vina.orc", this parameter is not treated as continuous because it represents a quick move from one fret to the next. Therefore, the _cont(slide) instruction is irrelevant for this version of the grammar. It could be deleted or replaced by _step(slide).
Making the sound file
Open a Unix console and go to the folder containing "vina3.sco" and "new-vina.orc".
Type :
csound -o Vina3.aif new-vina.orc out.sco

If the operation is successful — as confirmed by messages on the console — the desired sound file "Vina3.aif" has been created.
WAV format, 24-bit resolution etc. are also available with Csound. Just type "csound" to see some options, or "csound --help" to see the full list.
By default, Csound displays messages that mimic the graphical representation of all tables used in the score. This option can be turned off.
This whole process of converting a Csound score into a sound file has been made automatic on the Bol Processor BP3 interface. If Csound is installed and responding, it will be called to do the conversion. The sound file it is instructed to create is in WAV format.
Microtonal intonation
An important feature of this example is the choice of a microtonal scale to replace the equal tempered 12 tone scale commonly used on electronic or modern keyboard instruments. The scale is defined in the tonal resource "-to.Vina" and is set by the instruction _scale(just intonation,0).
In BP3 it is possible to define microtonal scales and use them either in the MIDI or the Csound environment. (Read the MIDI microtonality page.) Csound uses function tables, which are automatically superimposed on the Csound score. For example, a "just intonation" scale can be defined as follows:
f2 0 128 -51 12 2 264 60 1 1.066 1.125 1.2 1.25 1.333 1.42 1.5 1.6 1.666 1.777 1.875
Numbers in red indicate frequency ratios. For example, the size of the fifth (C - G) is 1.333 = 4/3, which makes it "perfect". Listen to both interpretations in just intonation and equal temperament:
Discussion
This detailed interpretation of a musical phrase in Carnatic music was just an early demonstration of Bol Processor + Csound features. In 2013, Srikumar Karaikudi Subramanian submitted his PhD thesis to the National University of Singapore entitled Modeling Gamakās of Carnatic Music as a Synthesizer for Sparse Prescriptive Notation. He went on to develop the Pāṭāntarā system of high-quality Carnatic music notation.
Apart from using a sample of the real Sarasvati vīna sound to create the musical piece, is it worth using the Csound environment instead of MIDI on the Bol Processor? After all, any MIDI sampler could handle the waveform and produce the same sound as Csound…
We do not have a MIDI sampler to reproduce the sound of a Sarasvati vīna, but "-gr.vina3" can be played on a MIDI device, either in real time or via a MIDI file. The following is a rendering on PianoTeq:
Listening to this version, it is clear that the pitchbend instructions have been partially interpreted, while the "slide" parameter specific to the "vina" Csound instrument has been ignored. This confirms that Csound offers the possibility of enriching the description of any piece of music with performance parameters that do not belong to the standard MIDI categories: pitchbend, modulation, pressure, etc.
We have documented all the features of the Csound implementation on the Csound checkup and Csound objects page, showing examples that can be checked with BP3. More details on the handling of continuous parameters can be found on the page Continuous parameters in Csound scores.
A call for participation
We invite musicians who are familiar with Csound to create examples of the full use of Csound on Bol Processor. This will increase our confidence that none of the implemented Csound features are incomplete or erroneous.
➡ The development of Csound beyond our initial work on the subject (in 1995) is expected to stimulate new ideas for more advanced integration in future versions of BP3.
Bol Processor ‘BP3’ and its PHP interface

This is a presentation of Bol Processor ‘BP3’. Install it and try these examples in your environment: MacOS, Windows or Linux.
👉 ‘BP3’ produces real-time MIDI events, BP scores, standard MIDI files and Csound scores.
👉 Capturing and interpreting incoming MIDI messages is a work in progress. Importing MusicXML scores is fully functional.
👉 MIDI files are instantly audible thanks to a built-in MIDI player, while Csound scores are used to create sound files sent to a standard HTML5 audio player.
This page provides an overview of interactions with the Bol Processor console. The objective is to verify its operation in any environment. Musical examples are of low artistic value as their purpose is to be a comprehensive demonstration of technical aspects.
Once you have completed the installation of BP3 (and optional Csound), you can check these features in any order you like. A preview of the help file is available here.
Real-time MIDI was implemented in May 2024. It works beautifully in the three environments… After installing BP3, visit the Real Time MIDI page to enjoy the full range of possibilities it offers!
BP3 is currently being tested with MAMP (see below) on computers running MacOS Sequoia 15.3 and Windows 10, and with XAMPP on MacOS and LinuxLite 7.0 (Ubuntu). It hasn't yet been checked on Windows 11. A standalone "BolProcessor.app" application is available on MacOS.
👉 Send questions/suggestions to the developers via the contact form or join the BP developers list on SourceForge.
Install the Apache server and Bol Processor package
Installing the Bol Processor BP3 does not require any programming skills. Just use the installers for MacOS and Windows, or the installation scripts for Linux.
Follow instructions on installation pages for MacOS, Windows and Linux.
Compile the console and check its operation
The Bol Processor's PHP interface recognises the system your computer is running. It checks key features and tells you what is missing or needs fixing.

👉 If you have installed the standalone "BolProcessor.app" application on MacOS, you can start it and go directly to Produce items.
- Start your Apache/PHP server and point your web browser at the file bolprocessor/php/index.php.
- The URL looks like http://localhost/bolprocessor/php/. Note that "http" is used, not "https". On Windows, the URL is displayed as localhost/bolprocessor/php/.
- MacOS and Linux users: if you get an error message or see nothing, check file permissions ("775" in the "bolprocessor" folder) in your installation. The installer or the installation script takes care of it: did you use it? This issue did not occur on Windows 10.
- MacOS and Windows users: the Bol Processor console ("bp" or "bp.exe") is distributed precompiled if you use the installer. You should see that the console is "responding" at the top right of the window. Otherwise, proceed as shown below for Linux.
- Linux users: If you have just done a new installation or an upgrade, you will get a warning that the console "bp3" is not "responding" along with a link to the compilation page. It will compile the console if the installation is correct. More information is found on the Quick install page. After the compilation, you will get a confirmation message if it was successful, or a list of errors if it was not — which should never happen, otherwise tell us!
You can then reload the home page, now looking like the picture above, by default in dark mode.
😀 You've done the difficult part! 😀
The "bp" (or "bp.exe" or "bp3") console is now working.
If you wish to recompile the console, you can simply point your browser to localhost/bolprocessor/compile.php. This will automatically run the "Makefile". In MacOS and Linux, the console is automatically recompiled each time you run the installer to patch an update of the Bol Processor. In Windows, the precompiled (and certified) "bp.exe" is distributed, but you can recompile it after deleting "bp.exe".
- The home page displays the contents of the "bolprocessor" folder, in particular a link to the "ctests" folder.
- Follow the "ctests" link. You will find a list of available example files classified in distinctive frames. In general, the name of a grammar project starts with "-gr", but it can also end with the extension "bpgr". The name of a set of data project starts with "-da", but it can also end with the extension "bpda". Both type conventions are supported. This became necessary a long time ago, when upgrading BP2 from MacOS 9 to MacOS 10…
- Click on "-gr.koto3" to open a grammar. This will automatically create a folder called "my_output" at the top of the "bolprocessor" folder if it doesn't already exist. You can try to create an output folder with a different name and check its presence at the top of "bolprocessor". The current name of the output folder is saved in "_settings.php" which is recalled each time the interface is used.
- You can create subfolders of the current output folder. For example, if the current output is set to "my_output", create "my_output/todays_folder". The interface automatically replaces spaces with '_' as these may be unwanted on some systems.
On the page displaying the files in a workspace (e.g. "ctests") you will see the DOWNLOAD FILES, MOVE and IMPORT FILES buttons. These are used to move files between workspaces. Files can indeed be moved from the Finder or File Manager, but he interface takes care of the owner/group permissions required for its operation. Therefore, uploading a file using the IMPORT FILES button is a better idea than moving it using the Finder.
👉 The Bol Processor interface can be displayed in both dark and light modes. There is an icon in the top right corner to switch between these modes.
Produce items
👉 In June 2024, the prefixes and suffixes of some files have been changed to make them more meaningful:
- Prefix "-ho" and suffix "bpho" are replaced by "-al" and "bpal" (Alphabet files)
- Prefix "-mi" and suffix "bpmi" are replaced by "-so" and "bpso" (Sound-object files)
These changes are automatically managed by the interface and the console. No manual editing is required.
In the following sections, the output options are either MIDI file or CSOUND file. However, we recommend opting for real-time MIDI if your machine is set up for it: see details.


- Open the "-gr.koto3" grammar and click PRODUCE ITEM(s). This will open a "BP console" pop-up window and launch the console application.
- By default, the output is set to MIDI files. A link is provided to download this MIDI file, and a javascript MIDI player is displayed to listen to its contents.
👉 If your computer is not connected to the Internet, you won't hear anything on this player… - In the absence of "MIDI program" messages, piano-like sounds are produced which do not resemble the rendering of the -"gr.koto3" grammar on a proper MIDI device — here a Roland D-50 synthesiser, listen to the real thing.
- Don't waste time trying to understand how this grammar works, we're just doing a technical test!
- While the console application is running, a detailed list of actions is recorded, which you can display in the pop-up window.
- At the top of the window, the command line created to call the console is displayed in red. This is used by programmers to check the console's response.
- "Image" links will appear at the top of the BP console window. Click them to display images in new windows. By default, this picture shows the sound-objects a, b, c, chik, etc. We will see a pianoroll later as another option.
- At the top of the "BP console" there is a link to the "trace file" which shows the full process of derivations for creating items. It was created by adding the --trace-production option to the command line to check the details. The Trace mode can be enabled or disabled in the "-se.koto3" settings page.
- The "my_ouput" folder should contain "koto3.mid" — the name for this MIDI file.

- Return to the grammar and select "BP data file" as the output option, then click the SAVE button. Now the name "koto3.bpda" will be created, but you can change it to anything you like, keeping the "bpda" extension, or using the "-da" prefix instead.
- Click the PRODUCE ITEM(s) button again. A link to the data file in Bol Processor score notation appears at the top (see image). The Trace file shows the same derivations. The file "koto3.bpda" should also be in the "my_ouput" folder.

- In the settings for "-gr.koto3" it is possible to change the format of the graphics display. Currently it is "Show objects". Let us try "Piano roll". This format emphasises the melodic and harmonic structure of the composition whereas the "objects" format is explicit about the size and position of the sound-objects.
- Comparing the two images we can guess that "a" contains a stroke of the note A5 and "b" contains two strokes of the note B5. The <<f>> sound-object is an out-time object of zero duration, containing a single stroke of the note F2. The <<chik>> object is also out-time and contains a chord: {C3, F3, C4}.
The main mechanism for creating musical items in this grammar is called substitutions, indicated as SUB on top of the 2nd subgrammar. A substitution rule, when selected, is applied simultaneously to each fragment of the work string. This is made clear by displaying the derivations of the string. To do this, select the "Display production" option on the Settings page. The derivation steps will appear in the Trace window:

Clicking "Trace production" in the settings will give more details about the inference process.
In the "Non-stop improvize" mode, every step of the substitution is used for the sound output. To do this, variables are erased and only terminal symbols are played. The effect is that the work string "grows" until it collapses as a polyphonic phrase with out-time objects <<f>> and <<chik>> playing the bass. The theoretical model behind this process is a (one-dimensional) cellular automaton. For example, listen to this performance of "-gr.koto3" with the original sounds:
If you set up the output format to "Real-time MIDI", the improvisation will play forever on the MIDI device connected to your computer. Clicking the STOP or PANIC button will stop it. Read explanations on the page Real-time MIDI.
As this is only a technical review of how BP3 works, we won't discuss the arcanes or rule-based composition in the Bol Processor. You should have a look at the tutorials and experiment with your own creations to get familiar with it.
Create or import data
The demo items shown on this page are all located in the "ctests" folder, which is created when BP3 is installed and is refreshed during updates.
👉 If you are running the standalone "BolProcessor.app" application on MacOS, the "ctests" folder is visible after clicking "Show Package Contents" and moving down to "Contents/Resources/www".
It is not a good idea to move files in and out of data folders using the Finder or the File Manager, as this can lead to read-write permission errors. Use only the import features documented in this section.

A button CREATE FILES AND FOLDERS on the right displays a form to this effect. Creating your own folders (workspaces) is recommended, as files in the "ctests" folder are restored to their initial status during updates.
When a file is created, the appropriate prefix or extension is added, depending on the type of file. For example, a grammar named "mygrammar" will be saved as "-gr.mygrammar" or "mygrammar.bpgr", depending on your choice.
Using the import feature has two advantages:
- Only files relevant to the Bol Processor will be imported;
- File permissions will be set to the same permissions as the "bolprocessor" (or "Contents/Resources/www") folder, i.e. "775".
A DOWNLOAD FILES button is also available to facilitate the export of data to other computers. However, if you need to change the location of data within the "bolprocessor" (or "Contents/Resources/www") folder, it is more practical to use the MOVE command.
Download/upload is also possible on project pages (Data or Grammar):

The procedure ensures that you upload the same type of file, i.e. do not replace a Data project with a Grammar project or vice versa. The operation can be undone with a single click until the modified page is saved.
Moving folders and projects outside the "bolprocessor" (or "Contents/Resources/www") folder is made possible by creating symbolic links so that they can be accessed via the interface. Read the Move data page to learn how to do this.
Import MusicXML scores
The previous section was an introduction to the main features of Bol Processor: creating music using a grammar, an alphabet and sound-object prototypes, which we will present in more detail below. This requires some knowledge of both music composition and the specific task environment of Bol Processor, as shown in the old BP2 reference manual, and more recent tutorials.
With BP3 it is possible to take a simpler (but arguably less creative) approach: import pre-composed music and reuse its fragments to create new musical works. This process is achieved by using standard sheet music converted into the MusicXML format. MusicXML files are downloaded from the web or exported by score editors such as MuseScore. A (very technical) description of this method can be found on the Importing MusicXML scores page, along with an introduction to the MusicXML format.
Another technique for importing music will be the real-time recording and interpretation of MIDI events, which is still in development. Follow the progress of this approach on the Capture MIDI input page.
Below is an example of Beethoven's Fugue in B flat major imported from MusicXML and converted as Bol Processor data — a set of polymetric expressions, see tutorial. It was played on the PianoTeq physical-model synthesiser receiving real-time MIDI messages produced by BP3. We interpreted it as a piano piece because we had no synthesiser that could do a good imitation of the string instruments.
This example illustrates both the accuracy of the conversion and the level of complexity handled by Bol Processor.
Using a very short quantization (typically less than 10 milliseconds) on a large item can increase memory usage to the point where the MAMP or XAMPP driver hangs without warning. For this reason, the quantization is set by default to 10 ms.
Help messages

- Open the "-gr..Visser.Waves" grammar (designed by Harm Visser). At the bottom of the page, click the SHOW HELP ENTRIES button. This will display the grammar with links appearing on reserved words. For example, click on the link for "_transpose". A pop-up window will open, displaying the help at the exact location of the reserved word.
- At the bottom of the grammar file, there is one more more button: EDIT ‘-se.Visser.Waves’. It has been created automatically because the "-se.Visser.Waves" declaration was found at the top of the grammar. Click on it to edit or create the file.
- You can now produce the "Visser.Waves" item, listen to its sound rendering and view the graphic output as "pianoroll" or "objects". Below is a rendering of this grammar with physical model instruments (read explanations):
played on physical model synthesis saxophone and piano
Error messages
- Now, let us do something wrong to check for errors. In "-se.Visser.Waves" change the "Note convention" from ‘0’ (English) to another option such as ‘1’ (Italian/Spanish/French). Click on SAVE PARAMETERS, go back to the "-gr.Visser.Waves" grammar, click on SAVE and PRODUCE ITEM(s). Now, neither the "output file" nor the graphics will be visible, because the console cannot not create an item due to its misunderstanding of note names. For example, "B3" is interpreted as a variable and not as a simple note. This is not acceptable in the first argument of control "_transpose()".
- The note "B3" should have been replaced by its French equivalent "si2". The good news is that this can be done automatically in a grammar: select the convention you want to use at the bottom of the page.
- PRODUCE ITEM(s) sometimes reports that errors have been detected by the console. They appear in the "error" trace file and a link is provided to display it.
- Try the same procedure with "-gr.trial.mohanam". It is set for the Indian sargam note convention = 2. After changing the convention to "French", the output file will only contain notes "re6" which have the same name in both conventions. Confusing note conventions is a common source of error when designing music with the Bol Processor. For this reason, the current setting of this convention is displayed on the Grammar window.
- Note that the rendering of "-gr.trial.mohanam" is better with the output selection set to "CSOUND file". If Csound is installed and responding on your machine, just try it!
Compile a grammar
- So far, the grammars have been well formed, so clicking on the COMPILE GRAMMAR button would certify that there is no error. Now go to the grammar called "unknown-terminal.bpgr"and click on COMPILE GRAMMAR. It tells you that errors have been found, and the "trace" file explains that it has found (at least) one unknown terminal symbol. In fact, the symbols 'x' and 'a' have not been declared as sound-objects in a related "-al" alphabet file.
- The COMPILE GRAMMAR procedure renumbers subgrammars and rules. If you are still playing with "unknown-terminal.bpgr", replace "gram#1[1] S --> A B" with "S --> A B" and click on SAVE, then COMPILE GRAMMAR. The numbering "gram#1[1]" is restored. This takes account of inserting or deleting rules.
- The grammar named "symbols.bpgr" compiles successfully because its has an attached alphabet file containing all its terminal symbols. The alphabet file is called "symbols.bpal" and its declaration in the grammar is "-al.:symbols.bpal". This unexpected syntax is a trick to recognise file types whose names do not begin with the standard prefix. This is just to demonstrate how to manage files, as this alphabet does not produce any sound.
Change the start string

- Musical items are produced by a Bol Processor grammar which, by default, uses the symbol 'S' as the starting string for derivations. However, it is sometimes interesting to try to derive from another variable with the same grammar, or to listen to a polymetric expression. Both of these are easily achieved in the grammar window.
- An example of this is the use of "-gr.Mozart", where the variables represent musical fragments that are assembled in the final element (read explanation). All variables have been identified by the interface and displayed as buttons at the bottom of the page (see image on the right). Clicking on a button produces a derivation of the variable.
- Note however that in this grammar derivations from A1 to B8 won't be unique, because they are chosen randomly. Conversely, derivations from T1 to T176 are unique.
- At the bottom of the page is a field for entering a polymetric expression, for example {{2,sol3,si3}-,fa5 re5 si4}. This expression can contain variables. Click on PRODUCE ITEM to listen to the result or to obtain the output file (depending on the output format selected).
- For geeks: The "--start" and "-S" command line options used in these procedures are not yet implemented.
An example of using "-gr.Mozart" in Improvize mode is discussed on the Mozart’s musical dice game page. It will play forever if the real-time MIDI mode is active.
Play data
Open "-da.checkPoly":

- The Data window (see picture) extracts lines that can be interpreted as musical items in BP notation.
- Each line is associated with two buttons:
- The PLAY button sends a "play" command to the console after saving the data line to a temporary file "…outdata.bpda" stored in the "temp_bolprocessor" folder. The console is asked to process this data as a MIDI file or a Csound score.
- The EXPAND button sends an "expand" command to the console after saving the data line to a temporary file "…outdata.bpda" stored in the "temp_bolprocessor" folder. The result will be displayed as text.
Sound-object prototypes
The grammar "-gr.koto3" uses an alphabet of sound-objects, namely "-al.abc1", which is related with a set of sound-object prototypes "-so.abc1". This file is located in the TONALITY resource folder, which has a link on the right hand side of each page.
The pianoroll display of an item (above in the "Produce items" chapter) already indicated that the sound-object "chik" contains a chord of 3 notes. We will now show you how to create or modify these sound-objects.

- Open "-so.abc1" (or a copy of it). Below the horizontal line you should see a table with the names of its sound-object prototypes: a, a', b, chik, cycle1 etc.
- For geeks: When you opened "-so.abc1", a temporary folder was created in the "temp_bolprocessor" folder. It has a complicated name, for example "‑so.abc1_ec02bffaaee23e051fa2afee52e57520_temp" which contains the session identifier. If you restart your computer (or your browser), the session number will be different. This folder will therefore become obsolete and a new one will be created with the current session identifier.
- The interface automatically deletes outdated folders that are more than 24 hours old. Keep pages and tags open while you work on a particular set of sound-object prototypes!
- Despite the dependency on session identifiers, no data is ever lost because "-so.abc1" is in autosave mode, automatically saving every 30 seconds while working on its sound-object prototypes. This feature is indicated by red messages at the top of the page.
- In the table you will be offered the option of deleting sound-objects. Try a couple of DELETE buttons. The good news is that a button called RESTORE ALL DELETED OBJECTS will appear… Click it to undelete sound-objects and return to the initial state.
- You can also create or duplicate sound objects. If you do so, don't forget to add their names to any "-al" (alphabet) file that declares a link with "-so.abc1". The interface ensures that you do not create multiple objects with names that are currently in use or have recently been deleted.
- Now let us edit an object, for example "chik". Click on the button with this name. (Old timers: the parameters are the same as those shown in BP2.9.8.) You can modify any parameter and click on SAVE THIS PROTOTYPE. In most cases the consistency of the values is not checked. You will need a sound output to check the effect.
- Editing an object involves setting the metric and topological parameters used by the time-setting algorithm. Read the description of this constraint-solving algorithm that takes these parameters into account.
- PLAY sends a command to the console, which will later be executed to play the sound-object or a combination of sound-objects (arranged in a polymetric structure) entered on the form.
Modify MIDI codes in a sound-object prototype

- At the bottom of each sound-object prototype page, the EXPLICIT MIDI codes and TIME-STAMPED MIDI bytes links display the lists of MIDI instructions and time-stamped bytes that will be sent to the MIDI driver. (The first number is actually the number of bytes.)
- 👉 Don't forget that the “-so” file is saved in the background every 30 seconds (autosave) while you are modifying sound-object prototypes… To return to the original version, close the “-so” tag and restore the “-so” file from its copy!
- The IMAGE link displays an image of the sound-object prototype along with indications of its topological and metrical properties, similar to the BP2.9.8 interface.
- The Play MIDI file link produces a sound output based on MIDI events contained in the sound-object prototype. Here, the "chik" sound-object prototype plays a 250 ms chord on a stringed instrument. The interface uses the MIDI player to do this.
- Note that there are five "Channel pressure" MIDI instructions in this sound-object. These may have been picked up by playing on a pressure-sensitive keyboard and their relevance is low since channel pressure can be controlled at a higher level by performance parameters. It is therefore advisable to click on SUPPRESS channel pressure and check the effect on EXPLICIT MIDI codes and TIME-STAMPED MIDI bytes. If the change is not immediately visible (this depends on the browser), simply reload the pop-up window. Other "continuous" parameters such as "volume control" can be suppressed in a similar way.
- APPEND AllNotesOff (all channels) can be a useful option to ensure that this object turns off all pending notes on the sound machine. It sends an instruction to each of the 16 channels.
- The MIDI content of this object can be changed by loading a MIDI file. Click Choose File to select a MIDI file — for example, "test.mid" in the "ctests" folder — and then send to upload it. It is not finalised immediately: you can examine the EXPLICIT MIDI codes and TIME-STAMPED MIDI bytes of this file before saving it to the sound-object prototype. The example "test.mid" contains no less than 432 bytes because of the "Channel pressure" and "Parameter ctrl 7" messages, which control pressure and volume. You can accept the import by clicking SAVE or cancel it by clicking CANCEL. There is currently no "undo" function in case the MIDI sequence has been replaced or deleted by mistake.
- An important feature is QUANTIZE NoteOns. We are dealing with "striated sound-objects", which means that they are designed to be played at a certain tempo. The tempo at which the MIDI content of this object was captured is generally not the same as the tempo at which it will be played, as the latter depends on performance parameters. The reference tempo is given by Tref which in this case is 1000 ms for a metronome with 60 beats/mn. The MIDI content uploaded by "test.mid" has a duration of 3500 ms, i.e. 3.5 beats. This duration can be set either in milliseconds or in beats. Regardless of the duration, it is often convenient to locate NoteOn and NoteOff events to a precise fraction of a beat. An Quantizing to 1/64th of a beat is often a good choice. For simplicity's sake, we will set it to 1/50th of a beat, or 20 ms.
Before clicking on QUANTIZE NoteOns, check the EXPLICIT MIDI codes. You will notice that there is a NoteOn of key 62 at 804 ms and a NoteOff of key 60 at 825 ms. Set the quantization to 1/50th of a beat and click QUANTIZE NoteOns. Now the timings of these events have been changed to 800 ms and 820 ms respectively, which are multiples of 20 closest to the original timings.
Csound

Csound is a program for the design and transformation of digitised sounds. Csound and Bol Processsor are similar and complementary in their text-oriented, programming approach, with respective emphasis on sound and musical structures. Their interaction is summarised in the BP2 environment image.
Note that Csound orchestra files containing sound production algorithms can be edited on this interface although it is not used by the ‘BP3’ console — nor was it used by BP2.9.8. Its name is stored in the Csound orchestra file. Arguments declared in the latter should match those in the former.
A simple orchestra file called "0-default.orc" is provided in the "csound_resources" folder. It can be used for Csound scores created by Bol Processor when no Csound orchestra file is specified.
Linux users: At the moment "0-default.orc" is not accepted by Csound in the Linux environment. We hope to solve this problem in the near future. For the time being you can use "BP2test.orc".
The use of Csound by the Bol Processor ‘BP3’ is the same as documented in chapter 17 of the BP2.9.8 instructions manual. Advanced features are documented in the articles Csound checkup and Csound objects.
MacOS and Windows users can download a pre-built installation of Csound from the download page. In Linux, simply type the following instructions:
sudo apt update
sudo apt install csound
If Csound is installed and responding, this status will be mentioned on the top of each page. Otherwise the machine will recommend installing Csound, or changing the path to Csound. This path is by default "/usr/local/bin" on MacOS, "usr/bin" on Linux. The BP3 interface will be able to figure this out under Windows. If a new path is entered, the machine will try to call "csound --version" and will stop trying if once it is correct.
- Open "-gr.Mozart"in the "ctests" folder.
- Select the CSOUND file output option, which (by default) will creates a file called "Mozart.sco" in the "my_output" folder. You can modify these parameters.
- If Csound is installed and responding, this status will be mentioned on the grammar. Otherwise the machine will recommend installing of Csound (from this site) or changing the path to Csound — by default "/usr/local/bin/" on a Mac. Each time a new path is entered, the machine will try to call "csound --version" and will stop trying if it succeeds.
- Click PRODUCE ITEM(s). A pop-up window will indicate that the process was successful. Click Read the output file to read the Csound score on another pop-up window.

In this example, the Csound score has been generated by the Bol Processor as a sequence of "simple notes" that appear at the end of each score line: "mi5", "do3", "do5", etc. To do this, the Bol Processor uses conversion procedures to replace MIDI events with score lines.
If Csound is installed and responding, it will automatically be called to produce a sound file (in the WAV format) which will appear on a HTML player (see image). Checking the sound output — or rather the validity of the Csound score — is therefore the matter of a single click on PRODUCE ITEM(s).
On each score line, the "1" of "i1" is the value of argument "1", the leftmost one. The next two arguments are assigned to the start date and duration of the event, measured in beats. Then comes argument "4", which is assigned to the pitch in octave point pitch-class format. Arguments "5" and "6" are for continuous volume control (in the range 0…127). Argument "7" can contain the reference to a table for refining these variations. Arguments "8" and "9" are used for (continuous) pitchbend control, and argument "10" may contain the reference to a table for refining pitchbend variations.

A just-intonation version of Mozart's musical dice game can be heard on the Just intonation: a general framework page.
Csound instrument files
Bol Processor can generate a Csound output from scores stored in sound-objects or converted from the MIDI stream. It also has a direct control of the performance parameters that the Csound orchestra can independently manipulate on the standard MIDI controls ("pitchbend", "modulation", "volume", etc.). These parameters are further interpolated by the Csound orchestra, using the GEN07 (linear interpolation) or GEN08 (cubic spline) Csound generators. All this is documented in chapter 17 of the BP2.9.8 instructions manual and set up in a "-cs" Csound instrument file as the one shown below.

- Open "-cs.tryCsound" in the CSOUND resource folder. Note that this page is in autosave mode (see below): changes to Csound instruments are automatically saved at a rate of twice per minute.
- This Csound instrument file is declared to be linked to a Csound orchestra file called "tryCsound.orc". As this file is missing from the "csound_resources" folder, a link to create the file is displayed. Otherwise it would lead to editing the file.
- The text area for Tables needs no more explanation than given in the BP2.9.8 instructions manual. These tables are not used to create Csound scores. They are only inserted at the beginning of the score.
- Csound instruments can be associated to MIDI channels. For example, here, MIDI messages sent to channel 2 will be converted into instructions sent to instrument 3 "Harpsichord".
- At the bottom of the page is a list of the Csound instruments declared in this "-cs" file. These can be deleted, undeleted and duplicated much in the same way as sound-object prototypes (see above). Clicking on the blue button with the name of the instrument opens an editor for that instrument.
Editing a Csound instrument

The Csound instrument editor is very similar to that of the BP2.9.8's interface. A detailed description can be found in chapter 17 of the BP2.9.8 instructions manual.
- For example, let us examine the instrument Harpsichord in "-cs.tryCsound". Its index is "3", which means that it can be called as _ins(3) or _ins(Harpsichord) on a Bol Processor score.
- The parameters displayed on the "Harpsichord" page are those associated with MIDI controllers. These can be controlled continuously if arguments are given to modify the start and end date values in a continuous change. The argument under "table" is the reference of an optional tabular function.
- For the volume parameter, "0", "64" and "127" (MIDI values) must to be converted to "-24", "0" and "+24" (Csound values) respectively. The conversion is from a linear to a logarithmic scale.
- The start and end values of the continuously changing volume are set by arguments "7" and "8" respectively. These are used by an algorithm that sets the volume in the associated Csound orchestra, based on the GEN07 (linear interpolation) or GEN08 (cubic spline) generators.
- Given three pairs of input/output values, BP2 tries to define a quadratic mapping between the input and the output. However, it may be difficult to fit the three values to a monotone quadratic function… See the Csound argument mapping page for a detailed explanation.
- At the bottom of the page you will find a list of Csound parameters that have nothing to do with MIDI controllers. This is where Bol Processor Csound production can differ radically from MIDI!
- This instrument has only one additional parameter called "blurb".

These additional parameters can be created, deleted and undeleted in the same way as instruments (see above). The interface ensures that a new parameter does not have the same name as an existing one or a (temporarily) deleted parameter.
Let us look at the "blurb" parameter (image on the left). Each parameter has a default value which is not necessarily zero. Values found on Csound scores can be combined additively (ADDval) or multiplicatively (MULTval). This "blurb" parameter sends its start value to argument "9" of the algorithm in the Csound score, and its end value (for continuous variations) to argument "10".
Using a Csound instrument in a grammar

This use is demonstrated in a hypothetical music production that is simple enough to grasp the basic features of Csound in its Bol processor implementation. A complete demo based on a real musical example can be found in the article Sarasvati vina. We have also documented all the features of the Csound implementation in the articles Csound checkup and Csound objects, showing examples that can be checked with the evaluation version of BP3.
The grammar "-gr.tryCsound" calls "-cs.tryCsound" and uses its instrument "3" (Harpsichord):
S --> _ins(3) _volumecont _volume(127) A4 G4 C5 A5 A4 G4 C5 A5 _volume(0)
The Csound score produced by this grammar is shown below:
; Csound score
f1 0 256 10 1
f2 0 256 10 1 0.5 0.3 0.4
t 0.000 60.000
i3 0.000 1.000 440.00 8191.500 8191.500 24.000 21.688 0.000 0.000 0.000 0.000 0.000 ; A4
i3 1.000 1.000 392.00 8191.500 8191.500 21.688 18.431 0.000 0.000 0.000 0.000 0.000 ; G4
i3 2.000 1.000 523.25 8191.500 8191.500 18.431 12.899 0.000 0.000 0.000 0.000 0.000 ; C5
i3 3.000 1.000 880.00 8191.500 8191.500 12.899 -0.031 0.000 0.000 0.000 0.000 0.000 ; A5
i3 4.000 1.000 440.00 8191.500 8191.500 -0.031 -1.179 0.000 0.000 0.000 0.000 0.000 ; A4
i3 5.000 1.000 392.00 8191.500 8191.500 -1.179 -2.794 0.000 0.000 0.000 0.000 0.000 ; G4
i3 6.000 1.000 523.25 8191.500 8191.500 -2.794 -5.547 0.000 0.000 0.000 0.000 0.000 ; C5
i3 7.000 1.000 880.00 8191.500 8191.500 -5.547 -24.000 0.000 0.000 0.000 0.000 0.000 ; A5
s
e

- Arguments "5" and "6" show the pitchbend start and end values as specified by the instrument. These remain at the default value of "8191.5" in the absence of pitchbend instructions.
- Arguments "7" and "8" display the start and end values of the volume parameter as expected. The continuous range is from "+24" to "-24". This is the result of a mapping between MIDI values in the range [0…127] and the volume parameter of this instrument in the range [-24…+24] (see image). This mapping is based on a logarithmic interpolation using a quadratic regression.
- Csound will be able to achieve a continuous variation of this volume parameter. To do this, it will invoke its own interpolation scheme specified as GEN07.
- The _volumecont instruction at the beginning of the sequence actually means "continuity". This resolves a discrepancy between the MIDI and Csound representation of "musical events": in the MIDI environment, each event is associated with a time point whereas Csound scores deal with time segments of specific durations. It is up to the Csound orchestra to decide how to modify a parameter from the on-set to the off-set of a segment.
- Arguments "9" and "10" remain at the default value "0.000" as the "blurb" parameter is not used.
- Arguments "11" and "12" remain at the default value "0" of the unused modulation parameter.
- Argument "13" remains at the default value "0" of the unused panoramic parameter.
Csound scores created with "-gr.tryCsound" cannot be played with "BP2test.orc" because their arguments do not match. They require a different orchestra file called "tryCsound.orc" which we haven't been able to design yet…
A real musical example using many features of the Csound integration in the Bol Processor is a phrase of Carnatic music composed/designed by Srikumar K. Subramanian in 1996. Read the description of this example and listen to its musical rendering (in “just intonation”) below:
Microtonality
In conjunction with Csound, the Bol Processor BP3 is open to microtonality and the programming of custom scales. Read the pages Microtonality and Csound tuning in BP3. Applications to western harmony and to the intonation of ragas in Indian music are presented in the "Musicology" section.
Editing the Timebase

The Timebase is a device for creating a rhythmic pattern to be superimposed on a piece of music produced by the Bol Processor in real time via MIDI. Superimposition did not work well with BP2.9.8, but did work with older versions connected to MIDI via the OMS package. It has not yet been implemented in the 'BP3' console. Here we show a timebase editor which is a little more advanced than on BP2. We also try the overlay by importing the Bold Processor production as a MIDI file.
- Create a new time base called "try.bptb" in the "ctests" folder and open it.
- By default, the time base contains 3 tracks, 2 of which are set to a simple 4-beat tempo of mm = 60 beats/mn. The third track is empty. Fill it with 4 strokes on key = 100 at a speed ratio of 2/1.
- Now listen to the combined 4 tracks (repeated 3 times):
- To understand the structure you can mute some tracks.
- Now click on "Choose File" to select a MIDI file, for example "acceleration.mid", and click on the "send" button to import it.

- You can listen to the imported file and to the combination of this piece of music piece with the ticking pattern:

- The overlay sounds good because the piece was created at mm = 60 and it fits a rhythmic pattern of 4 beats. You can try changing the metronome value in the table above. You will receive a warning if the metronome setting does not match the tempo declared in the imported MIDI file.
- For example, check this rhythmic cycle above "this_song.mid" in the "ctests" folder. You will be asked to set the metronome to 9 beats in 4 seconds, as declared in the MIDI file (picture on the right). The timing is perfect:
- This interface allows an unlimited number of cycle tracks to be added. (The limit in BP2 was 3 tracks).
- Playing with speed ratios creates complex cycles that can be used to control a drum machine if the appropriate channels, key numbers and velocities are set up. Traditional rhythmic structures can also be easily programmed. See examples below:
![]() A 15-beat rhythmic structure called panchamasvari tala in Hindustani music | ![]() Slowly drifting rhythmic patterns |
Tick patterns as polymetric expressions
➡ For experts!
The Timebase page on the PHP interface provides a convenient way of superimposing a programmed tick pattern with a production of Bol Processor previously saved as a MIDI file. Another usage of time bases is the control of a MIDI drum machine taking part in the performance. It would be beneficial to design the drum machine track as part of the performance, as polymetric expressions are able to handle superpositions. We will see that although it is often possible, it remains a tedious task.
A polymetric equivalent of the tick pattern shown above would be:
{_chan(1) _vel(120) _staccato(99) C8 - - -, _chan(1) _vel(120) _staccato(99) - C7 C7 C7,
_chan(1) _vel(120) _staccato(98) E7 E7 E7 E7 E7 E7 E7 E7}
{_chan(1) _vel(120) _staccato(99) C8 - - -, _chan(1) _vel(120) _staccato(99) - C7 C7 C7,
_chan(1) _vel(120) _staccato(98) E7 E7 E7 E7 E7 E7 E7 E7}
This expression is displayed at the foot of the Timebase page.
Let us try to add this polymetric expression as variable "Drum" to the grammar "-gr.acceleration":
S --> {Piano, Drum}
Piano --> _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
Drum --> {_chan(1) _vel(120) _staccato(99) C8 - - -, _chan(1) _vel(120) _staccato(99) - C7 C7 C7,
_chan(1) _vel(120) _staccato(98) E7 E7 E7 E7 E7 E7 E7 E7}
Unfortunately, this will not work because the "Piano" pattern needs to be repeated at the correct tempo instead of being extended in duration… The solution will be to replace it with a cyclic sound object. Let us do it…
- Create the following "-gr.drum" grammar and use it to create a MIDI file called "drum.mid":
S --> {_chan(1) _vel(120) _staccato(99) C8 - - -, _chan(1) _vel(120) _staccato(99) - C7 C7 C7,
_chan(1) _vel(120) _staccato(98) E7 E7 E7 E7 E7 E7 E7 E7} - Create a sound-object prototypes file called "-so.drum" and define a sound-object called "cycle2".

- Set it to "cyclic" (see picture on the left).
- Import "drum.mid" into sound-object protype "cycle".
- Bad news: its duration is 6000 ms instead of the expected 4000 ms…
- A look at EXPLICIT MIDI codes reveals that the last 2 seconds are a fade-out added by the Bol Processor to avoid an abrupt end.
- Good news: the sound-object prototype editor allows you to crop the sound-object by truncating its end. So let us crop it to 4000 ms.
- Listen to the cropped "cycle2" sound-object and look at its image. Everything is perfect. This object sounds identical to the sequence previously programmed on the Timebase page:
Cropping sound-objects is done carefully. If necessary, the algorithm rewrites "NoteOff" messages that have been deleted by the cropping. - Now the sound-object will be added to the grammar as follows:
-al.drum
S --> {Piano, cycle2}
Piano --> _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
etc…
J --> D#2 I
K --> C#2 J
L --> F2 K

- The "cycle2" sound-object and its associated "-so.drum" prototype file must be declared in the following "-al.drum" alphabet file:
-so.drum
The ‘*’ on the second line of the alphabet is an arbitrary symbol declaring a homomorphism — not used here.
*
cycle2
- This method is tedious, although it conforms to the Bol Processor model. Worse still, the equivalent polymetric expression can become extremely complex if the speed ratios and/or beat cycles of all the tracks are not the same. In this case, it will not be displayed at the bottom of the Timebase page.
Scripts
- Bol Processor BP2.9.8 was fully scriptable in the sense that all commands launched from its menu could be captured as sequences of script instructions and reproduced at will. This included opening folders and files, modifying text or doing something with the selection.
- A script was run every evening for about half an hour checking all procedures and tracking changes in the output data, in addition to the sound check.
- This level of automation will not be achieved in the current release of BP3 because of the decoupling between the console and its PHP interface. As a result, many BP2 script instructions won't be valid in BP3. They will be ignored during script execution.
- Consider for instance "-sc.tryMe":
Show messages OFF
Note convention = English
Show graphics ON
Play - - {2,G4,E4,C4,- C5 - C5 {C5_-,A#4_ _}}
Show messages ON
Activate window Scrap
Type Welcome to Bol Processor BP3...
Type Hope you enjoyed the music!
Type BP3 is now waiting for you to play ‘C4’ on the MIDI keyboard
Type <return>
Wait for C4 channel 1
Run script -sc.trySubscript
Type That's all folks!

- In this script, instructions "Show messages OFF", "Show graphics ON", "Show messages ON", "Activate window Scrap" and "Wait for C4 channel 1" are ignored. The "Play" instruction will expand the polymetric expression - - {2,G4,E4,C4,- C5 - C5 {C5_-,A#4_ _}} and send it to MIDI in real time. The note convention has been set to "English" to recognise "G4", "E4" etc. as simple notes. The tempo is set to standard metronome = 60 beats per minute.
- The "Type" instruction displays a line of text (which may contain HTML elements).
- This script calls a subscript called "-sc.trySubscript" in the same folder. Its content is:
Load project -gr.Ames
Csound score ON
Produce items - Here the machine will call the grammar "-gr.Ames" and set the output format to "Csound score".
- The execution of the script is displayed in a pop-up window (see image above), which lists (in red) the commands sent to the console. The second command produces a Csound score, as expected.
- The image also shows (light blue) buttons for entering script instructions. No typing is required. There's a button called CHECK THIS SCRIPT which shows any errors, such as a file not found.
- Below the script, the LIST ALL SCRIPT INSTRUCTIONS button lists all the instructions handled by BP2.9.8, indicating which are obsolete for BP3 and which are under development.
Setting max computation time
👉 This feature is currently disabled.
There are many ways to ensure that a grammar does not repeat the same process over and over again. These are part of the syntax in the Bol processor. For example, a flag can be decremented each time a rule is applied, and can invalidate all rules when it reaches zero.
However, mistakes can — and will — happen. For example, consider the following grammar, where one rule rewrites the same string over and over:
RND
gram#1[1] S --> X Y
gram#1[2] X --> C4 D4 E4 [Let us at least produce this!]
gram#1[3] Y --> Y [This rule makes the grammar loop forever]

Running this grammar without any precautions would use rule [3] forever. The result would be an empty page until a break is called. Fortunately, a limit can be set in the preferences. For example 9 seconds.
Note that this grammar will stop, but it will still have created an item "C4 D4 E4" that can be displayed and heard in MIDI or Csound.
Programming tricks (for developers)
This PHP interface has been designed in a conventional manner, prioritising functionality over aesthetics. However, a few special features have been implemented which require explanations because of the painstaking search for documentation that was involved.
Pop-up windows
It is important to note that pop-up windows should be visible regardless of the security settings on the web browser. This is because they are created by a standard window.open() call attached to the button.
A typical link that activates a pop-up window is this one in "prototype.php":
echo "<a onclick=\"window.open('".$text_link."','MIDItext','width=300,height=300'); return false;\"
href=\"".$text_link."\">EXPLICIT MIDI codes</a>";
The same window.open() code may be incorporated into a "submit" button.
Autosave
The autosave feature is designed to emulate the automated updating process of Google Docs pages or WordPress posts/pages. This functionality has been integrated into the editing of sound-object prototypes and Csound instruments.
Please be aware that if you are editing prototypes belonging to "-so.abc1", all data is contained in this file. When working on a particular prototype and clicking the SAVE THIS PROTOTYPE button, only the temporary file will be updated — the path of which is shown at the top of the page. Once you have completed your work, you are expected to return to the "-so.abc1" file and click the SAVE ‘-so.abc1’ INCLUDING ALL CHANGES TO PROTOTYPES button. Fortunately, the autosave, which is indicated by a red line at the top of the page, does it for you in the backgraound.
The same feature has been implemented on the page dealing with Csound instrument files. For instance, the file "-cs.tryCsound" is automatically saved every 30 seconds while the user is working on the edition of instruments or additional parameters stored in this file.
In practice, the autosave feature is activated by a simple call of JavaScript code in files "autosaveObjects.js" or "autosaveInstruments.js". The command itself is myVar = setInterval(savePost, 30000), where "30000" represents 30 seconds. A savePost() function sends POSTs to file "autosaveObjects.php" or "autosaveInstruments.php".
GD graphics and Canvas
The GD graphics library is already included in current distributions of PHP. No installation is necessary if PHP has been compiled with the "gd" option. If you have any doubts, please display the "http://localhost/try/bolprocessor/php/phpinfo.php" page on your local server.
As an illustration of the use of GD instructions, please refer to page "prototype_image.php". It should be noted that all variables used to build the image have been stored in a temporary file "image.php". This eliminates the need to send hundreds of POST messages to "prototype_image.php".
The console has been enhanced with graphic procedures implemented in HTML Canvas, which is compliant with standard HTML5 and does not require PHP. Each image is saved as a set of JavaScript instructions, allowing its vectorised construction. This differs from GD graphics, used in the PHP/Javascript interface, which produces a PNG image. The Canvas script contains width and height values used for clipping the image. These are read by the PHP script on "produce.php" for setting up dimensions of the pop-up window that will contain the image.
👉 Don't hesitate to ask questions or send comments on the contact page!
Simple Csound orchestra
BP2 makes it possible to use Csound orchestra instructions such as
kr tablei kndx, ifn
to make continuous parameters vary according to a function table (indexed 'ifn') that BP2 produces and insert in the Csound score when necessary.
Below is a typical instrument in which volume and pitchbend are controlled either by linear interpolation, using start and end values, or by function tables.
- p5 and p6 are the start and end values of volume
- p8 and p9 are the start and end values of pitchbend
- p7 contains the index of the volume function table. If it is 0, then volume varies by linear interpolation.
- p10 contains the index of the pitchbend function table. If it is 0, then pitchbend varies by linear interpolation.
Indexes of function tables are assigned automatically by BP2, and each table is stored in the score as a 'f' statement just preceding the 'i' statement relating to an instrument using the table. BP2 takes care of not overwriting tables that might be refered by Csound instrument and enlisted in the Csound instrument description file.
In any case, it starts indexing from 100 onwards.
sr = 22050
kr = 2205
ksmps = 10
nchnls = 1
instr 1
ik1 = 32767. / 127.
ik2 = log(2.) / 1200.
ifvol = p7
ifcents = p10
kvol line p5, p3, p6
if (vol <= 0) goto volumelin
ilenvol = ftlen(ifvol)
kndxvol line 0, p3, ilenvol
kvol tablei kndxvol, ifvol
volumelin: kcents line p8, p3, p9
if (ifcents <= 0) goto pitchbendlin
ilencents = ftlen(ifcents)
kndxcents line 0, p3, ilencents
kcents tablei kndxcents, ifcents
pitchbendlin: kpitch = cpspch(p4) * exp(kcents * ik2)
kamp = kvol * ik1
a1 oscil kamp, kpitch, 1
out a1
endin
This instrument is currently saved as "BP2test.orc".
Function tables might invoke either GEN07 (straight lines, p.62) or GEN08 (cubic spline, p.64).
If for instance the function table index is 102, and GEN07 is used, the following instruction will be inserted by BP2 into the score:
f102 time size -7 v1 n1 v2 n2 v3 n3 … vmax
with n1 + n2 + … + n(max-1) = maxpoints
'size' is a power of two equal to or greater than the actual number of points 'maxpoints'.
'time' is exactly parameter p2 of the following 'i' statement which makes actual use of the table.
Writing '-7' instead of '7' after 'size' inhibits rescaling.
GEN08 looks better in terms of smoothing the table, but it has the drawback of setting first derivatives to 0 on the first and last points of the table. It also slows down Csound's sound file generation.
Timebase to polymetric
This algorithm is used by the PHP interface of Bol Processor ‘BP3’ under development. Read:
https://bolprocessor.org/misc/BP3/CheckList.html#timebase
It is implemented in function polymetric_expression() of file _basic_tasks.php (read below).
The function creates a polymetric expression equivalent to the rhythmic structure programmed on a Timebase page. We will take for instance a structure which does not sound musical because of its odd ratios:


The metronome speed is 208.571 beats per minute specified as 73 beats in 21 seconds. Bol Processor always compute durations as integer ratios.
Let us define p_clock = 73 and q_clock = 21.
This structure contains 2 tracks. The following algorithm deals with any number of tracks.
- Track 1 is a cycle of 5 beats [TickCycle] and its speed ratio is 3/2 [Ptick/Qtick]. It produces note C8 (in English notation) at velocity 120 (a MIDI parameter) and duration 10 milliseconds.
- Track 2 is a cycle of 3 beats [TickCycle] and its speed ratio is 4/5 [Ptick/Qtick]. It produces note C7 at velocity 120 and duration 10 milliseconds.
Tick cycles are made explicit by checked/unchecked boxes. Unchecked boxes denote silences ‘-’:
- C8 - C8 - - for the first track
- - C7 C7 for the second track
The rhythmic structure will be represented as a polymetric structure with 2 fields {Track1, Track2} in which fields are forced to the same symbolic duration by the polymetric expansion algorithm (described here). We need to design its content so that the expansion does not alter the tempo declared on each track.
To this effect, consider the symbolic duration of each track:
(q_clock / p_clock) * (TickCycle * Qtick) / Ptick
In order to match symbolic durations, each track should be repeated adequately:
repeat1 * (TickCycle1 * Qtick1) / Ptick1 = repeat2 * (TickCycle2 * Qtick2) / Ptick2 = …
Ratio (q_clock / p_clock) being identical for each track
was eliminated from this equation.
We need to find the set of smallest integers repeat1, repeat2 etc. satisfying this equation.
To this effect, we simplify ratio (TickCycle * Qtick) / Ptick using the greatest common divisor (GCD):
x = GCD((TickCycle * Qtick), Ptick)
y = (TickCycle * Qtick) / x
Then we calculate the least common multiple (LCM) of all y values:
lcm = LCM(y1, y2, …)
This yields for each field:
repeat = (lcm * Ptick) / (TickCycle * Qtick)
In practice,
x1 = GCD((TickCycle1 * Qtick1), Ptick1) = GCD((5 * 2), 3) = 1
y1 = (TickCycle1 * Qtick1) / x1 = (5 * 2) / 1 = 10
x2 = GCD((TickCycle2 * Qtick2), Ptick2) = GCD((3 * 5), 4) = 1
y2 = (TickCycle2 * Qtick2) / x2 = (3 * 5) / 1 = 15
lcm = LCM(10,15) = 30
repeat1 = (lcm * Ptick1) / (TickCycle1 * Qtick1) = (30 * 3) / (5 * 2) = 9
repeat2 = (lcm * Ptick2) / (TickCycle2 * Qtick2) = (30 * 4) / (3 * 5) = 8
The structure will therefore look like:
{Track1 Track1 Track1 Track1 Track1 Track1 Track1 Track1 Track1, Track2 Track2 Track2 Track2 Track2 Track2 Track2 Track2}
We need to include performance parameters setting the duration of ticks. To this effect, we use the _staccato(s) parameter in which s is the percentage of cropped duration at the end of the sound-event. Durations have been set to 10 milliseconds. We calculate the period of each track:
period1 = (((1000 * q_clock) / p_clock) * Qtick1) / Ptick1 = (((1000 * 21) / 73) * 2) / 3 = 192 ms
s1 = 100 * (192 - 10) / 192 = 94%
period2 = (((1000 * q_clock) / p_clock) * Qtick2) / Ptick2 = (((1000 * 21) / 73) * 5) / 4 = 359 ms
s2 = 100 * (359 - 10) / 359 = 97%
Finally, we specify the tempo of each field: 3/2 for the first one and 4/5 for the second one.
The resulting polymetric structure is:
{_tempo(3/2) _chan(1) _vel(120) _staccato(94) C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - , _tempo(4/5) _chan(1) _vel(120) _staccato(97) - C7 C7 - C7 C7 - C7 C7 - C7 C7 - C7 C7 - C7 C7 - C7 C7 - C7 C7}
Note that _tempo(4/5) does not need to be specified because it will be infered by the polymetric expansion algorithm. Therefore, the expression displayed at the bottom of the Timebase page is:
{_tempo(3/2) _chan(1) _vel(120) _staccato(94) C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - C8 - C8 - - , _chan(1) _vel(120) _staccato(97) - C7 C7 - C7 C7 - C7 C7 - C7 C7 - C7 C7 - C7 C7 - C7 C7 - C7 C7}
Implementation in PHP
The following is the code in file _basic_tasks.php.
Table $mute contains flags indicating whether a track is active or mute. Function key_to_note() returns the name of a note in English convention given its key number (MIDI).

Algorithms
Csound argument mapping
Performing a quadratic mapping using 3 points: how can we make sure that the function will be monotonous?
This is part of document “Check of Bol Processor ‘BP3’ with PHP interface” on the “Bol Processor” website.
The algorithm is implemented in function Findabc() of "CsoundMaths.c".
When three pairs of input/output values are supplied, BP2 attempts to define a quadratic mapping from the input (x) to output (y).
This is an example of a successful mapping:

BP2 expects the mapping function to be monotonous, i.e. the three values (x1, x2, x3) supplied as the input and the ones supplied as the output (y1, y2, y3) must be strictly ordered. Even in this case a proper quadratic mapping may not be possible. See for instance:

Here the quadratic function is not monotonous even though the input values are ordered properly. In this case, BP2 replaces the incorrect part (the one containing an extremum) with a linear function, and changes the other part to make the curve tangent to the linear part. This yields the graph shown below:

Bol Processor BP3

BP3 is the multi-platform version of the Bol Processor that has been in development since 2020. It consists of two modules:
- A console written in C language for cross-platform compilation, containing the core algorithms of the Bol Processor
- An interface that allows non-technical users to edit or create specific material (grammars, sound-objects, Csound instruments) and interact with the console to produce Bol Processor scores, MIDI files, Csound scores and real-time MIDI output/input.
Currently, the interface has been built in the HTML5/JavaScript/PHP environment which makes it possible to work with the Bol Processor on any web browser. The setup works in different environments (MacOS X, Windows, Linux, etc.) but it requires the installation of a local Apache/PHP server.
Follow the instructions on the Bol Processor ‘BP3’ and its PHP interface page to install the latest version.
A standalone version compiled from the PHP/JavaScript package is about to be released.


