Csound objects

This arti­cle is a con­tin­u­a­tion of Csound check in which we intro­duced the cre­ation of Csound para­me­ters mon­i­tored by per­for­mance con­trols. Musical phras­es were cre­at­ed from sim­ple notes trans­lat­ed into Csound events in a straight­for­ward man­ner. We now con­sid­er the cre­ation of Csound scores based on sound-objects con­tain­ing Csound instruc­tions — which may be called "Csound objects".

Csound object "e" in sound-object pro­to­types file "-so.tryCsoundObjects"

Csound objects con­tain a Csound score with a spe­cif­ic tem­po and dura­tion. For exam­ple, in object "e" shown above, the tem­po (line "t" of the score) is 120 beats/min. The total dura­tion is 2 beats, or 1000 ms. Note that to cal­cu­late the total dura­tion of this sound-object, the dura­tions of 'E3' and 'G3' (0.667 sec) shouldn't be added to those of 'C3' and 'D3', because of the start dates.

The dura­tion of a Csound object is inde­pen­dent of the dura­tion set by MIDI events that may coex­ist in the sound-object pro­to­type. In most sit­u­a­tions, note sequences and dura­tions are iden­ti­cal in the MIDI stream and the Csound score. This makes it pos­si­ble to play almost the same items via MIDI and Csound. However, as we will see, Csound is open to con­trols that are not avail­able in MIDI.

Calculations can be eas­i­ly ver­i­fied against the C-sound instru­ment file "‑cs.tryCsoundObjects" pro­vid­ed in the exam­ple set bp3-ctests-main.zip — down­load­able from GitHub along with the Bol Processor BP3 inter­face: php-frontend-master.zip. Items can be cre­at­ed with the gram­mar "‑gr.tryCsoundObjects" using the alpha­bet "‑ho.tryCsoundObjects" asso­ci­at­ed with the sound-object pro­to­type file "‑mi.tryCsoundObjects".

Csound score of sound-object "a"

Let us start with sound-object "a" whose score is shown in the pic­ture. The score is giv­en for a tem­po of 120 beats per minute, giv­ing a total dura­tion of 2 beats ( = 1.5 + 0.5) or 1000 ms.

The first event (note 'F0') is repeat­ed 2 times with iden­ti­cal tim­ing, a mean­ing­less detail to check that Csound can han­dle this abnor­mal case.

Events i1 and i2, call­ing instru­ments 1 and 2, describe tonal posi­tions in the octave point pitch-class for­mat: octave num­ber + semi­tones above C. We notice that "5.05" has been mis­la­belled as 'G5'. This will have no effect on the com­pu­ta­tion, as the Bol Processor will auto­mat­i­cal­ly cor­rect it to 'F1'. It will also rename notes accord­ing to the con­ven­tion set in the set­tings: English, French or Indian.

Pitch for­mat in instru­ment 3

Event i3, call­ing instru­ment 3, defines pitch as fre­quen­cy (in Hz). It is assumed that 643.5 Hz is 'D#5' because the dia­pa­son is 'A4' = 440 Hz. This tun­ing is defined in the set­tings (page "-se.tryCsoundObjects"). Bol Processor can change the name of this note accord­ing to the diapason.

Changes of the dia­pa­son are tak­en into account by BP3 when gen­er­at­ing Csound scores, but this was not yet the case with BP2. The fol­low­ing exam­ples have been pro­duced with the default 'A4' = 440 Hz, giv­ing iden­ti­cal results with BP2 and BP3. See the page Csound tun­ing in BP3 page to exam­ine dif­fer­ent cases.

Producing object "a" at a tem­po of 60 beats per minute results in the fol­low­ing Csound score:

a

Pianoroll of object "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 com­plete than the one con­tained in sound-object "a". This is because the sound-object pro­to­type file "-so.tryCsoundObjects" is linked to a Csound instru­ment file "-cs.tryCsoundObjects" (see fig­ure below).

Mention of the relat­ed Csound instru­ments file is nec­es­sary to bind it to the sound-objects pro­to­types file.

Instrument 1 of the Csound instru­ment file is designed to han­dle 10 argu­ments while the score of "i1" events in "a" only con­tains 4. The 6 miss­ing argu­ments are filled with default val­ues of the para­me­ters they rep­re­sent. Here, for exam­ple, '90' is the default vol­ume. Zeros rep­re­sent default pitch­bend or func­tion table index­es.

Note that "5.05" has been cor­rect­ly fixed to "F1". This is only rel­e­vant to human read­ers, as Csound ignores any text fol­low­ing a semicolon.

You can­not con­vert this and oth­er exam­ples to sound with the sup­plied Csound orches­tra "default.orc", because it only han­dles instru­ment 1. The exam­ples on this page are for visu­al inspec­tion only.

