Install the Bol Processor (BP3)

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.

To use the Bol Processor BP3, you first need to install a local Apache HTML/PHP serv­er on your desk­top com­put­er. This serv­er runs a ded­i­cat­ed "web ser­vice" that is restrict­ed to your com­put­er. Only PHP (with its GD Graphics option) needs to be run­ning, as no data­base is used by the Bol Processor interface.

On MacOS and Windows we rec­om­mend MAMP or XAMPP, both of which are Apache servers with pre-installed fea­tures. On Linux, XAMPP is the only choice. The pro­ce­dure is giv­en on the pages that show the instal­la­tion of BP3 in the dif­fer­ent sys­tems, see below.

Once you've installed MAMP or XAMPP, installing Bol Processor is almost a one-click process.

MacOS users can quick­ly do the instal­la­tion using an installer called BolProcessorInstaller.pkg.
Follow instruc­tions on this page.

Windows users can quick­ly do the instal­la­tion using an installer called BolProcessorInstaller.exe.
Follow instruc­tions on this page.

Linux users can quick­ly do the instal­la­tion using ded­i­cat­ed scripts.
Follow instruc­tions on this page.

👉   Once you've installed the Bol Processor BP3, vis­it this page to famil­iarise your­self with how to use it.

The file structure of your installation

👉  Only for geeks!

Let us assume that your instal­la­tion was suc­cess­ful. It cre­at­ed a "htdocs/bolprocessor" fold­er.

The file struc­ture inside this fold­er is shown on the left. There is noth­ing relat­ed to Bol Processor out­side of this folder.

This image includes "bp" which is the com­piled ver­sion of the BP3 con­sole for MacOS. The same is called "bp.exe" in Windows and "bp3" in Linux.

The "temp_bolprocessor" and "my_output" fold­ers are auto­mat­i­cal­ly cre­at­ed when the inter­face is run. The con­tents of the "temp_bolprocessor" fold­er is cleared of all files/folders old­er than 24 hours.

Another fold­er called "midi_resources" is also cre­at­ed to store the set­tings for the real-time MIDI input and out­put ports.

Two addi­tion­al fold­ers, "csound_resources" and "tonality_resources", are cre­at­ed by the instal­la­tion and filled with data shared by all projects.

Running the inter­face will also cre­ate "BP2_help.html" in the "php" fold­er using "BP2_help.txt" as its source.

The "ctests" fold­er — which we call a work­space — con­tains sam­ple mate­r­i­al used to check the oper­a­tion of Bol Processor and to illus­trate some musi­co­log­i­cal issues. It is updat­ed by the instal­la­tion scripts each time you upgrade to a new version.

If you cre­ate new mate­r­i­al in the "ctests" work­space it won't be delet­ed by upgrades. However, if you mod­i­fy files that come from the dis­tri­b­u­tion, they will revert to the cur­rent dis­tri­b­u­tion ver­sion on each upgrade. It is there­fore a good idea to keep a copy of the "ctests" fold­er, as you are like­ly to mod­i­fy some of its data files while using the pro­gram. You may want to restore the orig­i­nal ver­sions lat­er. You can also cre­ate your own work­spaces (in tree struc­tures) using either the BP3 inter­face or your computer's file manager.

Produce all items

 
The core of the Bol Processor, in all its ver­sions, is an infer­ence engine capa­ble of gen­er­at­ing  'items'  — strings of vari­ables and ter­mi­nal sym­bols — treat­ed like the score of a musi­cal work. The infer­ence engine does this through the use of rules from a for­mal grammar.

In its ini­tial ver­sions (BP1 and BP2), the infer­ence engine was also able to analyse a score — for exam­ple, a sequence of drum beats — to check its valid­i­ty against the cur­rent gram­mar. This fea­ture is not (yet) imple­ment­ed in BP3.

A brief presentation of grammars

The gram­mars used by the Bol proces­sor are sim­i­lar to those described in for­mal lan­guage the­o­ry with a com­pre­hen­sive layout:

  • Rules can be context-sensitive, includ­ing with remote con­texts on the left and the right.
  • Rules can con­tain pat­terns of exact or pseu­do rep­e­ti­tions of frag­ments. Pseudo rep­e­ti­tions make use of trans­for­ma­tions (homo­mor­phisms) on the ter­mi­nal symbols.
  • A ter­mi­nal sym­bol rep­re­sents a time object which can be instan­ti­at­ed as a sim­ple note or a sound object, i.e. a sequence of sim­ple actions (MIDI mes­sages or Csound score lines).
  • The gram­mars are lay­ered — we call them 'trans­for­ma­tion­al'. The infer­ence engine first does every­thing it can with the first gram­mar, then jumps to the sec­ond, and so on.

The “produce all items” procedure

Grammars can pro­duce infi­nite strings of sym­bols if they con­tain recur­sive rules. This is of no prac­ti­cal use in the  Bol Processor, as it will even­tu­al­ly lead to a mem­o­ry over­flow. When recur­sive rules are used, con­trol is exer­cised by dynam­i­cal­ly decreas­ing rule weights or using  'flags'  to inval­i­date recursivity.

This means that the machine only gen­er­ates finite lan­guages with­in its tech­ni­cal lim­i­ta­tions. Theoretically, it should be able to enu­mer­ate all pro­duc­tions. This is the aim of the "pro­duce all items" pro­ce­dure. In addi­tion, iden­ti­cal items are not repeat­ed; to this effect, each new item is com­pared with the pre­ced­ing ones.

For geeks: This is done by stor­ing pro­duc­tions in a text file which is scanned for rep­e­ti­tions. The effi­cien­cy of this method depends on the tech­nol­o­gy of the work­ing disk. A SSD is high­ly recommended!

A simple example

Let us start with a very sim­ple gram­mar "-gr.tryAllItems0" which is made up of two lay­ers of subgrammars:

-se.tryAllItems0
-al.abc

RND
gram#1[1] S --> X X X
gram#1[2] S --> X X
-----
RND
gram#2[1] X --> a
gram#2[2] X --> b

The RND instruc­tion indi­cates that the rules in the gram­mar will be select­ed ran­dom­ly until no rule applies. The first sub­gram­mar pro­duces either "X X X" or "X X", then the machine jumps to the sec­ond sub­gram­mar to replace each 'X' with either 'a' or 'b'.

In the " Produce all items" mode, rules are called in sequence, and their deriva­tions are per­formed by pick­ing up the left­most occur­rence of the left argu­ment in the work string.

In the set­tings of " tryAllItems0 " (see pic­ture), "Produce all items" is checked. A para­me­ter " Max items pro­duced" can be used to lim­it the num­ber of productions.

The out­put is set to "BP data file" for this demo, although real-time MIDI, MIDI files and Csound score are pos­si­ble because 'a' and 'b' are defined as sound-objects. However, the sound out­put is com­plete­ly irrel­e­vant with this sim­ple grammar.

Any pro­duc­tion that still con­tains a vari­able is dis­card­ed. This nev­er hap­pens with the " tryAllItems0 " grammar.

The pro­duc­tion of this gram­mar is:

a a a
a a b
a b a
a b b
b a a
b a b
b b a
b b b
a a
a b
b a
b b

All the steps are shown on the self-explanatory trace:

S
X X X
a X X
a a X
a a a
a a b
a X a
a a a
a b a
a b X
a b a
a b b
a X b
a a b
a b b
X a X
a a X
a a a
a a b
X a a
a a a
b a a
b a X
b a a
b a b
X a b
a a b
b a b
X X a
a X a
a a a
a b a
X a a
a a a
b a a
b X a
b a a
b b a
X b a
a b a
b b a
b X X
b a X
b a a
b a b
b X a
b a a
b b a
b b X
b b a
b b b
b X b
b a b
b b b
X b X
a b X
a b a
a b b
X b a
a b a
b b a
b b X
b b a
b b b
X b b
a b b
b b b
X X b
a X b
a a b
a b b
X a b
a a b
b a b
b X b
b a b
b b b
X b b
a b b
b b b
X X
a X
a a
a b
X a
a a
b a
b X
b a
b b
X b
a b
b b

A pattern grammar

Let us mod­i­fy "-gr.tryAllItems0" as follows:

-se.tryAllItems0
-al.abc

RND
gram#1[1] S --> (= X) X (: X)
gram#1[2] S --> X X
-----
RND
gram#2[1] X --> a
gram#2[2] X --> b

The first rule gram#1[1] con­tains a pat­tern of exact rep­e­ti­tion: the third 'X' should remain iden­ti­cal to the first one. Keeping the pat­tern brack­ets, the pro­duc­tion would be:

(= a) a (: a)
(= a) b (: a)
(= b) a (: b)
(= b) b (: b)
a a
a b
b a
b b

This out­put shows that the third ter­mi­nal sym­bol is a copy of the first. These items can be played on MIDI or Csound, as the machine will remove struc­tur­al mark­ers. However, struc­tur­al mark­ers can also be delet­ed on the dis­play by plac­ing a " _destru" instruc­tion under the "RND" of the sec­ond sub­gram­mar. This yields

a a a
a b a
b a b
b b b
a a
a b
b a
b b

To become more famil­iar with pat­terns (includ­ing embed­ded forms), try "-gr.tryDESTRU" in the "ctests" fold­er.

A more complex example

Consider the fol­low­ing gram­mar "-gr.tryAllItems1" in the "ctests" fold­er:

RND
gram#1[1] S --> X Y /Flag = 2/ /Choice = 1/
-----
RND
gram#2[1] /Choice = 1/ /Flag - 1/ X --> C1 X
gram#2[2] /Choice = 2/ X --> C2 X _repeat(1)
gram#2[3] <100-50> /Choice = 3/ X --> C3 X
gram#2[4] X --> C4 _goto(3,1)
gram#2[5] Y --> D3
Gram#2[6] X --> T
-----
RND
gram#3[1] T --> C5 _failed(3,2)
gram#3[2] Y --> D6

This gram­mar uses a flag 'Choice' to select which of the rules 1, 2 or 3 will be used in sub­gram­mar #2. Just change its val­ue to try a dif­fer­ent option, as they pro­duce the same 'lan­guage'. Terminals are sim­ple notes in the English con­ven­tion: C1, C2, etc. 

The flag 'Flag' is set to 2 by the first rule. If 'Choice' is equal to 1, rule gram#2[1] is applied, and it can only be applied twice due to the decre­men­ta­tion. This ensures that the lan­guage will be finite.

Rule gram#2[4] con­tains a "_goto(3,1)" instruc­tion. Whenever it is fired, the infer­ence engine will leave sub­gram­mar #2 and jump to rule #1 of sub­gram­mar #3. If the rule is a can­di­date, it will be used and the engine will con­tin­ue to look for can­di­date rules in sub­gram­mar #3. If the gram#3[1] rule is not applic­a­ble, the engine will jump to rule #2 of sub­gram­mar #3, as instruct­ed by "_failed(3,2)". In fact, these _goto() and _failed() instruc­tion have no effect on the final pro­duc­tion, but they do mod­i­fy the trace.

If 'Choice' is equal to 2, the " _repeat(1)" instruc­tion will force the gram#2[2] rule to be applied two times. If 'Choice' is equal to 3, the rule gram#2[3] will be applied twice because it has an ini­tial weight of 100 which is reduced by 50 after each appli­ca­tion. When it reach­es zero, the rule is neutralised.

For all val­ues of 'Choice' the pro­duc­tion is:

C1 C1 C4 D6
C1 C1 C4 D3
C1 C1 C5 D3
C1 C1 C5 D6
C1 C4 D6
C1 C4 D3
C1 C5 D3
C1 C5 D6
C4 D6
C4 D3
C5 D3
C5 D6

Since you insist, here is the out­put played in real time on a Pianoteq instrument!

We hope for more con­vinc­ing musi­cal examples. 😀

Capture MIDI input

Work in progress

Capturing MIDI input opens the way to "learn­ing" from the per­for­mance of a musi­cian or anoth­er MIDI device. The first step is to use the cap­tured incom­ing NoteOn/Noteoff events, and option­al­ly ControlChange and PitchBend events, to build a poly­met­ric struc­ture that repro­duces the stream.

The dif­fi­cul­ty of this task lies in the design of the most sig­nif­i­cant poly­met­ric struc­ture — for which AI tools may prove help­ful in the future. Proper time quan­ti­za­tion is also need­ed to avoid over­ly com­pli­cat­ed results.

We've made it pos­si­ble to cap­ture MIDI events while oth­er events are play­ing. For exam­ple, the out­put stream of events can pro­vide a frame­work for the tim­ing of the com­pos­ite per­for­mance. Consider, for instance, the tem­po set by a bass play­er in a jazz improvisation.

The _capture() command

A sin­gle com­mand is used to enable/disable a cap­ture: _capture(x), where x (in the range 1…127) is an iden­ti­fi­er of the 'source'. This para­me­ter will be used lat­er to han­dle dif­fer­ent parts of the stream in dif­fer­ent ways.

_capture(0) is the default set­ting: input events are not recorded.

The cap­tured events and the events per­formed on them are stored in a 'cap­ture' file in the temp_bolprocessor fold­er. This file will lat­er be processed by the interface.

