Csound tuning in BP3

This page deals with the Bol Processor BP3 using an updat­ed ver­sion of the Csound orches­tra file "default.orc". Changes to the dia­pa­son ('A4' fre­quen­cy) in the set­tings now affect the pro­duc­tion of Csound scores.

In the revised Csound orches­tra file, a few lines have been added to change the val­ue of icps (oscil­la­tor fre­quen­cy) accord­ing to that of the p4 argument:

if (p4 < 15.0) then
icps = cpspch(p4)
else icps = p4
endif

By default, this instru­ment receives the pitch val­ue (argu­ment p4) in the octave point pitch-class for­mat — see doc­u­men­ta­tion. In this case, the fre­quen­cy depends only on the dia­pa­son set up in the Csound orches­tra, or 440 Hz by default, i.e. cpspch(8.09) = 440.

To "tune" the Csound instru­ment to the dia­pa­son select­ed for the project in the Bol Processor BP3, if the base fre­quen­cy is not exact­ly 440 Hz, p4 will con­tain the actu­al fre­quen­cy of the note (cps for­mat) instead of its octave point pitch-class val­ue. The orches­tra file "default.orc" can decide which for­mat is used because (1) no note is ever sent above the 14th octave and (2) fre­quen­cies are nev­er low­er than 15 Hz. So, the val­ue of p4 auto­mat­i­cal­ly makes the deci­sion in "default.orc".

Let us try for example:

S --> A4 B4 C5

If the dia­pa­son is 440 Hz, we get the stan­dard Csound score output:

i1 0.000 1.000 8.09 90.000 90.000 0.000 0.000 0.000 0.000 ; A4
i1 1.000 1.000 8.11 90.000 90.000 0.000 0.000 0.000 0.000 ; B4
i1 2.000 1.000 9.00 90.000 90.000 0.000 0.000 0.000 0.000 ; C5

On the first line, 'A4' is set to 8.09 in the octave point pitch-class format.

Once we set the dia­pa­son to 435 Hz the Csound score will become:

i1 0.000 1.000 435.00 90.000 90.000 0.000 0.000 0.000 0.000 ; A4
i1 1.000 1.000 488.27 90.000 90.000 0.000 0.000 0.000 0.000 ; B4
i1 2.000 1.000 517.31 90.000 90.000 0.000 0.000 0.000 0.000 ; C5

This score shows the actu­al fre­quen­cies of the notes, for exam­ple 'A4' = 435 Hz. This sequence of notes will sound slight­ly low­er than the pre­vi­ous one.

If the dia­pa­son is rad­i­cal­ly dif­fer­ent from 440 Hz, the names of the notes will not change. Only the fre­quen­cies will be change accord­ing­ly. See for exam­ple the Csound score cre­at­ed with 'A4' = 300 Hz:

i1 0.000 1.000 300.00 90.000 90.000 0.000 0.000 0.000 0.000 ; A4
i1 1.000 1.000 336.74 90.000 90.000 0.000 0.000 0.000 0.000 ; B4
i1 2.000 1.000 356.76 90.000 90.000 0.000 0.000 0.000 0.000 ; C5

Let us now exam­ine the changes in dia­pa­son when deal­ing with Csound objects. Take for exam­ple the object "a" in "-gr.tryCsoundObjects". The Csound score of its pro­to­type (as shown in "-so.tryCsoundObjects") is a mix of 3 instruments:

t 0 120
i1 0 0.5 4.05 ; F0
i2 1.5 0.5 5.05 ; F1
i3 1.5 0.2 643.5 1 ; D#5
e

Instruments i1 and i2 use the octave point pitch-class for­mat, while instru­ment i3 uses the direct cps for­mat. This score has been cre­at­ed with 'A4' = 440 Hz which explains why 643.5 Hz is labelled D#5. The labelling of the notes is of minor impor­tance as it will be revised when the per­for­mance Csound score is created.

When 'A4' = 440 Hz the Csound score of a per­for­mance of "a" exact­ly reflects the score in its prototype:

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
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
s
e

If the dia­pa­son is set to 500 Hz the Csound score of the per­for­mance will be:

t 0.000 60.000
i1 0.000 0.250 24.80 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i2 0.750 0.250 49.61 0.000 0.000 90.000 90.000 0.000 0.000 0.000 ; F1
i3 0.750 0.100 643.50 1.000 ; C#5
s
e

Pianorolls with A4 = 440 Hz (left) and 500 Hz (right)

All pitch­es are now giv­en in the cps for­mat. The pitch­es of notes F0 and F1 would be changed in the sound out­put. However, the pitch of instru­ment i3 would remain at 643.50 Hz as set in the sound-object's pro­to­type. As a result of the change in ref­er­ence, the name of the note pro­duced by i3 would now be 'C#5'. This change is reflect­ed in the pianorolls (see image).

Important…

This auto­mat­ic the pitch for­mat selec­tion does not work if you try to send a fre­quen­cy low­er than 15 Hz, as it would be the case for 'F0' in the pre­vi­ous exam­ple if the dia­pa­son was set to 300 Hz. This should nev­er hap­pen, how­ev­er, as 15 Hz is below the range of audi­ble sounds.

At the oppo­site end, octaves beyond 14 are way beyond the musi­cal range since 'C15' is already more than 535 KHz…

This might have an inci­dence on Csound scores being used for pro­duc­ing any­thing else than music, although in this case the use of the octave point pitch-class for­mat is very unlikely.

Changing middle C key number

"Middle C", or 'C4' in the English con­ven­tion, is the key in the mid­dle of a piano key­board. By con­ven­tion, its MIDI key num­ber is 60, but this val­ue can be changed in the settings.

For exam­ple, set­ting 'C4' to key #48 will cause all notes on a MIDI device to be one octave (12 semi­tones) low­er . This does not change the Csound sound out­put. Playing "A4 B4 C5" with 'C4' oth­er than 60 will pro­duce the same sound out­put and the same Csound score, but in the cps pitch format:

t 0.000 120.000
i1 0.000 1.000 440.00 90.000 90.000 0.000 0.000 0.000 0.000 ; A4
i1 1.000 1.000 493.88 90.000 90.000 0.000 0.000 0.000 0.000 ; B4
i1 2.000 1.000 523.25 90.000 90.000 0.000 0.000 0.000 0.000 ; C5
s
e

When applied to Csound objects, chang­ing 'C4' to a key num­ber oth­er than 60 will not change the note names or their actu­al fre­quen­cies, but it will use the cps pitch for­mat. For exam­ple, play­ing "a" will result in the fol­low­ing Csound score:

t 0.000 60.000
i1 0.000 0.250 21.83 90.000 90.000 0.000 0.000 0.000 0.000 ; F0
i2 0.750 0.250 43.65 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
s
e

Misc. grammar controls

The fol­low­ing short exam­ples illus­trate the usage of spe­cif­ic con­trols of the infer­ence mech­a­nism in gram­mars of Bol Processor (BP2 and BP3).

_destru

This instruc­tion is use­ful in pat­tern gram­mars con­tain­ing rep­e­ti­tion and pseudo-repetition mark­ers. For instance, the fol­low­ing gram­mar cre­ates a sequence of two occur­rences of vari­able "X" which may fur­ther be derived as "abc" or "de".

S --> (= X)(: X)
X --> abc
X --> de

In the first rule, (= ) is called a mas­ter paren­the­sis and (: ) a slave paren­the­sis — con­tain­ing a copy of the for­mer. This master-slave depen­den­cy is main­tained through­out sub­se­quent derivations.

The only eli­gi­ble final deriva­tions would be "abcabc" or "dede". However, the final string would be dis­played for instance "(= abc)(: abc)". To obtain a usable string in which 'a', 'b', 'c' may be fur­ther instan­ti­at­ed as sound-objects, it is nec­es­sary to remove struc­tur­al mark­ers. The Bol Processor does it auto­mat­i­cal­ly once the final string has been cre­at­ed, i.e. there are no more can­di­date rules for fur­ther deriva­tions. However, the user may want to dis­play strings with­out their mark­ers. Instruction _destru is used to this effect.

Let us con­sid­er for instance "-gr.tryDESTRU":

-se.tryDESTRU
-al.abc
// This gram­mar pro­duces var­i­ous pat­terns on alpha­bet …

RND
gram#1[1] <2-1> S --> (= (= X) S (:X)) (: (= X) S (:X))
gram#1[2] <2-1> X --> Y
gram#1[3] <2-1> X --> Y S Z
gram#1[4] <2-1> X --> Z

ORD
gram#2[1] LEFT S --> lamb­da [This is an eras­ing rule]

LIN
_destru
gram#3[1] X X --> abca
gram#3[2] Z Y --> abc
gram#3[3] Y Z --> cba
gram#3[4] Y Y --> cbbc
gram#3[5] Z Z --> lamb­da [This is an eras­ing rule]

The first rule in sub­gram­mar #1 cre­ates a self-embedding pat­tern in which the start sym­bol S is cre­at­ed again recur­sive­ly. This recur­siv­i­ty might pro­duce unlim­it­ed strings. To avoid this, each rule in sub­gram­mar #1 is assigned ini­tial weight "2" decreased by "1" once the rule has been fired. Therefore, no rule may be used more than 2 times. Subgrammar #2 con­tains a sin­gle rule delet­ing the left-over "S".

Subgrammar #3 destroys the struc­ture by eras­ing all paren­the­ses and master/slave mark­ers, then it rewrites vari­ables "X", "Y", "Z" as strings of ter­mi­nal sym­bols. Tracing the pro­duc­tion shows for instance that workstring

(=(= Z)(=(= Y)(: Y))(:(= Y)(: Y))(: Z))(:(= Z)(=(= Y)(: Y))(:(= Y)(: Y))(: Z))

is replaced with "Z Y Y Y Y Z Z Y Y Y Y ZZ Y Y Y Y Z Z Y Y Y Y Z".

Rewriting is then done strict­ly from left to right due to the LIN instruction.

The fol­low­ing is a series of 10 items pro­duced by this grammar:

abc­cb­bc­cbaabc­cb­bc­c­ba
cbacbacbacbacbacbacbacbacbacbacbac­ba
abc­cb­bc­cbaabc­cb­bc­c­ba
cbaabc­cbaabc
cbacbacbacbacbacbacbacbacbacbacbac­ba
abcab­cab­cab­cab­cab­cab­cabc
abcab­cab­cab­cab­cab­cab­cabc
cbb­cab­cab­cabc­cb­b­cab­cab­cabc­cb­b­cab­cab­cabc­cb­b­cab­cab­cabc
cbacbacbac­ba
cbbc­cb­bc­cbacb­bc­cb­bc­cbacb­bc­cb­bc­cbacb­bc­cb­bc­c­ba

Complex pat­terns are vis­i­ble on the fol­low­ing sound ren­der­ing of the first item using "-so.abc" sound-object prototypes.

Item "abc­cb­bc­cbaabc­cb­bc­c­ba" cre­at­ed by -gr.tryDESTRU

Mozart’s musical dice game

Dice animation
Source: MaskOfVirtue

The fol­low­ing is a ver­sion of a Musikalisches Würfelspiel attrib­uted to the Austrian com­pos­er Wolfgang Amadeus Mozart (1756-1791). The source is a man­u­script pub­lished by B. Schott's Söhne (Mainz 39542) con­tain­ing musi­cal frag­ments and their cor­re­spon­dances to num­bers select­ed by rolling two dice.

We will show an imple­men­ta­tion of this game that works with both BP2.9.8 and BP3. The BP3 exam­ple has already been intro­duced in the page Bol Processor ‘BP3’ and its PHP inter­face. Here we will focus on the impro­vi­sa­tion­al aspects.

The imple­men­ta­tion took time because the score frag­ments were not avail­able in dig­i­tal for­mat. Today, sim­i­lar projects can be eas­i­ly han­dled using MusicXML scores and the import pro­ce­dure imple­ment­ed in the Bol Processor BP3.

Set up options

Settings of “-gr.Mozart”
Settings of "-gr.Mozart"

In the set­tings of the gram­mar "-gr.Mozart" (see pic­ture), the option "Non-stop improvize" is checked. This means that the machine is expect­ed to cre­ate and play new vari­a­tions of the theme for­ev­er. On the BP3, in the absence of real-time MIDI, only 10 vari­a­tions are pro­duced, saved in a MIDI or Csound file and imme­di­ate­ly avail­able for lis­ten­ing via the inter­face players.

At the bot­tom of the set­tings, the note con­ven­tion has been set to "French". At the top of it is the "seed for ran­dom­iza­tion" which deserves a comment.

Computers pro­duce sequences of ran­dom num­bers deter­mined by suc­ces­sive calls to the rand() func­tion in the C pro­gram­ming lan­guage. Another func­tion called srand(x) reseeds the sequence with num­ber "x": the seed. A giv­en seed will pro­duce the same sequence for sub­se­quent calls of rand(). The only way to get unpre­dictable sequences is to use a dif­fer­ent seed each time a ran­dom sequence is required. In oth­er words, shuf­fle the cards. To do this, the Bol Processor picks up a seed in the time() func­tion which returns the cur­rent date/time as an inte­ger number.

Here, the seed is set to "999". Unless mod­i­fied, the sequence of vari­a­tions of Mozart's dice game should be iden­ti­cal (on the same com­put­er). In order to gen­er­ate ran­dom sequences we need to instruct the machine to reseed the sequence with an arbi­trary num­ber of its choice. By con­ven­tion, this is done by set­ting the seed to 0.

The result

Below you can hear a sequence of 10 vari­a­tions cre­at­ed with seed = 999. The MIDI file was down­loaded and sent to a PianoTeq syn­the­sis­er tuned to equal temperament:

Ten vari­a­tions of "-gr.Mozart" pro­duced with seed = 999

I remem­ber play­ing vari­a­tions of "-gr.Mozart" to a team of music teach­ers who con­clud­ed enthu­si­as­ti­cal­ly: "That must be Mozart!"

You can also down­load the MIDI file and send it to a MIDI device. Below is anoth­er set of vari­a­tions sent by BP2.9.8 to a Roland D-50 syn­the­sis­er whose split patch assigned notes to dif­fer­ent instru­ments accord­ing to their tonal position:

Variations of "-gr.mozart" played on a split patch of Roland D-50

The same can be achieved by using _chan() or _ins() instruc­tions in the gram­mar to assign instru­ments via reserved MIDI chan­nels or their indices in Csound.

These exam­ples are played on elec­tron­ic instru­ments tuned to equal tem­pera­ment. However, Bol Processor + Csound can pro­duce the same by exploit­ing micro­tonal­i­ty to pro­duce works tuned in dif­fer­ent tem­pera­ments or in pure into­na­tion. Below is the same set of pieces using Zarlino's mean­tone tem­pera­ment (Asselin 2000 p. 85):

Mozart's musi­cal dice game in Zarlino's mean­tone temperament

Finally, "just into­na­tion" can be achieved by retun­ing the instru­ment at each mea­sure to match the har­mon­ic con­text, as explained on the page Just into­na­tion, a gen­er­al frame­work. This gives the fol­low­ing inter­pre­ta­tion — the best tun­ing, in my opinion:

Mozart's musi­cal dice game in just intonation

The MIDI for­mat does not allow for these pre­cise context-sensitive micro­ton­al adjustments.

The stochastic model

A chal­leng­ing aspect of this game is that there is no equal prob­a­bil­i­ty of get­ting num­bers in the range 2 … 12. For exam­ple, a sum of 7 is six times more like­ly than a sum of 2 or 12. The design­er of this game may have been aware of this, as the less like­ly num­bers have been mapped to musi­cal sequences that sound more "dis­so­nant".

In order to sim­u­late the dice game, it was there­fore nec­es­sary to assign weights to the rules that reflect­ed the real prob­a­bil­i­ties. This was achieved in the gram­mar (below) by assign­ing weights K1, K2 etc. to all rules acti­vat­ed by dice rolls.

-se.Mozart

// Use a harp­si­chord or piano sound

LIN [Select rules ran­dom­ly and apply from left to right]

gram#1[1] S --> _vel(80) A B
gram#1[2] A --> A1 A2 A3 A4 A5 A6 A7 A8 A1 A2 A3 A4 A5 A6 A7 A'8
gram#1[3] B --> B1 B2 B3 B4 B5 B6 B7 B8 B1 B2 B3 B4 B5 B6 B7 B8