Object graph­ic of f {a b, c}

In the fol­low­ing exam­ple, we need to look at the graph to under­stand why the events of "a" are delayed by 160ms com­pared to "b". Object "b" has a piv­ot set at 20% of its dura­tion from the start date. This can be checked in "-so.tryCsoundObjects".

Although the object graph­ic and the pianoroll for this item indi­cate that "b" should start on a neg­a­tive date (-160ms), the Csound score is shift­ed to show only pos­i­tive or zero dates.

{a, b} c

Pianoroll of {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 piv­ots and relo­ca­tion: sound-object "b" has its piv­ot shown as a full arrow, unlike oth­er sound-objects in this set which only have a red tri­an­gle. This means that it is not relo­cat­able. Relocation would be per­formed if these sound-objects had topo­log­i­cal prop­er­ties such as pro­hibit­ing the cov­er­ing of their beginning/end, allow­ing trun­ca­tion of beginning/end to a cer­tain degree, break­ing the tem­po etc. A constraint-satisfaction algo­rithm is run on each pro­duc­tion to pro­duce a solu­tion that min­imis­es the num­ber of con­straints vio­lat­ed. This is best illus­trat­ed by "-gr.koto3" (read the arti­cle).

Sequence "b midiobject"

Let us now look at a phrase con­tain­ing "mid­iob­ject", a sound-object with both a MIDI stream and a Csound score. The MIDI stream is ignored when con­struct­ing the score. The time res­o­lu­tion (10 ms) also has no effect on the accu­ra­cy of tim­ings in the Csound score.

b mid­iob­ject

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 "mid­iob­ject" has been defined with a tem­po of 60 beats/min for a dura­tion of 2 beats, the dura­tions of the notes E3, C3, D3, G3 are unchanged.

Expression {a b a, c midiobject}

Now con­sid­er a poly­met­ric struc­ture in which the first line con­tains 3 sound-objects and the sec­ond line con­tains 2 sound-objects. The struc­ture will be forced to a sym­bol­ic dura­tion of 3 beats — the dura­tion of "a b a" — and the sec­ond line will arrange the objects as "two in three" with sym­bol­ic dura­tions of 1.5 beats.

This is clear on the pic­ture, look­ing at the piv­ots of sound-objects, if one does not get con­fused by the phys­i­cal dura­tion of the sound-objects. The sound-object pro­to­type "b" has a dura­tion of 0.8 beats, result­ing in a phys­i­cal dura­tion of 800 ms.

PIanoroll of {a b a, c midiobject}

On the sec­ond line, the sym­bol­ic dura­tion of each object is 1.5 beats. Consequently, the sound-object "c", whose pro­to­type has a phys­i­cal dura­tion of 500 ms, is set to phys­i­cal dura­tion = 500 * 1.5 = 750 ms. The object "c" appears as sequence "C5 D5 E5 F5" with total phys­i­cal dura­tion of 4 * 188 ms = 752 ms. These dura­tions are reflect­ed 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

Combined objects and notes

In the fol­low­ing exam­ple, we com­bine sound-objects (con­tain­ing Csound scores) with sim­ple notes that are con­vert­ed to Csound events. These notes are played on (default) MIDI chan­nel 1, which is assigned to instru­ment 1.

a C4 D4 b c

Combined objects and notes on pianoroll. Notes in brown colour are those avail­able on both MIDI and Csound out­puts. Notes in green are exclu­sive­ly Csound.

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 com­bi­na­tion is high­light­ed in the pianoroll. Notes that are present in both the MIDI stream and the Csound score are dis­played in brown, while notes that are present only in the Csound out­put are dis­played in green.

Pitchbend map­ping by instru­ment 2

Let us apply a con­tin­u­ous pitch­bend con­trol to a sound-object con­tain­ing four Csound instruc­tions, using instru­ment 2, which maps the MIDI pitch­bend range [0..16384] to a range of [-200..+200], both on log­a­rith­mic scales. (This map­ping is there­fore linear.)

In the Bol Processor score, the use of mapped val­ues in _pitchbend() con­trols is pos­si­ble, thanks to a _pitchrange(200) instruc­tion at the begin­ning of the sequence.

The result­ing Csound score makes it clear that the pitch­bend should vary con­tin­u­ous­ly over each Csound event : 0 to 24.997, 24.997 to 49.994 etc. Csound will fur­ther inter­po­late the val­ues using its GEN 07 (lin­ear inter­po­la­tion) gen­er­a­tor.

_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 con­trol is pos­si­ble on instru­ments 1 and 2, but not on instru­ment 3. Therefore its effect is only applied to cer­tain 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

Csound score of sound-object "d"

In the fol­low­ing exam­ple, a con­tin­u­ous pitch­bend cor­rec­tion can­not be applied because instru­ment 5, called by "d", does not have a pitch­bend para­me­ter. However, the val­ue of +100 cents is applied to the pitch para­me­ter itself.

The Csound score of sound-object "d" is lim­it­ed to 1 note at 440 Hz (with ref­er­ence to instru­ment 5). This note was labelled 'A4' on the pro­to­type, but we should remem­ber that with a dia­pa­son of 435 Hz it will be slight­ly high­er than 'A4'. The increase is 1200 * log2(440/435) = 24 cents. So, in the per­for­mance it will be set to 124 cents above 435 Hz, giv­ing 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 fol­low­ing exam­ple, a con­tin­u­ous pitch­bend cor­rec­tion results in dif­fer­ent adjust­ments of the pitch­bend para­me­ters of the instru­ments called by sound-objects "a", "b" and "c". Simple notes 'C4' and 'D4' call instru­ment 1 because it is the one assigned to the (default) chan­nel 1. The vol­ume is also adjust­ed continuously.

Note that we also apply neg­a­tive val­ues to the pitch­bend para­me­ter, expect­ing the Csound orches­tra 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

Settings of the "blurb" parameter

Let us check an arbi­trary para­me­ter "burb" which affects argu­ments 9, 10 and 11 of instru­ment 2.

This para­me­ter is designed as addi­tive in its com­bi­na­tions. The default val­ue is '0'.

In sound-object "e", the third event 'D3' is required to set 'blurb' to a start val­ue of 10 and to an end val­ue of 30.

Csound score of sound-object "e"

These val­ues are added to those inter­po­lat­ed over the con­tin­u­ous 'blurb' vari­a­tion: 25.6 + (100 - 25.6) * 0.5 = 62.8 and 100 at dates 0.5 and 1 sec. This gives an ini­tial val­ue of 62.8 + 10 = 72.8 and a final val­ue 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 vari­a­tion of "blurb" becomes more com­plex, the Bol Processor will han­dle it
through func­tion 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 ini­tial val­ues on argu­ments 9 and 10. These val­ues are added to those deter­mined by vari­a­tions of the "blurb" para­me­ter, there­by giv­ing 40 for argu­ment 9 (the ini­tial val­ue of "blurb") and 70 for argu­ment 10 (the final val­ue). The same cal­cu­la­tion is applied to the attached table f103. Consequently, the first and last val­ues of a func­tion table always reflect the ini­tial and final val­ues of the para­me­ter. This allows Csound instru­ments to oper­ate in a con­sis­tent man­ner, either inter­po­lat­ing the ini­tial and final val­ues, or pick­ing up (and inter­po­lat­ing) the val­ues in the attached func­tion table.

The "oops" para­me­ter in instru­ment 6

The Bol Processor com­bines Csound para­me­ters either addi­tive­ly or mul­ti­plica­tive­ly. For pre­de­fined MIDI-mapped para­me­ters, the com­bi­na­tion mode is pre­set: all para­me­ters, except vol­ume, are com­bined addi­tive­ly. For addi­tion­al (non-MIDI) para­me­ters, the com­pos­er can choose both the default val­ue and the com­bi­na­tion mode.

For exam­ple, instru­ment 6 deals with an "oops" para­me­ter that com­bines mul­ti­plica­tive­ly. Sound-object "f" con­tains calls to this instru­ment with val­ues of "oops" oth­er 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

Sound-object f for mm = 60 beats/min

The "oops" para­me­ter varies from 0 to 4 over 1500 ms. At the start of 'D3' and 'E3', its val­ues are 4 * (500 / 1500) = 1.33 and 4 * (1000 / 1500) = 2.66 respectively.

The ini­tial val­ue of "oops" in 'C3' is 0 * 0.5 = 0, and its final val­ue 1.5 * 1.33 = 2, as shown on the score.

The ini­tial val­ue for 'D3' will be O, and for 'E3' it will be 0.25 * 2.66 = 0.665. The val­ue at the end of D3 is 4.7 * 2.66 = 12.5. The val­ue at the end of D3 is 2.5 * 4 = 10.


These exam­ples have been designed to test all the fea­tures of the Csound inter­face as it is imple­ment­ed in Bol Processor. We expect more to come as both envi­ron­ments con­tin­ue to explore new con­cepts and build tools for musicians.

We apol­o­gise for the lack of a cor­pus of real musi­cal pieces cre­at­ed with Bol Processor and Csound. A first exam­ple of high musi­cal qual­i­ty was com­posed in 1996: read and lis­ten to Sarasvati vina!

Leave a Reply

Your email address will not be published. Required fields are marked *