(Examples are found in the project "-da.tryCapture".

The first step to use _capture() is to set up the MIDI input and more specif­i­cal­ly its fil­ter. It should at least treat NoteOn and NoteOff events. ControlChange and PitchBend mes­sages can also be captured.

If the pass option is set (see pic­ture), incom­ing events will also be heard on the out­put MIDI device. This is use­ful if the input device is a silent device.

It is pos­si­ble to cre­ate sev­er­al inputs con­nect­ed to sev­er­al sources of MIDI events, each one with its own fil­ter set­tings. Read the Real-time MIDI page for more explanations.

Another impor­tant detail is the quan­ti­za­tion set­ting. If we want to con­struct poly­met­ric struc­tures, it may be impor­tant to set the data to the near­est mul­ti­ple of a fixed dura­tion, typ­i­cal­ly 100 mil­lisec­onds. This can be set in the set­tings file "-se.tryCapture".

Simple example

Let us take a look at a very sim­ple exam­ple of a cap­ture on top of a performance.

C4 _D4 _capture(104) E4 F4 G4 _capture(0) A4 B4

The machine will play the sequence of notes C4 D4 E4 F4 G4 A4 B4. It will lis­ten to the input while play­ing E4 F4 G4. It will record both the sequence E4 F4 G4 and the notes received from a source tagged "104".

Suppose that the sequence G3 F3 D3 was played on top of E4 F4 G4. The cap­ture file might look like this:

Note that all dates are approx­i­mat­ed to mul­ti­ples of 100 mil­lisec­onds. For exam­ple, the NoteOff of input note G3 falls exact­ly on the date 3000 ms, which is the NoteOff of the played note E4.

The record­ing of input and played notes starts at note E4 and ends at note G4, as spec­i­fied by _capture(104) and _capture(0).

An accept­able approx­i­ma­tion of this sequence would be the poly­met­ric expression:

C4 D4 {E4 F4 G4, - - G3 - F3 - D3 - -} A4 B4

Approximations will be cre­at­ed from the cap­ture files at a lat­er stage.

Combining 'wait' instructions

Try:

_script(wait for C3 channel 1) C4 D4 _capture(104) E4 F4 G4 _script(wait for D3 channel 1) _capture(0) A4 B4

The record­ing takes place dur­ing the exe­cu­tion of E4 F4 G4 and dur­ing the unlim­it­ed wait­ing time for note D3. This allows events to be record­ed even when no events are being played.

The C3 and D3 notes have been used for ease of access on a sim­ple key­board. The dates in the cap­ture file are not incre­ment­ed by the wait times.

The fol­low­ing is a set­up for record­ing an unlim­it­ed sequence of events while no event is being played. Note C0 will not be heard as it has a veloc­i­ty of zero. Recording ends when the STOP or PANIC but­ton is clicked.

_capture(65) _vel(0) C0 _script(wait forever) C0

Interpreting the record­ed input as a poly­met­ric struc­ture will be made more com­plex by the fact that no rhyth­mic ref­er­ence has been provided.

Microtonal corrections

In the fol­low­ing exam­ple, both input and out­put receive micro­ton­al cor­rec­tions of the just into­na­tion scale.

_scale(just intonation,0) C4 D4 _capture(104) E4 F4 G4 A4 _capture(0) B4

Below is a cap­ture file obtained by enter­ing G3 F3 D3 over the sequence E4 F4 G4 A4.

The out­put events (source 0) are played on MIDI chan­nel 2, and the input events (source 104) on MIDI chan­nel 1. More chan­nels will be used if out­put notes have an over­lap — see the page MIDI micro­tonal­i­ty. In this way, pitch­bend com­mands and the notes they address are dis­trib­uted across dif­fer­ent channels.

Added pitchbend

In the fol­low­ing exam­ple, a pitch­bend cor­rec­tion of +100 cents is applied to the entire piece. It does mod­i­fy out­put events, but it has no effect on input events.

_pitchrange(200) _pitchbend(+100) _scale(just intonation,0) C4 D4 _capture(104) E4 F4 G4 A4 _capture(0) B4

Again, after play­ing G3 F3 D3 over the sequence E4 F4 G4 A4:

Pitchbend cor­rec­tions applied to the input (source 104) are only those induced by the micro­ton­al scale. Pitchbend cor­rec­tions applied to the out­put (source 0) are the com­bi­na­tion of micro­ton­al adjust­ments (see pre­vi­ous exam­ple) and the +100 cents of the pitch­bend command.

Capturing and recording more events

The _capture() com­mand allows you to cap­ture most types of MIDI events: all 3-byte types, and the 2-byte type Channel pres­sure (also called Aftertouch).

Below is a (com­plete­ly unmu­si­cal) exam­ple of cap­tur­ing dif­fer­ent messages.

The cap­ture will take place in a project called "-da.tryReceive":

_script(wait for C0 chan­nel 1) _capture(111) D4 _pitchrange(200) _pitchbend(+50) _press(35) _mod(42) D4 _script(wait forever)

The record­ing will have a "111" mark­er to indi­cate which events have been received. Only two notes D4 are played dur­ing the record­ing, the sec­ond one is raised by 50 cents and has a chan­nel pres­sure of 35 and a mod­u­la­tion of 42.

After play­ing back the two D4s, the machine will wait until the STOP but­ton is clicked. This gives the oth­er machine time to send its own data and have it recorded.

The sec­ond machine is anoth­er instance of BP3 — actu­al­ly anoth­er tag on the interface's brows­er with the "-da.trySend" project:

{_vel(0) <<C0>>} G3 _press(69) _mod(5430) D3 _pitchrange(200) _pitchbend(+100) E3

This project will start by send­ing "{_vel(0) <<C0>>} " which is the note C0 with veloc­i­ty 0 and dura­tion null (an out-time object). This will trig­ger "-da.tryReceive" which wait­ed for C0. The curly brack­ets {} restrict veloc­i­ty 0 to the note C0. Outside of this expres­sion, the veloc­i­ties are set to their default val­ue (64). In this data, chan­nel pres­sure, mod­u­la­tion and a pitch­bend cor­rec­tion of +100 cents are applied to the final note E3.

The result­ing sound is ter­ri­ble, you've been warned:

Performed and cap­tured events. Forget the way it sounds and look at the file below!

However, the 'cap­ture' file shows that all events have been cor­rect­ly recorded:

Captured events (from "-da.trySend") are coloured red. They have been auto­mat­i­cal­ly assigned to MIDI chan­nel 2, so that cor­rec­tions will not be mixed between per­for­mance and reception.

The pitch­bend cor­rec­tions are shown in the "cents cor­rec­tion" col­umn, each applied to its own channel.

The chan­nel pres­sure cor­rec­tions (coloured blue) dis­play the expect­ed val­ues. The mod­u­la­tion cor­rec­tions (in the range 0 to 16383) are divid­ed into two 3-byte mes­sages, the first car­ry­ing the MSB and the sec­ond the LSB.

There is a time mis­match of approx­i­mate­ly 150 mil­lisec­onds between the expect­ed and actu­al dates, but the dura­tions of the notes are accu­rate. The mis­match is caused by the delay in the trans­mis­sion of events over the vir­tu­al port. The data looks bet­ter if the quan­ti­za­tion in the "-da.tryReceive" project is set to 100 ms instead of 10 ms. However, this is of minor impor­tance, as a "nor­mal­i­sa­tion" will take place dur­ing the (forth­com­ing) analy­sis of the "cap­ture" file.

For geeks: The last col­umn indi­cates where events have been record­ed in the pro­ce­dure sendMIDIEvent(), file MIDIdriver.c.

Capture events without the need to perform

The set­up of the "-da.tryReceive" project should be for example:

_capture(99) _vel(0) C4 _script(wait forever)

Note C4 is not heard due to its veloc­i­ty 0. It is fol­lowed with all MIDI events received by the input until the STOP but­ton is clicked. This makes it pos­si­ble to record an entire per­for­mance. The pro­ce­dure can be checked with items pro­duced and per­formed by the Bol Processor.

Note that the inclu­sion of pitch­bend mes­sages makes it pos­si­ble to record music played on micro­ton­al scales and (hope­ful­ly) iden­ti­fy the clos­est tun­ings suit­able for repro­duc­tion of the piece of music.

For exam­ple, try to cap­ture this phrase from Oscar Peterson's Watch What Happens:

_tempo(2) {{4, {{2, F5 Bb4 C5 C4} {3/2, D4} {1/2, Eb4 Db4 D4}, {F4, C5} {1/2, F4, G4} {1/2, F3, G3} {2, Gb3}}}, {4, {C4 {1, Bb3 Bb2} {2, A2}, {D3, A3} {1, Eb3 Eb2} {2, D2}}}}

This phrase was import­ed from a MusicXML score (read page)

The result is com­plex, but it's going to lend itself to being analysed automatically:

0 F5 NoteOn 77 64
0 F4 NoteOn 65 64
0 C5 NoteOn 72 64
0 C4 NoteOn 60 64
0 D3 NoteOn 50 64
0 A3 NoteOn 57 64
230 F5 NoteOff 77 0
230 Bb4 NoteOn 70 64
470 Bb4 NoteOff 70 0
470 C5 NoteOff 72 0
470 C5 NoteOn 72 64
470 F4 NoteOff 65 0
470 C5 NoteOff 72 0
470 F4 NoteOn 65 64
470 G4 NoteOn 67 64
470 C4 NoteOff 60 0
470 Bb3 NoteOn 58 64
470 D3 NoteOff 50 0
470 A3 NoteOff 57 0
470 Eb3 NoteOn 51 64
710 C5 NoteOff 72 0
710 C4 NoteOn 60 64
710 F4 NoteOff 65 0
710 G4 NoteOff 67 0
710 F3 NoteOn 53 64
710 G3 NoteOn 55 64
710 Bb3 NoteOff 58 0
710 Bb2 NoteOn 46 64
710 Eb3 NoteOff 51 0
710 Eb2 NoteOn 39 64
960 C4 NoteOff 60 0
960 D4 NoteOn 62 64
960 F3 NoteOff 53 0
960 G3 NoteOff 55 0
960 F#3 NoteOn 54 64
960 Bb2 NoteOff 46 0
960 A2 NoteOn 45 64
960 Eb2 NoteOff 39 0
960 D2 NoteOn 38 64
1730 D4 NoteOff 62 0
1730 Eb4 NoteOn 63 64
1830 Eb4 NoteOff 63 0
1830 C#4 NoteOn 61 64
1880 C#4 NoteOff 61 0
1880 D4 NoteOn 62 64
1960 D4 NoteOff 62 0
1960 F#3 NoteOff 54 0
1960 A2 NoteOff 45 0
1960 D2 NoteOff 38 0

Only sig­nif­i­cant columns are dis­played. The ori­gin of dates is set to the first NoteOn or NoteOff received.

The next task on our agen­da will be to analyse the 'cap­ture' file and recon­struct the orig­i­nal poly­met­ric expres­sion (shown above) or an equiv­a­lent ver­sion. Then we can con­sid­er mov­ing on to gram­mars, sim­i­lar to what we've done with import­ed MusicXML scores (read page).

Donations

From the out­set, I have viewed the Bol Processor project as a research endeav­or rather than a straight­for­ward soft­ware design project. Its focus is on "com­pu­ta­tion­al musi­col­o­gy," which involves using com­pu­ta­tion­al mod­els to explore musi­col­o­gy across and beyond cul­tur­al boundaries.

This project rep­re­sents a long-term com­mit­ment to devel­op­ing music cre­ation soft­ware that address­es musi­co­log­i­cal chal­lenges, rather than sim­ply cre­at­ing tools for recom­bin­ing pre-composed music or sound frag­ments. Our cur­rent goal is to inte­grate this approach with high-quality music and sound edi­tors used by com­posers and sound designers.

The Bol Processor mod­el could eas­i­ly be extend­ed to oth­er activ­i­ties such as sched­ul­ing, siz­ing and pre­cise tim­ing of video clips, robot com­mands and so on. These exten­sions are high­ly desirable.

The research nature of this project neces­si­tates an open-access eth­ic. As such, the Bol Processor, includ­ing its instal­la­tion and source files, will remain freely acces­si­ble. Software devel­op­ers are encour­aged to reuse the source code to cre­ate vari­ants or updat­ed ver­sions of BP3.

However, there is a prac­ti­cal rea­son why I have cho­sen not to decline per­son­al dona­tions: I am increas­ing­ly incur­ring costs for var­i­ous tools required for soft­ware devel­op­ment. These include host­ing fees, the remu­ner­a­tion of "vir­tu­al" assis­tants (AI tools), and, when nec­es­sary, human experts.

For this rea­son, if you are so inclined, you can make a dona­tion using the PayPal link below. Any funds not used for project relat­ed activ­i­ties will be trans­ferred to charities.

Bernard Bel

https://www.paypal.com/donate/?hosted_button_id=WQSG23AMN7BLG

MIDI microtonality

 

This page is a demo of the han­dling of micro­tonal­i­ty in the real-time MIDI and MIDI file envi­ron­ments of the Bol Processor BP3  (ver­sion 3.0.7 and high­er). Install BP3 by fol­low­ing the instruc­tions for  MacOSLinux and Windows on the page Bol Processor 'BP3' and its PHP inter­face.

All exam­ples here are from the "-da.tryMPE" project, which is part of the ctests fold­er (down­load here). The syn­tac­tic mod­el for micro­tonal­i­ty is explained here. For details on work­ing with real-time MIDI, read the Real-time MIDI page. Some Csound scores are shown for the sake of clar­i­ty, as the han­dling of micro­tonal­i­ty in the Csound envi­ron­ment of BP3 pro­duces the same results as MIDI.

👉 The fol­low­ing is a com­pre­hen­sive but detailed pre­sen­ta­tion of all aspects of the use of micro­tonal­i­ty in BP3. It is not nec­es­sary to under­stand the details when start­ing with micro­tonal­i­ty! The expla­na­tion is only intend­ed to assist musi­cians who wish to cre­ate new mate­r­i­al by com­bin­ing sev­er­al tun­ing schemes in the same musi­cal work. To try the micro­ton­al process on real musi­cal works, lis­ten for instance to the com­par­i­son of tem­pera­ments, or play François Couperin's Les Ombres Errantes (in the ctests/Imported_MusicXML folder) on a MIDI instru­ment using its opti­mal tun­ing scheme rameau_en_sib:

Couperin's Les Ombres Errantes, Csound ren­der­ing with scale rameau_en_sibImage

For geeks: Microtonality in real-time MIDI and MIDI files mim­ics the MIDI Polyphonic Expression (MPE) method of mod­i­fy­ing pitch­bend val­ues on notes dis­trib­uted on sep­a­rate chan­nels (up to 15 simul­ta­ne­ous notes). However, it works on devices that are not MPE-compliant.

Check pitchbender sensitivity

Make sure that your out­put MIDI device is sen­si­tive to pitch­bend mes­sages. Try the following:

_chan(2) C4 _pitchrange(200) _pitchbend(+100) E4 _pitchbend(+200) C4 _pitchbend(-200) C4 _pitchbend(0) C4

You should hear C4 F4 D4 Bb3 C4 instead of C4 C4 C4 C4 C4. This shows that the MIDI device accepts pitch­bend mes­sages and that its range is ± 200 cents, or ± 2 semi­tones. This is the range we use for microtonality.

For geeks: The actu­al val­ues are in the range 0 - 16383, but thanks to the "_pitchrange(200)" instruc­tion, the actu­al cent val­ues can be used.

When using micro­ton­al scales, this pitch range of ± 200 cents is set auto­mat­i­cal­ly by send­ing an appro­pri­ate mes­sage to the 16 MIDI channels.

The "_pitchbend()" com­mands will be tak­en care of, and their val­ues will be added to the pitch­bend com­mands that adjust the pitch­es to the micro­ton­al scale. If this com­bi­na­tion exceeds the range of ± 200 cents, an error mes­sage will be displayed.

MIDI channels

In the pre­vi­ous exam­ple, MIDI events (notes and pitch­ben­der com­mands) were sent on chan­nel 2. This is to ensure that your MIDI out­put device is receiv­ing and mix­ing all chan­nels, tech­ni­cal­ly MIDI mode 4 (omni off, mono).

It was pos­si­ble to send mes­sages on chan­nel 2 because the Microtonality mode was not set. This mode is set on as a "_scale()" com­mand is found. In this case, the "_chan()" com­mands are ignored, as all chan­nel assign­ments are made by the micro­tonal­i­ty process.

Diapason tuning

Since note fre­quen­cies are dis­played when the Trace micro­tonal­i­ty mode is acti­vat­ed in "-se.tryMPE", the tun­ing of the dia­pa­son (note A4/la 3 on a con­ven­tion­al key­board) is important.

By default (in Bol Processor set­tings and on MIDI devices) this set­ting is 440 Hz. If you change the val­ue in the set­tings, the note fre­quen­cies will change accord­ing­ly. The BP3 will send a mes­sage to the MIDI device to tune the dia­pa­son, but many devices do not under­stand this com­mand. (This is the case with PianoTeq Stage.) In this case, tune the device independently.

Microtonal scales

On top of project "-da.tryMPE" you can see the line:

-to.tryMPE

This refers to a tonal­i­ty resource stored in the "tonality_resources" fold­er. This resource has been down­loaded to your com­put­er when run­ning an installer (or a Linux script) as explained on pages Quick install MacOS, Quick install Windows, or Quick install Linux.

At the bot­tom of the project page there is a but­ton called EDIT '-to.tryMPE'. This will take you to this resource:

Here are the scales stored in "-to.tryMPE":

Most of these are "exot­ic" in the sense that they won't pro­duce inter­est­ing music. They have been designed to high­light tech­ni­cal features:

  • The gra­ma scale is an inter­pre­ta­tion of the Indian sys­tem that divides the octave into "twenty-two shrutis", see The two-vina exper­i­ment for details. We use one par­tic­u­lar (prob­a­bly incor­rect) solu­tion, which sets the pra­mana shru­ti at 21 cents. Technically speak­ing — the rea­son for this choice — this scale has 23 grades which count as 22 notes. Click the EDIT but­ton to see its structure.
  • The just into­na­tion scale is a stan­dard scale with 12 grades and 12 notes, prob­a­bly suit­able for use in some har­mon­ic con­texts. Click the EDIT but­ton and dis­play the image to see that it has a wolf's fifth between D and A.
  • The meantone_try scale is pure­ly tech­ni­cal. It has 12 grades and 7 notes. The grades are approx­i­mate­ly semi­tones and the notes sug­gest the white keys of a piano key­board. Another fea­ture is that it has an extend­ed octave of 1219 cents instead of 1200. Notes are labelled by key numbers.
  • The meantone_try2 scale is iden­ti­cal to meantone_try except that its base key is #64 instead of #60. This may be nec­es­sary to use spe­cif­ic key num­bers of the key­board of the MIDI out­put device.
  • The piano scale has 12 grades and 12 notes. It is an equal-tempered scale with an extend­ed octave of 1204 cents. An inter­est­ing point is that all its fifths are per­fect (see pic­ture).
  • The zest24-supergoya17plus3_Db scale was cre­at­ed by import­ing its SCALA def­i­n­i­tion (from this archive). It cov­ers a con­ven­tion­al octave (ratio 2/1) with 20 grades, but the SCALA file did not con­tain any note names. So, 12 notes were cho­sen at ran­dom, with key num­bers as their names.
  • The Bohlen-Pierce scale which has a "tri­tave" inter­val of ratio 3/1 instead of 2/1 in the octave. The tri­tave is divid­ed into 13 grades and 13 notes (see Wikipedia and pic­ture).

These scales cov­er all the cas­es nec­es­sary to check the tech­ni­cal oper­a­tion of micro­tonal­i­ty han­dling in real-time MIDI, MIDI files, and Csound envi­ron­ments. Don't expect to hear inter­est­ing music in the fol­low­ing exam­ples! Only make sure that Trace micro­tonal­i­ty is checked in "-se_tryMPE", so that you can read cent cor­rec­tions in the trace.

Listening to scales

The fol­low­ing are exam­ples of 12-note scales:

_scale(piano,0) C4 C#4 D4 D#4 E4 F4 F#4 G4 G#4 A4 A#4 B4 C5
_velcont _scale(just intonation,0) _vel(120) C4 C#4 D4 D#4 E4 F4 F#4 G4 G#4 A4 A#4 B4 C5 _vel(60)

The sec­ond argu­ment to the "_scale()" com­mand is called the block key. It is the key whose fre­quen­cy should remain equal to that of a con­ven­tion­al 12-grade equal-tempered scale (a stan­dard tun­ing of elec­tron­ic instru­ments). If it is set to 0 or 60, this means that the block key is the 60th key on a piano key­board, usu­al­ly called "mid­dle C" or C4/do3. If the A4/la3 is 440 Hz, key #60 should be 261.63 Hz, which we call the base fre­quen­cy, fol­low­ing the prac­tice in Csound..

See for exam­ple the top of set­tings of the piano scale in the tonal­i­ty resource "-to.tryMPE":

For geeks: The Csound GEN51 line at the top is pure­ly infor­ma­tive. It could be placed on top of Csound scores, but the Bol Processor uses note fre­quen­cies instead when uncon­ven­tion­al posi­tions are required — see Csound tun­ing in BP3.

Looking at the trace of the process when play­ing the "_scale(piano,0)" sequence yields the following:

§ key 60: "C4" chan 2 scale #5, block key 60, corr 0 cents, freq 261.630 Hz
§ key 61: "C#4" chan 2 scale #5, block key 60, corr 0 cents, freq 277.187 Hz
§ key 62: "D4" chan 2 scale #5, block key 60, corr 0 cents, freq 293.670 Hz
§ key 63: "D#4" chan 2 scale #5, block key 60, corr 1 cents, freq 311.312 Hz
§ key 64: "E4" chan 2 scale #5, block key 60, corr 1 cents, freq 329.824 Hz
§ key 65: "F4" chan 2 scale #5, block key 60, corr 1 cents, freq 349.436 Hz
§ key 66: "F#4" chan 2 scale #5, block key 60, corr 2 cents, freq 370.428 Hz
§ key 67: "G4" chan 2 scale #5, block key 60, corr 1 cents, freq 392.229 Hz
§ key 68: "G#4" chan 2 scale #5, block key 60, corr 2 cents, freq 415.792 Hz
§ key 69: "A4" chan 2 scale #5, block key 60, corr 2 cents, freq 440.516 Hz
§ key 70: "A#4" chan 2 scale #5, block key 60, corr 3 cents, freq 466.980 Hz
§ key 71: "B4" chan 2 scale #5, block key 60, corr 2 cents, freq 494.463 Hz
§ key 72: "C5" chan 2 scale #5, block key 60, corr 3 cents, freq 524.168 Hz

The first thing we notice is that the fre­quen­cy of C4 (key #60) is 261.630 Hz, the base fre­quen­cy of the block key. One octave high­er, the fre­quen­cy of C5 is 525.260 Hz. This gives an octave ratio of 2.0034, which equates to a stretch­ing of 3 cents, close to 4 cents due to the rounding.

This is con­firmed by the Csound score:

t 0.000 60
i1 0.000 0.333 261.630 90.000 90.000 0.000 0.000 0.000 0.000 ; C4
i1 0.333 0.333 277.187 90.000 90.000 0.000 0.000 0.000 0.000 ; C#4
i1 0.666 0.334 293.670 90.000 90.000 0.000 0.000 0.000 0.000 ; D4
i1 1.000 0.333 311.312 90.000 90.000 0.000 0.000 0.000 0.000 ; D#4
i1 1.333 0.333 329.824 90.000 90.000 0.000 0.000 0.000 0.000 ; E4
i1 1.666 0.334 349.436 90.000 90.000 0.000 0.000 0.000 0.000 ; F4
i1 2.000 0.333 370.428 90.000 90.000 0.000 0.000 0.000 0.000 ; F#4
i1 2.333 0.333 392.229 90.000 90.000 0.000 0.000 0.000 0.000 ; G4
i1 2.666 0.334 415.792 90.000 90.000 0.000 0.000 0.000 0.000 ; G#4
i1 3.000 0.333 440.516 90.000 90.000 0.000 0.000 0.000 0.000 ; A4
i1 3.333 0.333 466.980 90.000 90.000 0.000 0.000 0.000 0.000 ; A#4
i1 3.666 0.334 494.463 90.000 90.000 0.000 0.000 0.000 0.000 ; B4
i1 4.000 0.333 524.168 90.000 90.000 0.000 0.000 0.000 0.000 ; C5

When the fre­quen­cies are dis­played using the just into­na­tion scale, the octave ratio is exact­ly 2/1. Listen to the scale with decreas­ing velocities:

On the same scale, lis­ten to a series of fifths C4/G4, D4/A4, E4/B4, F5/C5 show­ing that they are per­fect except the wolf's fifth D4/A4 (see pic­ture):

scale(just intonation,0) {C4 D4_ E4_ F4_, G4 A4 B4 C5}

Checking large intervals

Due to round­ing (3 cents instead of 4) in the piano scale, check that round­ing errors do not accu­mu­late over octaves. The fol­low­ing is also an exer­cise for those whose ear is trained in piano tun­ing. We'll play iden­ti­cal notes in two scales: the piano scale with its extend­ed octave, then the stan­dard equal tem­pera­ment scale with an octave of 2/1:

_tempo(1/2) {_scale(piano,0) C2 C3 C4 C5 C6 C7 _scale(0,0) C2 C3 C4 C5 C6 C7 1/16, 1/16 C2 C3 C4 C5 C6 C7 C2 C3 C4 C5 C6 C7}

The instruc­tion "_scale(0,0)" sets the scale to the stan­dard stan­dard equal tem­pera­ment scale. The lay­out of the notes in this poly­met­ric struc­ture is as follows:

There is a short delay (1/16 beat) on the notes of the sec­ond line to empha­sise the beats, if there are any. You can hear beats in the first part, as scales are dif­fer­ent, but per­fect uni­son in the sec­ond part. This is how it sounds on a PianoTeq Stage phys­i­cal mod­el­ling synthesiser:

This result should not be tak­en as a rad­i­cal state­ment about how to tune a piano! Pianoteq syn­the­siz­ers already repro­duce the octave stretch­ing that piano tuners tend to do to com­pen­sate for the inhar­monic­i­ty of the strings. An addi­tion­al octave stretch­ing of four cents is there­fore not worth mentioning.

The trace only shows notes whose fre­quen­cies have been corrected:

§ key 36: "C2" chan 2 scale #6, block key 60, corr -7 cents, freq 65.144 Hz
§ key 48: "C3" chan 2 scale #6, block key 60, corr -3 cents, freq 130.589 Hz
§ key 60: "C4" chan 2 scale #6, block key 60, corr 0 cents, freq 261.630 Hz
§ key 72: "C5" chan 2 scale #6, block key 60, corr 3 cents, freq 524.168 Hz
§ key 84: "C6" chan 2 scale #6, block key 60, corr 7 cents, freq 1050.760 Hz
§ key 96: "C7" chan 2 scale #6, block key 60, corr 11 cents, freq 2106.381 Hz

We note that 5 octaves gives a total stretch of 18 cents, or 3.6 cents per octave. The fre­quen­cy ratio between C4 and C7, three octaves high­er, is 2106.381/261.630 = 8.0509, whose cube root is 2.0042, again very close to the ratio of 2.0046 in the piano scale def­i­n­i­tion. Unsurprisingly, the C-sound score reveals exact­ly the same numbers.

Effect of the block key

Let us super­im­pose two phras­es of the same notes in the same scale but with­out the same block key:

G3 A3 B3 {_scale(just intonation,A4) C4 D4 E4 A4, _scale(just intonation,C4) C5 D5 E5 A5}

It sounds strange, giv­en that the note inter­vals are not exact­ly one octave:

The analy­sis of the trace gives an inter­est­ing result:

§ key 60: "C4" chan 2 scale #3, block key 69, corr 15 cents, freq 263.907 Hz
§ key 72: "C5" chan 3 scale #3, block key 60, corr 0 cents, freq 523.260 Hz
§ key 62: "D4" chan 2 scale #3, block key 69, corr 18 cents, freq 296.739 Hz
§ key 74: "D5" chan 3 scale #3, block key 60, corr 3 cents, freq 588.358 Hz
§ key 64: "E4" chan 2 scale #3, block key 69, corr 2 cents, freq 330.014 Hz
§ key 76: "E5" chan 3 scale #3, block key 60, corr -13 cents, freq 654.334 Hz
§ key 69: "A4" chan 2 scale #3, block key 69, corr 0 cents, freq 440.007 Hz
§ key 81: "A5" chan 3 scale #3, block key 60, corr -15 cents, freq 872.423 Hz

First, key #72 (C5) of scale #4 has 0 cents cor­rec­tion because the block key of this scale is C4 and it has no octave stretch­ing. The same for key #69 (A4) of scale #3 whose block key is A4.

Pitch val­ues can be deduced from the image of the just into­na­tion scale., For instance, A4 (key #69) has 0 cent cor­rec­tion on the score because it is the block key. The cor­rect­ed C4 fre­quen­cy of this scale is 263.907 Hz (i.e. 15 cents above its base fre­quen­cy 261.63 Hz) and the fre­quen­cy ratio for A is 5/3, which yields 440.007 Hz as shown above.

Secondly, since notes C4 and C5 are super­im­posed with dif­fer­ent cent cor­rec­tions, i.e. dif­fer­ent pitch­ben­der set­tings, they must be sent on dif­fer­ent MIDI chan­nels: 2 and 3. This is the approach bor­rowed from MPE. Same for D4/D5, E4/E5, A4/A5. Note that each MIDI chan­nel is reused as soon as it is free of notes.

For geeks: In this exam­ple, the notes G3 A3 B3 played at the begin­ning are not mod­i­fied by a micro­ton­al scale. They are there­fore played on the stan­dard equal tem­pered scale of the MIDI device. As a result, they appear on the Csound score in octave point pitch-class format:

i1 0.000 1.000 7.07 90.000 90.000 0.000 0.000 0.000 0.000 ; G3
i1 1.000 1.000 7.09 90.000 90.000 0.000 0.000 0.000 0.000 ; A3
i1 2.000 1.000 7.11 90.000 90.000 0.000 0.000 0.000 0.000 ; B3
i1 3.000 1.000 263.907 90.000 90.000 0.000 0.000 0.000 0.000 ; C4
i1 3.000 1.000 523.260 90.000 90.000 0.000 0.000 0.000 0.000 ; C5
i1 4.000 1.000 296.739 90.000 90.000 0.000 0.000 0.000 0.000 ; D4
i1 4.000 1.000 588.358 90.000 90.000 0.000 0.000 0.000 0.000 ; D5
i1 5.000 1.000 330.014 90.000 90.000 0.000 0.000 0.000 0.000 ; E4
i1 5.000 1.000 654.334 90.000 90.000 0.000 0.000 0.000 0.000 ; E5
i1 6.000 1.000 440.007 90.000 90.000 0.000 0.000 0.000 0.000 ; A4
i1 6.000 1.000 872.423 90.000 90.000 0.000 0.000 0.000 0.000 ; A5

Effect of the base key

The meantone_try scale

Let us use meantone_try and meantone_try2 scale to play the same phrase. We call these scales "exot­ic" because the names of their notes are not in the English, Italian/Spanish/French, or Indian stan­dard. Here we use the key num­bers of the MIDI out­put device.

The only dif­fer­ence is the key num­bers. In meantone_try2, the base key is #64 instead of #60.

Try:

_scale(meantone_try,69) key#60 key#62 key#65 key#69 key#72

The result:

§ key 60: "key#60" chan 2 scale #4, block key 69, corr -5 cents, freq 260.875 Hz
§ key 62: "key#62" chan 2 scale #4, block key 69, corr -2 cents, freq 293.331 Hz
§ key 65: "key#65" chan 2 scale #4, block key 69, corr 13 cents, freq 351.866 Hz
§ key 69: "key#69" chan 2 scale #4, block key 69, corr 0 cents, freq 440.007 Hz
§ key 72: "key#60" chan 2 scale #4, block key 69, corr 13 cents, freq 527.204 Hz

The fre­quen­cy of key#69 is 440 Hz since it is the block key. The actu­al sequence heard on the MIDI out­put device is C4 D4 F4 A4 C5. Note that the octave ratio C5/C4 is 527.204/260.875 which is greater than 2 because this scale has an octave stretched by 19 cents.

Now try:

_scale(meantone_try2,73) key#64 key#66 key#69 key#73 key#76

The result:

§ key 64: "key#64" chan 2 scale #5, block key 73, corr -5 cents, freq 260.875 Hz
§ key 66: "key#66" chan 2 scale #5, block key 73, corr -2 cents, freq 293.331 Hz
§ key 69: "key#69" chan 2 scale #5, block key 73, corr 13 cents, freq 351.866 Hz
§ key 73: "key#73" chan 2 scale #5, block key 73, corr 0 cents, freq 440.007 Hz
§ key 76: "key#64" chan 2 scale #5, block key 73, corr 13 cents, freq 527.204 Hz

Note again that the fre­quen­cy of the base key #73 is 440 Hz. The fre­quen­cies are iden­ti­cal, the only change is the key num­bers asso­ci­at­ed with the notes. The actu­al sequence played on the MIDI out­put device should again be C4 D4 F4 A4 C5, assum­ing that key #64 is the mid­dle key of its keyboard.

A very exotic scale

The scale called zest24-supergoya17plus3_Db is more "exot­ic" than the pre­vi­ous one because it has 20 grades and 12 notes. The orig­i­nal scale down­loaded from an archive did not have note names, so we decid­ed to label twelve posi­tions with the key num­bers #60 to #71. As you can see in the pic­ture, the inter­vals are very irreg­u­lar. The choice of 12 tones is moti­vat­ed by the desire to be able to map them onto the 12 keys of a stan­dard piano key­board. We'll see a dif­fer­ent case later.

Try the following:

_scale(zest24-supergoya17plus3_Db,0) key#60 key#62 key#65 key#69 key#72

The result in real-time MIDI:

§ key 60: "key#60" chan 2 scale #7, block key 60, corr 0 cents, freq 261.630 Hz
§ key 62: "key#62" chan 2 scale #7, block key 60, corr 67 cents, freq 305.258 Hz
§ key 65: "key#65" chan 2 scale #7, block key 60, corr 176 cents, freq 386.605 Hz
§ key 69: "key#69" chan 2 scale #7, block key 60, corr 75 cents, freq 459.488 Hz
§ key 72: "key#60" chan 2 scale #7, block key 60, corr 0 cents, freq 523.260 Hz

and the Csound score:

i1 0.000 1.000 261.630 90.000 90.000 0.000 0.000 0.000 0.000 ; key#60
i1 1.000 1.000 305.258 90.000 90.000 0.000 0.000 0.000 0.000 ; key#62
i1 2.000 1.000 386.605 90.000 90.000 0.000 0.000 0.000 0.000 ; key#65
i1 3.000 1.000 459.488 90.000 90.000 0.000 0.000 0.000 0.000 ; key#69
i1 4.000 1.000 523.260 90.000 90.000 0.000 0.000 0.000 0.000 ; key#60

Key #60 is the base key and its fre­quen­cy is 261.630 Hz as declared in the tonal­i­ty resource. Note that the key #72, an octave high­er, also has "key#60" as its note name. Its fre­quen­cy of 523.260 Hz is twice 261.630 since octaves are not stretched.

Looking at the pic­ture, we can cal­cu­late the fre­quen­cy of key#65 which has a fre­quen­cy ratio of 1.478. This gives 1.478 x 261.63 = 386.69 Hz, which is very close to that in the score. Minor errors are due to the round­ing of cents to whole numbers.

If you play this score on a con­ven­tion­al MIDI device, you won't hear the cor­rect fre­quen­cies unless the device is tuned to a 20-grade equal tem­pera­ment scale. Conversely, the ren­der­ing in C-Sound is accurate.

When a scale has more than 12 grades, the ref­er­ence tem­pered scale must have the same num­ber of grades, regard­less of the num­ber of notes (which is indeed small­er). Apart from the musi­cal aspect — which we won't dis­cuss here — this has a tech­ni­cal advan­tage: the cent cor­rec­tions, which are devi­a­tions from the equal tem­pera­ment scale, will always be less than 100 cents. This is impor­tant because the sen­si­tiv­i­ty of pitch­ben­ders is set to ± 200 cents.

The Bohlen-Pierce scale

The Bohlen-Pierce scale has a "tri­tave" inter­val of ratio 3/1 instead of 2/1 in the octave. The tri­tave is divid­ed into 13 grades and 13 notes (see Wikipedia).

The "just-intonation" ver­sion has been imple­ment­ed in the tonal resource -to.tryMPE — see pic­ture.

Play the full sequence of notes over a tritave:

_scale(Bohlen-Pierce,0) C4 Db4 D4 E4 F4 Gb4 G4 H4 Jb4 J4 A4 Bb4 B4 C5

Be aware that notes with names like C, Db, D, etc. have dif­fer­ent posi­tions than notes with the same names in a 12 tone scale.

This yields:

§ key 60: "C4" … corr 0 cents, freq 261.630 Hz
§ key 61: "Db4" … corr 33 cents, freq 282.522 Hz
§ key 62: "D4" … -> key 63 corr 1 cents, freq 311.312 Hz
§ key 63: "E4" … -> key 64 corr 35 cents, freq 336.365 Hz
§ key 64: "F4" … -> key 65 corr 82 cents, freq 366.174 Hz
§ key 65: "Gb4" … -> key 67 corr 36 cents, freq 400.239 Hz
§ key 66: "G4" … -> key 68 corr 84 cents, freq 435.960 Hz
§ key 67: "H4" … -> key 70 corr 17 cents, freq 470.772 Hz
§ key 68: "Jb4" … -> key 71 corr 65 cents, freq 512.788 Hz
§ key 69: "J4" … -> key 73 corr 19 cents, freq 560.492 Hz
§ key 70: "A4" … -> key 74 corr 66 cents, freq 610.163 Hz
§ key 71: "Bb4" … -> key 76 corr 0 cents, freq 659.266 Hz
§ key 72: "B4" … -> key 77 corr 68 cents, freq 726.449 Hz
§ key 73: "C5" … -> key 79 corr 1 cents, freq 784.457 Hz

The fre­quen­cy ratio C5 / C4 is, as expect­ed, 784.457 / 261.630 = 3.

The Bohlen-Pierce scale played on Pianoteq

Since the scale cov­ers a tri­tave that would extend from A4 (key #60) to G5 (key #79) on a con­ven­tion­al 12-note MIDI device, each note is mapped to the key that requires the least amount of pitch­bend. As a result, pitch­bend cor­rec­tions are nev­er greater than ± 100 cents.

The Csound score:

i1 0.000 1.000 261.630 90.000 90.000 0.000 0.000 0.000 0.000 ; C4
i1 1.000 1.000 282.522 90.000 90.000 0.000 0.000 0.000 0.000 ; Db4
i1 2.000 1.000 311.312 90.000 90.000 0.000 0.000 0.000 0.000 ; D4
i1 3.000 1.000 336.365 90.000 90.000 0.000 0.000 0.000 0.000 ; E4
i1 4.000 1.000 366.174 90.000 90.000 0.000 0.000 0.000 0.000 ; F4
i1 5.000 1.000 400.239 90.000 90.000 0.000 0.000 0.000 0.000 ; Gb4
i1 6.000 1.000 435.960 90.000 90.000 0.000 0.000 0.000 0.000 ; G4
i1 7.000 1.000 470.772 90.000 90.000 0.000 0.000 0.000 0.000 ; H4
i1 8.000 1.000 512.788 90.000 90.000 0.000 0.000 0.000 0.000 ; Jb4
i1 9.000 1.000 560.492 90.000 90.000 0.000 0.000 0.000 0.000 ; J4
i1 10.000 1.000 610.163 90.000 90.000 0.000 0.000 0.000 0.000 ; A4
i1 11.000 1.000 659.266 90.000 90.000 0.000 0.000 0.000 0.000 ; Bb4
i1 12.000 1.000 726.449 90.000 90.000 0.000 0.000 0.000 0.000 ; B4
i1 13.000 1.000 784.457 90.000 90.000 0.000 0.000 0.000 0.000 ; C5

Examples of music using the Bohlen-Pierce scale :
https://en.xen.wiki/w/Bohlen-Pierce_scale/Music

To con­vert to Bohlen-Pierce notes played on an exter­nal MIDI device, con­nect it to the input of BP3, then run the fol­low­ing "tun­ing dae­mon" (see below):

_vel(0) C0 _script(wait for­ev­er) _scale(Bohlen-Pierce,0)

Combination of several scales

In the fol­low­ing exam­ple, two phras­es are played on top of each oth­er, using dif­fer­ent micro­ton­al scales.

On the pianoroll (see pic­ture), key#60 is shown as C4. The note key#62, shown as D4, seems to be unique, although two key#62 notes are super­im­posed with slight­ly dif­fer­ent cent cor­rec­tions. The same is true with key#72 shown as C5.

{ _scale(zest24-supergoya17plus3_Db,0) key#60 key#62 key#69 key#72 , _scale(meantone_try,69) key#69 key#62 key#60 key#72 }

The result:

§ key 60: "key#60" chan 2 scale #7, block key 60, corr 0 cents, freq 261.630 Hz
§ key 69: "key#69" chan 3 scale #4, block key 69, corr 0 cents, freq 440.007 Hz
§ key 62: "key#62" chan 2 scale #7, block key 60, corr 67 cents, freq 305.258 Hz
§ key 62: "key#62" chan 3 scale #4, block key 69, corr -2 cents, freq 293.331 Hz
§ key 69: "key#69" chan 2 scale #7, block key 60, corr 75 cents, freq 459.488 Hz
§ key 60: "key#60" chan 3 scale #4, block key 69, corr -5 cents, freq 260.875 Hz
§ key 72: "key#60" chan 2 scale #7, block key 60, corr 0 cents, freq 523.260 Hz
§ key 72: "key#60" chan 3 scale #4, block key 69, corr 13 cents, freq 527.204 Hz

The sec­ond (key 62) and last (key 72) notes are iden­ti­cal, but because they belong to dif­fer­ent scales, their fre­quen­cies are not iden­ti­cal. For this pur­pose, they are played on dif­fer­ent MIDI chan­nels. The super­im­po­si­tion cre­ates (nasty) mis­match­es that reflect the dif­fer­ences in tuning:

Use of _scale(0,0)

So far we have used "_scale(0,0)" to spec­i­fy the return to a 12-grade equal tem­pered scale after using a micro­ton­al scale. It can also be used to force micro­ton­al mode in a musi­cal item that does not require spe­cif­ic micro­ton­al scales.

Pitchbend adjust­ments are not shown on this graph

For exam­ple, try to play the phrase:

_pitchrange(200) C4 _pitchbend(100) C4 {_pitchbend(-100) C4, _pitchbend(200) C4} C4 _pitchbend(0) C4

This is a (rather sil­ly) way of cre­at­ing a sequence of notes using the same note with pitch­bend cor­rec­tions. In fact, we are look­ing for­ward to hearing:

C4 C#4 {B3, D4} C#4 C4

The first solu­tion does not work because the chord {B3, D4} con­sists of two of the same note A4 with dif­fer­ent pitch­bend val­ues. It works in Csound, but in MIDI we hear:

An incor­rect ren­der­ing of C4 C#4 {B3, D4} C#4 C4

Proper nota­tion, with­out the aid of micro­tonal­i­ty, would be, for example:

_pitchrange(200) C4 _pitchbend(100) C4 {_pitchbend(-100) C4, _chan(2) _pitchrange(200) _pitchbend(200) C4} C4 _pitchbend(0) C4

So we have to send the two C4s of the poly­met­ric expres­sion on sep­a­rate MIDI chan­nels. But the micro­ton­al cal­cu­la­tion does this auto­mat­i­cal­ly. So, putting "_scale(0,0)" at the begin­ning won't change the tun­ing but it will force the micro­ton­al mode:

_scale(0,0) _pitchrange(200) C4 _pitchbend(100) C4 {_pitchbend(-100) C4, _pitchbend(200) C4} C4 _pitchbend(0) C4

Now we hear:

A cor­rect ren­der­ing of C4 C#4 {B3, D4} C#4 C4 using the micro­ton­al mode

and the trace shows:

§ key 60: "C4" chan 2
§ key 60: "C4" chan 2
--> with addi­tion­al pitch­bend val­ue of 4095
§ key 60: "C4" chan 2
--> with addi­tion­al pitch­bend val­ue of -4096
§ key 60: "C4" chan 3
--> with addi­tion­al pitch­bend val­ue of 8191
§ key 60: "C4" chan 2
--> with addi­tion­al pitch­bend val­ue of 4095
§ key 60: "C4" chan 2

Csound scores are the same in all cas­es (pitch­bend para­me­ters in bold):

i1 0.000 1.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 ; C4
i1 1.000 1.000 8.00 90.000 90.000 0.000 99.988 99.988 0.000 ; C4
i1 2.000 1.000 8.00 90.000 90.000 0.000 -100.000 -100.000 0.000 ; C4
i1 2.000 1.000 8.00 90.000 90.000 0.000 199.976 199.976 0.000 ; C4
i1 3.000 1.000 8.00 90.000 90.000 0.000 99.988 99.988 0.000 ; C4
i1 4.000 1.000 8.00 90.000 90.000 0.000 0.000 0.000 0.000 ; C4

For geeks: It wouldn't be a good idea to set micro­tonal­i­ty mode by default for all musi­cal works, because (1) chan­nel assign­ment takes up pro­cess­ing time, and (2) this would ren­der all "_chan()" com­mands inef­fec­tive. In some MIDI envi­ron­ments, MIDI chan­nels are used to send mes­sages to dif­fer­ent instruments.

Combination with pitchbend commands

The fol­low­ing is an exam­ple of com­bin­ing a micro­ton­al phrase with a glob­al pitch­bend com­mand of + 100 cents:

_chan(4) _pitchrange(200) _scale(zest24-supergoya17plus3_Db,0) _pitchbend(+100) key#60 key#62 key#65 key#69 key#72 _pitchbend(0) key#72

The result is:

§ key 60: "key#60" chan 2 scale #7, block key 60, corr 0 cents, freq 261.630 Hz
--> with addi­tion­al pitchbend value 4095
§ key 62: "key#62" chan 2 scale #7, block key 60, corr 67 cents, freq 305.258 Hz
--> with addi­tion­al pitch­bend val­ue 4095
§ key 65: "key#65" chan 2 scale #7, block key 60, corr 176 cents, freq 386.605 Hz
--> with addi­tion­al pitch­bend val­ue 4095
§ key 69: "key#69" chan 2 scale #7, block key 60, corr 75 cents, freq 459.488 Hz
--> with addi­tion­al pitch­bend val­ue 4095
§ key 72: "key#60" chan 2 scale #7, block key 60, corr 0 cents, freq 523.260 Hz
--> with addi­tion­al pitch­bend val­ue 4095
§ key 72: "key#60" chan 2 scale #7, block key 60, corr 0 cents, freq 523.260 Hz

The "_chan(4)" com­mand is used here to prove that it is ignored in micro­tonal­i­ty mode. The MIDI trace shows that an addi­tion­al cor­rec­tion has been applied. Therefore, the fre­quen­cy val­ues are not those played on the out­put MIDI device. However, the Csound score is explicit:

i1 0.000 1.000 261.630 90.000 90.000 0.000 99.988 99.988 0.000 ; key#60
i1 1.000 1.000 305.258 90.000 90.000 0.000 99.988 99.988 0.000 ; key#62
i1 2.000 1.000 386.605 90.000 90.000 0.000 99.988 99.988 0.000 ; key#65
i1 3.000 1.000 459.488 90.000 90.000 0.000 99.988 99.988 0.000 ; key#69
i1 4.000 1.000 523.260 90.000 90.000 0.000 99.988 99.988 0.000 ; key#60
i1 5.000 1.000 523.260 90.000 90.000 0.000 0.000 0.000 0.000 ; key#60

The num­bers 99.988 and 99.988 are the pitch­bend cor­rec­tions (in cents) at the begin­ning and end of the note declared on each line.

The "grama" Indian scale

The gra­ma scale

We have already dis­cussed the ancient Indian tonal sys­tem which divides the octave into "twenty-two shrutis", see The two-vina exper­i­ment for details. We'll try this gra­ma scale by set­ting the pramāņa ṣru­ti to 21 cents.

In short, this tun­ing scheme is a twelve degree chro­mat­ic scale: Sa, Re komal, Re, Ga komal, Ga, Ma, Ma tivra, Pa, Dha komal, Dha, Ni komal, Ni. These names stand for C, Db, D, Eb, E, F, F#, G, Ab, A, Bb, B in English notation.

Each note of the Indian scale, except Sa (C) and Ma tivra (F#), can occu­py two enhar­mon­ic posi­tions. This explains why the gra­ma tun­ing scheme has 23 posi­tions and 22 notes.

In accor­dance with the syn­tax of the Bol proces­sor, notes are referred to as sound objects in low­er case. For exam­ple, the two enhar­mon­ic posi­tions of Re komal are called r1_ and r2_, and the two posi­tions of Re are called r3_ and r4_. A trail­ing '_' is nec­es­sary to indi­cate octave num­bers unam­bigu­ous­ly: the note d3_4 is the low posi­tion of Dha in the 4th octave, which is admit­ted­ly close to A4 in the Western scale.

The pramāņa ṣru­ti is the tonal dis­tance between all pairs of enhar­mon­ic posi­tions, for instance between r1_ and r2_. For the sake of sim­plic­i­ty, we've set it to 21 cents (a syn­ton­ic com­ma), which is a com­mon mis­take made by Western and Indian musi­col­o­gists. In real­i­ty it is a vari­able val­ue — see Raga into­na­tion.

Play the scale:

_scale(grama, d3_4) sa_4 r1_4 r2_4 r3_4 r4_4 g1_4 g2_4 g3_4 g4_4 m1_4 m2_4 m3_4 p3_4 p4_4 d1_4 d2_4 d3_4 d4_4 n1_4 n2_4 n3_4 n4_4 sa_5

The result (Csound is identical):

§ key 60: "sa_4" …corr 15 cents, freq 263.907 Hz
§ key 61: "r1_4" …corr 6 cents, freq 278.150 Hz
§ key 62: "r2_4" …corr -73 cents, freq 281.544 Hz
§ key 63: "r3_4" …-> key 61 corr 98 cents, freq 293.331 Hz
§ key 64: "r4_4" …-> key 62 corr 19 cents, freq 296.910 Hz
§ key 65: "g1_4" …-> key 63 corr 10 cents, freq 312.935 Hz
§ key 66: "g2_4" …-> key 63 corr 31 cents, freq 316.754 Hz
§ key 67: "g3_4" …-> key 64 corr 2 cents, freq 330.014 Hz
§ key 68: "g4_4" …-> key 64 corr 23 cents, freq 334.042 Hz
§ key 69: "m1_4" …-> key 65 corr 14 cents, freq 352.070 Hz
§ key 70: "m2_4" …-> key 65 corr 35 cents, freq 356.366 Hz
§ key 71: "m3_4" …-> key 66 corr 6 cents, freq 371.285 Hz
§ key 72: "p3_4" …-> key 66 corr 96 cents, freq 391.097 Hz
§ key 73: "p4_4" …-> key 67 corr 17 cents, freq 395.870 Hz
§ key 74: "d1_4" …-> key 68 corr 8 cents, freq 417.235 Hz
§ key 75: "d2_4" …-> key 68 corr 29 cents, freq 422.327 Hz
§ key 76: "d3_4" …-> key 69 corr 0 cents, freq 440.007 Hz
§ key 77: "d4_4" …-> key 69 corr 21 cents, freq 445.377 Hz
§ key 78: "n1_4" …-> key 70 corr 12 cents, freq 469.414 Hz
§ key 79: "n2_4" …-> key 70 corr 33 cents, freq 475.143 Hz
§ key 80: "n3_4" …-> key 71 corr 4 cents, freq 495.034 Hz
§ key 81: "n4_4" …-> key 71 corr 25 cents, freq 501.075 Hz
§ key 82: "sa_5" …-> key 72 corr 16 cents, freq 528.118 Hz

The gra­ma scale (22 notes) played on Pianoteq

Listen to the same scale played against a drone (read the Microtonality page):

The Csound ren­der­ing of the gra­ma scale (23 grades) played against a drone. This ver­sion has an addi­tion­al note m4_ that does not belong to the pre­ced­ing scale. 

We said ear­li­er that, in the gra­ma tun­ing scheme, d3_4 occu­pies the posi­tion of A4 in the Western scale. Since the block key is #76 (d3_4), the fre­quen­cy of d3_4 is close to 440 Hz. Consequently, the posi­tion of sa_4 (263.907 Hz) is 15 cents high­er than the base fre­quen­cy (261.63 Hz).

This scale can be played on any MIDI device that accepts pitch­bend com­mands. The 22 notes of the scale, cov­er­ing an octave, are mapped to the 12 keys of a MIDI key­board. Each note is mapped to the key that requires the least amount of pitch­bend. As a result, pitch­bend cor­rec­tions are nev­er greater than ± 100 cents. For exam­ple, d3_4 is mapped to key #69, which hap­pens to be that of A4 on a con­ven­tion­al keyboard.

Read the Raga Intonation page to see how this the­o­ret­i­cal frame­work can be adapt­ed for mod­el­ling real music.

Microtonality in sound-objects

A sound-object is a sequence of MIDI events and/or Csound score lines — read Sound-object pro­to­types for details. Therefore the pitch­es of notes it con­tains can be mod­i­fied by micro­ton­al scales. In the "-da.tryMPE" project, try for instance:

_scale(just intonation,0) a f b b

and check fre­quen­cy cor­rec­tions in the trace (both MIDI and Csound):

§ key 69: "A4" octave 4 scale #3, block key 60, corr -15 cents, freq 436.212 Hz
§ key 41: "F2" octave 2 scale #3, block key 60, corr -1 cents, freq 87.258 Hz
§ key 71: "B4" octave 4 scale #3, block key 60, corr -11 cents, freq 490.764 Hz
§ key 71: "B4" octave 4 scale #3, block key 60, corr -11 cents, freq 490.764 Hz
§ key 71: "B4" octave 4 scale #3, block key 60, corr -11 cents, freq 490.764 Hz
§ key 71: "B4" octave 4 scale #3, block key 60, corr -11 cents, freq 490.764 Hz

The posi­tion of A on the just into­na­tion scale (see pic­ture) is 884 cents above C, which is 15 cents below its posi­tion on the equal tem­pera­ment scale (900 cents). The same goes for B which is 1088 cents above C, and thus 11 cents below its posi­tion on the equal tem­pera­ment scale (1100 cents). 

Applying microtonal corrections to MIDI input notes

This demon­strates the BP3's abil­i­ty to act as an inter­face between MIDI devices, retun­ing the input in real time to a micro­ton­al scale.

The fil­ter of the input MIDI device should be set to "treat & pass" for all cat­e­gories of events that will be trans­mit­ted (see picture).

We show a tem­po­rary solu­tion that works very well, but will be sim­pli­fied in the future.

If, for exam­ple, you want to retune the input to the just into­na­tion scale, run the fol­low­ing "tun­ing daemon":

_script(wait for C0 channel 16) _scale(just intonation,A4) _vel(0) C0

The "wait for C0 channel 16" com­mand that caus­es the machine to hang up while it lis­tens for some kind of input. In fact, the note "C0 channel 16" should not be part of the stream of notes you need to retune, oth­er­wise it will stop the process!

The note C0 with veloc­i­ty 0 is inaudi­ble and will not be played unless the note "C0 channel 16" releas­es the wait­ing state. This note is need­ed for attach­ing the script instruction.

An alter­na­tive to this set­up is:

_vel(0) C0 _script(wait forever) _scale(just intonation,A4)

The "wait forever" com­mand caus­es the machine to hang until the STOP or PANIC but­ton is pressed. Again, we need a dum­my (inaudi­ble) note C0, at the end of which the script instruc­tion is appended.

Because mul­ti­ple instances of BP3 can be run simul­ta­ne­ous­ly (read Real-time MIDI), you can set up a bank of "tun­ing dae­mons" that inter­act with peo­ple and MIDI devices to cre­ate inter­est­ing vari­a­tions of tonal structures.

Quick install Linux

   

This is a sup­ple­ment to the page Bol Processor ‘BP3’ and its PHP inter­face.

This instal­la­tion is checked with Ubuntu + Linux Lite 7.0 run­ning on an HP Intel Core i5-6200U (64-bit, 8 Gb RAM).

Install XAMPP

The instal­la­tion of BP3 should take place after the instal­la­tion of the local Apache serv­er XAMPP. Follow instruc­tions here: https://www.apachefriends.org/

XAMPP cre­ates a /opt/lampp/htdocs/ direc­to­ry that will con­tain "bolprocessor". The "bolprocessor" fold­er will con­tain (lan­guage C) source files for the "bp3" con­sole, the "MakeFile" to com­pile them, and all the data files. It will also con­tain a "php" fold­er filled with PHP pages and some relat­ed files for run­ning the interface.

If you wish to open XAMPP auto­mat­i­cal­ly at start­up, read this page.
(This can be done later.)

Download Bol Processor files

You need these files:

bolprocessor-graphics-for-BP3.zip con­tains source files for cre­at­ing the BP3 con­sole;
php-frontend-master.zip con­tains the PHP inter­face;
bp3-ctests-main.zip con­tains a set of exam­ples called "ctests".

These zip files are updat­ed reg­u­lar­ly. Major updates are announced on the BP devel­op­ers list and uploaded to their GIT repos­i­to­ries. Make sure that they can be found in your Downloads fold­er: /home/linuxlite/Downloads

Install the Bol Processor

Safely do the instal­la­tion using the shell scripts "linux-scripts" down­loaded here.
Current ver­sion: 16 December 2024, size 12040 bytes.
Unpack and copy these scripts to the /home folder:

cd /home/linuxlite/Downloads/
unzip linux-scripts.zip -x "__MACOSX/*"
sudo chmod -R 775 linux-scripts
cd linux-scripts
sudo cp -a . /home/
cd /home/
sudo chmod +x *.sh

Scripts "modify_xampp.sh", "prepare.sh", "unpack_bp3.sh", "install_bp3.sh" and "get_ready_bp3.sh" have been copied to the /home fold­er.

Four more scripts: "update_console.sh", "update_interface.sh", "update_data.sh" and "restart_xampp.sh", have been copied to the /home fold­er. They will be used later.

The instal­la­tion pro­ce­dure is sim­i­lar to that for MacOS and Windows, but includes a few actions spe­cif­ic to Linux.

Run the scripts in the fol­low­ing order.
👉   You will be asked for your pass­word the first time, as they need to be run in "admin" mode (the "sudo" com­mand).

  1. sudo /home/modify_xampp.sh will adjust XAMPP settings.
  2. sudo /home/prepare.sh will install required resources on your machine, and cre­ate two vir­tu­al MIDI ports if they are not yet existing.
  3. sudo /home/unpack_bp3.sh will unpack the zip files.
  4. sudo /home/install_bp3.sh will cre­ate the /opt/lampp/htdocs/bolprocessor/ direc­to­ry and fill it with the con­tents of BP3 pack­ages. Files/folders already exist­ing will sim­ply be updated.
  5. sudo /home/get_ready_bp3.sh will set up per­mis­sions and own­ers for using the con­sole. The own­er is "daemon" (the same one used by XAMPP) and per­mis­sions are "775".
    👉 The con­tent of "bolprocessor" is strict­ly pri­vate. No risk set­ting up permissions!

Avoid run­ning the same script more than once, although this should not cre­ate dupli­cates or unwant­ed effects.

Once the Bol Processor BP3 is installed and run­ning, you should delete the "zip" files in the Downloads fold­er. This will allow down­load­ing new versions.

Compile the 'bp3' console

Start the XAMPP Apache serv­er. You can send the ter­mi­nal command:

sudo /home/restart_xampp.sh

Point your brows­er at localhost/bolprocessor/php/. This will dis­play the home page of the Bol Processor.

If you see this frame in the image at the top right of the page, your life will be easy! All you have to do is click on the link to com­pile the con­sole, which will take less than a minute.

f you don't see the link to com­pile, and instead a men­tion that 'gcc' is not respon­sive, you are in great trou­ble! This sug­gests a bug in the inter­face (con­tact us) or in your installation.

Install Csound

Csound is not required to run the Bol Processor, as you can work with MIDI files and real-time MIDI. However, it will give you access to a dif­fer­ent approach to sound syn­the­sis, and it will han­dle micro­tonal­i­ty in its own way.

If you wish to install Csound, sim­ply type the fol­low­ing commands:

sudo apt update
sudo apt install csound

Then ver­i­fy the instal­la­tion and check the path to the console:

csound --ver­sion
which csound

By default, the Bol Processor sets the path to "usr/bin", which seems to be stan­dard on Linux. It is giv­en by the "which csound" com­mand.

A frame ask­ing for a cor­rec­tion
of the path to Csound.
The path "/usr/local/bin" is incor­rect in Linux.

The BP3 inter­face will be able to fig­ure out the loca­tion of "csound" and fix its path accord­ing­ly. If it does not respond, you will be asked to change the path and per­haps the name of the Csound con­sole (see image).

Contact us if this happens!

👉 Currently, the Csound orches­tra file "0-default.orc" does not work on Linux. We're try­ing to fix this… In the set­tings of your projects, enter "BP2test.orc" as replace­ment, or select oth­er files such as "new-vina.orc".

😀  Enjoy Bol Processor BP3 on Linux!

Restart XAMPP after a crash

If you blow up the mem­o­ry, for exam­ple with a quan­ti­za­tion that is too low for the size of a piece played in real­time MIDI, the XAMPP serv­er may freeze: the brows­er will refuse to dis­play pages.

To restart XAMPP, go to the ter­mi­nal and run the fol­low­ing script:

sudo /home/restart_xampp.sh

Updating to new versions

👉  If you update the "bp3" con­sole, you should also update the "php" inter­face, as the two are linked.

  • (1) Update the "bp3" con­sole:
    Delete the graphics-for-BP3.zip file if it exists in your Downloads fold­er.
    Download https://github.com/bolprocessor/bolprocessor/archive/graphics-for-BP3.zip
    Run the (super­fast!) script: sudo /home/update_console.sh
    This script deletes the 'bp3' con­sole to force a com­pi­la­tion of the new version.
  • (2) Update the "php" inter­face:
    Delete the php-frontend-master.zip file if it exists in your Downloads fold­er.
    Download https://github.com/bolprocessor/php-frontend/archive/master.zip
    Run the (super­fast!) script: sudo /home/update_interface.sh
    Note that this script will pre­serve the "_settings.php" file (if it exists), which con­tains your project settings.
  • (3) Update the test data: this will only update the con­tents of the "ctests" fold­er. If you have cre­at­ed fold­ers and files for your per­son­al data, these will not be affect­ed. However, if you have mod­i­fied a sam­ple file with­out chang­ing its name, it will be revert­ed to its dis­tri­b­u­tion ver­sion.
    Delete the bp3-ctests-main.zip file if it exists in your Downloads fold­er.
    Download https://github.com/bolprocessor/bp3-ctests/archive/main.zip
    Run the (super­fast!) script: sudo /home/update_data.sh

👉 Please send your sug­ges­tions or mod­i­fied files to our con­tact.

Uninstall the Bol Processor

Uninstalling the Bol Processor and all the data down­loaded or cre­at­ed for its use, is very sim­ple: delete the "htdocs/bolprocessor" fold­er.

Bernard Bel
August 2024

Quick install MacOS

   

This is a sup­ple­ment to the page Bol Processor ‘BP3’ and its PHP inter­face.

A one-click nota­rized installer of Bol Processor BP3 is avail­able. It is called "BolProcessorInstaller.pkg" and it can be down­loaded from here (unique location).

Geeks may pre­fer an equiv­a­lent method using a script includ­ed in this pack­age, see below.

This installer (or the script) is used for both ini­tial instal­la­tion and updates. Each time you run it, it will down­load the lat­est ver­sions of the BP3 con­sole source files, the inter­face PHP files and the sam­ple set con­tained in the 'ctests' fold­er. Data, gram­mars and scripts that you've cre­at­ed will not be delet­ed. However, if you have mod­i­fied files in the 'ctests' fold­er, they will be revert­ed to the cur­rent dis­tri­b­u­tion version.

Install MAMP or XAMPP

If you try to run the installer of Bo Processor, it will first check that a local Apache serv­er (MAMP or XAMPP) has been installed. Both are suit­able since the Bol Processor inter­face con­tains exclu­sive­ly HTML, PHP and JavaScript code. No data­base is required.

Don't try the vir­tu­al machine ver­sion of XAMPP! It won't work on Macs with M1 chips (and above). Use the native installer.

if you choose the (free) MAMP ver­sion, both MAMP and MAMP PRO will be installed, and the inter­face will occa­sion­al­ly prompt you to "upgrade" to MAMP PRO. But you don't need it for the Bol Processor!

For MAMP, the "htdocs" fold­er is in "Applications/MAMP".
For XAMPP, it is in "Applications/XAMPP/xamppfiles".

If you want Apache to start auto­mat­i­cal­ly when you start your com­put­er, this process is easy with MAMP.
For XAMPP, you can cre­ate a start­up script.

You will not be able to run both MAMP/MAMP PRO and XAMPP Apache servers at the same time if they use the same ports. This wouldn't be a good idea anyway…

MAMP PRO

Below are instruc­tions for rich peo­ple run­ning MAMP PRO.

The MAMP PRO main page on MacOS (ver­sion 5.7)
  1. Launch MAMP PRO from the Applications folder.
  2. In the MAMP main win­dow, click the Apache Enable but­ton (see image). No need for MySQL.
  3. The image shows the default set­tings for PHP, which is start­ed with Apache.
  4. In case of trou­ble, check the set­tings for ports (see image) and of hosts (gen­er­al  and  Apache).

XAMPP

Open the XAMPP fold­er in the  Applications  fold­er and launch  manager-osx.app  as shown below.

The XAMPP main page will appear. Click on the  Manage Servers  tab, then select  Apache Web Server  and click Configure. This is nec­es­sary to set up the port to any val­ue except "80" (or except "8888" in case you are also run­ning MAMP). Suggestion: set it to "81".
Then click the Start but­ton. If there is no con­flict with the ports, Apache will show up as "run­ning":

This image has an empty alt attribute; its file name is XAMPP.jpg
The XAMPP fold­er (in the Applications fold­er on a Mac) and the XAMPP main page

Once Apache is run­ning, you can click on the  Welcome  tag and the  Go to Application  but­ton. This should dis­play a (local) page about XAMPP in the path  http://localhost/dashboard. Both the  dashboard  and  bolprocessor  fold­ers will be locat­ed in the  Applications/XAMPP/xamppfiles/htdocs  folder.

Install the Bol Processor

After installing MAMP or XAMPP, you can run the installer "BolProcessorInstaller.pkg" or the "install_bolprocessor.sh" script. Both are equivalent.

Using the installer

Download "BolProcessorInstaller.pkg" from here and double-click it.

This installer has been nota­rized, which means it con­tains infor­ma­tion that allows Apple to cer­ti­fy its validity.

Once that's done, go down to the sec­tion Compile the 'bp' con­sole.

Using the script (geeks only!)

An equiv­a­lent method is to run the "install_bolprocessor.sh" script found in the "macos-scripts" fold­er down­loaded here. This makes it pos­si­ble to under­stand each step of the instal­la­tion and pos­si­bly sug­gest improvements.

After down­load­ing "macos-scripts.zip", open the Terminal and type:

cd Downloads
unzip -qo macos-scripts.zip
cd macos-scripts
sudo ./install_bolprocessor.sh

Installation issues

If the installer (or the script) does not find a "htdocs" fold­er cre­at­ed by MAMP or XAMP, it will stop the instal­la­tion, warn­ing you that one of them should be installed. In case both MAMP and XAMPP are installed — a bad idea! — the installer will choose MAMP.

Compile the 'bp' console

Now, assum­ing that the instal­la­tion was suc­cess­ful, start MAMP or XAMPP and point your brows­er to  localhost/bolprocessor/php/. This will dis­play the home page of the Bol Processor.

If you see this frame in the image at the top right of the page, your life will be easy! All you have to do is click on the link to com­pile the con­sole, which will take a minute or two.

If you don't see the link to com­pile, and instead a men­tion that 'gcc' is not respon­sive, things are bad! You are prob­a­bly using an obso­lete ver­sion of MacOS. You may need to install the com­mand line devel­op­er tools in OS X (expla­na­tions) or the Xcode toolk­it on your machine. 

Install Csound

Csound is not required to run the Bol Processor, as you can work with MIDI files and real-time MIDI. However, it will give you access to a dif­fer­ent approach to sound synthesis.

Just down­load a pre-built instal­la­tion of Csound (MacOS 6.18) from its down­load page.

A frame ask­ing for a cor­rec­tion of the path to Csound

The BP3 inter­face should be able to fig­ure out the loca­tion of "csound" and fix its path accord­ing­ly. If it does not respond, you will be asked to change the path and per­haps the name of the Csound con­sole (see image).

😀  Now, the Bol Processor is ful­ly operational!

You can try exam­ples con­tained in the 'ctests' fold­er, or fol­low the guid­ed tour on page Bol Processor ‘BP3’ and its PHP inter­face.

Updating to new versions

To update the Bol Processor con­sole, its PHP inter­face and exam­ples (the con­tents of the "ctests" fold­er), sim­ply rerun "BolProcessorInstaller.pkg". Using the lat­est ver­sion is safe!

The installer will down­load and install cur­rent ver­sions of the soft­ware and data. It will delete the com­piled  "bp"  con­sole and prompt you to recom­pile it (with a sin­gle click).

Updating will not mod­i­fy or delete any data you have cre­at­ed in the "ctests" fold­er or out­side it. However, if you have mod­i­fied a sam­ple file with­out chang­ing its name, it will be revert­ed to its dis­tri­b­u­tion version.

The installer will also pre­serve the "_settings.php" file (if it exists), which con­tains your project settings.

Security

You are right to be con­cerned about secu­ri­ty. Can you be sure that you have down­loaded the cor­rect ver­sion of "BolProcessorInstaller.pkg"? Normally yes, it is safe, because this installer has been nota­rized.

The size of the "BolProcessorInstaller.pkg" file is exact­ly 19966 bytes and its MD5 is
806a83f72daf1abd22436555abc2cc8b. You can calculate the MD5 checksum on this page. These numbers will indeed be subject to change with the release of new versions of the installer. Current version: 28 October 2024.

Please DO NOT SHARE THE INSTALLER, only its link: https://bolprocessor.org/misc/BolProcessorInstaller.pkg

Geeks may want to cus­tomise it for their own use. Just down­load this fold­er which con­tains the script files (install_bolprocessor.sh and postinstall) along with instruc­tions on how the installer has been built.

For read­ers not con­ver­sant with Unix shell scripts, the fol­low­ing is a descrip­tion of the process in human language:

Check that an Apache serv­er MAMP or XAMPP is installed by find­ing either MAMP/htdocs or xampp/htdocs on the com­put­er (not case-sensitive). If it is not found, exit with the warn­ing that either MAMP or XAMPP should be installed.

Download the lat­est dis­tri­b­u­tion files from GitHub:
https://github.com/bolprocessor/bolprocessor/archive/graphics-for-BP3.zip
https://github.com/bolprocessor/php-frontend/archive/master.zip
https://github.com/bolprocessor/bp3-ctests/archive/main.zip

Unzip these three files. They cre­ate fold­ers with names:
bolprocessor-graphics-for-BP3
php-frontend-master
bp3-ctests-main

Create a fold­er named "bol­proces­sor" (if it does not yet exist) inside the "htdocs" fold­er of the Apache server

Copy bolprocessor-graphics-for-BP3/source to htdocs/bolprocessor/
If there is already a "source" fold­er, delete it

Copy bolprocessor-graphics-for-BP3/Makefile to htdocs/bolprocessor/
Copy bolprocessor-graphics-for-BP3/BP3_help.txt to htdocs/bolprocessor/
Copy bolprocessor-graphics-for-BP3/Credits.txt to htdocs/bolprocessor/
Copy bolprocessor-graphics-for-BP3/BP3-To-Do.txt to htdocs/bolprocessor/
Copy bolprocessor-graphics-for-BP3/License.txt to htdocs/bolprocessor/
Copy bolprocessor-graphics-for-BP3/ReadMe.txt to htdocs/bolprocessor/

Copy bolprocessor/php/_settings.php to bolprocessor/ (if it exists)

Copy php-frontend-master/php to htdocs/bolprocessor/
If there is already a "php" fold­er, delete it

Copy bolprocessor/_settings.php to bolprocessor/php/ (if it exists)

Create a fold­er htdocs/bolprocessor/csound_resources if it does not yet exist

Copy the con­tent of php-frontend-master/csound_resources to htdocs/bolprocessor/csound_resources
Files that already exist should be replaced with their updat­ed versions

Create a fold­er htdocs/bolprocessor/ctests if it does not yet exist

Copy the con­tent of bp3-ctests-main to htdocs/bolprocessor/ctests
Files that already exist should be replaced with their updat­ed versions

Delete the tem­po­rary down­load directory

Set per­mis­sions of the bol­proces­sor fold­er recur­sive­ly to "775"

There is no secu­ri­ty risk in set­ting "775" per­mis­sions, as the MAMP or XAMPP Apache serv­er will be run­ning on your pri­vate com­put­er. The Bol Processor nev­er creates/modifies files out­side of its  "bolprocessor"  folder.

Delete htdocs/bolprocessor/bp if it exists. This ensures that the 'bp' con­sole is recom­piled after each update.

Uninstall the Bol Processor

Uninstalling the Bol Processor, and all the data down­loaded or cre­at­ed for its use, is very sim­ple: delete the "htdocs/bolprocessor" fold­er.

Bernard Bel
August 2024

Quick install Windows

   

This is a sup­ple­ment to the page Bol Processor ‘BP3’ and its PHP inter­face.

A one-click installer of Bol Processor BP3 is avail­able. It is called "BolProcessorInstaller.exe" and it can be down­loaded here (unique location).

This installer is used for both ini­tial instal­la­tion and updates. Each time you run it, it will down­load the lat­est ver­sions of the BP3 con­sole, includ­ing its source files, the inter­face PHP files, and the sam­ple set con­tained in the 'ctests' fold­er. Data, gram­mars and scripts that you've cre­at­ed will not be delet­ed. However, if you have mod­i­fied files in the 'ctests' fold­er, they will be revert­ed to the dis­tri­b­u­tion version.

This instal­la­tion is checked with Windows 10 run­ning on an HP Intel Core i5-6200U (64-bit, 8 Gb RAM). It should work fine with Windows 11, please check it and report!

First install MAMP or XAMPP

The (free) MAMP device run­ning on Windows 10 (July 2024). Note that Apache Server is active. You can click "Open WebStart Page" to check that it is effective.

If you try to run the installer, it will first check that a local Apache serv­er (MAMP or XAMPP) has been installed. Both are suit­able since the Bol Processor inter­face con­tains exclu­sive­ly HTML, PHP and JavaScript code. No data­base is required. 

if you choose the (free) MAMP ver­sion, both MAMP and MAMP PRO will be installed, and the inter­face will occa­sion­al­ly prompt you to "upgrade" to MAMP PRO. But you don't need it for the Bol Processor!

For MAMP on Windows, the "htdocs" fold­er is in "C:\MAMP".
For XAMPP on Windows, the "htdocs" fold­er is in "C:\xampp". (To be verified)

If you want Apache to start auto­mat­i­cal­ly when you start your com­put­er, this process is easy with MAMP, but a bit more com­plex with XAMPP: try this method,

Create the 'bp.exe' console

After installing MAMP or XAMPP, run the installer "BolProcessorInstaller.exe" down­loaded here . In case both MAMP and XAMPP are installed (a bad idea!) the installer will choose MAMP.

Now start MAMP or XAMPP and point your brows­er at localhost/bolprocessor/php/. This will dis­play the home page of Bol Processor BP3.

If you see this image at the top right of the page, the con­sole is ready. Click on the lamp if you pre­fer to use the light mode for the interface.

You can ignore the next sec­tion. 😀

Compile the 'bp.exe' console (if necessary)

The Windows instal­la­tion of Bol Processor includes the pre-compiled con­sole (named 'bp.exe' ). If, some some rea­son, the con­sole is not respond­ing, or if you mod­i­fied its source code (in the source/BP3 direc­to­ry), you may need to recom­pile it.

If you see this image at the top right of the page, your life will be easy!

All you have to do is click on the link to com­pile the con­sole, which will take a minute or two.

If the frame says that 'gcc' is not respond­ing (see pic­ture) you need to install MinGW. This is the main draw­back of Windows: its default instal­la­tion does not han­dle 'gcc' (the stan­dard C com­pil­er). You need 'gcc' to com­pile the Bol Processor con­sole, and per­haps oth­er appli­ca­tions to come. So, install MinGW, care­ful­ly fol­low­ing instruc­tions on this page. It is sim­ple, but you shouldn't miss a step!

Once 'gcc' is respond­ing, reload the Bol Processor home page and click on the link to com­pile the console.

Install Csound

Csound is not required to run the Bol Processor, as you can work with MIDI files and real-time MIDI. However, it will give you access to a dif­fer­ent approach to sound synthesis.

Just down­load a pre-built instal­la­tion of Csound from its down­load page. Select "64bit Full Installer 6.18.1".

A frame ask­ing you to cor­rect the path to Csound. This is the default path for Windows 10, by the way. We tricked the inter­face into say­ing it was wrong!

The BP3 inter­face will be able to fig­ure out the loca­tion of "csound.exe" and fix its path accord­ing­ly. If it does not respond, you will be asked to change the path and per­haps the name of the Csound con­sole (see image). Once it works after a mod­i­fi­ca­tion, please con­tact us so that we can update the default paths and names of Csound in your instal­la­tion of Windows.

😀  Now, the Bol Processor is ful­ly operational!

You can try exam­ples con­tained in the "ctests" fold­er, or fol­low the guid­ed tour on the page Bol Processor ‘BP3’ and its PHP inter­face.

Updating to new versions

To update the Bol Processor con­sole, its PHP inter­face and exam­ples (the con­tents of the "ctests" fold­er), sim­ply rerun the instal­la­tion. It will down­load and install the lat­est ver­sions of the soft­ware and data. It will delete and replace the com­piled "bp.exe" con­sole.

The installer will not mod­i­fy or delete any data you have cre­at­ed in the "ctests" fold­er or out­side it. However, if you have mod­i­fied a sam­ple file with­out chang­ing its name, it will be revert­ed to its dis­tri­b­u­tion version.

The installer will also pre­serve the "_settings.php" file (if it exists), which con­tains your project settings.

Security

You are right to be con­cerned about secu­ri­ty. Can you be sure that you have down­loaded the cor­rect ver­sion of "BolProcessorInstaller.exe"?

The size of this file is exact­ly 1810925 bytes and its MD5 is
03b53cf9a18e1e382bc7bd8e8d046a7a. You can calculate the MD5 on this page. These numbers will indeed be subject to change with the release of new versions of the installer. The current version is dated 26 November 2024.

👉  Please DO NOT SHARE THE INSTALLER, only its link: https://bolprocessor.org/misc/BolProcessorInstaller.exe

You may also want to know all the details of how it works. Geeks may want to cus­tomise it for their own use. Just down­load this fold­er which con­tains the source files (installer.ps1 and setup.iss) along with a sum­ma­ry of how to build the installer.

For read­ers not con­ver­sant with Windows PowerShell, the fol­low­ing is a descrip­tion of the process in human language:

Check that an Apache serv­er MAMP or XAMPP is installed by find­ing either MAMP\htdocs or xampp\htdocs on the com­put­er (not case-sensitive). If it is not found, exit with the warn­ing that either MAMP or XAMPP should be installed.

Download the lat­est dis­tri­b­u­tion files from GitHub:
https://github.com/bolprocessor/bolprocessor/archive/graphics-for-BP3.zip
https://github.com/bolprocessor/php-frontend/archive/master.zip
https://github.com/bolprocessor/bp3-ctests/archive/main.zip

Unzip these three files. They cre­ate fold­ers with names:
bolprocessor-graphics-for-BP3
php-frontend-master
bp3-ctests-main

Create a fold­er named "bol­proces­sor" (if it does not yet exist) inside the "htdocs" fold­er of the Apache server

Copy bolprocessor-graphics-for-BP3/source to htdocs/bolprocessor/
If there is already a "source" fold­er, delete it

Copy bolprocessor-graphics-for-BP3/Makefile to htdocs/bolprocessor/
Copy bolprocessor-graphics-for-BP3/BP2_help.txt to htdocs/bolprocessor/
Copy bolprocessor-graphics-for-BP3/Credits.txt to htdocs/bolprocessor/
Copy bolprocessor-graphics-for-BP3/BP3-To-Do.txt to htdocs/bolprocessor/
Copy bolprocessor-graphics-for-BP3/License.txt to htdocs/bolprocessor/
Copy bolprocessor-graphics-for-BP3/ReadMe.txt to htdocs/bolprocessor/

Copy bolprocessor/php/_settings.php to bolprocessor/ (if it exists)

Copy php-frontend-master/php to htdocs/bolprocessor/
If there is already a "php" fold­er, delete it

Copy bolprocessor/_settings.php to bolprocessor/php/ (if it exists)

Create a fold­er htdocs/bolprocessor/csound_resources if it does not yet exist

Copy the con­tent of php-frontend-master/csound_resources to htdocs/bolprocessor/csound_resources
Files that already exist should be replaced with their updat­ed versions

Create a fold­er htdocs/bolprocessor/ctests if it does not yet exist

Copy the con­tent of bp3-ctests-main to htdocs/bolprocessor/ctests
Files that already exist should be replaced with their updat­ed versions

Delete the tem­po­rary down­load directory

Replace htdocs/bolprocessor/bp.exe with the updat­ed version.

Uninstall the Bol Processor

Uninstalling the Bol Processor and all the data down­loaded or cre­at­ed for its use, is very sim­ple: delete the "htdocs/bolprocessor" fold­er.

Bernard Bel
August 2024

XAMPP startup

👉  For the users of Linux

If you need to start XAMPP auto­mat­i­cal­ly after a reboot, here's a basic way to do it using sys­temd, which is the init sys­tem for most Linux distributions:

1) Create a systemd service file

Open a text edi­tor to cre­ate a new file, for example:

sudo nano /etc/systemd/system/xampp.service

Add the fol­low­ing con­tent to the file:

[Unit]
Description=XAMPP Control Panel
After=network.target

[Service]
Type=forking
ExecStart=/opt/lampp/lampp start
ExecStop=/opt/lampp/lampp stop
ExecReload=/opt/lampp/lampp reload
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Save and close the file (Ctrl+X, then Y to con­firm, and Enter to save).

2) Enable the new service

Reload the sys­temd man­ag­er configuration:

sudo sys­tem­ctl daemon-reload

Enable the XAMPP ser­vice to start at boot:

sudo sys­tem­ctl enable xampp

3) You can now start XAMPP using:

sudo sys­tem­ctl start xampp

Real-time MIDI

    

In May 2024, the Bol Processor BP3 acquired the abil­i­ty to man­age the input and out­put of MIDI events. This allows it to "com­mu­ni­cate" in real time with exter­nal MIDI devices (key­boards, syn­the­siz­ers) and even with oth­er instances of BP3 run­ning on the same machine.

For geeks and programmers: This fea­ture had already been imple­ment­ed in the ear­li­er (MacOS only) ver­sion called 'BP2'. However, the imple­men­ta­tion in a C lan­guage 'con­sole' to work in MacOS, Linux and Windows envi­ron­ments was more tech­ni­cal. In addi­tion, the con­cept of "real time" in the cur­rent MIDI set­up is dif­fer­ent from the pre­vi­ous one using Opcode Music System.

The fol­low­ing exam­ples will work the same in MacOS, Windows and Linux. They have been test­ed on a recent PowerBook run­ning MacOS (Sonoma) with 16 Gb RAM, and an HP Intel Core com­put­er with 8 Gb RAM run­ning Windows 10 (64-bit) and LinuxLite 7.0 (in Ubuntu). Memory size can become crit­i­cal if many MIDI devices or vir­tu­al ports are connected. 

Using micro­ton­al scales is now pos­si­ble in real-time MIDI. Read the Check MIDI micro­tonal­i­ty page for details.

Setting up the MIDI environment

Let us assume that you have suc­cess­ful­ly down­loaded, installed and com­piled the Bol proces­sor BP3, as described on the page Bol Processor ‘BP3’ and its PHP inter­face.

In Bol Processor jar­gon, a 'project' is either a gram­mar (with a '-gr' pre­fix) or a set of data (with a '-da' pre­fix). So, cre­ate or load a sim­ple project, e.g. "-da.acceleration" which can be found in the "ctests" fold­er (down­load it here).

An output

By default, a project is set up to cre­ate MIDI files, as shown on the selec­tor (see pic­ture). Make sure your project is work­ing! Then select Real-time MIDI and click SAVE for­mat.

The selec­tor will now dis­play a dif­fer­ent image, as shown below:

By default, the MIDI out­put used for send­ing events is num­bered '0' — and the MIDI input used for receiv­ing events will be num­bered '1'. This is a com­mon sit­u­a­tion. In MacOS and Windows, these num­bers are tak­en as 'ports'. In Linux they are con­sid­ered as 'clients', each 'client' hav­ing its own 'ports', so cer­tain­ly num­bers '0' and '1' won't work… Never mind this issue, BP3 will take care of it when scan­ning real or vir­tu­al devices and try­ing to con­nect. Read more below.

We can­not rely on "port num­bers" alone because they change when we turn on and off MIDI devices con­nect­ed to the com­put­er. In Linux, the client num­ber is more spe­cif­ic to a MIDI device. In fact, the only reli­able iden­ti­fi­ca­tion is its name, which is emp­ty by default: the next field at the right of the input/output number.

Let us check the MIDI out­put. Windows does this auto­mat­i­cal­ly. The good news is that Windows 10 (and pre­sum­ably lat­er ver­sions) comes with a built-in MIDI device called Microsoft GS Wavetable Synth. The Bol Processor will auto­mat­i­cal­ly detect it and con­nect to it if no oth­er device is con­nect­ed to the system.

Linux also con­nects, by default, the out­put to a vir­tu­al device whose client num­ber is '0', but it won't pro­duce any sound in the basic instal­la­tion of Ubuntu. So, to try real-time MIDI on Linux, you need to con­nect an exter­nal MIDI device via its USB/MIDI inter­face, or to install a soft­ware syn­the­siz­er. Read more below.

Clicking Add an input will cre­ate fields for you to select an input device. We'll use this later.

To con­nect exter­nal MIDI input/output devices to Windows, you may need to install an envi­ron­ment sim­i­lar to IAC on MacOS. Read details below. However, most tests shown on this page can be per­formed on Windows with­out any addi­tion­al installation.

The fol­low­ing para­graphs are for MacOS users. Windows and Linux users can hap­pi­ly jump to the next section.

Turn on a MIDI device (syn­the­siz­er, piano, etc.) con­nect­ed to the com­put­er. On my per­son­al Mac, I usu­al­ly use the Pianoteq syn­the­sis­er, which pro­duces a phys­i­cal mod­el syn­the­sis of var­i­ous key­board instru­ments. It com­mu­ni­cates with BP3 via a device called the Inter-Application Communication (IAC) archi­tec­tureread this if you need details.

The IAC dri­ver is installed by default on recent MacOS sys­tems. (It is a part of the CoreMIDI frame­work pro­vid­ed by Apple.) It allows you to cre­ate vir­tu­al MIDI ports that enable MIDI appli­ca­tions to com­mu­ni­cate inter­nal­ly with­in the same machine. Equivalent devices exist in the Linux and Windows envi­ron­ments, see below.

The IAC also com­mu­ni­cates with exter­nal MIDI devices via the USB ports, BlueTooth and pos­si­bly more net­work pro­to­cols. We'll try it later.

To set up the IAC, run the Audio MIDI Setup appli­ca­tion (in the Utilities fold­er). Ask it to show "MIDI Studio". On my per­son­al com­put­er, it looks like this: the IAC dri­ver, the Pianoteq syn­the­sis­er, a Pocket Key 15 key­board con­nect­ed to a USB port, and a Yamaha piano con­nect­ed by stan­dard MIDI cables and a USB MIDI inter­face. The Yamaha piano appears grey because it is switched off.

On active MIDI devices you will see tri­an­gles indi­cat­ing input/output ports. These are used to con­nect devices direct­ly by draw­ing a 'cable' to con­nect them. We don't need to use these 'con­nec­tors' as BP3 com­mu­ni­cates via the IAC MIDI ports.

Check output options

(MacOS, Linux and Windows)

The eas­i­est way to pro­ceed now is to run any project in the Real-time MIDI mode, and see if sounds are pro­duced… Whatever the result, at the end of the (poten­tial­ly silent) per­for­mance, you will see a Show all … mes­sages but­ton along with a blink­ing red sig­nal "=> 1 warning". Click on the but­ton to read detailed expla­na­tions of the fail­ure (or success):

🎹 Setting up MIDI sys­tem
MIDI out­put = 0: “Bus 1” 👉 the num­ber of your choice

MIDI set­tings saved to ../temp_bolprocessor/trace_974dd9ab22_-gr.tryTimePatterns_midiport
🎹 Name(s) of MIDI input or/and output changed and will be updated when saving the page of your project

(For MacOS users)

This all makes sense giv­en the Audio MIDI Setup shown above. The Bol Processor scanned all out­put (and input) MIDI ports. Given port '0' as an out­put by default, it assigned it to "Bus 1" which the 'port' set up in IAC.

If your syn­the­sis­er hap­pens to be con­nect­ed to "Bus 1", you will hear sounds and the prob­lem is solved. Let us sup­pose that you are run­ning Pianoteq and hear noth­ing. Open the set­tings of Pianoteq and select "Devices". All you have to do is check "IAC Driver Bus 1". You might also check oth­er inputs, includ­ing Pocket Key 25 if you want to con­nect your small key­board direct­ly to Pianoteq, but these are extra procedures.

Opening Pianoteq set­tings informed us that it is com­mu­ni­cat­ing with IAC, and it sug­gest­ed to use a IAC 'Bus' for this com­mu­ni­ca­tion. The 'Bus 1' port is tech­ni­cal­ly called a vir­tu­al port.

Screenshot

All you need to do to ensure that the con­nec­tion remains cor­rect when more devices are switched on/off and MIDI port num­bers change. The only reli­able way is to write the name "Bus 1" as the MIDI out­put. You can also write "Pocket Key 25" (or what­ev­er is detect­ed as your input MIDI device) to the MIDI input, as we will use it lat­er. Note that MIDI port num­bers are now irrel­e­vant, as names take prece­dence. BP3 will cor­rect them automatically.

Click the SAVE MIDI ports but­ton to store this set­ting. Clicking on the SAVE for­mat does the same thing, so don't wor­ry about con­fus­ing buttons!

To the right of the MIDI port name is an emp­ty field where you can enter a com­ment. For exam­ple, write "Pianoteq synth" to the right of "Bus 1".

Let us now switch on a Yamaha piano which is con­nect­ed via a USB MIDI inter­face. The inter­face I use has a green light that indi­cates it has pow­er. If the piano is actu­al­ly com­mu­ni­cat­ing with it, we should see a flash­ing red light. In MacOS, some­times it is nec­es­sary to restart the com­put­er after switch­ing on the piano… But in Windows and Linux the red light flash­es immediately.

As soon as the red light flash­es, open the Pianoteq set­tings. Great! We can now see that the Yamaha piano is recog­nised and con­nect­ed to the IAC.

The eas­i­est way to con­nect the Yamaha piano to BP3 is to click PLAY. Whatever hap­pens, we'll get a warn­ing and see the fol­low­ing diagnosis:

🎹 Your real-time MIDI set­tings:
MIDI out­put = 0: “Bus 1” -
MIDI input = 1: “new input” -

🎹 Setting up MacOS MIDI sys­tem
MIDI out­put = 0: “Bus 1” 👉 the name of your choice
Trying to assign ports to 1 input(s) with­out names but pos­si­bly with num­bers
MIDI input = 1: “Bus 2” 👉 the num­ber of your choice
MIDI input 1 makes BP3 inter­ac­tive

🎶 More MIDI out­put options are avail­able:
MIDI out­put = 1: “Bus 2”
MIDI out­put = 2: “Pocket Key 25”
MIDI out­put = 3: “USB MIDI Interface”

🎶 More MIDI input options are avail­able:
MIDI input = 0: “Bus 1”
MIDI input = 2: “Pocket Key 25”
MIDI input = 3: “USB MIDI Interface”

MIDI set­tings saved to ../temp_bolprocessor/trace_974dd9ab22_-gr.tryTimePatterns_midiport
🎹 Name(s) of MIDI input or/and output changed and will be updated when saving the page of your project

The MIDI input iden­ti­fied as "Pocket Key 25" is cor­rect­ly con­nect­ing to port '2'. But the Yamaha piano is iden­ti­fied as "USB MIDI Interface". This is the name we need to copy to the MIDI out­put, then SAVE MIDI ports and PLAY. Another option is to leave the name emp­ty and enter the MIDI out­put num­ber '3'.

We hear the out­put on the Yamaha piano, although port num­bers were incor­rect on the inter­face. The incon­sis­ten­cy is resolved by the MIDI dri­ver select­ing ports by name in order of pri­or­i­ty. Port num­bers (and names) are updat­ed as soon as you save or reload the project (data or gram­mar). Then you get:

Why does the name "Yamaha piano" appear in Pianoteq set­tings, but not in the MIDI ports scanned by BP3? This is a mys­tery that expert users of a MIDI stu­dio could prob­a­bly solve… For the time being, just write "Yamaha piano" in the com­ment field at the right of "USB MIDI interface". 

The _part() command

An impor­tant fea­ture imple­ment­ed in October 2024 is the abil­i­ty to send parts of a Bol Processor score to sep­a­rate out­puts. Parts are iden­ti­fied by the "_part(x)" com­mand in which 'x' is an inte­ger in range 1..12. We will be able to han­dle more than 12 parts if it turns out to be necessary.

The "_part(x)" com­mand directs MIDI mes­sages to a spe­cif­ic MIDI out­put, which in most cas­es will be an instru­ment. The image on the side shows the map­ping of port #3 (USB MIDI inter­face) to part #2, as set up in its filter.

By default, MIDI out­puts "hear" all 12 parts, but here we've restrict­ed this one to part #2.

For MIDI port #0 (Bus 1) we've restrict­ed the out­put to part #5.

Let us play the fol­low­ing score:

C3 D3

This sequence of notes is heard on both instru­ments. As there is no "_part()" com­mand in the score, all out­puts send the MIDI messages.

Now let us try:

G2 _part(5) C3 _part(2) D3

Note G2 is heard on both instru­ments. But, as expect­ed, the note C3 is heard on Bus 1 and D3 is heard on the USB MIDI inter­face.

The "_part()" com­mand has exact­ly the same syn­tac­tic behav­iour as "_chan()" and "_ins()". For exam­ple, it "fol­lows" the score along the fields of poly­met­ric struc­tures:

G2 _part(5) C3 {D3 E3, _part(2) B2 _part(5) A2} F3 _part(2) G3

In this exam­ple, G2 is heard on both instru­ments. Then C3 is sent to Bus 1, as well as D3 and E3, since they are the first field of the poly­met­ric struc­ture. In the same time, B2 is sent to the USB MIDI inter­face, then A2 to Bus1. At the out­put of the poly­met­ric struc­ture, F3 is sent to Bus 1 which was the map­ping before the struc­ture. At last, G3 is sent to the USB MIDI inter­face.

The sound-object graph shows that D3 and B2 are played togeth­er, although on dif­fer­ent instru­ments, and E3 and A2 are played togeth­er on the instru­ment con­nect­ed to Bus 1.

Parts are most­ly rel­e­vant when import­ing digi­tised scores. They are used to declare instru­ments in MusicXML files. When import­ing a score, the Bol Processor will option­al­ly place "_part()" or "_chan()" com­mands in the import­ed score, so that it can be played on the same set of dig­i­tal instruments.

Using "_part()" is a bet­ter option than "_chan()" to name an instru­ment, because MIDI chan­nels can be mod­i­fied to han­dle micro­ton­al adjust­ments. On the Data page, there is a MANAGE _chan(), _ins(), _part() but­ton that opens a dia­log for con­vert­ing parts to/from chan­nels, parts to/from instru­ments, etc.

An input

Setting up an input fol­lows exact­ly the same pro­to­col as set­ting up the out­put. For exam­ple, we can set up the input on "Pocket Key 25” as shown above. “USB MIDI Interface” (the Yamaha piano) is anoth­er pos­si­ble choice. Let us con­tin­ue with Pocket Key 25.

Windows users can sim­ply plug their exter­nal MIDI key­board (e.g. "Pocket Key 25”) to a USB port of their com­put­er, as it will be auto­mat­i­cal­ly recog­nised and set up by the system.

Connecting an input to BP3 is of lit­tle inter­est if BP3 does noth­ing with input events. The instruc­tions it can han­dle are list­ed in the sec­tion List of scripts for deal­ing with real-time MIDI below. "Wait for note…" means that BP3 will stop play­ing until it receives a NoteOn of the note in ques­tion — even with veloc­i­ty zero.

Let us pro­gram this on a Data page for example:

_script(Iwait for C3 channel 1) _transpose(12) _vel(60) E2 • D2 E2 • _vel(65) B2 D2 E2 • G2 B2 D2 E2 • _vel(70) F#2 G2 B2 D2 E2 • Bb2 F#2 G2 B2 D2 E2 • _vel(75) C2 Bb2 F#2 G2 B2 D2 E2 • _vel(77) G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(80) A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(85) Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(87) C#2 Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(90) F2 C#2 Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2

The script com­mand tells that the per­for­mance should start when note C3 is received on MIDI chan­nel 1. To avoid any con­fu­sion about octave num­bers, I have writ­ten the name on the low­est key of my Pocket Key 25 (see pho­to). This con­fu­sion is made worse by the fact that the Italian/Spanish/French con­ven­tion uses low­er octave numbers!

So, the labelled key is the one we need to press to start this show. Let's try it…

When the PLAY but­ton is clicked on the Data page, a flash­ing STOP but­ton is dis­played. The machine would wait for­ev­er unless the cor­rect MIDI event has been received. The STOP but­ton — or the PANIC but­ton at the top right — can be used to abort the process clean­ly. If all goes well, press­ing the C3 key should pro­duce this sound:

Harm Visser's '-da.acceleration' example
Notice that the _transpose(12) instruc­tion plays notes one octave higher!

(This lit­tle "accel­er­a­tion" piece was com­posed by Harm Visser to illus­trate the peri­od nota­tion. Read his tuto­r­i­al.)

Multiple inter­rup­tions are of course pos­si­ble. Try this:

_script(wait for C3 channel 1) _transpose(12) _vel(60) E2 • D2 E2 • _vel(65) B2 D2 E2 • G2 B2 D2 E2 _script(wait for C4 channel 1) • _vel(70) F#2 G2 B2 D2 E2 • Bb2 F#2 G2 B2 D2 E2 • _vel(75) C2 Bb2 F#2 G2 B2 D2 E2 • _vel(77) G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(80) A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(85) Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(87) C#2 Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(90) F2 C#2 Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2

Now the machine will start its per­for­mance after receiv­ing a NoteOn of C3. It will then stop after three beats and wait for a NoteOn of C4. A note­wor­thy detail is that one sec­ond after an inter­rup­tion, AllNotesOff is sent to all MIDI chan­nels and the ped­als are set to off. This pre­vents notes wait­ing for their NoteOff from being heard. This "All Notes Off" fea­ture can be turned off in the pref­er­ences file.

MIDI input filters

Let us play with the con­tin­u­ous impro­vi­sa­tion "Mozart’s musi­cal dice game" (called "-gr.Mozart" in the "ctests" fold­er). If this project is set for real-time MIDI, the impro­vi­sa­tion will not stop until we click on the STOP or PANIC but­ton. Inserting a "wait for note…" at the begin­ning would of course stop the per­for­mance at the begin­ning of every vari­a­tion. Beware that you will have to write "do2" instead of "C3" due to the note convention!

But let's try some­thing else, using the exter­nal key­board (the Pocket Key 25 or Yamaha piano) to play notes on top of the per­for­mance. How strange! We don't hear any notes played on the exter­nal key­board unless it's con­nect­ed direct­ly to the out­put device.

The rea­son for this becomes clear after click­ing on the FILTER but­ton for MIDI input 2:

All types of MIDI events are list­ed along with how they are processed by BP3. Here we are only inter­est­ed in NoteOn/NoteOff events. The default set­ting is '1', which means that they can trig­ger script com­mands, but are not for­ward­ed to the MIDI out­put. This is why 'C3/do2' was able to start the per­for­mance, although we could not hear it.

To play notes over the per­for­mance, we need to set the sta­tus of NoteOn and NoteOff to '2'. Note: If we only set the NoteOn sta­tus, BP3 will auto­mat­i­cal­ly set the NoteOff sta­tus to avoid con­fu­sion. Once you have changed the set­tings, click SAVE MIDI ports, then PRODUCE ITEM(S).

Since the Pocket Key 25 key­board sends only NoteOn/Noteoff mes­sages, we could as well set oth­er event fil­ters (KeyPressure, etc.) to '0'.

These fil­ter set­tings are stored, togeth­er with the MIDI port names or num­bers, in a tem­po­rary file whose name depends on both the ses­sion num­ber (cre­at­ed by your brows­er) and the project name. A copy of these set­tings is stored in the (per­ma­nent) fold­er "midi_resources". This stor­age makes it pos­si­ble to launch sev­er­al instances of BP3 on the same brows­er or on dif­fer­ent browsers, as we will now see.

Several BP3s performing and communicating

From the pre­vi­ous descrip­tion of inter­ac­tions via MIDI events — lim­it­ed for the time being to wait­ing for a par­tic­u­lar note — you may have guessed that a great fea­ture of the Bol Processor BP3 envi­ron­ment is the pos­si­bil­i­ty of run­ning sev­er­al BP3s, on dif­fer­ent machines, or even on a sin­gle machine and the same brows­er… in coop­er­a­tion with real humans play­ing MIDI instruments!

Each instance of BP3 can be thought of as a 'musi­cian' with their own com­po­si­tion­al skills embed­ded in a gram­mar or data (a set of pre-composed musi­cal frag­ments). We are work­ing on inter­ac­tions that will allow each musi­cian to mod­i­fy the behav­iour of anoth­er musician's gram­mar, for exam­ple by chang­ing rule weights — which may result in some rules being sup­pressed while oth­ers are acti­vat­ed — or chang­ing metronome set­tings if they need to per­form faster/slower, etc. All these fea­tures were part of ear­li­er ver­sions (BP2) sev­er­al decades ago!

Let us start with an extreme­ly sim­ple exam­ple using the "wait for note…" script.

Create two projects that con­tain only data, for exam­ple "-da.Beatrix" and "-da.Alan":

-se.Beatrix
{2, C#4 Eb4 A4 G#4 C4 Bb4 F#4 G4 B4 D4 E4}

-se.Alan
_script(wait for E4 channel 1) {2, - F3 C#3 Eb3 A3 G#3 C3 Bb3 F#3 G3 B3 D3 E3}

Note that these melodies do not con­tain the same num­ber of notes, but they will have the same dura­tion (2 beats) because of their poly­met­ric struc­tures.

We want Alan's per­for­mance to start pre­cise­ly after the last note of Beatrix's per­for­mance. As we don't want E4 to over­lap with F3, we have put a silence '-' before F3. In the fol­low­ing, we'll have a solu­tion to over­come this limitation.

To man­age the inter­ac­tion in MacOS, we need an addi­tion­al IAC port which is (auto­mat­i­cal­ly) named "Bus2". To do this, open Audi MIDI Setup and click on the IAC dri­ver. Then add a port (see pic­ture). You can cre­ate as many ports as you wish.

Set both Beatrix's MIDI out­put and Alan's MIDI input to "Bus2".

Now we want to hear both per­for­mances. Alan's MIDI out­put is sent to "Bus1" and will there­fore be audi­ble on the Pianoteq synthesiser.

Windows and Linux users can con­nect the two per­form­ers more eas­i­ly: send both Beatrix's and Alan's mes­sages to the exter­nal MIDI device, and con­nect Alan's input to the same MIDI device. But… the input fil­ter should receive events and not for­ward them to the out­put, which is the same device, oth­er­wise the loop will pro­duce a dis­as­trous bounc­ing effect!

Back to MacOS, there are two ways to send Beatrix's per­for­mance to the Pianoteq synthesiser:

  • Pianoteq set­tings make it pos­si­ble to lis­ten to both "Bus1" and "Bus2" vir­tu­al ports.
  • You can set up the MIDI event fil­ter on Alan's project to route input NoteOn/NoteOff events to the cur­rent MIDI out­put. See above for filters.

To play the per­for­mance, click PLAY on Alan's project so that it is ready to per­form. Then click PLAY on Beatrix's project. This is the result:

Two phras­es played in sequence by two instances of the BP3 (Beatrix & Alan).

No doubt this sounds rather unmu­si­cal! In fact, we pub­lish taste­less tech­ni­cal exam­ples to encour­age musi­cians to com­pose inter­est­ing pieces! 😀

Using out-time inaudible notes as signals

The idea of begin­ning Alan's per­for­mance with a silence that is filled by Beatrix's final note E4 is unel­e­gant. Below is a bet­ter solution:

-se.Beatrix
{2, C#4 Eb4 A4 G#4 C4 Bb4 F#4 G4 B4 D4 E4} _vel(0) <<C0>>

-se.Alan
_script(wait for C0 channel 1) {2, - F3 C#3 Eb3 A3 G#3 C3 Bb3 F#3 G3 B3 D3 E3}

The secret is the expres­sion "_vel(0) <<C0>>" which is an out-time expres­sion of note C0 with veloc­i­ty zero. The veloc­i­ty ensures that the note won't be heard, and the out-time prop­er­ty gives it a null dura­tion. Any note can be used here pro­vid­ed that it is men­tio­nend in the "_script(wait…)" instruc­tion.

If "_vel(0) <<C0>>" is fol­lowed by more notes, it is nec­es­sary to reset the veloc­i­ty to its default val­ue. The solu­tion is to write it between curly brack­ets, so that _vel(0) only applies to the con­tent of the expres­sion: "{_vel(0) <<C0>>}"

Checking the time accuracy

Let us check that the real-time syn­chro­ni­sa­tion is not affect­ed by delays. We'll now ask Alan and Beatrix to play the same piece of music (one octave apart) in the same time.

This time, Alan will start:

_transpose(12) _vel(60) E2 • D2 E2 • _vel(65) B2 D2 E2 • G2 B2 D2 E2 • _vel(70) F#2 G2 B2 D2 E2 • Bb2 F#2 G2 B2 D2 E2 • _vel(75) C2 Bb2 F#2 G2 B2 D2 E2 • _vel(77) G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(80) A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(85) Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(87) C#2 Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(90) F2 C#2 Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2

In MacOS, Alan will send MIDI events to "Bus2". Beatrix will lis­ten to "Bus2" and send MIDI events to "Bus1" (Pianoteq). Beatrix will set her input fil­ter to the pass option, rout­ing the incom­ing events to the out­put. The Pianoteq syn­the­sis­er will be set to lis­ten to "Bus1" only.

This is the score of Beatrix:

_script(wait for E3 channel 1) _transpose(24) _vel(60) E2 • D2 E2 • _vel(65) B2 D2 E2 • G2 B2 D2 E2 • _vel(70) F#2 G2 B2 D2 E2 • Bb2 F#2 G2 B2 D2 E2 • _vel(75) C2 Bb2 F#2 G2 B2 D2 E2 • _vel(77) G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(80) A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(85) Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(87) C#2 Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2 • _vel(90) F2 C#2 Eb2 A2 G#2 C2 Bb2 F#2 G2 B2 D2 E2

To start the per­for­mance, first click on the PLAY but­ton of Beatrix's project, then on the PLAY but­ton of Alan's project.

Have you noticed that Beatrix is wait­ing for E3, which does not appear in Alan's score? Oh yes, it does! There is a _transpose(12) com­mand that changes E2 (the first note) to E3. So, it works. This is the performance:

Two super­im­posed per­for­mances (one octave apart), played by two instances of the BP3 (Beatrix & Alan).

Not too bad? Despite the lack of musi­cal inter­est, we must admit that the super­im­po­si­tion is tech­ni­cal­ly accept­able, even if it is not per­fect: there is a delay of about 60 mil­lisec­onds on the first note, the time it takes Beatrix's machine to detect that it has received a NoteOn for C3. The sub­se­quent notes are pro­grammed to com­pen­sate for this delay, but there are still dis­crep­an­cies (which can be quan­ti­fied on the Pianoteq MIDI input). They seem to be caused by delays out­side BP3.

You can adjust the delay in Beatrix's project set­tings "-se.Beatrix". There is a para­me­ter called "Sync delay", which is the num­ber of mil­lisec­onds Beatrix's out­put events should be post­poned after the syn­chro­ni­sa­tion. We cur­rent­ly find that 380 ms is a good value.

In fact, the super­im­po­si­tion would sound even bet­ter if both per­for­mances were trig­gered by the same event, such as the con­duc­tor press­ing a key on the exter­nal key­board. This exer­cise was only intend­ed to show that syn­chro­ni­sa­tion between "vir­tu­al musi­cians" works well.

Working with multiple MIDI inputs

In the pre­vi­ous exam­ple, we could decide that Alan's per­for­mance will start when he receives a par­tic­u­lar note from the Pocket Key 25 key­board. In this case, we need to click on both START but­tons, putting both 'musi­cians' in wait mode, and the per­for­mance will not start until the cor­rect key is pressed on the keyboard.

This case is man­age­able with sin­gle inputs on each instance of BP3. More com­pli­cat­ed cas­es, how­ev­er, require exter­nal 'actors', such as a Pocket Key 25 key­board send­ing to all the 'musi­cians' syn­chro­ni­sa­tion mes­sages, or mes­sages mod­i­fy­ing para­me­ters in gram­mars, chang­ing the metronome val­ue, etc.

To achieve this, the Bol Processor is a able to man­age mul­ti­ple MIDI inputs.

The new game is as fol­lows: both Beatrix and Alan will take turns play­ing vari­a­tions of Mozart's musi­cal dice game (see '-gr.Mozart'), one octave apart. They will use the Improvise mode to con­tin­ue throw­ing the dice and cre­at­ing unheard vari­a­tions. But they will wait for a sig­nal from the oth­er to start play­ing a new variation.

In short, both musi­cians will use the same gram­mar, with only a small change for mutu­al syn­chro­ni­sa­tion. Their set­tings must be care­ful­ly adjusted:

  • Select Italian/Spanish/French as a note convention
  • Check Non-stop improvise
  • Adjust Pclock = 3 and Qclock = 11 to get the same metronome speed of 220 bpm
  • Set Sync delay to 380 ms
  • We do't want both musi­cians to repeat the same vari­a­tions. So, set the Seed for randomization to dif­fer­ent val­ues, for instance '1' and '2'. Or set it to zero to instruct the machine to seed the ran­dom sequence with an arbi­trary num­ber of its choice.

In the cur­rent ver­sion of BP3, the eas­i­est way to send a sig­nal is to send a note with a veloc­i­ty of zero, which will there­fore go unheard. So we need to change the gram­mar to add these par­tic­u­lar notes.

In fact, the same notes should nev­er be part of the score, so that the sig­nal is real­ly sent at the end. This is easy with Mozart's game, for exam­ple we can use C# (do#) for the syn­chro­ni­sa­tion. Below are the tops of the gram­mars used by Beatrix and Alan.

Beatrix '-gr.Beatrix':

-se.Beatrix
ORD
gram#1[1] S --> _script(wait for do#3 chan­nel 1) _vel(80) A B _vel(0) do#2
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 [Select rules ran­dom­ly and apply from left to right]
etc.

Alan's '-gr.Alan':

-se.Alan
ORD
gram#1[1] S --> _script(wait for do#2 chan­nel 1) _vel(80) _transpose(-12) A B _vel(0) do#4
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 [Select rules ran­dom­ly and apply from left to right]
etc.

Again, we put do#4 at the end of Alan's per­for­mance because it is played as do#3 (one octave low­er) due to the _transpose(-12) instruc­tion.

Now we need to set up the MIDI inputs and out­puts. Beatrix will send events to "Bus 1" which is the Pianoteq syn­the­siz­er. She will receive events from "Bus 2", use them for syn­chro­ni­sa­tion, and for­ward them to the output.

Alan will send events to "Bus 2" and lis­ten to "Bus 1" for the synchronisation.

This is all per­fect on paper, but who is going to start? We have cre­at­ed a chick­en and egg sit­u­a­tion, so we need a super­pow­er to start the process! Actually, a real human press­ing the do#2 key on a Pocket Key 25 key­board will do.

The inter­face has a Add an input but­ton. We click it on Alan's project and paste the name Pocket Key 25. We also use the com­ment fields to remem­ber the use of each port:

To start the con­cert, we'll click START on both projects. The order is irrel­e­vant. Then we'll press a key on the Pocket Key 25. Which key?

If we press the do#2 key, we will cer­tain­ly trig­ger Alan's impro­vi­sa­tion and the cycle will start. But if we press the do#3 key, noth­ing will hap­pen because the fil­ter of the Pocket Key 25's input, by default, does not trans­mit NoteOns to the out­put. So Beatrix won't hear it… By set­ting NoteOn to sta­tus '2' (treat and pass) on this fil­ter, it will be pos­si­ble to decide who will start the per­for­mance: do#2 for Alan and do#3 for Beatrix.

Here we go (start­ing with Alan):

Alan and Beatrix (two instances of BP3) play­ing vari­a­tions of Mozart's musi­cal dice game

👉  This sim­ple show should con­vince musi­cians to cre­ate "vir­tu­al bands" of BP3s play­ing dif­fer­ent gram­mars and send­ing spe­cif­ic syn­chro­ni­sa­tion sig­nals accord­ing to which vari­a­tion has just been pro­duced. Along with human per­form­ers who join in the fun!

The "vir­tu­al musi­cians" can be on the same com­put­er or remote­ly con­nect­ed via net­work (BlueTooth) or MIDI cables and USB inter­faces. If they are on the same com­put­er, they can be run on dif­fer­ent browsers and/or the same brows­er. In the lat­ter case, BP3 will not allow the same project (gram­mar or data) to be run in the same ses­sion. In gen­er­al, just like human musi­cians in an orches­tra have indi­vid­ual scores, it makes sense that vir­tu­al musi­cians don't share the same project…

The num­ber of MIDI inputs and out­puts in a project is cur­rent­ly lim­it­ed to 32. It is very unlike­ly that a (human) musi­cian will need more!

Synchronise to a sequence (or list) of notes

The fol­low­ing expression

gram#1[1] S --> _script(wait for C3 chan­nel 1) - _script(wait for E3 chan­nel 1) etc.

syn­chro­nis­es the pro­duc­tion to the sequence of notes C3 E3 (what­ev­er the dura­tion and veloc­i­ty). This cre­ates inter­est­ing sit­u­a­tions where a "vir­tu­al musi­cian" is expect­ed to start play­ing after receiv­ing a sig­nal (C3) from one part­ner, then a sig­nal (E3) from anoth­er partner.

Note that there is a silence '-' between the two script instruc­tions. If there is no silence, then BP3 will resume play­ing if either C3 or E3 has been received.

Remember that because of the MIDI chan­nel spec­i­fi­ca­tion (range 1 to 16), the detec­tion of sig­nals can be very selec­tive. They are also inaudi­ble when trans­mit­ted by NoteOns with veloc­i­ty zero.

Crashing the band!

In the exam­ple of Alan & Beatrix play­ing Mozart, the con­nec­tion seems to cre­ate a loop: Beatrix sends events to Pianoteq and Alan (bus 1), who in turn sends events to Beatrix (bus 2). Isn't that dangerous?

The rea­son it doesn't crash is that Alan's input "fromBeatrix" (Bus 1) is fil­tered: NoteOns are received and processed (for syn­chro­ni­sa­tion), but not passed to the out­put (Bus 2), i.e. to Beatrix. You can try to change the fil­ter of input "Bus1" on Alan's project, set­ting NoteOns to sta­tus '2' (treat + pass): you will get a superb crash after a flood of notes!
➡  This shouldn't hap­pen, because BP3's MIDI dri­vers have been equipped with an anti-bouncing mechanism.

Working with multiple MIDI outputs

The Bol Processor cur­rent­ly accepts up to 32 MIDI inputs and outputs.

Example of a project using two inputs and two outputs:

A set­up with two MIDI out­puts and two MIDI inputs

The pro­ce­dure for adding out­puts is the same as the one for adding inputs: click on the Add an out­put but­ton, then enter the name of the MIDI device if you know it exact­ly, oth­er­wise leave it blank and let the machine con­nect it by default to the next avail­able out­put, while sug­gest­ing oth­er options:

🎹 Your real-time MIDI set­tings:
MIDI out­put = 0: “Bus 1” - Pianoteq
MIDI out­put = 3: “USB MIDI Interface” - Yamaha piano
MIDI input = 1: “Bus 2” - from Alex
MIDI input = 2: “Pocket Key 25” - a small key­board

🎹 Setting up MacOS MIDI sys­tem
MIDI out­put = 0: “Bus 1” 👉 the name of your choice
MIDI out­put = 3: “USB MIDI Interface” 👉 the name of your choice
MIDI input = 1: “Bus 2” 👉 the name of your choice
MIDI input 1 makes BP3 inter­ac­tive
MIDI input = 2: “Pocket Key 25” 👉 the name of your choice
MIDI input 2 makes BP3 inter­ac­tive

🎶 More MIDI out­put options were avail­able:
MIDI out­put = 1: “Bus 2”
MIDI out­put = 2: “Pocket Key 25”

🎶 More MIDI input options were avail­able:
MIDI input = 0: “Bus 1”
MIDI input = 3: “USB MIDI Interface”

The fact that a MIDI input or out­put is "avail­able" does not guar­an­tee that it will do what we want it to do. For exam­ple, send­ing MIDI mes­sages to the Pocket Key 25 key­board will actu­al­ly do nothing.

Filtering MIDI outputs

In the exam­ple above, MIDI out­put 3 (the Yamaha piano con­nect­ed to the USB MIDI Interface) has the fol­low­ing filter:

A fil­ter for MIDI out­put 3

The chan­nel fil­ter spec­i­fies that the Yamaha piano will receive all MIDI chan­nels except those emit­ted on MIDI chan­nel 2. Filtering MIDI chan­nels makes it pos­si­ble to send events exclu­sive­ly to dif­fer­ent instruments.

MIDI events can also be fil­tered by type. The idea is the same as for MIDI input fil­ters, see above.

👉  If you do not hear any sound in real-time MIDI, you may con­sid­er check­ing the out­put MIDI fil­ters before you kick the piano or screw up its cables!

Using standard MIDI control

MIDI has stan­dard con­trol mes­sages, name­ly Start, Continue and Stop, which can be used to coor­di­nate mul­ti­ple "vir­tu­al musi­cians" (instances of BP3). The advan­tage is the clar­i­ty of the data and the gram­mars pro­grammed for inter­ac­tions. The dis­ad­van­tage is that these mes­sages are not assigned to spe­cif­ic MIDI chan­nels. This can be a prob­lem with a large num­ber of "musi­cians". They also intro­duce a delay of about 250 mil­lisec­onds due to the time it takes for the MIDI device to process them.

Let us look at a triv­ial exam­ple (of no musi­cal inter­est), again with Beatrix and Alan play­ing togeth­er. This time, they take turns play­ing their items (sim­ple sequences of notes).

Alan will start first. Below is the data:

E3 D3 C3 _script(MIDI send Start) _script(wait for Continue) A2 B2 C3

In short, he will play three notes (E3 D3 C3), then send a START to Beatrix and wait for a CONTINUE from Beatrix, then on receipt play the final three notes A2 B2 C3.

This is Beatrix's data:

_script(wait for Start) E4 D4 C4 _script(MIDI send Continue)

Start and Continue should be "heard" by Beatrix. Automatically, Stop will have the same status.

Beatrix's project sends its out­put to "Bus 1", the Pianoteq syn­the­siz­er. Its input is con­nect­ed to the vir­tu­al port "Bus 2".

Alan's project sends its out­put to the vir­tu­al port "Bus 2", and its input is con­nect­ed to "Bus 1".

We'll start the per­for­mance with Beatrix. Her machine will stay wait­ing for START. Then we'll start Alan's part, which will play three notes, then send a START mes­sage to Beatrix, who will play her part, and return to Alan, via a CONTINUE mes­sage, for the final part…

This all sounds log­i­cal, but it doesn't work! We do hear Alan's E3 D3 C3, but then noth­ing… The first rea­son is that Beatrix should be able to hear Alan's START com­mand, which is no longer a NoteOn as in the pre­vi­ous exam­ples. This means that the fil­ter of her input "Bus 2", from which she receives Alan's MIDI mes­sages, must be set cor­rect­ly. The Start event should be received, see pic­ture on the side. Also remem­ber that NoteOn and NoteOff should be received and trans­mit­ted to the out­put (the Pianoteq synth).

Well, now we hear Alan's E3 D3 C3 fol­lowed with Beatrix's E4 D4 C4, but then… nothing! 😢

Careful analy­sis is need­ed to solve the prob­lem. However, this is sim­ple log­ic. Remember that Alan is play­ing on "Bus 2", which is not con­nect­ed to any MIDI device. If we hear Alan's pro­duc­tion, it is because it is received by Beatrix on "Bus 2" and then for­ward­ed to "Bus 1" (the Pianoteq synth). The prob­lem is that the final part A2 B2 C3 is sent to Beatrix, but she has already stopped lis­ten­ing because her own data is finished!

You can imag­ine a band in which one musi­cian plays an impro­vi­sa­tion and then gives a sig­nal to anoth­er musi­cian to start their own impro­vi­sa­tion, but the care­less musi­cian has already vacat­ed the place believ­ing that the pro­gramme was fin­ished. The solu­tion is to tell the musi­cians not to go away until they receive a STOP sig­nal. Maybe a sig­nal from a con­duc­tor (here using the Pocket Key 25 key­board), maybe a sig­nal from the musi­cian who is in charge of end­ing the per­for­mance. So we'll tell Alan to send a STOP sig­nal at the end of his per­for­mance, and Beatrix to wait for Alan's STOP sig­nal. Below are the revised scores.

// Alan
E3 D3 C3 _script(MIDI send Start) _script(wait for Continue) A2 B2 C3 _script(MIDI send Stop)

// Beatrix
_script(wait for Start) E4 D4 C4 _script(MIDI send Continue) _script(wait for Stop)

The MIDI mes­sages Start, Continue, Stop have been used here to facil­i­tate the read­ing of scores (or gram­mars), but these can be replaced by NoteOns with dura­tions and veloc­i­ties zero on dif­fer­ent MIDI chan­nels when work­ing with a larg­er num­ber of actors.

By the way, using MIDI mes­sages Start, Continue and Stop can be prob­lem­at­ic with phys­i­cal or vir­tu­al MIDI devices. The Yamaha piano, for exam­ple, does not trans­mit these mes­sages. So, when con­nect­ed to an input, it will only send 3-byte mes­sages such as NoteOn/NoteOffs. In the Windows envi­ron­ment, the Microsoft GS Wavetable Synth also does not trans­mit any mes­sage at all. The best way to exchange mes­sages is via vir­tu­al MIDI ports cre­at­ed by "loopMIDI" (see below). In Linux, vir­tu­al ports such as 'VirMIDI 0-0' (see below) do not seem to trans­mit these Start, Continue and Stop messages.

For geeks: In the Bol proces­sor, scripts are append­ed to the next fol­low­ing sound object. For exam­ple, _script(wait for Start) is append­ed to note E4 in Beatrix's score. But what about scripts at the end of a score? The secret is that BP3 cre­ates an invis­i­ble MIDI event (ActiveSensing) at the end of each ele­ment to which it can append the final scripts.

List of scripts for dealing with real-time MIDI

The list below will be kept up to date as there are many scripts on the agen­da. These instruc­tions are not case-sensitive.

Input scripts

When a note is spec­i­fied, be sure to use the same note con­ven­tion as in the project, e.g. C3 or do2 or sa3, etc.

Wait for note chan­nel cWait for a NoteOn of the spec­i­fied note on chan­nel c (1…16)
Wait for StartWait for a Start MIDI mes­sage (250)
Wait for ContinueWait for a Continue MIDI mes­sage (251)
Wait for StopWait for a Stop MIDI mes­sage (252)
Wait for­ev­erWait until STOP or PANIC but­ton is clicked
Velocity param Kx = note chan­nel cSet para­me­ter Kx (0 < x < 128) to the veloc­i­ty (range 0…127) of the spe­cif­ic note on chan­nel c (1…16)
Control param Kx = #y chan­nel cSet para­me­ter Kx (0 < x < 128) to the val­ue (range 0…127) of MIDI con­troller #y (0 < y < 128) on chan­nel c (1…16)

Output scripts

Hold for x millisecondsDelay all sub­se­quent events by the spec­i­fied dura­tion x (inte­ger).
Send StartSend Start MIDI mes­sage (250)
Send ContinueSend Continue MIDI mes­sage (251)
Send StopSend Stop MIDI mes­sage (252)

Scripts on top of a grammar

(To be continued)

Capture incoming events

The _capture() com­mand allows incom­ing MIDI events to be record­ed to a 'cap­ture' text file. See the Capture MIDI input page for explanations.

Alternatives to IAC

Here are the equiv­a­lents of Apple's IAC (Inter-Application Communication) for each system:

Windows environment

On Windows, you can use soft­ware like loopMIDI or virtualMIDISynth to cre­ate vir­tu­al MIDI ports. These tools work sim­i­lar­ly to the IAC Driver on macOS:

  • loopMIDI: Created by Tobias Erichsen, loopMIDI is a pop­u­lar choice for cre­at­ing vir­tu­al MIDI ports on Windows. It allows you to cre­ate and man­age sev­er­al vir­tu­al ports which can be used by appli­ca­tions to com­mu­ni­cate with each other. 
  • virtualMIDISynth: This is anoth­er tool that can be used to cre­ate a MIDI syn­the­siz­er device which can be accessed via a vir­tu­al MIDI cable. 

These tools inte­grate with soft­ware appli­ca­tions that sup­port MIDI, pro­vid­ing a seam­less way to con­nect var­i­ous MIDI appli­ca­tions with­out need­ing exter­nal MIDI hardware.

Linux environment

On Linux, ALSA (Advanced Linux Sound Architecture) pro­vides capa­bil­i­ties to cre­ate vir­tu­al MIDI devices through its sequenc­ing API.

  • snd-virmidi: This ALSA MIDI dri­ver pro­vides vir­tu­al MIDI ports for send­ing and receiv­ing MIDI between appli­ca­tions run­ning on the same sys­tem. It's part of the stan­dard ALSA mod­ule set and can be con­fig­ured to pro­vide mul­ti­ple ports.

To set up vir­tu­al MIDI ports on Linux using ALSA, you typ­i­cal­ly need to load the snd-virmidi mod­ule. You can do this by running:

sudo modprobe snd-virmidi midi_devs=2

This com­mand loads the snd-virmidi mod­ule and sets it up to pro­vide two vir­tu­al MIDI devices (you can increase the num­ber of devices by chang­ing the midi_devs para­me­ter). The vir­tu­al ports, name­ly 'VirMIDI 0-0' and 'VirMIDI 0-1' , can then be accessed by MIDI appli­ca­tions on the Linux sys­tem. Please note that they do not appear to trans­mit the Start, Stop and Continue messages.

👉 This is done auto­mat­i­cal­ly by the "install_bp3.sh" shell script installing BP3 on Linux/Ubuntu (down­load here).

Bernard Bel
June-August 2024