LIN
gram#2[1] <K1=1> A1 --> T96
gram#2[2] <K2=2> A1 --> T32
gram#2[3] <K3=3> A1 --> T69
gram#2[4] <K4=4> A1 --> T40
gram#2[5] <K5=5> A1 --> T148
gram#2[6] <K6=6> A1 --> T104
gram#2[7] <K7=5> A1 --> T152
gram#2[8] <K8=4> A1 --> T119
gram#2[9] <K9=3> A1 --> T98
gram#2[10] <K10=2> A1 --> T3
gram#2[11] <K11=1> A1 --> T54

LIN [These rules could be mixed with the pre­ced­ing ones. But pro­duc­tion is faster in this way.]
gram#3[1] <K1> A2 --> T22
gram#3[2] <K2> A2 --> T6
gram#3[3] <K3> A2 --> T95
gram#3[4] <K4> A2 --> T17
gram#3[5] <K5> A2 --> T74
gram#3[6] <K6> A2 --> T157
gram#3[7] <K7> A2 --> T60
gram#3[8] <K8> A2 --> T84
gram#3[9] <K9> A2 --> T142
gram#3[10] <K10> A2 --> T87
gram#3[11] <K11> A2 --> T130

LIN
gram#4[1] <K1> A3 --> T141
gram#4[2] <K2> A3 --> T128
gram#4[3] <K3> A3 --> T158
gram#4[4] <K4> A3 --> T113
gram#4[5] <K5> A3 --> T163
gram#4[6] <K6> A3 --> T27
gram#4[7] <K7> A3 --> T171
gram#4[8] <K8> A3 --> T114
gram#4[9] <K9> A3 --> T42
gram#4[10] <K10> A3 --> T165
gram#4[11] <K11> A3 --> T10

LIN
gram#5[1] <K1> A4 --> T41
gram#5[2] <K2> A4 --> T63
gram#5[3] <K3> A4 --> T13
gram#5[4] <K4> A4 --> T85
gram#5[5] <K5> A4 --> T45
gram#5[6] <K6> A4 --> T167
gram#5[7] <K7> A4 --> T53
gram#5[8] <K8> A4 --> T50
gram#5[9] <K9> A4 --> T156
gram#5[10] <K10> A4 --> T61
gram#5[11] <K11> A4 --> T103

LIN
gram#6[1] <K1> A5 --> T105
gram#6[2] <K2> A5 --> T146
gram#6[3] <K3> A5 --> T153
gram#6[4] <K4> A5 --> T161
gram#6[5] <K5> A5 --> T80
gram#6[6] <K6> A5 --> T154
gram#6[7] <K7> A5 --> T99
gram#6[8] <K8> A5 --> T140
gram#6[9] <K9> A5 --> T75
gram#6[10] <K10> A5 --> T135
gram#6[11] <K11> A5 --> T28

LIN
gram#7[1] <K1> A6 --> T122
gram#7[2] <K2> A6 --> T46
gram#7[3] <K3> A6 --> T55
gram#7[4] <K4> A6 --> T2
gram#7[5] <K5> A6 --> T97
gram#7[6] <K6> A6 --> T68
gram#7[7] <K7> A6 --> T133
gram#7[8] <K8> A6 --> T86
gram#7[9] <K9> A6 --> T129
gram#7[10] <K10> A6 --> T47
gram#7[11] <K11> A6 --> T37

LIN
gram#8[1] <K1> A7 --> T11
gram#8[2] <K2> A7 --> T134
gram#8[3] <K3> A7 --> T110
gram#8[4] <K4> A7 --> T159
gram#8[5] <K5> A7 --> T36
gram#8[6] <K6> A7 --> T118
gram#8[7] <K7> A7 --> T21
gram#8[8] <K8> A7 --> T169
gram#8[9] <K9> A7 --> T62
gram#8[10] <K10> A7 --> T147
gram#8[11] <K11> A7 --> T106

LIN
gram#9[1] A8 --> T5
gram#9[2] A'8 --> T'5

LIN
gram#10[1] <K1> B1 --> T70
gram#10[2] <K2> B1 --> T117
gram#10[3] <K3> B1 --> T66
gram#10[4] <K4> B1 --> T90
gram#10[5] <K5> B1 --> T25
gram#10[6] <K6> B1 --> T138
gram#10[7] <K7> B1 --> T16
gram#10[8] <K8> B1 --> T120
gram#10[9] <K9> B1 --> T65
gram#10[10] <K10> B1 --> T102
gram#10[11] <K11> B1 --> T35

LIN
gram#11[1] <K1> B2 --> T121
gram#11[2] <K2> B2 --> T39
gram#11[3] <K3> B2 --> T139
gram#11[4] <K4> B2 --> T176
gram#11[5] <K5> B2 --> T143
gram#11[6] <K6> B2 --> T71
gram#11[7] <K7> B2 --> T155
gram#11[8] <K8> B2 --> T88
gram#11[9] <K9> B2 --> T77
gram#11[10] <K10> B2 --> T4
gram#11[11] <K11> B2 --> T20

LIN
gram#12[1] <K1> B3 --> T26
gram#12[2] <K2> B3 --> T126
gram#12[3] <K3> B3 --> T15
gram#12[4] <K4> B3 --> T7
gram#12[5] <K5> B3 --> T64
gram#12[6] <K6> B3 --> T150
gram#12[7] <K7> B3 --> T57
gram#12[8] <K8> B3 --> T48
gram#12[9] <K9> B3 --> T19
gram#12[10] <K10> B3 --> T31
gram#12[11] <K11> B3 --> T108

LIN
gram#13[1] <K1> B4 --> T9
gram#13[2] <K2> B4 --> T56
gram#13[3] <K3> B4 --> T132
gram#13[4] <K4> B4 --> T34
gram#13[5] <K5> B4 --> T125
gram#13[6] <K6> B4 --> T29
gram#13[7] <K7> B4 --> T175
gram#13[8] <K8> B4 --> T166
gram#13[9] <K9> B4 --> T82
gram#13[10] <K10> B4 --> T164
gram#13[11] <K11> B4 --> T92

LIN
gram#14[1] <K1> B5 --> T112
gram#14[2] <K2> B5 --> T174
gram#14[3] <K3> B5 --> T73
gram#14[4] <K4> B5 --> T67
gram#14[5] <K5> B5 --> T76
gram#14[6] <K6> B5 --> T101
gram#14[7] <K7> B5 --> T43
gram#14[8] <K8> B5 --> T51
gram#14[9] <K9> B5 --> T137
gram#14[10] <K10> B5 --> T144
gram#14[11] <K11> B5 --> T12

LIN
gram#15[1] <K1> B6 --> T49
gram#15[2] <K2> B6 --> T18
gram#15[3] <K3> B6 --> T58
gram#15[4] <K4> B6 --> T160
gram#15[5] <K5> B6 --> T136
gram#15[6] <K6> B6 --> T162
gram#15[7] <K7> B6 --> T168
gram#15[8] <K8> B6 --> T115
gram#15[9] <K9> B6 --> T38
gram#15[10] <K10> B6 --> T59
gram#15[11] <K11> B6 --> T124

LIN
gram#16[1] <K1> B7 --> T109
gram#16[2] <K2> B7 --> T116
gram#16[3] <K3> B7 --> T145
gram#16[4] <K4> B7 --> T52
gram#16[5] <K5> B7 --> T1
gram#16[6] <K6> B7 --> T23
gram#16[7] <K7> B7 --> T89
gram#16[8] <K8> B7 --> T72
gram#16[9] <K9> B7 --> T149
gram#16[10] <K10> B7 --> T173
gram#16[11] <K11> B7 --> T44

LIN
gram#17[1] <K1> B8 --> T8
gram#17[2] <K2> B8 --> T78
gram#17[3] <K3> B8 --> T8
gram#17[4] <K4> B8 --> T8
gram#17[5] <K5> B8 --> T8
gram#17[6] <K6> B8 --> T8
gram#17[7] <K7> B8 --> T8
gram#17[8] <K8> B8 --> T8
gram#17[9] <K9> B8 --> T8
gram#17[10] <K10> B8 --> T8
gram#17[11] <K11> B8 --> T8

