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 pro­gram­mers: 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 exact­ly the same in MacOS, Windows and Linux. They have been test­ed on a recent PowerBook run­ning MacOS (Sonoma), and an HP Intel Core com­put­er run­ning Windows 10 (64-bit) and LinuxLite 7.0 (in Ubuntu).

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. 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 is 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’… Never mind the dif­fer­ence, BP3 will take care of it when try­ing to con­nect to real or vir­tu­al devices!

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. The client num­ber is more spe­cif­ic to a MIDI device. But the only reli­able iden­ti­fi­ca­tion is its name, which is emp­ty by default: the next field after the input/output number.

Let us first 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 the 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 synthesizer.

To con­nect exter­nal MIDI devices to Windows, you may need to install an envi­ron­ment sim­i­lar to IAC on MacOS. Read details below. However, the 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 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 devices that enable MIDI appli­ca­tions to com­mu­ni­cate inter­nal­ly with­in the same machine with­out requir­ing exter­nal MIDI hard­ware. 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 warn­ing”. 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 out­put = 1: “Bus 2”
MIDI out­put = 2: “Pocket Key 25”
MIDI input = 0: “Bus 1”
MIDI input = 1: “Bus 2” 👉 the num­ber of your choice
MIDI input = 2: “Pocket Key 25”
BP3 will be inter­ac­tive
Warning: name of MIDI source or/and out­put changed (see above)

(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. It also assigned MIDI input to port ‘1’, but we won’t need this immediately.

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 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 solu­tion is to write the name “Bus 1″ as the MIDI out­put. In the same way, you can write “Pocket Key 25″ (or what­ev­er is detect­ed as your input MIDI device) to the MIDI input, as we may 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 setting.

To the right of the MIDI port name is anoth­er 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. However, if the piano is actu­al­ly com­mu­ni­cat­ing with it, we should see a flash­ing red light. In MacOS, have found that 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 piano is recog­nised and con­nect­ed. The eas­i­est way to con­nect it to the BP3 is to delete the MIDI out­put name “Bus 1”, click SAVE, then PLAY. Whatever hap­pens, we’ll get a warn­ing and see the fol­low­ing diagnosis:

MIDI input = 1: “Pocket Key 25”
MIDI out­put = 0: “???”
🎹 Setting up MacOS MIDI sys­tem
MIDI out­put = 0: “Bus 1” 👉 the num­ber of your choice
MIDI out­put = 1: “Bus 2”
MIDI out­put = 2: “Pocket Key 25”
MIDI out­put = 3: “USB MIDI Interface
MIDI input = 0: “Bus 1”
MIDI input = 1: “Bus 2” 👉 the num­ber of your choice
MIDI input = 2: “Pocket Key 25” 👉 the name of your choice
MIDI input = 3: “USB MIDI Interface”
BP3 will be inter­ac­tive
Warning: name of MIDI source or/and out­put changed (see above)

As the MIDI input is iden­ti­fied as “Pocket Key 25”, it 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.

We hear the out­put on the Yamaha piano, although port num­bers are incor­rect on the inter­face. The port num­bers (and names) will be fixed as soon as you save or reload the project (data or grammar).

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 expe­ri­enced users of a MIDI stu­dio could prob­a­bly solve…

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 chan­nel 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 chan­nel 1) _transpose(12) _vel(60) E2 • D2 E2 • _vel(65) B2 D2 E2 • G2 B2 D2 E2 _script(wait for C4 chan­nel 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 work 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 as “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 ‘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 musi­cian’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 want to play 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 chan­nel 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 structures.

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.

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 only pub­lish taste­less tech­ni­cal exam­ples to encour­age musi­cians to com­pose inter­est­ing pieces! 😀

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 have a fil­ter that routes the received 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 chan­nel 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. 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 impro­vise
  • 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 ran­dom­iza­tion 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 (recent) 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’ (accept and for­ward) 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 session.

The num­ber of MIDI inputs in a project is cur­rent­ly lim­it­ed to 32. It is very unlike­ly that a 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 does­n’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 won’t hap­pen on Linux, because its MIDI dri­ver has been equipped with an anti-bouncing mech­a­nism. The same will soon be imple­ment­ed on MacOS and Windows.

Working with multiple MIDI outputs

The Bol Processor accepts up to 32 MIDI 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”

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 this instru­ment will receive all MIDI chan­nels except chan­nel 2. Filtering MIDI chan­nels makes it pos­si­ble to send events exclu­sive­ly to dif­fer­ent instruments.

In this set­up, for exam­ple, chan­nel 2 events can be sent exclu­sive­ly to MIDI out­put 0 (Pianoteq). This allows parts of the musi­cal work to be played by spe­cif­ic instruments.

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

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”.

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). The same approach can be used with gram­mars where each part is an impro­vi­sa­tion, as we have shown with the Mozart example.

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)

We’ll start the per­for­mance with Beatrix. Her machine will wait for START. Then we’ll start Alan’s part, which will play three notes, then hand over to Beatrix, who will play her part, and return to Alan for the final part…

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

This all sounds log­i­cal, but it does­n’t work! We 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 oth­er musi­cian has left the place believ­ing that the pro­gramme was fin­ished. The solu­tion is to tell the musi­cians not to leave their places 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 NoteOn with veloc­i­ty zero on dif­fer­ent MIDI chan­nels when work­ing with a larg­er num­ber of actors.

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)
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)

Alternatives to IAC

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

👉  The fol­low­ing is an expla­na­tion from ChatGPT…

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 mod­probe snd-virmidi midi_devs=1

This com­mand loads the snd-virmidi mod­ule and sets it up to pro­vide one vir­tu­al MIDI device (you can increase the num­ber of devices by chang­ing the midi_devs para­me­ter). The vir­tu­al ports can then be accessed by MIDI appli­ca­tions on the Linux system.

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

Leave a Reply

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