This article is the continuation of Csound check in which we introduced the creation of Csound parameters monitored by performance controls. Musical phrases were made of simple notes translated to Csound events in a straightforward manner. We are now considering 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 specific tempo and duration. For instance, in object “e” shown above, the tempo (line “t” of the score) is 120 beats/min. The total duration is 2 beats, therefore 1000 ms. Beware that, to calculate the total duration of this sound-object, durations of ‘E3’ and ‘G3’ (0.667 sec) shouldn’t be added to those of ‘C3’ and ‘D3’, due to start dates.
The duration of a Csound object is independent on the one set by MIDI events which 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. Nonetheless, as we will see, Csound is open to controls inaccessible to MIDI.
Computations can easily be verified in reference to the Csound instruments file “‑cs.tryCsoundObjects” supplied in sample set bp3-ctests-main.zip — downloadable from GitHub along with Bol Processor BP3’s interface: php-frontend-master.zip. Items can be produced with grammar “‑gr.tryCsoundObjects” using alphabet “‑ho.tryCsoundObjects” associated with the sound-object prototypes file “‑mi.tryCsoundObjects”.

Let us start with sound-object “a” whose score is shown on the image. The score is given for a tempo of 120 beats/min, yielding a total duration of 2 beats ( = 1.5 + 0.5) or 1000 ms.
The first event (note ‘F0’) is repeated 2 times with identical dates, a meaningless detail for verifying 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 wrongly labelled ‘G5’. Yet this will have no incidence on the computation as Bol Processor will automatically fix it to ‘F1’. It will also rename notes as per 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 may change the name of this note according to the diapason.
Changes of the diapason are taken care by BP3 when producing Csound scores, but this was not yet the case with BP2. The following examples have been produced with the standard ‘A4’ = 440 Hz, yielding identical results with BP2 and BP3. Refer to page Csound tuning in BP3 to examine different cases.
Producing object “a” at a tempo of 60 beats/min yields 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”. The reason is that the sound-object prototypes file “-mi.tryCsoundObjects” is linked to a Csound instruments file “-cs.tryCsoundObjects” (see picture below).

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

In the following example, we need to look at the graphic display to understand why events of “a” are 160ms delayed compared with “b”. Object “b” has a pivot set from the start date at 20% of its duration. This can be verified in “-mi.tryCsoundObjects”.
Even though the object graphic and the pianoroll of this item indicate that “b” should start at a negative date (-160ms), the Csound score is shifted to display only positive or null 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
Remark on pivots and relocation: sound-object “b” is displayed with its pivot shown as a complete 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 every production to produce a solution minimizing breaches of constraints. This is best illustrated by “-gr.koto3″ (read 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 in the construction of the score. The time resolution (10 ms) also has no effect on the accuracy of timings in Csound scores.
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 at a tempo of 60 beats/min for a duration of 2 beats, durations of notes E3, C3, D3, G3 are unchanged.

Let us now look at a polymetric structure in which the first line contains 3 sound-objects and the second line 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 objects as “two in three” with symbolic durations 1.5 beats.
This is clear on the picture, looking at the pivots of sound-objects, if one is not confused by the physical duration of sound-objects. 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, sound-object “c”, whose prototype has a physical duration of 500 ms, is set to physical duration = 500 * 1.5 = 750 ms. 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 will be 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 existing in both the MIDI stream and the Csound score are displayed in brown whereas notes existing only in the Csound output are displayed in green.

Let us apply a continuous control of pitchbend over a sound-object containing four Csound statements, using instrument 2 which is mapping 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, using mapped values in _pitchbend() controls is possible owing to a _pitchrange(200) instruction in the beginning of the sequence.
The resulting Csound score makes it clear that pitchbend is meant to vary continuously over each Csound event : 0 to 24.997, 24.997 to 49.994 etc. Csound will further interpolate 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, yet not on instrument 3. Therefore its effect will be applied only to particular 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 +100 cents value will be 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 had been labelled ‘A4’ on the prototype, but we should remember that with a diapason of 435 Hz it will be a little higher than ‘A4’. The raise is 1200 * log2(440/435) = 24 cents. Therefore, in the performance it will be set to 124 cents above 435 Hz, yielding 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 continous pitchbend correction results in various adjustments of pitchbender parameters on 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. Volume is also adjusted continuously.
Note that we also apply negative values to the pitchbend parameter, expecting that the Csound orchestra will 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” affecting arguments 9, 10 and 11 of instrument 2.
This parameter is designed as additive with respect to its combinations. The default value is ‘0’.
In sound-object “e”, the third event ‘D3’ is required to set ‘blurb’ to start value 10 and to end value 30.

These values are added to the ones 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 yields a start value of 62.8 + 10 = 72.8 and an end 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” gets more complex, Bol Processor will handle it
via 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 the ones determined by variations of the “blurb” parameter, thereby yielding 40 for argument 9 (the start value of “blurb”) and 70 for argument 10 (the end value). The same computation is applied to its attached table f103. Consequently, the first and last values of a function table always reflect the start and end values of the parameter. This allows Csound instruments to operate in a consistent manner, either interpolating start and end values or picking up (and interpolating) values in the attached function table.

Bol Processor combines Csound parameters either additively or multiplicatively. For predefined parameters mapped to MIDI the combination mode is preset: all parameters, except volume, are combined additively. For additional (non-MIDI) parameters, the composer may decide on both the default value and the combination mode.
For instance, instrument 6 deals with a “oops” parameter combining multiplicatively. Sound-object “f” contains calls to this instrument with values of “oops” that are not the default ones.
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

Parameter “oops” varies from 0 to 4 over 1500 ms. At the onsets of ‘D3’ and ‘E3’ its values are 4 * (500 / 1500) = 1.33 and 4 * (1000 / 1500) = 2.66 respectively.
The start value of “oops” in ‘C3’ is 0 * 0.5 = 0, and its end value 1.5 * 1.33 = 2 as shown on the score.
The start 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. At the end of D3 the value is 2.5 * 4 = 10.
These examples had been designed to check all features of the Csound interface during its implementation in Bol Processor. We expect more to come as both environments keep on exploring new concepts and building tools for musicians.
We apologize for a yet-to-exist corpus of real musical pieces constructed with Bol Processor and Csound. A first example of high musical quality has been composed in 1996 : read and listen to Sarasvati vina!