SUB1 [Substitute only once.]
gram#18[1] T1 --> {fa3 re3 sol3,fa5 re5 sol5}
gram#18[2] T2 --> {{2,si2,sol3}-,la4 {2,fa#4 sol4 si4 sol5}}
gram#18[3] T3 --> {{2,do3,mi3}-,sol5 do5 mi5}
gram#18[4] T4 --> {{1,sol2 si2} sol3 si2,sol5 re5_}
gram#18[5] T5 --> {sol2 {2,sol3 fa3 mi3 re3}, {2,sol4,si4,re5,sol5}-}
gram#18[6] T'5 --> {sol2 {2,si3 sol3 fa#3 mi3}, {2,sol4,si4,re5,sol5}-}
gram#18[7] T6 --> {{2,do3,mi3}-,sol4 do5 mi5}
gram#18[8] T7 --> {{2,do3,sol3}-,mi5 do5 mi5 sol5 do6 sol5}
gram#18[9] T8 --> {do3 sol2 do2,do5_ -}
gram#18[10] T9 --> {sol3_ sol2,{do5,mi5}{si4,re5}-}
gram#18[11] T10 --> {sol3_ -,si4 la4 si4 do5 re5 si4}
gram#18[12] T11 --> {do3 re3 re2,mi5 do5 si4 la4 sol4 fa#4}
gram#18[13] T12 --> {do3 do3 do3,{mi4 mi4 mi4},{do5 do5 do5}}
gram#18[14] T13 --> {{2,mi3,sol3}-,do5 sol4 mi4}
gram#18[15] T15 --> {{2,do3,sol3}{do3,mi3},mi5 {1,sol5 mi5}do5}
gram#18[16] T16 --> {{2,re3,fa#3}{do3,fa#3},la5 fa#5 re5}
gram#18[17] T17 --> {{2,mi3,sol3}-,do5 sol4 do5 mi5 sol4 do5}
gram#18[18] T18 --> {{2,do3,mi3}{do3,sol3},sol4 do5 mi5}
gram#18[19] T19 --> {{2,do3,sol3}{do3,mi3},{1,mi5 do5}mi5 sol5}
gram#18[20] T20 --> {si2_ -,sol5{1,si5 re6}re5}
gram#18[21] T21 --> {do3 re3 re2,do5 mi5 sol5 re5 la4 fa#5}
gram#18[22] T22 --> {do3_ -,mi5 do5 sol4}
gram#18[23] T23 --> {{3,fa3 mi3 re3 mi3 fa3 sol3},fa5 mi5 re5 mi5 fa5 sol5}
gram#18[24] T25 --> {re3_ do3,re4 fa#4 la4 re5 fa#5 la5}
gram#18[25] T26 --> {{3,do3 mi3 sol3 mi3 do4 do3}, {do5,mi5}{do5,mi5}{do5,mi5}}
gram#18[26] T27 --> {{2,sol3,si3}-,fa5 mi5 fa5 re5 do5 si4}
gram#18[27] T28 --> {{2,do3,la3}-,fa#5 re5 la4 la5 fa#5 re5}
gram#18[28] T29 --> {sol3_ sol2,{2,si4 re5 sol5 re5}si4}
gram#18[29] T31 --> {{2,do3,sol3}{do3,sol3},{1,mi5 do5}sol4 mi5}
gram#18[30] T32 --> {{2,do3,mi3}-,sol4 do5 mi5}
gram#18[31] T34 --> {sol3_ -,{2,mi5 do5 re5 si4} sol4}
gram#18[32] T35 --> {{2,re3,fa#3}{do3,la3},la4 re5 fa#5}
gram#18[33] T36 --> {do3 re3 re2,la4 mi5 re5 sol5 fa#5 la5}
gram#18[34] T37 --> {{2,si2,re3}-,{2,sol5 si5 sol5 re5}si4}
gram#18[35] T38 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_}, do5 sol4 mi5}
gram#18[36] T39 --> {{3,si2 re3 sol3 re3 si2 sol2},sol5 sol4 sol4}
gram#18[37] T40 --> {{2,do3,mi3}-,do5 si4 do5 mi5 sol4 do5}
gram#18[38] T41 --> {{2,do3,mi3}-,{2,do5 si4 do5 mi5} sol4}
gram#18[39] T42 --> {sol2_ -,si4 do5 re5 si4 la4 sol4}
gram#18[40] T43 --> {{2,do3,mi3}-,sol5{2,fa5 mi5 re5 do5}}
gram#18[41] T44 --> {fa3_ sol3,la4{2,fa5 re5 la4 si4}}
gram#18[42] T45 --> {{2,mi3,sol3}-,do5 si4 do5 sol4 mi4 do4}
gram#18[43] T46 --> {{2,si2,re3}-,sol5{2,si5 sol5 re5 si4}}
gram#18[44] T47 --> {{2,si2,re3}-,sol5{1,sol5 re5}si5}
gram#18[45] T48 --> {{2,do3,sol3}{do3,mi3},mi5{2,do5 mi5 sol5 do6}}
gram#18[46] T49 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_},mi5 do5 sol4}
gram#18[47] T50 --> {{2,mi3,sol3}-,do5{1,mi5 do5}sol4}
gram#18[48] T51 --> {{2,do3,mi3}-,do5 sol4 mi5 do5 sol5 mi5}
gram#18[49] T52 --> {fa3_ sol3,re5 do#5 re5 fa5 sol4 si4}
gram#18[50] T53 --> {do3_ -,{do5,mi5}{1,do5 re5,mi5 fa5}{mi5,sol5}}
gram#18[51] T54 --> {do3 do3 do3,{mi4,do5}{mi4,do5}{mi4,do5}}
gram#18[52] T55 --> {{2,si2,re3}-,sol5 si5 re5}
gram#18[53] T56 --> {{2,sol2,sol3}sol3,{1,re5 si4}sol4 -}
gram#18[54] T57 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_},mi5 do5 sol4}
gram#18[55] T58 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_},sol5 mi5 do5}
gram#18[56] T59 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_},sol5 do5 mi5}
gram#18[57] T60 --> {{2,do3,mi3}-,sol5{2,fa5 mi5 re5 do5}}
gram#18[58] T61 --> {{2,mi3,sol3}-,do5{1,mi5 do5}sol5}
gram#18[59] T62 --> {do3 re3 re2,mi5 do5 si4 sol4 la4 fa#4}
gram#18[60] T63 --> {do3_ -,{2,mi5 do5 si4 do5} sol4}
gram#18[61] T64 --> {{2,do3,sol3}{do3,sol3},mi5 sol5 do6 sol5 mi5 do5}
gram#18[62] T65 --> {{2,re3 fa#3}-,{1,re5 la4}re5 fa#5}
gram#18[63] T66 --> {{re3,la3}{re3,fa#3}{do3,re3},fa#5 la5 fa#5}
gram#18[64] T67 --> {{2,do3,mi3}{mi3,sol3},do5 si4 do5 mi5 sol4 do5}
gram#18[65] T68 --> {si2_ -,sol5{2,si5 sol5 re5 sol5}}
gram#18[66] T69 --> {{2,do3,mi3}-,sol5 mi5 do5}
gram#18[67] T70 --> {re3_ do3,fa#5{2,la5 fa#5 re5 fa#5}}
gram#18[68] T71 --> {{2,si2,re3}{si2,re3},{2,sol5 si5 re6 si5} sol5}
gram#18[69] T72 --> {fa3_ sol3,fa5 mi5 re5 do5 si4 re5}
gram#18[70] T73 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_},sol5 mi5 do5}
gram#18[71] T74 --> {{2,do3,mi3}-,do6 si5 do6 sol5 mi5 do5}
gram#18[72] T75 --> {do3 do3 do3,{re5,fa#5}{re5,fa#5}{re5,fa#5}}
gram#18[73] T76 --> {{2,do3,mi3}{do3,sol3},do6 si5 do6 sol5 mi5 do5}
gram#18[74] T77 --> {{2,si2,re3}{si2,sol3},{1,sol5 si5}sol5 re5}
gram#18[75] T78 --> {do3_ do2,do5 do4 -}
gram#18[76] T80 --> {do3_ -,re5 la4 fa#5}
gram#18[77] T82 --> {{2,si2,sol3}{si2,re3},{1,re5 si4}sol4 sol5}
gram#18[78] T84 --> {{2,do3,mi3}-,do5 sol4 mi5 do5 sol5 mi5}
gram#18[79] T85 --> {{2,mi3,sol3}-,do5 mi5 sol4}
gram#18[80] T86 --> {{2,si2,sol3}-,re5{1,re5 sol5}si5}
gram#18[81] T87 --> {{2,do3,mi3}{do3,sol3},sol5 do5 mi5}
gram#18[82] T88 --> {{2,si2,re3}{si2,re3},sol5 re5 sol5 si5 sol5 re5}
gram#18[83] T89 --> {{1,fa3 mi3}re3 sol3,{1,fa5 mi5}re5 sol5}
gram#18[84] T90 --> {{2,do3,la3}{do3,la3},fa#5 la5 re6 la5 fa#5 la5}
gram#18[85] T92 --> {{2,sol2,sol3}sol3,{si4,re5}{1,sol5 si5}re5}
gram#18[86] T95 --> {{2,do3,mi3}-,sol5 mi5 do5}
gram#18[87] T96 --> {do3_ -,mi5 do5 sol4}
gram#18[88] T97 --> {{2,si2,re3}{si2,sol3},sol5 fa#5 sol5 re5 si4 sol4}
gram#18[89] T98 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_},do5 sol4 mi5}
gram#18[90] T99 --> {{2,do3,la3}{do3,la3},fa#5 la5 re5}
gram#18[91] T101 --> {{2,do3,sol3}{do3,mi3},mi5 re5 mi5 sol5 do6 sol5}
gram#18[92] T102 --> {{2,do3,la3}{do3,la3},{1,fa#5 re5}la4 fa#5}
gram#18[93] T103 --> {{2,mi3,sol3}-,{2,do5 mi5 do5 sol4} mi4}
gram#18[94] T104 --> {do3_ -,mi5 re5 mi5 sol5 do6 sol5}
gram#18[95] T105 --> {do3_ -,fa#5{2,la5 fa#5 re5 fa#5}}
gram#18[96] T106 --> {do3 re3 re2,la4{2,re5 do5 si4 la4}}
gram#18[97] T108 --> {{2,do3,sol3}{do3,mi3},mi5 sol5 do6}
gram#18[98] T109 --> {{2,fa3,la3}{sol3,re4},re5 fa5 re5 fa5 si4 re5}
gram#18[99] T110 --> {do3 re3 re2,si4 la4 la4 sol4 sol4 fa#4,re5 do5 do5 si4 si4 la4}
gram#18[100] T112 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_},mi5 do5 sol4}
gram#18[101] T113 --> {{2,sol3,si3}-,fa5 re5 si4}
gram#18[102] T114 --> {sol3 sol3 sol3,{si4,re5}{si4,re5}{si4,re5}}
gram#18[103] T115 --> {{2,do3,mi3}-,do5 sol4 mi5 do5 sol5 mi5}
gram#18[104] T116 --> {fa3_ sol3,re5 fa5 la5 fa5 re5 si4}
gram#18[105] T117 --> {{2,re3,fa#3}-,re5 la4 re5 fa#5 la5 fa#5}
gram#18[106] T118 --> {do3 re3 re2,mi5 la5 sol5 si5 fa#5 la5}
gram#18[107] T119 --> {{2,do3,mi3}-,mi5 do5 sol5 mi5 do6 sol5}
gram#18[108] T120 --> {{2,re3,fa#3}{do3,fa#3},re6{2,la5 fa#5 re5 la4}}
gram#18[109] T121 --> {{2,si2,sol3}-,sol5{1,si5 sol5}re5}
gram#18[110] T122 --> {{si2,re3}{si2,re3}{si2,re3},{2,sol5 fa#5 sol5 si5} re5}
gram#18[111] T124 --> {do3 do3 do3,{mi4,do5}{mi4,do5}{mi4,do5}}
gram#18[112] T125 --> {sol3 sol2 -,{2,sol5 mi5 re5 si4}sol4}
gram#18[113] T126 --> {mi3_ {1,mi3 do3},do5 sol4 do5 mi5 sol5 {do5,mi5}}
gram#18[114] T128 --> {sol2_ -,si4 re5 sol5}
gram#18[115] T129 --> {{si2,re3}{si2,re3}{si2,sol3},{2,la5 sol5 fa#5 sol5}re5}
gram#18[116] T130 --> {do3 do3 do3,mi4 mi4 mi4,do5 do5 do5}
gram#18[117] T132 --> {sol3 sol2 -,{do5,mi5}{1,si4 sol4,re5 si4}sol4}
gram#18[118] T133 --> {{2,si2,sol3}-,re5{2,sol5 re5 si4 re5}}
gram#18[119] T134 --> {do3 re3 re2,la4 mi5{si4,re5}{la4,do5}{sol4,si4}{fa#4,la4}}
gram#18[120] T135 --> {{do3,re3}{do3,re3}{do3,re3},fa#5{1,fa#5 re5}la5}
gram#18[121] T136 --> {{2,do3,mi3}-,do6 si5 do6 sol5 mi5 do5}
gram#18[122] T137 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_},do5 sol4 mi5}
gram#18[123] T138 --> {{3,re2 re3 do#3 re3 do3 re3},{la4,re5,fa#5}fa#5_}
gram#18[124] T139 --> {si2_ -,{2,sol5 si5 sol5 si5}re5}
gram#18[125] T140 --> {{do3,fa#3}{do3,fa#3}{do3,la3},la4{1,la4 re5}fa#5}
gram#18[126] T141 --> {{2,si2,sol3}sol2,re5 mi5 fa5 re5 do5 si4}
gram#18[127] T142 --> {{2,do3,mi3}-,do5 sol4 mi5}
gram#18[128] T143 --> {{2,si2,re3}{si2,re3},sol5{1,re5 si4}sol4}
gram#18[129] T144 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_},sol5 do5 mi5}
gram#18[130] T145 --> {fa3_ sol3,re5 fa5 la4 re5 si4 re5}
gram#18[131] T146 --> {do3 do3 do3,{fa#4,re5}{re5,fa#5}{fa#5,la5}}
gram#18[132] T147 --> {do3 re3 re2,mi5 do6 si5 sol5 la5 fa#5}
gram#18[133] T148 --> {{2,do3,mi3}-,do6 si5 do6 sol5 mi5 do5}
gram#18[134] T149 --> {fa3_ sol3,{1,fa5 re5}la4 si4}
gram#18[135] T150 --> {{3,do3 si2 do3 re3 mi3 fa#3},{sol4,do5,mi5}mi5_}
gram#18[136] T152 --> {{2,do3,mi3}-,sol5{2,fa5 mi5 re5 do5}}
gram#18[137] T153 --> {do3_ -,re5 la4 fa#5 re5 la5 fa#5}
gram#18[138] T154 --> {do3_ -,re5 do#5 re5 fa#5 la5 fa#5}
gram#18[139] T155 --> {{2,si2,re3}-,sol5 si5 sol5 re5 si4 sol4}
gram#18[140] T156 --> {{2,mi3,sol3}-,{2,do5 sol4 mi5 do5} sol5}
gram#18[141] T157 --> {do3_ -,mi5 re5 mi5 sol5 do6 sol5}
gram#18[142] T158 --> {sol2_ -,si4{2,re5 si4 la4 sol4}}
gram#18[143] T159 --> {do3 re3 re2,mi5 sol5 re5 do5 si4 la4}
gram#18[144] T160 --> {{2,do3,mi3}{do3,mi3},do5 si4 do5 mi5 sol4 do5}
gram#18[145] T161 --> {do3 do3 do3,{fa#4,re5}{fa#4,re5}{fa#4,re5}}
gram#18[146] T162 --> {{2,do3,sol3}{do3,mi3},mi5 re5 mi5 sol5 do6 sol5}
gram#18[147] T163 --> {{2,si2,re3}-,sol5 fa#5 sol5 re5 si4 sol4}
gram#18[148] T164 --> {{3,sol3 fa#3 sol3 re3 si2 sol3},re5 sol4_}
gram#18[149] T165 --> {si2_ -,re5 si4 sol4}
gram#18[150] T166 --> {{2,sol3,si3}-,{2,re5 si5 sol5 re5}si4}
gram#18[151] T167 --> {{2,do3,mi3}-,do5{1,do5 re5}mi5}
gram#18[152] T168 --> {{2,do3,mi3}{mi3,sol3},sol5{2,fa5 mi5 re5 do5}}
gram#18[153] T169 --> {do3 re3 re3,mi5 sol5 re5 sol5 la4 fa#5}
gram#18[154] T171 --> {{2,sol2,sol3}{si2,sol3},si4 do5 re5 mi5 fa5 re5}
gram#18[155] T173 --> {fa3_ sol3,{1,fa5 la5}la4{1,si4 re5}}
gram#18[156] T174 --> {{1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_} {1,{do3,mi3}sol3_},sol4 do5 mi5}
gram#18[157] T175 --> {sol3 sol2 -,{2,mi5 do5 si4 re5}sol5}
gram#18[158] T176 --> {{2,si2,re3}{si2,re3},la5 sol5 si5 sol5 re5 sol5}

COMMENT:
This is Mozart's musi­cal dice game…
[Source: B. Schott's Söhne, Mainz 39542]

Sound-object and pianoroll displays of a polymetric expression {{2,do3,sol3}{do3,mi3},mi5 re5 mi5 sol5 do6 sol5} produced by T162 in "-gr.Mozart"
Sound-object and pianoroll dis­plays of a poly­met­ric expres­sion {{2,do3,sol3}{do3,mi3},mi5 re5 mi5 sol5 do6 sol5} pro­duced by T162 in "-gr.Mozart"

Subgrammars #1 to #17 rewrite the work string — ini­tial­ly "S" — as strings of vari­ables "A1", "A2", "B1", "T96" etc. The num­bers of the "T-variables" are tak­en from tables in the game.

Subgrammar #18 rewrites each "T-variable" as a poly­met­ric expres­sion of ter­mi­nal sym­bols (sim­ple notes). For exam­ple, "la3" is equiv­a­lent to "A4" in English which is set to 440 Hz in "-se.Mozart". This instru­ment can be tuned.

The pic­tures show self-explanatory pianoroll and sound-object dis­plays of the poly­met­ric expres­sion pro­duced by "T162":

{{2,do3,sol3}{do3,mi3},mi5 re5 mi5 sol5 do6 sol5}

Octave numbering and diapason

When we cap­tured notes from a MIDI key­board to con­struct the rules for sub­gram­mar #18, we had the Bol Processor set up incor­rect­ly due to con­fu­sion over octave num­ber­ing in the English and French conventions.

In English, the "mid­dle C" on a piano key­board is called "C4" and its num­ber is 60. In French, the key with the same num­ber is called "do3". When we mis­tak­en­ly called it "do4", all the notes were writ­ten an octave higher…

After fix­ing the prob­lem on BP2, there were two ways to cor­rect the octave shift:

  • Set the "Middle C" num­ber to 48 
  • Keep the stan­dard "Middle C" = "C4" = 60 and trans­pose the whole piece down 12 semi­tones:
    S --> _transpose(-12) _vel(80) A B

We believe that the sec­ond solu­tion makes more sense because it is based on a uni­ver­sal stan­dard of key numbering.

Both solu­tions have the same cor­rec­tive effect on the Csound score: only note names will change, for exam­ple "mi5" is replaced with "mi4" but both octave point pitch-class nota­tions remain "9.04".

Settings on -gr.Mozart

On the Settings page the dia­pa­son (fre­quen­cy of "A4") is set to 440 Hz which is the most com­mon stan­dard for tun­ing instru­ments. If "A4" was num­bered 48 this fre­quen­cy should be low­ered to 220 Hz.

However, this dia­pa­son set­ting has no effect on the tonal­i­ty of pieces pro­duced by "-gr.Mozart" in MIDI for­mat. The real-time MIDI stream or MIDI file will be played by MIDI devices — such as the MIDIjs javascript play­er — using their own default set­ting of "A4".

In the Bol Processor BP2, the fre­quen­cy of "A4" also had no effect on the Csound out­put. In the orches­tra file "default.orc", the oscil­la­tor para­me­ter kpitch was derived from the octave point pitch-class para­me­ter p4 via the func­tion cpspch() also using the default 440 Hz dia­pa­son = cpspch(8.09) — see doc­u­men­ta­tion. This has been changed in BP3, using an updat­ed ver­sion of "default.orc". See Csound tun­ing in BP3 for more details.

References

Asselin, P.-Y. Musique et tem­péra­ment. Paris, 1985, repub­lished in 2000: Jobert. Soon avail­able in English.

Csound

No posts found.

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!

Csound checkup

Csound in the Bol Processor (BP2, BP3) environment

This arti­cle and the next one on Csound objects are reserved for Csound geeks inter­est­ed in cre­at­ing Csound scores with Bol Processor. They are com­ple­men­tary but they can be stud­ied independently.

The exam­ples in this sec­tion are not intend­ed to be audi­to­ry. Rather, the idea was to pro­duce short Csound scores that could be used to illus­trate the treat­ment of para­me­ters in a vari­ety of contexts.

The cal­cu­la­tions in this arti­cle can be eas­i­ly checked against the Csound instru­ment file "‑cs.chekAllCsound" includ­ed in the bp3-ctests-main.zip exam­ple set, which can be down­loaded from GitHub along with the Bol Processor BP3's inter­face: php-frontend-master.zip. See the Bol Processor ‘BP3’ and its PHP inter­face page for the instal­la­tion and testing.

All items can be pro­duced with the gram­mar "‑gr.checkAllCsound".

Let us start with a sim­ple example:

A4 G4 C5 A4

This pro­duces the fol­low­ing 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 chan­nel 1 by default in the Csound instru­ment file "-cs.checkAllCsound".
This score will not pro­duce any sound with the default orches­tra file "default.orc" because it does not con­tain a def­i­n­i­tion for instru­ment 2.
Argument 4 is the pitch (in Herz) relat­ed to the dia­pa­son (fre­quen­cy of A4) set in "-se.checkAllCsound".
Argument 5 is the MIDI val­ue of the vol­ume, default 90 accord­ing to the set­tings.
Arguments 6 and 7 can be used for the 'blurb' para­me­ter (see infra).
Argument 8 is not not used, its val­ue remains 0.

No treat­ment of MIDI pitch­bend in instru­ment 2

Instrument 2 does not use the pitch­bend val­ue as a para­me­ter, but changes the pitch para­me­ter (in Hz) accord­ing­ly. In the fol­low­ing exam­ple, G4, which is 200 cents high­er, will be played 2 semi­tones high­er, 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

Volume map­ping in instru­ment 3

Now we will force the instru­ment to 3. Note that many new para­me­ters are dis­played.
The default vol­ume is 90 on the MIDI scale. This is con­vert­ed to 16.98 (log scale) using the vol­ume map­ping defined in instru­ment 3.
As instru­ment 3 accepts pitch­bend cor­rec­tions (argu­ments 5 and 6), pitch­bend = 16383 (+2 semi­tones) is applied to G4 instead of chang­ing 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 rep­re­sent the start and end val­ues of the pitch­bend. This makes it pos­si­ble to tell Csound to cal­cu­late a por­ta­men­to (see infra).

Mapping of mod­u­la­tion in instru­ment 3

Playing sim­ple notes on chan­nel 2 calls up instru­ment 3, which has vol­ume and mod­u­la­tion con­trol para­me­ters. Here the mod­u­la­tion range (0 to 12431) is mapped to 0 to 3035.097 (argu­ments 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 with­out tem­per­ing with chan­nels is to use instru­ment 3.

ins(3) _modcont _mod(0) C4 D4__ E4 _mod(12431)

Note that instru­ment spec­i­fi­ca­tions over­ride the assign­ments of The_default instru­ment, which are made on the basis of the MIDI chan­nel. For instance, in the fol­low­ing exam­ple, because of the _ins(1) state­ment, _chan(2) does not set the instru­ment 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

Polymetric struc­ture {C5 D5 E5 F5, G5 D5 C6}

Let us con­sid­er a poly­met­ric struc­ture in which the same note (D5) has two con­sec­u­tive NoteOn's.

In MIDI, a NoteOff is insert­ed before the sec­ond NoteOn of "D5". In Csound the same
instru­ment is called twice. In both ver­sions the break between suc­ces­sive occur­rences 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 exam­ple would sound strange with­out the vol­ume con­trols: we would get a silence dur­ing the time the two D5' are super­im­posed, sim­ply because they are sine waves with equal ampli­tudes and oppo­site phases!

Let us look at the same note played at dif­fer­ent vol­umes in step­wise vari­a­tions. Notice that instru­ment 3 is now spec­i­fied by its name "Harpsichord". (Don't look for it in an orches­tra 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 fol­low­ing illus­tra­tion shows the vol­ume decreas­ing con­tin­u­ous­ly from 127 (i.e. +24 after map­ping) to 0 (i.e. -24 after map­ping). Instrument 3 has two para­me­ters (7 and 8) that take the start and end vol­umes respec­tive­ly, and these val­ues are inter­po­lat­ed by Csound (using scheme GEN07) to pro­duce a con­tin­u­ous 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 sim­i­lar con­tin­u­ous changes over sev­er­al notes invok­ing 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 vol­ume con­tin­u­ous­ly on the first two notes, then the vol­ume 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 pitch­bend vari­a­tion 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, pitch­bend and vol­ume 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 instru­ments inter­po­late between sin­gle start and end val­ues.
Instrument 1, here called "The_default", i.e. the one defined in "default.orc", is able to vary pitch­bend and vol­ume in a more sophis­ti­cat­ed way, using a func­tion table.

BP3 auto­mat­i­cal­ly cre­ates func­tion tables when required and when the instru­ment spec­i­fi­ca­tion (here "-cs.checkAllCsound") pro­vides slots (argu­ments) for enter­ing func­tion table indexes.

Let us look at a sim­ple exam­ple with pitch­bend. Both of the fol­low­ing nota­tions result in the same score.
You will hear the pro­duc­tion of this score with the demo orches­tra "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 inter­po­la­tion) could be con­sid­ered, but it has the dis­ad­van­tage of forc­ing the first deriv­a­tive to zero at the start and end points. GEN07 is also much faster.

Here, C4 needs a 4-point table, because of _pitchcont where­as D4 only needs lin­ear 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 ini­tial por­ta­men­to on a silence '-' is only pro­vid­ed by the
MIDI out­put. 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 sec­tion between brack­ets { } fol­lows an inde­pen­dent 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 poly­met­ric struc­ture. E4 retains the ini­tial pitch­bend val­ue 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 inde­pen­dent move­ment, which would be impos­si­ble 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 for­get to set _pitchrange(200) on chan­nel 2, oth­er­wise _pitchbend(180) will be used as the MIDI val­ue (range 0..16383). Note again that chan­nel 2 will not call instru­ment 3 because instru­ment 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 exam­ple, if you for­get to set the instru­ment to 1, instru­ments will be assigned based on MIDI chan­nels. This results in:

pitch­cont _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 arbi­trary para­me­ter 'blurb' (which has no MIDI equiv­a­lent)
on the two instru­ments '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 han­dle func­tion 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 'arbi­trary' para­me­ter is called 'vol­ume', it will be MIDI vol­ume, 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 'pitch­bend', 'pres­sure', 'panoram­ic' and 'mod­u­la­tion' (all case sen­si­tive). In instru­ment 3, MIDI mod­u­la­tion 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 addi­tion­al para­me­ter is unknown to the instru­ment, it will sim­ply be ignored. No warn­ing will be giv­en. 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' instru­ment han­dles the 'splash' para­me­ter which is instruct­ed to cre­ate func­tion 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 instru­ment 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 writ­ten 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 exam­ples pro­duce iden­ti­cal results with BP2.9.8 and its cur­rent ver­sion BP3.

Want to know more? Read the page Csound objects!

Sarasvati vina

Sarasvati vīna. Source: Wikipedia

The fol­low­ing is an exam­ple of suc­cess­ful com­bi­ina­tion of Bol Processor and Csound. Both music cre­ation soft­ware pack­ages are still in devel­op­ment after four decades… Csound was orig­i­nal­ly writ­ten by Barry Vercoe at MIT in 1985, while Bol Processor dates back to 1981.

Short musi­cal phras­es were com­posed in 1995 by Srikumar Karaikudi Subramanian, an accom­plished prac­ti­tion­er of Carnatic music with deep under­stand­ing of math­e­mat­ics and physics — read his blog, PhD the­sis (2013) and list of patents.

Listen to the result:

"Pallavi" of song "Maayaatiita Svaruupini, Nannu brovave" in raga "maya­maalava­gaula". (The fade­out is post-produced.)

The mak­ing of this exam­ple requires a 33-millisecond wave­form sam­ple of Sarasvati vīna (vina-wave-table.aif) and a gram­mar (-gr.vina3) asso­ci­at­ed with a Csound instru­ment descrip­tion (-cs.Vina). All this is han­dled by the Bol Processor in both BP2 and BP3 ver­sions. This process pro­duces a Csound score which Csound con­verts into a sound file using a Csound orches­tra file (new-vina.orc).

The demo was ini­tial­ly devel­oped on Bol Processor BP2, the stand­alone appli­ca­tion still avail­able for Mac com­put­ers. In October 2020, it was repeat­ed on BP3, the multi-platform ver­sion, to check the valid­i­ty of Csound pro­ce­dures in the new environment.

The grammar

The gram­mar "-gr.vina3" is avail­able with all the nec­es­sary ingre­di­ents in the exam­ple set bp3-ctests-main.zip shared on GitHub. Follow the instruc­tions on the Bol Processor ‘BP3’ and its PHP inter­face page to install BP3 and learn its basic oper­a­tion. Download and install Csound as instructed.

The gram­mar "-gr.vina3" is shown below.

-se.Vina3
-cs.Vina
-to.Vina

// "Pallavi" of song "Maayaatiita Svaruupini, Nannu brovave" in raga "maya­maalava­gaula"
// scale - C, C#, E, F, G , G#, B
// Note phrase vari­a­tions giv­en.

// Terms:
// Spuritam - Quick (dis­crete) two note suc­ces­sion.
// Taalam - Measure of time (played on vina using the 3 sym­pa­thet­ic strings tuned to C-G-C).
// Gamaka - Smooth motion between two pitch­es (usu­al­ly pull of string).
// Pallavi - Theme of com­po­si­tion

ORD

gram#1[1] S --> _ins(Vina) _scale(just intonation,0) {Taalam4 Taalam4, Pallavi Pallavi} Taalam

gram#1[2] Pallavi --> {Maa Yaa Tii • Ta {2, Sva Ruu Pi}•{2, Ni} {1, Nan Nu}• Bro {2, Va Ve}}
gram#1[3] Maa --> C3
gram#1[4] Yaa --> LongSpuritam C3 Slide1
gram#1[5] Tii --> {1, StartSlidePull C3 Slide1 _ _ Slide1 Pull0 _ Slide4 • Pull1 _ Pull0 •Pull0 Pull1 - StopSlidePull }
gram#1[6] Ta --> F3
gram#1[7] Sva --> {3, G3}
gram#1[9] Ruu --> {3, StartSlidePull G3 SlideBack2 _ SlideBack3 _ SlideBack2 _ SlideBack3 Pull0 _ Pull1 - StopSlidePull}
gram#1[10] Pi --> {2, F3}
gram#1[11] Ni --> G3
gram#1[12] Nan --> G3
gram#1[13] Nu --> {1, StartPull Pull1 G3 Pull0 _ Pull1 - StopPull}
gram#1[14] Bro --> {1, StartSlide F3 Slide2 _ _ _ StopSlide} /slideVa/
gram#1[15] Bro --> {1, GamakaHold F3 Pull2} /pullVa/
gram#1[16] /slideVa/ Va --> StartSlide G3 SlideBack2 StopSlide
gram#1[17] /pullVa/ Va --> StartPull Pull2 F3 Pull0 StopPull
gram#1[18] Ve --> {3, Ve1 Ve2 Ve3}
gram#1[19] Ve1 --> {5, GamakaOscil E3 Pull1}
gram#1[20] Ve2 --> StartSlide C#3 SlideBack1 _ StopSlide
gram#1[21] Ve3 --> StartPull B2 Pull1 StopPull

RND
gram#2[1] Taalam4 --> Taalam Taalam Taalam Taalam
gram#2[2] Taalam --> {3, C3, G3, C4}

SUB1

gram#3[1] LongSpuritam ?1 ?2 --> {1, StartSlide ?1 _ Slide0 _ ?2 }
gram#3[2] GamakaOscil ?1 ?2 --> {StartPull ?1 ?2 Pull0 _ ?2 _ Pull0 _ ?2 StopPull}
gram#3[3] GamakaHold ?1 ?2 --> {1, StartPull ?1 ?2 _ _ _ StopPull}

SUB1

gram#4[1] StartSlidePull --> StartSlide StartPull
gram#4[2] StopSlidePull --> StopSlide StopPull

SUB1

// Lowest lev­el struc­tures

gram#5[1] Pull0 --> _pitchbend(0)
gram#5[2] Pull1 --> _pitchbend(100)
gram#5[3] Pull2 --> _pitchbend(200)

gram#5[4] Slide0 --> _value(slide, 0)
gram#5[5] SlideBack1 --> _value(slide, -101)
gram#5[6] SlideBack2 --> _value(slide, -201)
gram#5[7] SlideBack3 --> _value(slide, -301)
gram#5[8] Slide1 --> _value(slide, 101)
gram#5[9] Slide2 --> _value(slide, 201)
gram#5[10] Slide4 --> _value(slide, 401)

gram#5[11] StartSlide --> _cont(slide) _value(slide, 0)
gram#5[12] StopSlide --> _fixed(slide)
gram#5[13] StartPull --> _pitchcont _pitchrange(500) _pitchbend(0)
gram#5[14] StopPull --> _pitchfixed

This gram­mar is exem­plary for its use of vari­ables that rep­re­sent "musi­cal ges­tures" before their sound rep­re­sen­ta­tion. For exam­ple, "Pull0", "Pull1" and "Pulll2" are dif­fer­ent ways of pulling the string to raise its pitch. This is reflect­ed by chang­ing the val­ue of a pitch­ben­der, which is a MIDI stan­dard and has been repro­duced in the Csound orchestra.

Another ges­ture is named "slide", which is the move­ment from one fret to the next one. It also affects the fre­quen­cy of the note, but in a dis­con­tin­u­ous way, because the move­ment is a rapid change.

A more sophis­ti­cat­ed mod­el might include the strength of the pluck­ing of a note, which could be mapped to a para­me­ter sim­i­lar to the veloc­i­ty para­me­ter in MIDI.

The Csound score

Once the gram­mar is open in the BP3/PHP inter­face envi­ron­ment, click­ing on "Produce item(s)" will (by default) cre­ate a Csound score named "vina3.sco", as shown below.

; Csound score
f1 0 256 1 "vina-wave-table.aiff" 0 4 0

t 0.000 60.000
i1 0.000 1.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C3
f101 1.000 512 -7 0.000 256 -101.000 128 101.000 128 101.000
i1 1.000 1.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 101.000 101.000 ; C3
f102 2.000 256 -7 0.000 76 0.000 25 100.000 51 0.000 51 0.000 53 100.000
f103 2.000 256 -7 0.000 25 101.000 51 101.000 25 401.000 155 0.000

i1 2.000 0.833 7.00 90.000 90.000 0.000 0.000 100.000 102.000 0.000 0.000 103.000 ; C3
i1 0.000 3.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C3
i1 0.000 3.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; G3
i1 0.000 3.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C4
i1 3.000 1.000 7.05 90.000 90.000 0.000 0.000 0.000 0.000 401.000 401.000 0.000 ; F3
i1 4.000 0.750 7.07 90.000 90.000 0.000 0.000 0.000 0.000 401.000 401.000 0.000 ; G3
f104 4.750 1024 -7 0.000 877 0.000 147 100.000
f105 4.750 1024 -7 0.000 146 -201.000 146 -301.000 146 -201.000 438 -301.000 148 0.000
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
i1 3.000 3.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C3
i1 3.000 3.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; G3
i1 3.000 3.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C4
i1 5.500 0.500 7.05 90.000 90.000 0.000 0.000 0.000 0.000 -345.444 -345.444 0.000 ; F3
i1 6.000 2.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 -345.444 -345.444 0.000 ; G3
i1 8.000 0.500 7.07 90.000 90.000 0.000 0.000 0.000 0.000 -345.444 -345.444 0.000 ; G3
f106 8.500 256 -7 100.000 128 0.000 128 100.000
i1 8.500 0.333 7.07 90.000 90.000 0.000 100.000 100.000 106.000 -345.444 -345.444 0.000 ; G3
i1 6.000 3.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C3
i1 6.000 3.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; G3
i1 6.000 3.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C4
f107 9.000 512 -7 0.000 128 201.000 384 201.000
i1 9.000 1.000 7.05 90.000 90.000 0.000 0.000 0.000 0.000 0.000 201.000 107.000 ; F3
f108 10.000 1024 -7 0.000 256 -201.000 768 -201.000
i1 10.000 0.500 7.07 90.000 90.000 0.000 0.000 0.000 0.000 0.000 -201.000 108.000 ; G3
f109 10.500 1024 -7 0.000 204 100.000 204 0.000 204 100.000 204 0.000 208 100.000
i1 10.500 0.937 7.04 90.000 90.000 0.000 0.000 100.000 109.000 -201.000 -201.000 0.000 ; E3
f110 11.437 512 -7 0.000 256 -101.000 256 0.000
i1 11.437 0.375 7.01 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 110.000 ; C#3
i1 9.000 3.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C3
i1 9.000 3.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; G3
i1 9.000 3.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C4
i1 11.812 0.188 6.11 90.000 90.000 0.000 0.000 33.333 0.000 -101.000 -101.000 0.000 ; B2
i1 12.000 1.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 -101.000 -101.000 0.000 ; C3
f111 13.000 512 -7 0.000 256 -101.000 128 101.000 128 101.000
i1 13.000 1.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 101.000 111.000 ; C3
f112 14.000 256 -7 0.000 76 0.000 25 100.000 51 0.000 51 0.000 53 100.000
f113 14.000 256 -7 0.000 25 101.000 51 101.000 25 401.000 155 0.000

i1 14.000 0.833 7.00 90.000 90.000 0.000 0.000 100.000 112.000 0.000 0.000 113.000 ; C3
i1 12.000 3.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C3
i1 12.000 3.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; G3
i1 12.000 3.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C4
i1 15.000 1.000 7.05 90.000 90.000 0.000 0.000 0.000 0.000 401.000 401.000 0.000 ; F3
i1 16.000 0.750 7.07 90.000 90.000 0.000 0.000 0.000 0.000 401.000 401.000 0.000 ; G3
f114 16.750 512 -7 0.000 472 0.000 40 100.000
f115 16.750 512 -7 0.000 236 -201.000 236 -301.000 40 0.000

i1 16.750 0.468 7.07 90.000 90.000 0.000 0.000 100.000 114.000 0.000 0.000 115.000 ; G3
i1 15.000 3.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C3
i1 15.000 3.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; G3
i1 15.000 3.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C4
i1 17.500 0.500 7.05 90.000 90.000 0.000 0.000 0.000 0.000 -351.000 -351.000 0.000 ; F3
i1 18.000 2.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 -351.000 -351.000 0.000 ; G3
i1 20.000 0.500 7.07 90.000 90.000 0.000 0.000 0.000 0.000 -351.000 -351.000 0.000 ; G3
f116 20.500 256 -7 100.000 128 0.000 128 100.000
i1 20.500 0.333 7.07 90.000 90.000 0.000 100.000 100.000 116.000 -351.000 -351.000 0.000 ; G3
i1 18.000 3.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C3
i1 18.000 3.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; G3
i1 18.000 3.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C4
f117 21.000 512 -7 0.000 128 201.000 384 201.000
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
f118 22.000 1024 -7 200.000 256 0.000 768 0.000
i1 22.000 0.500 7.05 90.000 90.000 0.000 200.000 0.000 118.000 0.000 0.000 0.000 ; F3
f119 22.500 1024 -7 0.000 204 100.000 204 0.000 204 100.000 204 0.000 208 100.000
i1 22.500 0.937 7.04 90.000 90.000 0.000 0.000 100.000 119.000 0.000 0.000 0.000 ; E3
f120 23.437 512 -7 0.000 256 -101.000 256 0.000
i1 23.437 0.375 7.01 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 120.000 ; C#3
i1 21.000 3.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C3
i1 21.000 3.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; G3
i1 21.000 3.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C4
i1 23.812 0.188 6.11 90.000 90.000 0.000 0.000 33.333 0.000 -101.000 -101.000 0.000 ; B2
i1 24.000 3.000 7.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C3
i1 24.000 3.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; G3
i1 24.000 3.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ; C4
s
e


Settings of "slide" in "vina"

Note that the first line of this score — table "f1" — con­tains the link to the sam­pled wave­form "vina-wave-table.aiff" and the Csound orches­tra file "new-vina.orc" locat­ed in the same fold­er. The val­ue "1" in the fourth argu­ment indi­cates that data from a sound file will be trans­ferred into a func­tion table (see doc­u­men­ta­tion).

Lines start­ing with "i1" are note instruc­tions sub­mit­ted to the instru­ment "vina" to pro­duce notes 'C3', 'G3', 'F4' etc. The sec­ond and third argu­ments are the start time and dura­tion respec­tive­ly (see doc­u­men­ta­tion). The fourth argu­ment is the pitch, expressed as "octave.note": for exam­ple, "7.05" means the 7th note of octave 7, which is F3. The pitch could also be giv­en in Herz with respect to 'A4' = 440Hz — see Csound tun­ing in BP3.

Instructions "f102", "f103" etc. describe tables used for the inter­po­la­tion of pitch­bend and "slide" para­me­ters asso­ci­at­ed with the "vina" instru­ment. In the "slide" para­me­ter set­tings, the table index is the 13th argu­ment. In fact, the 13th para­me­ter of the "i1" instruc­tions con­tains "101", "103" etc. In each of these tables, the fourth argu­ment indi­cates the GEN rou­tine that Csound will use for its inter­po­la­tion. The val­ue "-7" means "GENO7" (lin­ear inter­po­la­tion) with no post-normalization (see doc­u­men­ta­tion).

Pitchbender set­tings of instru­ment "vina"

Instructions "f102", "f104" etc. are tables for inter­po­lat­ing pitch­ben­der val­ues. These are ref­er­enced in the 10th argu­ment of "i1" events, as shown in the pic­ture. We see that the range of MIDI val­ues [0 .. 16383] is mapped to the [-500 .. +500] inter­val used by the Csound instru­ment, both being log­a­rith­mic scales. The cen­tral map­ping of 8191.50 to 0 is used to con­struct this inter­po­la­tion with a qua­drat­ic regres­sion. See the Csound argu­ment map­ping page for a detailed explanation.

For exam­ple, 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

table "f104" (10th argu­ment) is invoked to inter­po­late pitch­bend val­ues between 0.000 and 100.000 (the 8th and 9th argu­ments). 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

table "f117" (13th argu­ment) is used to inter­po­late the "slide" para­me­ter between 0.000 and 201.000 (the 11th and 13th argu­ments). However, in the orches­tra file "new-vina.orc", this para­me­ter is not treat­ed as con­tin­u­ous because it rep­re­sents a quick move from one fret to the next. Therefore, the _cont(slide) instruc­tion is irrel­e­vant for this ver­sion of the gram­mar. It could be delet­ed or replaced by _step(slide).

Making the sound file

Open a Unix con­sole and go to the fold­er con­tain­ing "vina3.sco" and "new-vina.orc".

Type :

csound -o Vina3.aif new-vina.orc out.sco

Running Csound on a con­sole: the ter­mi­na­tion of a suc­cess­ful process

If the oper­a­tion is suc­cess­ful — as con­firmed by mes­sages on the con­sole — the desired sound file "Vina3.aif" has been created.

WAV for­mat, 24-bit res­o­lu­tion etc. are also avail­able with Csound. Just type "csound" to see some options, or "csound --help" to see the full list.

By default, Csound dis­plays mes­sages that mim­ic the graph­i­cal rep­re­sen­ta­tion of all tables used in the score. This option can be turned off.

This whole process of con­vert­ing a Csound score into a sound file has been made auto­mat­ic on the Bol Processor BP3 inter­face. If Csound is installed and respond­ing, it will be called to do the con­ver­sion. The sound file it is instruct­ed to cre­ate is in WAV for­mat, because this for­mat (unlike AIFF) is recog­nised by the 

Microtonal intonation

An impor­tant fea­ture of this exam­ple is the choice of a micro­ton­al scale to replace the equal tem­pered 12 tone scale com­mon­ly used on elec­tron­ic or mod­ern key­board instru­ments. The scale is defined in the tonal resource "-to.Vina" and is set by the instruc­tion _scale(just intonation,0).

In BP3 it is pos­si­ble to define micro­ton­al scales and use them either in the MIDI or the Csound envi­ron­ment. (Read the MIDI micro­tonal­i­ty page.) Csound uses func­tion tables, which are auto­mat­i­cal­ly super­im­posed on the Csound score. For exam­ple, a "just into­na­tion" 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 indi­cate fre­quen­cy ratios. For exam­ple, the size of the fifth (C - G) is 1.333 = 4/3, which makes it "per­fect". Listen to both inter­pre­ta­tions in just into­na­tion and equal temperament:

Just into­na­tion
Equal-tempered inter­vals

Discussion

This detailed inter­pre­ta­tion of a musi­cal phrase in Carnatic music was just an ear­ly demon­stra­tion of Bol Processor + Csound fea­tures. In 2013, Srikumar Karaikudi Subramanian sub­mit­ted his PhD the­sis to the National University of Singapore enti­tled Modeling Gamakās of Carnatic Music as a Synthesizer for Sparse Prescriptive Notation. He went on to devel­op the Pāṭāntarā sys­tem of high-quality Carnatic music notation.

Apart from using a sam­ple of the real Sarasvati vīna sound to cre­ate the musi­cal piece, is it worth using the Csound envi­ron­ment instead of MIDI on the Bol Processor? After all, any MIDI sam­pler could han­dle the wave­form and pro­duce the same sound as Csound…

We do not have a MIDI sam­pler to repro­duce 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 fol­low­ing is a ren­der­ing on PianoTeq:

(Dreadful) ren­der­ing of -gr.vina3 on a MIDI device. Sorry Srikumar! 😀

Listening to this ver­sion, it is clear that the pitch­bend instruc­tions have been par­tial­ly inter­pret­ed, while the "slide" para­me­ter spe­cif­ic to the "vina" Csound instru­ment has been ignored. This con­firms that Csound offers the pos­si­bil­i­ty of enrich­ing the descrip­tion of any piece of music with per­for­mance para­me­ters that do not belong to the stan­dard MIDI cat­e­gories: pitch­bend, mod­u­la­tion, pres­sure, etc.

We have doc­u­ment­ed all the fea­tures of the Csound imple­men­ta­tion on the Csound check­up and Csound objects page, show­ing exam­ples that can be checked with BP3. More details on the han­dling of con­tin­u­ous para­me­ters can be found on the page Continuous para­me­ters in Csound scores.

A call for participation

We invite musi­cians who are famil­iar with Csound to cre­ate exam­ples of the full use of Csound on Bol Processor. This will increase our con­fi­dence that none of the imple­ment­ed Csound fea­tures are incom­plete or erroneous.

 The devel­op­ment of Csound beyond our ini­tial work on the sub­ject (in 1995) is expect­ed to stim­u­late new ideas for more advanced inte­gra­tion in future ver­sions of BP3.

Bol Processor ‘BP3’ and its PHP interface

This is a pre­sen­ta­tion of  BOL PROCESSOR ‘BP3’.
Install it and try these exam­ples in your envi­ron­ment: MacOSWindows or Linux.

👉 ‘BP3’ pro­duces real-time MIDI events, BP scores, stan­dard MIDI files and Csound scores.
👉 Capturing and inter­pret­ing incom­ing MIDI mes­sages is a work in progress. Importing MusicXML scores is ful­ly func­tion­al.
👉 MIDI files are instant­ly audi­ble thanks to a built-in MIDI play­er, where­as Csound scores are used to cre­ate sound files that are sent to a stan­dard HTML5 audio play­er.

This page pro­vides an overview of inter­ac­tions with the Bol Processor con­sole. The objec­tive is to ver­i­fy its oper­a­tion in any envi­ron­ment. Musical exam­ples are of low artis­tic val­ue as their pur­pose is to be a com­pre­hen­sive demon­stra­tion of tech­ni­cal aspects.

Once you have com­plet­ed the instal­la­tion of BP3 (and option­al Csound), you can check these fea­tures in any order you like.

Real-time MIDI was imple­ment­ed in May 2024. It works beau­ti­ful­ly in the three envi­ron­ments… After installing BP3, vis­it the Real Time MIDI page to enjoy the full range of pos­si­bil­i­ties it offers!

BP3 is cur­rent­ly being test­ed with MAMP (see below) on com­put­ers run­ning MacOS Sequoia 15.1 and Windows 10, and with XAMPP on LinuxLite 7.0 (Ubuntu).

👉  Send questions/suggestions to the devel­op­ers via the con­tact form or join the BP devel­op­ers list on SourceForge.

Install the Apache server and Bol Processor package

Installing the Bol Processor BP3 does not require any pro­gram­ming skills. Just use the installers for MacOS and Windows, or the instal­la­tion scripts for Linux.

Follow instruc­tions on instal­la­tion pages for MacOSWindows and Linux.

Compile the console and check its operation

The Bol Processor's PHP inter­face recog­nis­es the sys­tem your com­put­er is run­ning. It checks key fea­tures and tells you what is miss­ing or needs fixing.

The Bol Processor BP3 home page (in light mode) when the con­sole is installed and run­ning. The dis­play is the same in all three environments.
  • Start your Apache/PHP serv­er and point your web brows­er 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 dis­played as localhost/bolprocessor/php/.
  • MacOS and Linux users: if you get an error mes­sage or see noth­ing, check file per­mis­sions ("775" in the "bolprocessor" fold­er) in your instal­la­tion. The installer or the instal­la­tion script takes care of it: did you use it? This issue did not occur on Windows 10.
  • If you have just done a new instal­la­tion or an upgrade, you will get a warn­ing that the con­sole "bp" (or "bp.exe" or "bp3") is not "respond­ing" along with a link to the "compile.php" page. This page will com­pile the con­sole if the "source" fold­er has been prop­er­ly copied to "bolprocessor". More infor­ma­tion is found on the Quick install page of your sys­tem (see above).
  • After the com­pi­la­tion, you will get a con­fir­ma­tion mes­sage if it was suc­cess­ful, or a list of errors if it was not — which should nev­er hap­pen, oth­er­wise tell us!
  • You can then reload the home page, now look­ing like the pic­ture above, by default in dark mode.

😀  You've done the dif­fi­cult part!  😀
The "bp" (or "bp.exe" or "bp3") con­sole is now working.

If you wish to recom­pile the con­sole, you can sim­ply point your brows­er to localhost/bolprocessor/compile.php. This will auto­mat­i­cal­ly run the "Makefile". The con­sole is auto­mat­i­cal­ly recom­piled each time you run an installer to patch an update of the Bol Processor.

  • The home page dis­plays the con­tents of the "bolprocessor" fold­er, in par­tic­u­lar a link to the "ctests" fold­er.
  • Follow the "ctests" link. You will find a list of avail­able exam­ple files clas­si­fied in dis­tinc­tive frames. In gen­er­al, the name of a gram­mar starts with "-gr", but it can also end with the exten­sion "bpgr". The name of a set of data starts with "-da", but it can also end with the exten­sion "bpda". Both file type con­ven­tions are sup­port­ed by BP2 and BP3. This became nec­es­sary a long time ago, when upgrad­ing BP2 from MacOS 9 to MacOS 10…
  • Click on "-gr.koto3" to open a gram­mar. This will auto­mat­i­cal­ly cre­ate a fold­er called "my_output" at the top of the "bolprocessor" fold­er if it doesn't already exist. Try cre­at­ing an out­put fold­er with a dif­fer­ent name and check its pres­ence at the top of "bolprocessor". The cur­rent name of the out­put fold­er is saved in "_settings.php" which is recalled each time the inter­face is used.
  • You can cre­ate sub­fold­ers of the cur­rent out­put fold­er. For exam­ple, if the cur­rent out­put is set to "my_output", cre­ate "my_output/todays_folder". The inter­face auto­mat­i­cal­ly replaces spaces with '_' as these may be unwant­ed on some systems.

👉 The Bol Processor inter­face can be dis­played in both dark and light modes. There is an icon in the top right cor­ner to switch between these modes.

Produce items

👉 In June 2024, the pre­fix­es and suf­fix­es of some files have been changed to make them more meaningful:

  • Prefix "-ho" and suf­fix "bpho" are replaced by "-al" and "bpal" (Alphabet files)
  • Prefix "-mi" and suf­fix "bpmi" are replaced by "-so" and "bpso" (Sound-object files)
    These changes are auto­mat­i­cal­ly man­aged by the inter­face and the con­sole. No man­u­al edit­ing is required.

In the fol­low­ing sec­tions, the out­put options are either MIDI file or CSOUND file. However, you can opt for real-time MIDI if your machine is set up for it: see details.

Page of the “-gr.koto3” gram­mar. Related files "-al.abc1", "-se.koto3" etc., have been iden­ti­fied and appear as but­tons at the bot­tom. The PANIC but­ton can­cels the per­for­mance if sev­er­al instances of BP3 are running.
Sound-object dis­play of an item pro­duced by gram­mar -gr.koto3
  • Open the "-gr.koto3" gram­mar and click PRODUCE ITEM(s). This will open a "BP con­sole" pop-up win­dow and launch the con­sole application.
  • By default, the out­put was set to MIDI files. A link is pro­vid­ed to down­load this MIDI file, and a javascript MIDI play­er is dis­played to lis­ten to its con­tents.
    👉  If your com­put­er is not con­nect­ed to the Internet, you won't hear any­thing on this player…
  • In the absence of "MIDI pro­gram" mes­sages, piano-like sounds are pro­duced which do not resem­ble the ren­der­ing of the -"gr.koto3" gram­mar on a prop­er MIDI device — here a Roland D-50 syn­the­sis­er, lis­ten to the real thing. Don't waste time try­ing to under­stand how this gram­mar works, we're just doing a tech­ni­cal test!
  • While the con­sole appli­ca­tion is run­ning, a detailed list of actions is record­ed, which you can dis­play in the pop-up window.
  • At the top of the win­dow, the com­mand line cre­at­ed to call the con­sole is dis­played in red. This is used by pro­gram­mers to check the console's response.
  • "Image" links will appear at the top of the BP con­sole win­dow. Click them to dis­play images in new win­dows. By default, this pic­ture shows the sound-objects a, b, c, etc. We will see a pianoroll lat­er as anoth­er option.
  • At the top of the "BP con­sole" there is a link to the "trace file" which shows the full process of deriva­tions for cre­at­ing items. It was cre­at­ed by adding the --trace-production option to the com­mand line to check the details. The Trace mode can be enabled or dis­abled in the "-se.koto3" set­tings page.
  • Check the "bolprocessor/my_ouput" fold­er. It should con­tain "koto3.mid" — the name for this MIDI file.
Part of the Bol Processor score of the "koto3" item
  • Return to the gram­mar and select "BP data file" as the out­put option, then click the SAVE but­ton. Now the name "koto3.bpda" will be cre­at­ed, but you can change it to any­thing you like, keep­ing the "bpda" exten­sion, or using the "-da" pre­fix instead.
  • Click the PRODUCE ITEM(s) but­ton again. A link to the data file in Bol Processor score nota­tion appears at the top (see image). The Trace file shows the same deriva­tions. The file "koto3.bpda" should also be vis­i­ble in the bolprocessor/my_ouput folder.
A pianoroll dis­play of the same item pro­duced by gram­mar -gr.koto3
  • In the set­tings for "-gr.koto3" it is pos­si­ble to change the for­mat of the graph­ics dis­play. Currently it is "Show objects". Let us try "Piano roll". This for­mat empha­sis­es the melod­ic and har­mon­ic struc­ture of the com­po­si­tion where­as the "objects" for­mat is explic­it about the size and posi­tion of the sound-objects.
  • Comparing the two images we can guess that "a" con­tains a stroke of the note A5 and "b" con­tains two strokes of the note B5. The <<f>> sound-object is an out-time object of zero dura­tion, con­tain­ing a sin­gle stroke of the note F2. The <<chik>> object is also out-time and con­tains a chord: {C3, F3, C4}.

The main mech­a­nism for cre­at­ing musi­cal items in this gram­mar is called sub­sti­tu­tions, indi­cat­ed as SUB on top of the 2nd sub­gram­mar. A sub­sti­tu­tion rule, when select­ed, is applied simul­ta­ne­ous­ly to each frag­ment of the work string. This is made clear by dis­play­ing the deriva­tions of the string. To do this, select the "Display pro­duc­tion" option on the Settings page. The deriva­tion steps will appear in the Trace window:

All deriva­tion steps of a piece pro­duced by "-gr.koto3"

Clicking "Trace pro­duc­tion" in the set­tings will give more details about the infer­ence process.

In the "Non-stop improvize" mode, every step of the sub­sti­tu­tion is used for the sound out­put. To do this, vari­ables are erased and only ter­mi­nal sym­bols are played. The effect is that the work string "grows" until it col­laps­es as a poly­phon­ic phrase with out-time objects <<f>> and <<chik>> play­ing the bass. The the­o­ret­i­cal mod­el behind this process is a (one-dimensional) cel­lu­lar automa­ton. For exam­ple, lis­ten to this per­for­mance of "-gr.koto3" with the orig­i­nal sounds:

An impro­vi­sa­tion of "-gr.koto3" pro­duced by BP2.9.8 and played on the "koto" instru­ment of a Roland D-50 synthesiser

If you set up the out­put for­mat to "Real-time MIDI", the impro­vi­sa­tion will play for­ev­er on the MIDI device con­nect­ed to your com­put­er. Clicking the STOP or PANIC but­ton will stop it. Read expla­na­tions on the page Real-time MIDI.

As this is only a tech­ni­cal review of how BP3 works, we won't dis­cuss the arcanes or rule-based com­po­si­tion in the Bol Processor. You should have a look at the tuto­ri­als and exper­i­ment with your own cre­ations to get famil­iar with it.

Create or import data

The demo items shown on this page are all locat­ed in the "ctests" fold­er, which is cre­at­ed when BP3 is installed and is refreshed dur­ing updates.

A but­ton CREATE FILES AND FOLDERS on the right dis­plays a form to this effect. Creating your own fold­ers (work­spaces) is rec­om­mend­ed, as files in the "ctests" fold­er are restored to their ini­tial sta­tus dur­ing updates.

When a file is cre­at­ed, the appro­pri­ate pre­fix or exten­sion is added, depend­ing on the type of file. For exam­ple, a gram­mar named "mygram­mar" will be saved as "-gr.mygrammar" or "mygrammar.bpgr", depend­ing on your choice.

Although files can be added to fold­ers using the Finder or File Manager, we rec­om­mend that you use the import fea­ture: but­ton UPLOAD FILES. This has two advantages:

  1. Only files rel­e­vant to the Bol Processor will be imported;
  2. File per­mis­sions will be set to the same per­mis­sions as the "bolprocessor" fold­er, i.e. "775". This point is par­tic­u­lar­ly impor­tant for Linux users.

A DOWNLOAD FILES but­ton is also avail­able to facil­i­tate the export of data to oth­er com­put­ers. However, if you need to change the loca­tion of data on the same com­put­er, it is more prac­ti­cal to use the MOVE command.

Import MusicXML scores

The pre­vi­ous sec­tion was an intro­duc­tion to the main fea­tures of Bol Processor: cre­at­ing music using a gram­mar, an alpha­bet and sound-object pro­to­types, which we will present in more detail below. This requires some knowl­edge of both music com­po­si­tion and the spe­cif­ic task envi­ron­ment of Bol Processor, as shown in the old BP2 ref­er­ence man­u­al, and more recent tuto­ri­als.

With BP3 it is pos­si­ble to take a sim­pler (but arguably less cre­ative) approach: import pre-composed music and reuse its frag­ments to cre­ate new musi­cal works. This process can be achieved by using stan­dard sheet music con­vert­ed into the MusicXML for­mat. MusicXML files are down­loaded from the web or export­ed by score edi­tors such as MuseScore. A descrip­tion of this method can be found on the Importing MusicXML scores page, along with a brief pre­sen­ta­tion of the MusicXML format.

Another tech­nique for import­ing music will be the real-time record­ing and inter­pre­ta­tion of MIDI events, which is still in devel­op­ment. Follow the progress of this approach on the Capture MIDI input page.

Below is an exam­ple of Beethoven's Fugue in B flat major import­ed from MusicXML and con­vert­ed as Bol Processor data — a set of poly­met­ric expres­sions, see tuto­r­i­al. It was played on the PianoTeq physical-model syn­the­sis­er using the MIDI file pro­duced by BP3. We inter­pret­ed it as a piano piece because we had no syn­the­sis­er that could do a good imi­ta­tion of the string instru­ments. This exam­ple illus­trates both the accu­ra­cy of the con­ver­sion and the lev­el of com­plex­i­ty han­dled by Bol Processor.

Beethoven's Fugue in B flat major — piano ver­sion played by the Bol Processor with PianoTeq

Using a very short quan­ti­za­tion (typ­i­cal­ly less than 10 mil­lisec­onds) on a large item can increase mem­o­ry usage to the point where the MAMP or XAMPP dri­ver hangs with­out warn­ing. For this rea­son, the quan­ti­za­tion is set by default to 10 ms.

Help messages

Displaying the help on reserved words in a grammar
  • Open the "-gr..Visser.Waves" gram­mar (designed by Harm Visser). At the bot­tom of the page, click the SHOW HELP ENTRIES but­ton. This will dis­play the gram­mar with links appear­ing on reserved words. For exam­ple, click on the link for "_transpose". A pop-up win­dow will open, dis­play­ing the help at the exact loca­tion of the reserved word.
  • At the bot­tom of the gram­mar file, there is one more more but­ton: EDIT ‘-se.Visser.Waves’. It has been cre­at­ed auto­mat­i­cal­ly because the "-se.Visser.Waves" dec­la­ra­tion was found at the top of the gram­mar. Click on it to edit or cre­ate the file.
  • You can now pro­duce the "Visser.Waves" item, lis­ten to its sound ren­der­ing and view the graph­ic out­put as "pianoroll" or "objects". Below is a ren­der­ing of this gram­mar with phys­i­cal mod­el instru­ments (read expla­na­tions):
“Waves” by Harm Visser (1998)
played on phys­i­cal mod­el syn­the­sis sax­o­phone and piano

Error messages

  • Now, let us do some­thing wrong to check for errors. In "-se.Visser.Waves" change the "Note con­ven­tion" from ‘0’ (English) to anoth­er option such as ‘1’ (Italian/Spanish/French). Click on SAVE PARAMETERS, go back to the "-gr..Visser.Waves" gram­mar, click on SAVE and PRODUCE ITEM(s). Now, nei­ther the "out­put file" nor the graph­ics will be vis­i­ble, because the con­sole can­not not cre­ate an item due to its mis­un­der­stand­ing of note names. For exam­ple, "B3" is inter­pret­ed as a vari­able and not as a sim­ple note. This is not accept­able in the first argu­ment of con­trol "_transpose()".
  • The note "B3" should have been replaced by its French equiv­a­lent "si2". The good news is that this can be done auto­mat­i­cal­ly in a gram­mar: select the con­ven­tion you want to use at the bot­tom of the page.
  • PRODUCE ITEM(s) some­times reports that errors have been detect­ed by the con­sole. They appear in the "error" trace file and a link is pro­vid­ed to dis­play it.
  • Try the same pro­ce­dure with "-gr.trial.mohanam". It is set for the Indian sargam note con­ven­tion = 2. After chang­ing the con­ven­tion to "French", the out­put file will only con­tain notes "re6" which have the same name in both con­ven­tions. Confusing note con­ven­tions is a com­mon source of error when design­ing music with the Bol Processor. For this rea­son, the cur­rent set­ting of this con­ven­tion is dis­played on the Grammar window.
  • Note that the ren­der­ing of "-gr.trial.mohanam" is bet­ter with the out­put selec­tion set to "CSOUND file". If Csound is installed and respond­ing on your machine, just try it!

Compile a grammar

  • So far, the gram­mars have been well formed, so click­ing on the COMPILE GRAMMAR but­ton would tell you that there is no error. Now go to the gram­mar 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 ter­mi­nal sym­bol. In fact, the sym­bols 'x' and 'a' have not been declared as sound-objects in a relat­ed "-al" alpha­bet file.
  • The COMPILE GRAMMAR pro­ce­dure renum­bers sub­gram­mars and rules. If you are still play­ing with "unknown-terminal.bpgr", replace "gram#1[1] S --> A B" with "S --> A B" and click on SAVE, then COMPILE GRAMMAR. The num­ber­ing "gram#1[1]" is restored. This takes account of insert­ing or delet­ing rules.
  • The gram­mar named "symbols.bpgr" com­piles suc­cess­ful­ly because its has an attached alpha­bet file con­tain­ing all its ter­mi­nal sym­bols. The alpha­bet file is called "symbols.bpal" and its dec­la­ra­tion in the gram­mar is "-al.:symbols.bpal". This unex­pect­ed syn­tax is a trick to recog­nise file types whose names do not begin with the stan­dard pre­fix. This is just to demon­strate how to man­age files, as this alpha­bet does not pro­duce any sound.

Change the start string

Grammar -gr.Mozart with all its vari­ables extract­ed at the bottom
  • Musical items are pro­duced by a Bol Processor gram­mar which, by default, uses the sym­bol 'S' as the start­ing string for deriva­tions. However, it is some­times inter­est­ing to try to derive from anoth­er vari­able with the same gram­mar, or to lis­ten to a poly­met­ric expres­sion. Both of these are eas­i­ly achieved in the gram­mar window.
  • An exam­ple of this is the use of "-gr.Mozart", where the vari­ables rep­re­sent musi­cal frag­ments that are assem­bled in the final ele­ment (read expla­na­tion). All vari­ables have been iden­ti­fied by the inter­face and dis­played as but­tons at the bot­tom of the page (see image on the right). Clicking on a but­ton pro­duces a deriva­tion of the variable.
  • Note how­ev­er that in this gram­mar deriva­tions from A1 to B8 won't be unique, because they are cho­sen ran­dom­ly. Conversely, deriva­tions from T1 to T176 are unique.
  • At the bot­tom of the page is a field for enter­ing a poly­met­ric expres­sion, for exam­ple {{2,sol3,si3}-,fa5 re5 si4}. This expres­sion can con­tain vari­ables. Click on PRODUCE ITEM to lis­ten to the result or to obtain the out­put file (depend­ing on the out­put for­mat selected).
  • For geeks: The "--start" and "-S" com­mand line options used in these pro­ce­dures are not yet implemented.

An exam­ple of using "-gr.Mozart" in Improvize mode is dis­cussed on the Mozart’s musi­cal dice game page. It will play for­ev­er if the real-time MIDI mode is active.

Play data

Open "-da.checkPoly":

Data file -da.checkPoly with auto­mat­i­cal­ly extract­ed items on the right side
  • The Data win­dow (see pic­ture) extracts lines that can be inter­pret­ed as musi­cal items in BP notation.
  • Each line is asso­ci­at­ed with two buttons:
  1. The PLAY but­ton sends a "play" com­mand to the con­sole after sav­ing the data line to a tem­po­rary file "…outdata.bpda" stored in the "temp_bolprocessor" fold­er. The con­sole is asked to process this data as a MIDI file or a Csound score.
  2. The EXPAND but­ton sends an "expand" com­mand to the con­sole after sav­ing the data line to a tem­po­rary file "…outdata.bpda" stored in the "temp_bolprocessor" fold­er. The result will be dis­played as text.

Sound-object prototypes

The gram­mar "-gr.koto3" uses an alpha­bet of sound-objects, name­ly "-al.abc1", which is relat­ed with a set of sound-object pro­to­types "-so.abc1". This file is locat­ed in the TONALITY resource fold­er, which has a link on the right hand side of each page.

The pianoroll dis­play of an item (above in the "Produce items" chap­ter) already indi­cat­ed that the sound-object "chik" con­tains a chord of 3 notes. We will now show you how to cre­ate or mod­i­fy these sound-objects.

The main page of a sound-object pro­to­type file
  • Open "-so.abc1" (or a copy of it). Below the hor­i­zon­tal line you should see a table with the names of its sound-object pro­to­types: a, a', b, chik, cycle1 etc.
  • For geeks: When you opened "-so.abc1", a tem­po­rary fold­er was cre­at­ed in the "temp_bolprocessor" fold­er. It has a com­pli­cat­ed name, for exam­ple "‑so.abc1_ec02bffaaee23e051fa2afee52e57520_temp" which con­tains the ses­sion iden­ti­fi­er. If you restart your com­put­er (or your brows­er), the ses­sion num­ber will be dif­fer­ent. This fold­er will there­fore become obso­lete and a new one will be cre­at­ed with the cur­rent ses­sion identifier.
  • The inter­face auto­mat­i­cal­ly deletes out­dat­ed fold­ers that are more than 24 hours old. Keep pages and tags open while you work on a par­tic­u­lar set of sound-object prototypes!
  • Despite the depen­den­cy on ses­sion iden­ti­fiers, no data is ever lost because "-so.abc1" is in autosave mode, auto­mat­i­cal­ly sav­ing every 30 sec­onds while work­ing on its sound-object pro­to­types. This fea­ture is indi­cat­ed by red mes­sages at the top of the page.
  • In the table you will be offered the option of delet­ing sound-objects. Try a cou­ple of DELETE but­tons. The good news is that a but­ton called RESTORE ALL DELETED OBJECTS will appear… Click it to undelete sound-objects and return to the ini­tial state.
  • You can also cre­ate or dupli­cate sound objects. If you do so, don't for­get to add their names to any "-al" (alpha­bet) file that declares a link with "-so.abc1". The inter­face ensures that you do not cre­ate mul­ti­ple objects with names that are cur­rent­ly in use or have recent­ly been deleted.
  • Now let us edit an object, for exam­ple "chik". Click on the but­ton with this name. (Old timers: the para­me­ters are the same as those shown in BP2.9.8.) You can mod­i­fy any para­me­ter and click on SAVE THIS PROTOTYPE. In most cas­es the con­sis­ten­cy of the val­ues is not checked. You will need a sound out­put to check the effect.
  • Editing an object involves set­ting the met­ric and topo­log­i­cal para­me­ters used by the time-setting algo­rithm. Read the descrip­tion of this constraint-solving algo­rithm that takes these para­me­ters into account.
  • PLAY sends a com­mand to the con­sole, which will lat­er be exe­cut­ed to play the sound-object or a com­bi­na­tion of sound-objects (arranged in a poly­met­ric struc­ture) entered on the form.

Modify MIDI codes in a sound-object prototype

Bottom of the page of a sound-object pro­to­type and its graph­ic display
  • At the bot­tom of each sound-object pro­to­type page, the EXPLICIT MIDI codes and TIME-STAMPED MIDI bytes links dis­play the lists of MIDI instruc­tions and time-stamped bytes that will be sent to the MIDI dri­ver. (The first num­ber is actu­al­ly the num­ber of bytes.)
  • 👉  Don't for­get that the “-so” file is saved in the back­ground every 30 sec­onds (autosave) while you are mod­i­fy­ing sound-object pro­to­types… To return to the orig­i­nal ver­sion, close the “-so” tag and restore the “-so” file from its copy!
  • The IMAGE link dis­plays an image of the sound-object pro­to­type along with indi­ca­tions of its topo­log­i­cal and met­ri­cal prop­er­ties, sim­i­lar to the BP2.9.8 interface.
  • The Play MIDI file link pro­duces a sound out­put based on MIDI events con­tained in the sound-object pro­to­type. Here, the "chik" sound-object pro­to­type plays a 250 ms chord on a stringed instru­ment. The inter­face uses the MIDI play­er to do this.
  • Note that there are five "Channel pres­sure" MIDI instruc­tions in this sound-object. These may have been picked up by play­ing on a pressure-sensitive key­board and their rel­e­vance is low since chan­nel pres­sure can be con­trolled at a high­er lev­el by per­for­mance para­me­ters. It is there­fore advis­able to click on SUPPRESS chan­nel pres­sure and check the effect on EXPLICIT MIDI codes and TIME-STAMPED MIDI bytes. If the change is not imme­di­ate­ly vis­i­ble (this depends on the brows­er), sim­ply reload the pop-up win­dow. Other "con­tin­u­ous" para­me­ters such as "vol­ume con­trol" can be sup­pressed in a sim­i­lar way.
  • APPEND AllNotesOff (all chan­nels) can be a use­ful option to ensure that this object turns off all pend­ing notes on the sound machine. It sends an instruc­tion to each of the 16 channels.
  • The MIDI con­tent of this object can be changed by load­ing a MIDI file. Click Choose File to select a MIDI file — for exam­ple, "test.mid" in the "ctests" fold­er — and then send to upload it. It is not finalised imme­di­ate­ly: you can exam­ine the EXPLICIT MIDI codes and TIME-STAMPED MIDI bytes of this file before sav­ing it to the sound-object pro­to­type. The exam­ple "test.mid" con­tains no less than 432 bytes because of the "Channel pres­sure" and "Parameter ctrl 7" mes­sages, which con­trol pres­sure and vol­ume. You can accept the import by click­ing SAVE or can­cel it by click­ing CANCEL. There is cur­rent­ly no "undo" func­tion in case the MIDI sequence has been replaced or delet­ed by mistake.
  • An impor­tant fea­ture is QUANTIZE NoteOns. We are deal­ing with "stri­at­ed sound-objects", which means that they are designed to be played at a cer­tain tem­po. The tem­po at which the MIDI con­tent of this object was cap­tured is gen­er­al­ly not the same as the tem­po at which it will be played, as the lat­ter depends on per­for­mance para­me­ters. The ref­er­ence tem­po is giv­en by Tref which in this case is 1000 ms for a metronome with 60 beats/mn. The MIDI con­tent uploaded by "test.mid" has a dura­tion of 3500 ms, i.e. 3.5 beats. This dura­tion can be set either in mil­lisec­onds or in beats. Regardless of the dura­tion, it is often con­ve­nient to locate NoteOn and NoteOff events to a pre­cise frac­tion 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 click­ing 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 quan­ti­za­tion to 1/50th of a beat and click QUANTIZE NoteOns. Now the tim­ings of these events have been changed to 800 ms and 820 ms respec­tive­ly, which are mul­ti­ples of 20 clos­est to the orig­i­nal timings.

Csound

Integration of Csound in the Bol Processor environment

Csound is a pro­gram for the design and trans­for­ma­tion of digi­tised sounds. Csound and Bol Processsor are sim­i­lar and com­ple­men­tary in their text-oriented, pro­gram­ming approach, with respec­tive empha­sis on sound and musi­cal struc­tures. Their inter­ac­tion is sum­marised in the BP2 envi­ron­ment image.

Note that Csound orches­tra files con­tain­ing sound pro­duc­tion algo­rithms can be edit­ed on this inter­face although it is not used by the ‘BP3’ con­sole — nor was it used by BP2.9.8. Its name is stored in the Csound orches­tra file. Arguments declared in the lat­ter should match those in the former.

A sim­ple orches­tra file called "0-default.orc" is pro­vid­ed in the "csound_resources" fold­er. It can be used for Csound scores cre­at­ed by Bol Processor when no Csound orches­tra file is specified.

Linux users: At the moment "0-default.orc" is not accept­ed by Csound in the Linux envi­ron­ment. We hope to solve this prob­lem 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 doc­u­ment­ed in chap­ter 17 of the BP2.9.8 instruc­tions man­u­al. Advanced fea­tures are doc­u­ment­ed in the arti­cles Csound check­up and Csound objects.

MacOS and Windows users can down­load a pre-built instal­la­tion of Csound from the down­load page. In Linux, sim­ply type the fol­low­ing instructions:

sudo apt update
sudo apt install csound

If Csound is installed and respond­ing, this sta­tus will be men­tioned on the top of each page. Otherwise the machine will rec­om­mend installing Csound, or chang­ing the path to Csound. This path is by default "/usr/local/bin" on MacOS, "usr/bin" on Linux. The BP3 inter­face will be able to fig­ure this out under Windows. If a new path is entered, the machine will try to call "csound --ver­sion" and will stop try­ing if once it is correct.

  • Open "-gr.Mozart"in the "ctests" fold­er.
  • Select the CSOUND file out­put option, which (by default) will cre­ates a file called "Mozart.sco" in the "my_output" fold­er. You can mod­i­fy these parameters.
  • If Csound is installed and respond­ing, this sta­tus will be men­tioned on the gram­mar. Otherwise the machine will rec­om­mend installing of Csound (from this site) or chang­ing 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 --ver­sion" and will stop try­ing if it succeeds.
  • Click PRODUCE ITEM(s). A pop-up win­dow will indi­cate that the process was suc­cess­ful. Click Read the out­put file to read the Csound score on anoth­er pop-up window.
Csound score pro­duced by gram­mar -gr.Mozart

In this exam­ple, the Csound score has been gen­er­at­ed by the Bol Processor as a sequence of "sim­ple notes" that appear at the end of each score line: "mi5", "do3", "do5", etc. To do this, the Bol Processor uses con­ver­sion pro­ce­dures to replace MIDI events with score lines.

If Csound is installed and respond­ing, it will auto­mat­i­cal­ly be called to pro­duce a sound file (in the WAV for­mat) which will appear on a HTML play­er (see image). Checking the sound out­put — or rather the valid­i­ty of the Csound score — is there­fore the mat­ter of a sin­gle click on PRODUCE ITEM(s).

On each score line, the "1" of "i1" is the val­ue of argu­ment "1", the left­most one. The next two argu­ments are assigned to the start date and dura­tion of the event, mea­sured in beats. Then comes argu­ment "4", which is assigned to the pitch in octave point pitch-class for­mat. Arguments "5" and "6" are for con­tin­u­ous vol­ume con­trol (in the range 0…127). Argument "7" can con­tain the ref­er­ence to a table for refin­ing these vari­a­tions. Arguments "8" and "9" are used for (con­tin­u­ous) pitch­bend con­trol, and argu­ment "10" may con­tain the ref­er­ence to a table for refin­ing pitch­bend variations.

Pianoroll dis­play of "-gr.Mozart"
Some vari­a­tions on "-gr.Mozart" ren­dered by Csound using the "0-default.orc" orches­tra and Zarlino's mean­tone tem­pera­ment to tune the instrument

A just-intonation ver­sion of Mozart's musi­cal dice game can be heard on the Just into­na­tion: a gen­er­al frame­work page.

Csound instrument files

Bol Processor can gen­er­ate a Csound out­put from scores stored in sound-objects or con­vert­ed from the MIDI stream. It also has a direct con­trol of the per­for­mance para­me­ters that the Csound orches­tra can inde­pen­dent­ly manip­u­late on the stan­dard MIDI con­trols ("pitch­bend", "mod­u­la­tion", "vol­ume", etc.). These para­me­ters are fur­ther inter­po­lat­ed by the Csound orches­tra, using the GEN07 (lin­ear inter­po­la­tion) or GEN08 (cubic spline) Csound gen­er­a­tors. All this is doc­u­ment­ed in chap­ter 17 of the BP2.9.8 instruc­tions man­u­al and set up in a "-cs" Csound instru­ment file as the one shown below.

  • Open "-cs.tryCsound" in the CSOUND resource fold­er. Note that this page is in autosave mode (see below): changes to Csound instru­ments are auto­mat­i­cal­ly saved at a rate of twice per minute.
  • This Csound instru­ment file is declared to be linked to a Csound orches­tra file called "tryCsound.orc". As this file is miss­ing from the "csound_resources" fold­er, a link to cre­ate the file is dis­played. Otherwise it would lead to edit­ing the file.
  • The text area for Tables needs no more expla­na­tion than giv­en in the BP2.9.8 instruc­tions man­u­al. These tables are not used to cre­ate Csound scores. They are only insert­ed at the begin­ning of the score.
  • Csound instru­ments can be asso­ci­at­ed to MIDI chan­nels. For exam­ple, here, MIDI mes­sages sent to chan­nel 2 will be con­vert­ed into instruc­tions sent to instru­ment 3 "Harpsichord".
  • At the bot­tom of the page is a list of the Csound instru­ments declared in this "-cs" file. These can be delet­ed, undelet­ed and dupli­cat­ed much in the same way as sound-object pro­to­types (see above). Clicking on the blue but­ton with the name of the instru­ment opens an edi­tor for that instrument.

Editing a Csound instrument

Page of a Csound instru­ment show­ing para­me­ters asso­ci­at­ed with MIDI controllers

The Csound instru­ment edi­tor is very sim­i­lar to that of the BP2.9.8's inter­face. A detailed descrip­tion can be found in chap­ter 17 of the BP2.9.8 instruc­tions man­u­al.

  • For exam­ple, let us exam­ine the instru­ment 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 para­me­ters dis­played on the "Harpsichord" page are those asso­ci­at­ed with MIDI con­trollers. These can be con­trolled con­tin­u­ous­ly if argu­ments are giv­en to mod­i­fy the start and end date val­ues in a con­tin­u­ous change. The argu­ment under "table" is the ref­er­ence of an option­al tab­u­lar function.
  • For the vol­ume para­me­ter, "0", "64" and "127" (MIDI val­ues) must to be con­vert­ed to "-24", "0" and "+24" (Csound val­ues) respec­tive­ly. The con­ver­sion is from a lin­ear to a log­a­rith­mic scale.
  • The start and end val­ues of the con­tin­u­ous­ly chang­ing vol­ume are set by argu­ments "7" and "8" respec­tive­ly. These are used by an algo­rithm that sets the vol­ume in the asso­ci­at­ed Csound orches­tra, based on the GEN07 (lin­ear inter­po­la­tion) or GEN08 (cubic spline) gen­er­a­tors.
  • Given three pairs of input/output val­ues, BP2 tries to define a qua­drat­ic map­ping between the input and the out­put. However, it may be dif­fi­cult to fit the three val­ues to a monot­o­ne qua­drat­ic func­tion… See the Csound argu­ment map­ping page for a detailed explanation.
  • At the bot­tom of the page you will find a list of Csound para­me­ters that have noth­ing to do with MIDI con­trollers. This is where Bol Processor Csound pro­duc­tion can dif­fer rad­i­cal­ly from MIDI!
  • This instru­ment has only one addi­tion­al para­me­ter called "blurb".
A spe­cif­ic "blurb" Csound parameter

These addi­tion­al para­me­ters can be cre­at­ed, delet­ed and undelet­ed in the same way as instru­ments (see above). The inter­face ensures that a new para­me­ter does not have the same name as an exist­ing one or a (tem­porar­i­ly) delet­ed parameter.

Let us look at the "blurb" para­me­ter (image on the left). Each para­me­ter has a default val­ue which is not nec­es­sar­i­ly zero. Values found on Csound scores can be com­bined addi­tive­ly (ADDval) or mul­ti­plica­tive­ly (MULTval). This "blurb" para­me­ter sends its start val­ue to argu­ment "9" of the algo­rithm in the Csound score, and its end val­ue (for con­tin­u­ous vari­a­tions) to argu­ment "10".

Using a Csound instrument in a grammar

This use is demon­strat­ed in a hypo­thet­i­cal music pro­duc­tion that is sim­ple enough to grasp the basic fea­tures of Csound in its Bol proces­sor imple­men­ta­tion. A com­plete demo based on a real musi­cal exam­ple can be found in the arti­cle Sarasvati vina. We have also doc­u­ment­ed all the fea­tures of the Csound imple­men­ta­tion in the arti­cles Csound check­up and Csound objects, show­ing exam­ples that can be checked with the eval­u­a­tion ver­sion of BP3.

The gram­mar "-gr.tryCsound" calls "-cs.tryCsound" and uses its instru­ment "3" (Harpsichord):

S --> _ins(3) _volumecont _volume(127) A4 G4 C5 A5 A4 G4 C5 A5 _volume(0)

The Csound score pro­duced by this gram­mar 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

Mapping of vol­ume in Csound instru­ment 3
  • Arguments "5" and "6" show the pitch­bend start and end val­ues as spec­i­fied by the instru­ment. These remain at the default val­ue of "8191.5" in the absence of pitch­bend instructions.
  • Arguments "7" and "8" dis­play the start and end val­ues of the vol­ume para­me­ter as expect­ed. The con­tin­u­ous range is from "+24" to "-24". This is the result of a map­ping between MIDI val­ues in the range [0…127] and the vol­ume para­me­ter of this instru­ment in the range [-24…+24] (see image). This map­ping is based on a log­a­rith­mic inter­po­la­tion using a qua­drat­ic regres­sion.
  • Csound will be able to achieve a con­tin­u­ous vari­a­tion of this vol­ume para­me­ter. To do this, it will invoke its own inter­po­la­tion scheme spec­i­fied as GEN07.
  • The _volumecont instruc­tion at the begin­ning of the sequence actu­al­ly means "con­ti­nu­ity". This resolves a dis­crep­an­cy between the MIDI and Csound rep­re­sen­ta­tion of "musi­cal events": in the MIDI envi­ron­ment, each event is asso­ci­at­ed with a time point where­as Csound scores deal with time seg­ments of spe­cif­ic dura­tions. It is up to the Csound orches­tra to decide how to mod­i­fy a para­me­ter from the on-set to the off-set of a segment.
  • Arguments "9" and "10" remain at the default val­ue "0.000" as the "blurb" para­me­ter is not used.
  • Arguments "11" and "12" remain at the default val­ue "0" of the unused mod­u­la­tion parameter.
  • Argument "13" remains at the default val­ue "0" of the unused panoram­ic parameter.

Csound scores cre­at­ed with "-gr.tryCsound" can­not be played with "BP2test.orc" because their argu­ments do not match. They require a dif­fer­ent orches­tra file called "tryCsound.orc" which we haven't been able to design yet…

A real musi­cal exam­ple using many fea­tures of the Csound inte­gra­tion in the Bol Processor is a phrase of Carnatic music composed/designed by Srikumar K. Subramanian in 1996. Read the descrip­tion of this exam­ple and lis­ten to its musi­cal ren­der­ing (in “just into­na­tion”) below:

"Pallavi" of song "Maayaatiita Svaruupini, Nannu brovave" in raga "maya­maalava­gaula"

Microtonality

In con­junc­tion with Csound, the Bol Processor BP3 is open to micro­tonal­i­ty and the pro­gram­ming of cus­tom scales. Read the pages Microtonality and Csound tun­ing in BP3. Applications to west­ern har­mo­ny and to the into­na­tion of ragas in Indian music are pre­sent­ed in the "Musicology" sec­tion.

Editing the Timebase

A time­base with 3 tracks set up in 4 beats

The Timebase is a device for cre­at­ing a rhyth­mic pat­tern to be super­im­posed on a piece of music pro­duced by the Bol Processor in real time via MIDI. Superimposition did not work well with BP2.9.8, but did work with old­er ver­sions con­nect­ed to MIDI via the OMS pack­age. It has not yet been imple­ment­ed in the 'BP3' con­sole. Here we show a time­base edi­tor which is a lit­tle more advanced than on BP2. We also try the over­lay by import­ing the Bold Processor pro­duc­tion as a MIDI file.

  • Create a new time base called "try.bptb" in the "ctests" fold­er and open it.
  • By default, the time base con­tains 3 tracks, 2 of which are set to a sim­ple 4-beat tem­po of mm = 60 beats/mn. The third track is emp­ty. Fill it with 4 strokes on key = 100 at a speed ratio of 2/1.
  • Now lis­ten to the com­bined 4 tracks (repeat­ed 3 times):
  • To under­stand the struc­ture you can mute some tracks.
  • Now click on "Choose File" to select a MIDI file, for exam­ple "acceleration.mid", and click on the "send" but­ton to import it.
A MIDI file "acceleration.mid" has been loaded in the timebase.
  • You can lis­ten to the import­ed file and to the com­bi­na­tion of this piece of music piece with the tick­ing pat­tern:
After load­ing "this_song.mid" a change of tem­po is suggested.
  • The over­lay sounds good because the piece was cre­at­ed at mm = 60 and it fits a rhyth­mic pat­tern of 4 beats. You can try chang­ing the metronome val­ue in the table above. You will receive a warn­ing if the metronome set­ting does not match the tem­po declared in the import­ed MIDI file.
  • For exam­ple, check this rhyth­mic cycle above "this_song.mid" in the "ctests" fold­er. You will be asked to set the metronome to 9 beats in 4 sec­onds, as declared in the MIDI file (pic­ture on the right). The tim­ing is per­fect:
  • This inter­face allows an unlim­it­ed num­ber of cycle tracks to be added. (The lim­it in BP2 was 3 tracks).
  • Playing with speed ratios cre­ates com­plex cycles that can be used to con­trol a drum machine if the appro­pri­ate chan­nels, key num­bers and veloc­i­ties are set up. Traditional rhyth­mic struc­tures can also be eas­i­ly pro­grammed. See exam­ples below:



A 15-beat rhyth­mic struc­ture called pan­chamas­vari tala in Hindustani music


Slowly drift­ing rhyth­mic patterns

Tick patterns as polymetric expressions

For experts!

The Timebase page on the PHP inter­face pro­vides a con­ve­nient way of super­im­pos­ing a pro­grammed tick pat­tern with a pro­duc­tion of Bol Processor pre­vi­ous­ly saved as a MIDI file. Another usage of time bases is the con­trol of a MIDI drum machine tak­ing part in the per­for­mance. It would be ben­e­fi­cial to design the drum machine track as part of the per­for­mance, as poly­met­ric expres­sions are able to han­dle super­po­si­tions. We will see that although it is often pos­si­ble, it remains a tedious task.

A poly­met­ric equiv­a­lent of the tick pat­tern 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 expres­sion is dis­played at the foot of the Timebase page.

Let us try to add this poly­met­ric expres­sion as vari­able "Drum" to the gram­mar "-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" pat­tern needs to be repeat­ed at the cor­rect tem­po instead of being extend­ed in dura­tion… The solu­tion will be to replace it with a cyclic sound object. Let us do it…

  • Create the fol­low­ing "-gr.drum" gram­mar and use it to cre­ate 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 pro­to­types file called "-so.drum" and define a sound-object called "cycle2".
Setting a sound-object to "cyclic"
  • Set it to "cyclic" (see pic­ture on the left).
  • Import "drum.mid" into sound-object protype "cycle".
  • Bad news: its dura­tion is 6000 ms instead of the expect­ed 4000 ms…
  • A look at EXPLICIT MIDI codes reveals that the last 2 sec­onds are a fade-out added by the Bol Processor to avoid an abrupt end.
  • Good news: the sound-object pro­to­type edi­tor allows you to crop the sound-object by trun­cat­ing its end. So let us crop it to 4000 ms.
  • Listen to the cropped "cycle2" sound-object and look at its image. Everything is per­fect. This object sounds iden­ti­cal to the sequence pre­vi­ous­ly pro­grammed on the Timebase page:

    Cropping sound-objects is done care­ful­ly. If nec­es­sary, the algo­rithm rewrites "NoteOff" mes­sages that have been delet­ed by the cropping.
  • Now the sound-object will be added to the gram­mar 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 cropped “cycle2” sound-object prototype
  • The "cycle2" sound-object and its asso­ci­at­ed "-so.drum" pro­to­type file must be declared in the fol­low­ing "-al.drum" alpha­bet file:
    -so.drum
    *
    cycle2
    The ‘*’ on the sec­ond line of the alpha­bet is an arbi­trary sym­bol declar­ing a homo­mor­phism — not used here.

     
  • This method is tedious, although it con­forms to the Bol Processor mod­el. Worse still, the equiv­a­lent poly­met­ric expres­sion can become extreme­ly com­plex if the speed ratios and/or beat cycles of all the tracks are not the same. In this case, it will not be dis­played at the bot­tom of the Timebase page.

Scripts

  • Bol Processor BP2.9.8 was ful­ly script­able in the sense that all com­mands launched from its menu could be cap­tured as sequences of script instruc­tions and repro­duced at will. This includ­ed open­ing fold­ers and files, mod­i­fy­ing text or doing some­thing with the selection.
  • A script was run every evening for about half an hour check­ing all pro­ce­dures and track­ing changes in the out­put data, in addi­tion to the sound check.
  • This lev­el of automa­tion will not be achieved in the cur­rent release of BP3 because of the decou­pling between the con­sole and its PHP inter­face. As a result, many BP2 script instruc­tions won't be valid in BP3. They will be ignored dur­ing 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!
Executing the -sc.tryMe script. A musi­cal sequence is played on MIDI and a Csound score is created.
  • In this script, instruc­tions "Show mes­sages OFF", "Show graph­ics ON", "Show mes­sages ON", "Activate win­dow Scrap" and "Wait for C4 chan­nel 1" are ignored. The "Play" instruc­tion will expand the poly­met­ric expres­sion - - {2,G4,E4,C4,- C5 - C5 {C5_-,A#4_ _}} and send it to MIDI in real time. The note con­ven­tion has been set to "English" to recog­nise "G4", "E4" etc. as sim­ple notes. The tem­po is set to stan­dard metronome = 60 beats per minute.
  • The "Type" instruc­tion dis­plays a line of text (which may con­tain HTML elements).
  • This script calls a sub­script called "-sc.trySubscript" in the same fold­er. Its con­tent is:
    Load project -gr.Ames
    Csound score ON
    Produce items
  • Here the machine will call the gram­mar "-gr.Ames" and set the out­put for­mat to "Csound score".
  • The exe­cu­tion of the script is dis­played in a pop-up win­dow (see image above), which lists (in red) the com­mands sent to the con­sole. The sec­ond com­mand pro­duces a Csound score, as expected.
  • The image also shows (light blue) but­tons for enter­ing script instruc­tions. No typ­ing is required. There's a but­ton called CHECK THIS SCRIPT which shows any errors, such as a file not found.
  • Below the script, the LIST ALL SCRIPT INSTRUCTIONS but­ton lists all the instruc­tions han­dled by BP2.9.8, indi­cat­ing which are obso­lete for BP3 and which are under development.

Setting max computation time

There are many ways to ensure that a gram­mar does not repeat the same process over and over again. These are part of the syn­tax in the Bol proces­sor. For exam­ple, a flag can be decre­ment­ed each time a rule is applied, and can inval­i­date all rules when it reach­es zero.

However, mis­takes can — and will — hap­pen. For exam­ple, con­sid­er the fol­low­ing gram­mar, 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 pro­duce this!]
gram#1[3] Y --> Y [This rule makes the gram­mar loop forever]

Setting max com­pu­ta­tion time

Running this gram­mar with­out any pre­cau­tions would use rule [3] for­ev­er. The result would be an emp­ty page until a break is called. Fortunately, a lim­it can be set in the pref­er­ences. For exam­ple 9 seconds.

Note that this gram­mar will stop, but it will still have cre­at­ed an item "C4 D4 E4" that can be dis­played and heard in MIDI or Csound.


Programming tricks (for developers)

This PHP inter­face has been designed in a con­ven­tion­al man­ner, pri­ori­tis­ing func­tion­al­i­ty over aes­thet­ics. The aim of this approach is to deliv­er a ful­ly oper­a­tional work envi­ron­ment which soft­ware design­ers will be able to "decode" as a base for the design of a stand­alone inter­face in var­i­ous sys­tems. However, a few spe­cial fea­tures have been imple­ment­ed which require expla­na­tions because of the painstak­ing search for doc­u­men­ta­tion that was involved.

It is impor­tant to note that pop-up win­dows should be vis­i­ble regard­less of the secu­ri­ty set­tings on the web brows­er. This is because they are cre­at­ed by a stan­dard window.open() call attached to the button.

A typ­i­cal link that acti­vates a pop-up win­dow 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 incor­po­rat­ed into a "sub­mit" button.

Autosave

The autosave fea­ture is designed to emu­late the auto­mat­ed updat­ing process of Google Docs pages or WordPress posts/pages. This func­tion­al­i­ty has been inte­grat­ed into the edit­ing of sound-object pro­to­types and Csound instruments.

Please be aware that if you are edit­ing pro­to­types belong­ing to "-so.abc1", all data is con­tained in this file. When work­ing on a par­tic­u­lar pro­to­type and click­ing the SAVE THIS PROTOTYPE but­ton, only the tem­po­rary file will be updat­ed — the path of which is shown at the top of the page. Once you have com­plet­ed your work, you are expect­ed to return to the "-so.abc1" file and click the SAVE ‘-so.abc1’ INCLUDING ALL CHANGES TO PROTOTYPES but­ton. Fortunately, the autosave, which is indi­cat­ed by a red line at the top of the page, does it for you in the backgraound.

The same fea­ture has been imple­ment­ed on the page deal­ing with Csound instru­ment files. For instance, the file "-cs.tryCsound" is auto­mat­i­cal­ly saved every 30 sec­onds while the user is work­ing on the edi­tion of instru­ments or addi­tion­al para­me­ters stored in this file.

In prac­tice, the autosave fea­ture is acti­vat­ed by a sim­ple call of JavaScript code in files "autosaveObjects.js" or "autosaveInstruments.js". The com­mand itself is myVar = setInterval(savePost, 30000), where "30000" rep­re­sents 30 sec­onds. A savePost() func­tion sends POSTs to file "autosaveObjects.php" or "autosaveInstruments.php".

GD graphics and Canvas

The GD graph­ics library is already includ­ed in cur­rent dis­tri­b­u­tions of PHP. No instal­la­tion is nec­es­sary if PHP has been com­piled with the "gd" option. If you have any doubts, please dis­play the "http://localhost/try/bolprocessor/php/phpinfo.php" page on your local server.

As an illus­tra­tion of the use of GD instruc­tions, please refer to page "prototype_image.php". It should be not­ed that all vari­ables used to build the image have been stored in a tem­po­rary file "image.php". This elim­i­nates the need to send hun­dreds of POST mes­sages to "prototype_image.php".

The con­sole has been enhanced with graph­ic pro­ce­dures imple­ment­ed in HTML Canvas, which is com­pli­ant with stan­dard HTML5 and does not require PHP. Each image is saved as a set of JavaScript instruc­tions, allow­ing its vec­torised con­struc­tion. This dif­fers from GD graph­ics, used in the PHP/Javascript inter­face, which pro­duces a PNG image. The Canvas script con­tains width and height val­ues used for clip­ping the image. These are read by the PHP script on "produce.php" for set­ting up dimen­sions of the pop-up win­dow that will con­tain the image.

👉 Don't hes­i­tate to ask ques­tions or send com­ments on the con­tact page!

Simple Csound orchestra

BP2 makes it pos­si­ble to use Csound orches­tra instruc­tions such as

kr tablei kndx, ifn

to make con­tin­u­ous para­me­ters vary accord­ing to a func­tion table (indexed 'ifn') that BP2 pro­duces and insert in the Csound score when necessary.

Below is a typ­i­cal instru­ment in which vol­ume and pitch­bend are con­trolled either by lin­ear inter­po­la­tion, using start and end val­ues, or by func­tion tables.

  • p5 and p6 are the start and end val­ues of volume
  • p8 and p9 are the start and end val­ues of pitchbend
  • p7 con­tains the index of the vol­ume func­tion table. If it is 0, then vol­ume varies by lin­ear interpolation.
  • p10 con­tains the index of the pitch­bend func­tion table. If it is 0, then pitch­bend varies by lin­ear interpolation.

Indexes of func­tion tables are assigned auto­mat­i­cal­ly by BP2, and each table is stored in the score as a 'f' state­ment just pre­ced­ing the 'i' state­ment relat­ing to an instru­ment using the table. BP2 takes care of not over­writ­ing tables that might be ref­ered by Csound instru­ment and enlist­ed in the Csound instru­ment descrip­tion file.

In any case, it starts index­ing 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 vol­umelin
ilen­vol = ftlen(ifvol)
kndxvol line 0, p3, ilen­vol
kvol tablei kndxvol, ifvol

vol­umelin: kcents line p8, p3, p9
if (ifcents <= 0) goto pitch­bendlin
ilen­cents = ftlen(ifcents)
kndx­cents line 0, p3, ilen­cents
kcents tablei kndx­cents, ifcents

pitch­bendlin: kpitch = cpspch(p4) * exp(kcents * ik2)
kamp = kvol * ik1

a1 oscil kamp, kpitch, 1
out a1
endin

This instru­ment is cur­rent­ly saved as "BP2test.orc".

Function tables might invoke either GEN07 (straight lines, p.62) or GEN08 (cubic spline, p.64).

If for instance the func­tion table index is 102, and GEN07 is used, the fol­low­ing instruc­tion will be insert­ed 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 pow­er of two equal to or greater than the actu­al num­ber of points 'max­points'.
'time' is exact­ly para­me­ter p2 of the fol­low­ing 'i' state­ment which makes actu­al use of the table.

Writing '-7' instead of '7' after 'size' inhibits rescaling.

GEN08 looks bet­ter in terms of smooth­ing the table, but it has the draw­back of set­ting first deriv­a­tives to 0 on the first and last points of the table. It also slows down Csound's sound file generation.

Timebase to polymetric

This algo­rithm is used by the PHP inter­face of Bol Processor ‘BP3’ under devel­op­ment. Read:

https://bolprocessor.org/misc/BP3/CheckList.html#timebase

It is imple­ment­ed in func­tion polymetric_expression() of file _basic_tasks.php (read below).

The func­tion cre­ates a poly­met­ric expres­sion equiv­a­lent to the rhyth­mic struc­ture pro­grammed on a Timebase page. We will take for instance a struc­ture which does not sound musi­cal because of its odd ratios:

The metronome speed is 208.571 beats per minute spec­i­fied as 73 beats in 21 sec­onds. Bol Processor always com­pute dura­tions as inte­ger ratios.

Let us define p_clock = 73 and q_clock = 21.

This struc­ture con­tains 2 tracks. The fol­low­ing algo­rithm deals with any num­ber of tracks.

  • Track 1 is a cycle of 5 beats [TickCycle] and its speed ratio is 3/2 [Ptick/Qtick]. It pro­duces note C8 (in English nota­tion) at veloc­i­ty 120 (a MIDI para­me­ter) and dura­tion 10 mil­lisec­onds.
  • Track 2 is a cycle of 3 beats [TickCycle] and its speed ratio is 4/5 [Ptick/Qtick]. It pro­duces note C7 at veloc­i­ty 120 and dura­tion 10 mil­lisec­onds.

Tick cycles are made explic­it by checked/unchecked box­es. Unchecked box­es denote silences ‘-’:

  • C8 - C8 - - for the first track
  • - C7 C7 for the sec­ond track

The rhyth­mic struc­ture will be rep­re­sent­ed as a poly­met­ric struc­ture with 2 fields {Track1, Track2} in which fields are forced to the same sym­bol­ic dura­tion by the poly­met­ric expan­sion algo­rithm (described here). We need to design its con­tent so that the expan­sion does not alter the tem­po declared on each track.

To this effect, con­sid­er the sym­bol­ic dura­tion of each track:

(q_clock / p_clock) * (TickCycle * Qtick) / Ptick

In order to match sym­bol­ic dura­tions, each track should be repeat­ed adequately:

repeat1 * (TickCycle1 * Qtick1) / Ptick1 = repeat2 * (TickCycle2 * Qtick2) / Ptick2 = …

Ratio (q_clock / p_clock) being iden­ti­cal for each track
was elim­i­nat­ed from this equation.

We need to find the set of small­est inte­gers repeat1, repeat2 etc. sat­is­fy­ing this equation.

To this effect, we sim­pli­fy ratio (TickCycle * Qtick) / Ptick using the great­est com­mon divi­sor (GCD):

x = GCD((TickCycle * Qtick), Ptick)
y = (TickCycle * Qtick) / x

Then we cal­cu­late the least com­mon mul­ti­ple (LCM) of all y values:

lcm = LCM(y1, y2, …)

This yields for each field:

repeat = (lcm * Ptick) / (TickCycle * Qtick)

In prac­tice,

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 struc­ture will there­fore look like:

{Track1 Track1 Track1 Track1 Track1 Track1 Track1 Track1 Track1, Track2 Track2 Track2 Track2 Track2 Track2 Track2 Track2}

We need to include per­for­mance para­me­ters set­ting the dura­tion of ticks. To this effect, we use the _staccato(s) para­me­ter in which s is the per­cent­age of cropped dura­tion at the end of the sound-event. Durations have been set to 10 mil­lisec­onds. We cal­cu­late the peri­od 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 spec­i­fy the tem­po of each field: 3/2 for the first one and 4/5 for the sec­ond one.

The result­ing poly­met­ric struc­ture 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 spec­i­fied because it will be infered by the poly­met­ric expan­sion algo­rithm. Therefore, the expres­sion dis­played at the bot­tom 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 fol­low­ing is the code in file _basic_tasks.php.

Table $mute con­tains flags indi­cat­ing whether a track is active or mute. Function key_to_note() returns the name of a note in English con­ven­tion giv­en its key num­ber (MIDI).