A one-click installer of Bol Processor BP3 is available. It is called "BolProcessorInstaller.exe" and it can be downloaded here (unique location).
This installer is used for both initial installation and updates. Each time you run it, it will download the latest versions of the BP3 console, including its source files, the interface PHP files, and the sample set contained in the 'ctests' folder. Data, grammars and scripts that you've created will not be deleted. However, if you have modified files in the 'ctests' folder, they will be reverted to the distribution version.
This installation is checked with Windows 10 running on an HP Intel Core i5-6200U (64-bit, 8 Gb RAM) and MAMP (free) running PHP 8.3.1. It should work fine with Windows 11, please check it and report!
26 January 2025: The installer "BolProcessorInstaller.exe" is now certified. It should not display a "malicious software" warning. Once opened, before starting the installation, it should mention the name of its creator: "Bernard Bel". Contact us if it doesn't work on your computer!
First install MAMP or XAMPP
The (free) MAMP device running 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 (see below), it will first check that a local Apache server (MAMP or XAMPP) has been installed. Both are suitable since the Bol Processor interface contains exclusively HTML, PHP and JavaScript code. No database is required.
if you choose the (free) MAMP version, both MAMP and MAMP PRO will be installed, and the interface will occasionally invite you to "upgrade" to MAMP PRO. But you don't need it for the Bol Processor!
For MAMP on Windows, the "htdocs" folder is in "C:\MAMP". For XAMPP on Windows, the "htdocs" folder is in "C:\xampp". (To be verified)
If you want Apache to start automatically when you start your computer, this process is easy with MAMP, but a bit more complex with XAMPP: try this method.
Create the 'bp.exe' console
After installing MAMP or XAMPP, run the installer "BolProcessorInstaller.exe" downloaded here.
The installer creates a "bolprocessor" folder in the "htdocs" folder used by MAMP or XAMPP. Make sure that there is only one such folder on your machine, notably if you tried both MAMP and XAMPP in the past. It is safe to rename any unused "htdocs" folder before running the installer.
If you plan to install the "bolprocessor" folder outside the "htdocs" folder, follow the instructions in Relocating "bolprocessor"before running the installer.
As "BolProcessorInstaller.exe" is not yet certified, you may receive a warning that it is from an "unknown source". Click on the option to ignore the warning. If you don't feel confident about doing this, please read the section on Security below.
All steps of the installation are displayed to ensure that they are successful. At the end you'll be asked to press a key.
Now start MAMP or XAMPP. There is an Open WebStart Page button on MAMP (free) which will display a page confirming that the Apache server is running. Probably you will find a Go to Application button on XAMPP manager.
Point your browser at localhost/bolprocessor/php/. This will display the home page of Bol Processor BP3. Otherwise, check that MAMP or XAMPP is set to use port #80.
If you see this image at the top right of the page, the console is ready. Click on the lamp if you prefer to use the light mode for the interface.
You can ignore the next section.
Compile the 'bp.exe' console (if necessary)
The Windows installation of Bol Processor includes the pre-compiled console (named 'bp.exe' ). If, some some reason, the console is not responding, or if you modified its source code (in the source/BP3 directory), you may need to recompile 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 compile the console, which will take a minute or two.
If the frame says that 'gcc' is not responding (see picture) you need to install MinGW. This is the main drawback of Windows: its default installation does not handle 'gcc' (the standard C compiler). You need 'gcc' to compile the Bol Processor console, and perhaps other applications to come. So, install MinGW, carefully following instructions on this page. It is simple, but you shouldn't miss a step!
Once 'gcc' is responding, reload the Bol Processor home page and click on the link to compile 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 different approach to sound synthesis.
A frame asking you to correct the path to Csound. This is the default path for Windows 10, by the way. We tricked the interface into saying it was wrong!
The BP3 interface will be able to figure out the location of "csound.exe" and fix its path accordingly. If it does not respond, you will be asked to change the path and perhaps the name of the Csound console (see image). Once it works after a modification, please contact us so that we can update the default paths and names of Csound in your installation of Windows.
To update the Bol Processor console, its PHP interface and examples (the contents of the "ctests" folder), simply rerun the installer. It will download and install the latest versions of the software and data. It will also delete and replace the precompiled "bp.exe" console.
The installer will not modify or delete any data you have created in the "ctests" folder or outside it. However, if you have modified a sample file without changing its name, it will be reverted to its distribution version.
The installer will also preserve the "_settings.php" file (if it exists), which contains your project settings.
Security
You are right to be concerned about security. Can you be sure that you have downloaded the correct version of "BolProcessorInstaller.exe"? As this executable is certified, there is no known risk of malicious modification.
The size of this file is exactly 1820992 bytes and its MD5 is 9524a9c20c3e300bab509238ad406db2. 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 27 January 2025.
You may also want to know all the details of how it works. Geeks may want to customise it for their own use. Just download this folder which contains the source files (installer.ps1 and setup.iss) along with a summary of how to build the installer.
For readers not conversant with WindowsPowerShell, the following is a description of the process in human language:
Check that an Apache server MAMP or XAMPP is installed by finding either MAMP\htdocs or xampp\htdocs on the computer (not case-sensitive). If it is not found, exit with the warning that either MAMP or XAMPP should be installed.
Download the latest distribution 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 create folders with names: bolprocessor-graphics-for-BP3 php-frontend-master bp3-ctests-main
Create a folder named "bolprocessor" (if it does not yet exist) inside the "htdocs" folder of the Apache server
Copy bolprocessor-graphics-for-BP3/source to htdocs/bolprocessor/ If there is already a "source" folder, 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" folder, delete it
Copy bolprocessor/_settings.php to bolprocessor/php/ (if it exists)
Create a folder htdocs/bolprocessor/csound_resources if it does not yet exist
Copy the content of php-frontend-master/csound_resources to htdocs/bolprocessor/csound_resources Files that already exist should be replaced with their updated versions
Create a folder htdocs/bolprocessor/ctests if it does not yet exist
Copy the content of bp3-ctests-main to htdocs/bolprocessor/ctests Files that already exist should be replaced with their updated versions
Delete the temporary download directory
Replace htdocs/bolprocessor/bp.exe with the updated version.
Relocating "bolprocessor"
The Bol Processor can be installed outside the "htdocs" folder created by MAMP or XAMPP (on your boot drive). You might want it near related projects, or use extra space from an external hard drive. There may also be situations where creating files on the boot drive is restricted.
Fortunately, the process of relocating is very simple.
If you have already created a "bolprocessor" folder by running the installer, copy it to the desired location and delete it from the "htdocs" folder. If not, create an empty "bolprocessor" folder in the desired location.
Let's say you've created an empty folder called "bolprocessor" inside a folder called "MUSIC" on an external drive labelled "D", and MAMP is installed on drive "C". Right-click the start icon at the bottom left of the screen, and select Windows PowerShell (admin). Then type the following command to create a symbolic link — in fact a junction (/J instead of /D):
If you are using XAMPP, replace "\MAMP\" with "\xampp\".
Make sure that the symbolic link you created points to the correct location: you will now see a "bolprocessor" icon in the "htdocs" folder. Double-click it, it should open the destination folder.
You can now safely run the installer. Updates to new versions will be the same way.
Never change the names of the "bolprocessor" folder and symbolic link, otherwise the installation will fail.
The first time you run the Bol Processor, MAMP or XAMPP may ask your permission to display files outside its "htdocs" folder. Please contact us if you're experiencing issues with this relocation!
You can use the same technique to relocate some data files outside the "bolprocessor" folder, for example to a location shared by Dropbox.
You can also use symbolic links to relocate folders outside the "bolprocessor" folder, as explained here.
Uninstall the Bol Processor
Uninstalling the Bol Processor and all the data downloaded or created for its use, is very simple: delete the "bolprocessor" folder and the "htdocs\bolprocessor" symbolic link, if you have created one.
If you need to start XAMPP automatically after a reboot, here's a basic way to do it using systemd, which is the init system for most Linux distributions:
1) Create a systemd service file
Open a text editor to create a new file, for example:
sudo nano /etc/systemd/system/xampp.service
Add the following content to the file:
[Unit] Description=XAMPP Control Panel After=network.target
In May 2024, the Bol Processor BP3 acquired the ability to manage the input and output of MIDI events. This allows it to "communicate" in real time with external MIDI devices (keyboards, synthesizers) and even with other instances of BP3 running on the same machine.
For geeks and programmers: This feature had already been implemented in the earlier (MacOS only) version called 'BP2'. However, the implementation in a C language 'console' to work in MacOS, Linux and Windows environments was more technical. In addition, the concept of "real time" in the current MIDI setup is different from the previous one using Opcode Music System.
The following examples will work the same in MacOS, Windows and Linux. They have been tested on a recent PowerBook running MacOS (Sonoma) with 16 Gb RAM, and an HP Intel Core computer with 8 Gb RAM running Windows 10 (64-bit) and LinuxLite 7.0 (in Ubuntu). Memory size can become critical if many MIDI devices or virtual ports are connected.
Using microtonal scales is now possible in real-time MIDI. Read the Check MIDI microtonality page for details.
Setting up the MIDI environment
Let us assume that you have successfully downloaded, installed and compiled the Bol processor BP3, as described on the page Bol Processor ‘BP3’ and its PHP interface.
In Bol Processor jargon, a 'project' is either a grammar (with a '-gr' prefix) or a set of data (with a '-da' prefix). So, create or load a simple project, e.g. "-da.acceleration" which can be found in the "ctests" folder (download it here).
An output
By default, a project is set up to create MIDI files, as shown on the selector (see picture). Make sure your project is working! Then select Real-time MIDI and click SAVE format.
The selector will now display a different image, as shown below:
By default, the MIDI output used for sending events is numbered '0' — and the MIDI input used for receiving events will be numbered '1'. This is a common situation. In MacOS and Windows, these numbers are taken as 'ports'. In Linux they are considered as 'clients', each 'client' having its own 'ports', so certainly numbers '0' and '1' won't work… Never mind this issue, BP3 will take care of it when scanning real or virtual devices and trying to connect. Read more below.
We cannot rely on "port numbers" alone because they change when we turn on and off MIDI devices connected to the computer. In Linux, the client number is more specific to a MIDI device. In fact, the only reliable identification is its name, which is empty by default: the next field at the right of the input/output number.
Let us check the MIDI output. Windows does this automatically. The good news is that Windows 10 (and presumably later versions) comes with a built-in MIDI device called Microsoft GS Wavetable Synth. The Bol Processor will automatically detect it and connect to it if no other device is connected to the system.
Linux also connects, by default, the output to a virtual device whose client number is '0', but it won't produce any sound in the basic installation of Ubuntu. So, to try real-time MIDI on Linux, you need to connect an external MIDI device via its USB/MIDI interface, or to install a software synthesizer. Read more below.
Clicking Add an input will create fields for you to select an input device. We'll use this later.
To connect external MIDI input/output devices to Windows, you may need to install an environment similar to IAC on MacOS. Read details below. However, most tests shown on this page can be performed on Windows without any additional installation.
The following paragraphs are for MacOS users. Windows and Linux users can happily jump to the next section.
Turn on a MIDI device (synthesizer, piano, etc.) connected to the computer. On my personal Mac, I usually use the Pianoteq synthesiser, which produces a physical model synthesis of various keyboard instruments. It communicates with BP3 via a device called the Inter-Application Communication (IAC) architecture — read this if you need details.
The IAC driver is installed by default on recent MacOS systems. (It is a part of the CoreMIDI framework provided by Apple.) It allows you to create virtual MIDI ports that enable MIDI applications to communicate internally within the same machine. Equivalent devices exist in the Linux and Windows environments, see below.
The IAC also communicates with external MIDI devices via the USB ports, BlueTooth and possibly more network protocols. We'll try it later.
To set up the IAC, run the Audio MIDI Setup application (in the Utilities folder). Ask it to show "MIDI Studio". On my personal computer, it looks like this: the IAC driver, the Pianoteq synthesiser, a Pocket Key 15 keyboard connected to a USB port, and a Yamaha piano connected by standard MIDI cables and a USB MIDI interface. The Yamaha piano appears grey because it is switched off.
On active MIDI devices you will see triangles indicating input/output ports. These are used to connect devices directly by drawing a 'cable' to connect them. We don't need to use these 'connectors' as BP3 communicates via the IAC MIDI ports.
Check output options
(MacOS, Linux and Windows)
The easiest way to proceed now is to run any project in the Real-time MIDI mode, and see if sounds are produced… Whatever the result, at the end of the (potentially silent) performance, you will see a Show all … messages button along with a blinking red signal "=> 1 warning". Click on the button to read detailed explanations of the failure (or success):
Setting up MIDI system MIDI output = 0: “Bus 1” the number of your choice
MIDI settings 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 given the Audio MIDI Setup shown above. The Bol Processor scanned all output (and input) MIDI ports. Given port '0' as an output by default, it assigned it to "Bus 1" which the 'port' set up in IAC.
If your synthesiser happens to be connected to "Bus 1", you will hear sounds and the problem is solved. Let us suppose that you are running Pianoteq and hear nothing. Open the settings of Pianoteq and select "Devices". All you have to do is check "IAC Driver Bus 1". You might also check other inputs, including Pocket Key 25 if you want to connect your small keyboard directly to Pianoteq, but these are extra procedures.
Opening Pianoteq settings informed us that it is communicating with IAC, and it suggested to use a IAC 'Bus' for this communication. The 'Bus 1' port is technically called a virtual port.
Screenshot
All you need to do to ensure that the connection remains correct when more devices are switched on/off and MIDI port numbers change. The only reliable way is to write the name "Bus 1" as the MIDI output. You can also write "Pocket Key 25" (or whatever is detected as your input MIDI device) to the MIDI input, as we will use it later. Note that MIDI port numbers are now irrelevant, as names take precedence. BP3 will correct them automatically.
Click the SAVE MIDI ports button to store this setting. Clicking on the SAVE format does the same thing, so don't worry about confusing buttons!
To the right of the MIDI port name is an empty field where you can enter a comment. For example, write "Pianoteq synth" to the right of "Bus 1".
Let us now switch on a Yamaha piano which is connected via a USB MIDI interface. The interface I use has a green light that indicates it has power. If the piano is actually communicating with it, we should see a flashing red light. In MacOS, sometimes it is necessary to restart the computer after switching on the piano… But in Windows and Linux the red light flashes immediately.
As soon as the red light flashes, open the Pianoteq settings. Great! We can now see that the Yamaha piano is recognised and connected to the IAC.
The easiest way to connect the Yamaha piano to BP3 is to click PLAY. Whatever happens, we'll get a warning and see the following diagnosis:
Setting up MacOS MIDI system MIDI output = 0: “Bus 1” the name of your choice Trying to assign ports to 1 input(s) without names but possibly with numbers MIDI input = 1: “Bus 2” the number of your choice MIDI input 1 makes BP3 interactive
MIDI settings 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 identified as "Pocket Key 25" is correctly connecting to port '2'. But the Yamaha piano is identified as "USB MIDI Interface". This is the name we need to copy to the MIDI output, then SAVE MIDI ports and PLAY. Another option is to leave the name empty and enter the MIDI output number '3'.
We hear the output on the Yamaha piano, although port numbers were incorrect on the interface. The inconsistency is resolved by the MIDI driver selecting ports by name in order of priority. Port numbers (and names) are updated as soon as you save or reload the project (data or grammar). Then you get:
Why does the name "Yamaha piano" appear in Pianoteq settings, but not in the MIDI ports scanned by BP3? This is a mystery that expert users of a MIDI studio could probably solve… For the time being, just write "Yamaha piano" in the comment field at the right of "USB MIDI interface".
The Pause and Continue buttons
During real-time playback, Pause and Continue buttons are displayed. These are self-explanatory. Clicking the Continue button will resume the performance with the exact timing.
These buttons affect all instances of BP3 that are playing together, if any (see below).
The _part() command
It is possible to send parts of a Bol Processor score to separate outputs. Parts are identified by the "_part(x)" command in which 'x' is an integer in range 1..30. We will be able to handle more than 30 parts if it turns out to be necessary.
The "_part(x)" command directs MIDI messages to a specific MIDI output, which in most cases will be an instrument. The image on the side shows the mapping of port #3 (USB MIDI interface) to part #2, as set up in its filter.
By default, MIDI outputs "hear" all 30 parts, but here we've restricted this one to part #2.
For MIDI port #0 (Bus 1) we've restricted the output to part #5.
Let us play the following score:
C3 D3
This sequence of notes is heard on both instruments. As there is no "_part()" command in the score, all outputs send the MIDI messages.
Now let us try:
G2 _part(5) C3 _part(2) D3
Note G2 is heard on both instruments. But, as expected, the note C3 is heard on Bus 1 and D3 is heard on the USB MIDI interface.
The "_part()" command has exactly the same syntactic behaviour as "_chan()" and "_ins()". For example, it "follows" the score along the fields of polymetric structures:
In this example, G2 is heard on both instruments. Then C3 is sent to Bus 1, as well as D3 and E3, since they are the first field of the polymetric structure. In the same time, B2 is sent to the USB MIDI interface, then A2 to Bus1. At the output of the polymetric structure, F3 is sent to Bus 1 which was the mapping before the structure. At last, G3 is sent to the USB MIDI interface.
The sound-object graph shows that D3 and B2 are played together, although on different instruments, and E3 and A2 are played together on the instrument connected to Bus 1.
Parts are mostly relevant when importing digitised scores. They are used to declare instruments in MusicXML files. When importing a score, the Bol Processor will optionally place "_part()" or "_chan()" commands in the imported score, so that it can be played on the same set of digital instruments.
Using "_part()" is a better option than "_chan()" to name an instrument, because MIDI channels can be modified to handle microtonal adjustments. On the Data page, there is a MANAGE _chan(), _ins(), _part() button that opens a dialog for converting parts to/from channels, parts to/from instruments, etc.
An input
Setting up an input follows exactly the same protocol as setting up the output. For example, we can set up the input on "Pocket Key 25” as shown above. “USB MIDI Interface” (the Yamaha piano) is another possible choice. Let us continue with Pocket Key 25.
Windows users can simply plug their external MIDI keyboard (e.g. "Pocket Key 25”) to a USB port of their computer, as it will be automatically recognised and set up by the system.
Connecting an input to BP3 is of little interest if BP3 does nothing with input events. The instructions it can handle are listed in the section List of scripts for dealing with real-time MIDI below. "Wait for note…" means that BP3 will stop playing until it receives a NoteOn of the note in question — even with velocity zero.
The script command tells that the performance should start when note C3 is received on MIDI channel 1. To avoid any confusion about octave numbers, I have written the name on the lowest key of my Pocket Key 25 (see photo). This confusion is made worse by the fact that the Italian/Spanish/French convention uses lower octave numbers!
So, the labelled key is the one we need to press to start this show. Let's try it…
When the PLAY button is clicked on the Data page, a flashing STOP button is displayed. The machine would wait forever unless the correct MIDI event has been received. The STOP button — or the PANIC button at the top right — can be used to abort the process cleanly. If all goes well, pressing the C3 key should produce this sound:
Harm Visser's '-da.acceleration' example
Notice that the _transpose(12) instruction plays notes one octave higher!
(This little "acceleration" piece was composed by Harm Visser to illustrate the period notation. Read his tutorial.)
Multiple interruptions are of course possible. Try this:
Now the machine will start its performance after receiving a NoteOn of C3. It will then stop after three beats and wait for a NoteOn of C4. A noteworthy detail is that one second after an interruption, AllNotesOff is sent to all MIDI channels and the pedals are set to off. This prevents notes waiting for their NoteOff from being heard. This "All Notes Off" feature can be turned off in the preferences file.
MIDI input filters
Let us play with the continuous improvisation "Mozart’s musical dice game" (called "-gr.Mozart" in the "ctests" folder). If this project is set for real-time MIDI, the improvisation will not stop until we click on the STOP or PANIC button. Inserting a "wait for note…" at the beginning would of course stop the performance at the beginning of every variation. Beware that you will have to write "do2" instead of "C3" due to the note convention!
But let's try something else, using the external keyboard (the Pocket Key 25 or Yamaha piano) to play notes on top of the performance. How strange! We don't hear any notes played on the external keyboard unless it's connected directly to the output device.
The reason for this becomes clear after clicking on the FILTER button for MIDI input 2:
All types of MIDI events are listed along with how they are processed by BP3. Here we are only interested in NoteOn/NoteOff events. The default setting is '1', which means that they can trigger script commands, but are not forwarded to the MIDI output. This is why 'C3/do2' was able to start the performance, although we could not hear it.
To play notes over the performance, we need to set the status of NoteOn and NoteOff to '2'. Note: If we only set the NoteOn status, BP3 will automatically set the NoteOff status to avoid confusion. Once you have changed the settings, click SAVE MIDI ports, then PRODUCE ITEM(S).
Since the Pocket Key 25 keyboard sends only NoteOn/Noteoff messages, we could as well set other event filters (KeyPressure, etc.) to '0'.
These filter settings are stored, together with the MIDI port names or numbers, in a temporary file whose name depends on both the session number (created by your browser) and the project name. A copy of these settings is stored in the (permanent) folder "midi_resources". This storage makes it possible to launch several instances of BP3 on the same browser or on different browsers, as we will now see.
Several BP3s performing and communicating
From the previous description of interactions via MIDI events — limited for the time being to waiting for a particular note — you may have guessed that a great feature of the Bol Processor BP3 environment is the possibility of running several BP3s, on different machines, or even on a single machine and the same browser… in cooperation with real humans playing MIDI instruments!
Each instance of BP3 can be thought of as a 'musician' with their own compositional skills embedded in a grammar or data (a set of pre-composed musical fragments). We are working on interactions that will allow each musician to modify the behaviour of another musician's grammar, for example by changing rule weights — which may result in some rules being suppressed while others are activated — or changing metronome settings if they need to perform faster/slower, etc. All these features were part of earlier versions (BP2) several decades ago!
Let us start with an extremely simple example using the "wait for note…" script.
Create two projects that contain only data, for example "-da.Beatrix" and "-da.Alan":
Note that these melodies do not contain the same number of notes, but they will have the same duration (2 beats) because of their polymetric structures.
We want Alan's performance to start precisely after the last note of Beatrix's performance. As we don't want E4 to overlap with F3, we have put a silence '-' before F3. In the following, we'll have a solution to overcome this limitation.
To manage the interaction in MacOS, we need an additional IAC port which is (automatically) named "Bus2". To do this, open Audi MIDI Setup and click on the IAC driver. Then add a port (see picture). You can create as many ports as you wish.
Set both Beatrix's MIDI output and Alan's MIDI input to "Bus2".
Now we want to hear both performances. Alan's MIDI output is sent to "Bus1" and will therefore be audible on the Pianoteq synthesiser.
Windows and Linux users can connect the two performers more easily: send both Beatrix's and Alan's messages to the external MIDI device, and connect Alan's input to the same MIDI device. But… the input filter should receive events and not forward them to the output, which is the same device, otherwise the loop will produce a disastrous bouncing effect!
Back to MacOS, there are two ways to send Beatrix's performance to the Pianoteq synthesiser:
Pianoteq settings make it possible to listen to both "Bus1" and "Bus2" virtual ports.
You can set up the MIDI event filter on Alan's project to route input NoteOn/NoteOff events to the current MIDI output. See above for filters.
To play the performance, click PLAY on Alan's project so that it is ready to perform. Then click PLAY on Beatrix's project. This is the result:
Two phrases played in sequence by two instances of the BP3 (Beatrix & Alan).
No doubt this sounds rather unmusical! In fact, we publish tasteless technical examples to encourage musicians to compose interesting pieces!
Using out-time inaudible notes as signals
The idea of beginning Alan's performance with a silence that is filled by Beatrix's final note E4 is unelegant. Below is a better solution:
The secret is the expression "_vel(0) <<C0>>" which is an out-time expression of note C0 with velocity zero. The velocity ensures that the note won't be heard, and the out-time property gives it a null duration. Any note can be used here provided that it is mentionend in the "_script(wait…)" instruction.
If "_vel(0) <<C0>>" is followed by more notes, it is necessary to reset the velocity to its default value. The solution is to write it between curly brackets, so that _vel(0) only applies to the content of the expression: "{_vel(0) <<C0>>}"
Checking the time accuracy
Let us check that the real-time synchronisation is not affected by delays. We'll now ask Alan and Beatrix to play the same piece of music (one octave apart) in the same time.
In MacOS, Alan will send MIDI events to "Bus2". Beatrix will listen to "Bus2" and send MIDI events to "Bus1" (Pianoteq). Beatrix will set her input filter to the pass option, routing the incoming events to the output. The Pianoteq synthesiser will be set to listen to "Bus1" only.
To start the performance, first click on the PLAY button of Beatrix's project, then on the PLAY button of Alan's project.
Have you noticed that Beatrix is waiting for E3, which does not appear in Alan's score? Oh yes, it does! There is a _transpose(12) command that changes E2 (the first note) to E3. So, it works. This is the performance:
Two superimposed performances (one octave apart), played by two instances of the BP3 (Beatrix & Alan).
Not too bad? Despite the lack of musical interest, we must admit that the superimposition is technically acceptable, even if it is not perfect: there is a delay of about 60 milliseconds on the first note, the time it takes Beatrix's machine to detect that it has received a NoteOn for C3. The subsequent notes are programmed to compensate for this delay, but there are still discrepancies (which can be quantified on the Pianoteq MIDI input). They seem to be caused by delays outside BP3.
You can adjust the delay in Beatrix's project settings "-se.Beatrix". There is a parameter called "Sync delay", which is the number of milliseconds Beatrix's output events should be postponed after the synchronisation. We currently find that 380 ms is a good value.
In fact, the superimposition would sound even better if both performances were triggered by the same event, such as the conductor pressing a key on the external keyboard. This exercise was only intended to show that synchronisation between "virtual musicians" works well.
Working with multiple MIDI inputs
In the previous example, we could decide that Alan's performance will start when he receives a particular note from the Pocket Key 25 keyboard. In this case, we need to click on both START buttons, putting both 'musicians' in wait mode, and the performance will not start until the correct key is pressed on the keyboard.
This case is manageable with single inputs on each instance of BP3. More complicated cases, however, require external 'actors', such as a Pocket Key 25 keyboard sending to all the 'musicians' synchronisation messages, or messages modifying parameters in grammars, changing the metronome value, etc.
To achieve this, the Bol Processor is a able to manage multiple MIDI inputs.
The new game is as follows: both Beatrix and Alan will take turns playing variations of Mozart's musical dice game (see '-gr.Mozart'), one octave apart. They will use the Improvise mode to continue throwing the dice and creating unheard variations. But they will wait for a signal from the other to start playing a new variation.
In short, both musicians will use the same grammar, with only a small change for mutual synchronisation. Their settings must be carefully 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 don't want both musicians to repeat the same variations. So, set the Seed for randomization to different values, for instance '1' and '2'. Or set it to zero to instruct the machine to seed the random sequence with an arbitrary number of its choice.
In the current version of BP3, the easiest way to send a signal is to send a note with a velocity of zero, which will therefore go unheard. So we need to change the grammar to add these particular notes.
In fact, the same notes should never be part of the score, so that the signal is really sent at the end. This is easy with Mozart's game, for example we can use C# (do#) for the synchronisation. Below are the tops of the grammars used by Beatrix and Alan.
Beatrix '-gr.Beatrix':
-se.Beatrix ORD gram#1[1] S --> _script(wait for do#3 channel 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 randomly and apply from left to right] etc.
Alan's '-gr.Alan':
-se.Alan ORD gram#1[1] S --> _script(wait for do#2 channel 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 randomly and apply from left to right] etc.
Again, we put do#4 at the end of Alan's performance because it is played as do#3 (one octave lower) due to the _transpose(-12) instruction.
Now we need to set up the MIDI inputs and outputs. Beatrix will send events to "Bus 1" which is the Pianoteq synthesizer. She will receive events from "Bus 2", use them for synchronisation, and forward them to the output.
Alan will send events to "Bus 2" and listen to "Bus 1" for the synchronisation.
This is all perfect on paper, but who is going to start? We have created a chicken and egg situation, so we need a superpower to start the process! Actually, a real human pressing the do#2 key on a Pocket Key 25 keyboard will do.
The interface has a Add an input button. We click it on Alan's project and paste the name Pocket Key 25. We also use the comment fields to remember the use of each port:
MIDI inputs and outputs are identified by their names. The numbers in the leftmost boxes are automatically set by the console during performance.
To start the concert, we'll click START on both projects. The order is irrelevant. Then we'll press a key on the Pocket Key 25. Which key?
If we press the do#2 key, we will certainly trigger Alan's improvisation and the cycle will start. But if we press the do#3 key, nothing will happen because, by default, the filter of the Pocket Key 25's input in "-gr.Alan" does not transmit NoteOns to the output. So Beatrix won't hear it… By setting NoteOn to status '2' (treat and pass) on this filter, it is possible to decide who will start the performance: do#2 for Alan and do#3 for Beatrix.
Here we go (starting with Alan):
Alan and Beatrix (two instances of BP3) playing variations of Mozart's musical dice game
You can interrupt this dual performance at any time by clicking the Pause button (of either project) and resume it by clicking the Continue button. You can also insert musical fragments by running a project such as "-da.tryStopContinue" (see below), if Stop and Continue MIDI events are sent to both "Bus 1" and "Bus 2" ports. In both cases the synchronisation is maintained.
This simple show should convince musicians to create "virtual bands" of BP3s playing different grammars and sending specific synchronisation signals according to which variation has just been produced. Along with human performers who join in the fun!
The "virtual musicians" can be on the same computer or remotely connected via network (BlueTooth) or MIDI cables and USB interfaces. If they are on the same computer, they can be run on different browsers and/or the same browser. In the latter case, BP3 will not allow the same project (grammar or data) to be run in the same session. In general, just like human musicians in an orchestra have individual scores, it makes sense that virtual musicians don't share the same project…
The number of MIDI inputs and outputs in a project is currently limited to 32. It is unlikely that a (human) musician will need more!
Synchronise to a sequence (or list) of notes
The following expression
gram#1[1] S --> _script(wait for C3 channel 1) - _script(wait for E3 channel 1) etc.
synchronises the production to the sequence of notes C3 E3 (whatever the duration and velocity). This creates interesting situations where a "virtual musician" is expected to start playing after receiving a signal (C3) from one partner, then a signal (E3) from another partner.
Note that there is a silence '-' between the two script instructions. If there is no silence, then BP3 will resume playing if either C3 or E3 has been received.
Remember that because of the MIDI channel specification (range 1 to 16), the detection of signals can be selective. They are also inaudible when transmitted by NoteOns with velocity zero.
Crashing the band!
In the example of Alan & Beatrix playing Mozart, the connection seems to create 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 reason it doesn't crash is that Alan's input "fromBeatrix" ("Bus 1") is filtered: NoteOns are received and processed (for synchronisation), but not passed to the output ("Bus 2"), i.e. to Beatrix. You can try to change the filter of input "Bus 1" on Alan's project, setting NoteOns to status '2' (treat + pass): you will get a superb crash after a flood of notes! This probably will not happen because BP3's MIDI drivers have been equipped with an anti-bouncing mechanism.
Working with multiple MIDI outputs
The Bol Processor currently accepts up to 32 MIDI inputs and outputs.
Example of a project using two inputs and two outputs:
A setup with two MIDI outputs and two MIDI inputs
The procedure for adding outputs is the same as the one for adding inputs: click on the Add an output button, then enter the name of the MIDI device if you know it exactly, otherwise leave it blank and let the machine connect it by default to the next available output, while suggesting other options:
Your real-time MIDI settings: MIDI output = 0: “Bus 1” - Pianoteq MIDI output = 3: “USB MIDI Interface” - Yamaha piano MIDI input = 1: “Bus 2” - from Alex MIDI input = 2: “Pocket Key 25” - a small keyboard
Setting up MacOS MIDI system MIDI output = 0: “Bus 1” the name of your choice MIDI output = 3: “USB MIDI Interface” the name of your choice MIDI input = 1: “Bus 2” the name of your choice MIDI input 1 makes BP3 interactive MIDI input = 2: “Pocket Key 25” the name of your choice MIDI input 2 makes BP3 interactive
More MIDI output options were available: MIDI output = 1: “Bus 2” MIDI output = 2: “Pocket Key 25”
More MIDI input options were available: MIDI input = 0: “Bus 1” MIDI input = 3: “USB MIDI Interface”
The fact that a MIDI input or output is "available" does not guarantee that it will do what we want it to do. For example, sending MIDI messages to the Pocket Key 25 keyboard will actually do nothing.
Filtering MIDI outputs
In the example above, MIDI output 3 (the Yamaha piano connected to the USB MIDI Interface) has the filter shown on this picture.
The channel filter specifies that the Yamaha piano will get all MIDI channels except those emitted on MIDI channel 2. Filtering MIDI channels makes it possible to send events exclusively to different instruments.
MIDI events can also be filtered by type. The idea is the same as for MIDI input filters, see above.
If you do not hear any sound in real-time MIDI, you may consider checking the output MIDI filters before you kick the piano or screw up its cables!
Using standard MIDI control
MIDI has standard control messages, namely Start, Continue and Stop, which can be used to coordinate multiple "virtual musicians" (instances of BP3). The advantage is the clarity of the data and the grammars programmed for interactions. The disadvantage is that these messages are not assigned to specific MIDI channels. This can be a problem with a large number of "virtual musicians". They also introduce a delay of about 250 milliseconds due to the time it takes for the MIDI device to process them.
Control messages can be used in two ways. The first, which we will now examine, is to "listen" to these messages via a script command. The second (see next section) is to respond to them as interruptions in the performance.
Let us look at a trivial example (of no musical interest), again with Beatrix and Alan playing together. This time, they take turns playing their items (simple sequences of notes).
It is important that the "Respond to Stop/Continue" option is unchecked in both the Alan and Beatrix project settings.
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 output to "Bus 1", the Pianoteq synthesizer. Its input is connected to the virtual port "Bus 2".
Alan's project sends its output to the virtual port "Bus 2", and its input is connected to "Bus 1".
We'll start the performance with Beatrix. Her machine will stay waiting for START. Then we'll start Alan's part, which will play three notes, then send a START message to Beatrix, who will play her part, and return to Alan, via a CONTINUE message, for the final part…
This all sounds logical, but it doesn't work! We do hear Alan's E3 D3 C3, but then nothing… The first reason is that Beatrix should be able to hear Alan's START command, which is no longer a NoteOn as in the previous examples. This means that the filter of her input "Bus 2", from which she receives Alan's MIDI messages, must be set correctly. The Start event should be received, see picture on the side. Also remember that NoteOn and NoteOff should be received and transmitted to the output (the Pianoteq synth).
Well, now we hear Alan's E3 D3 C3 followed with Beatrix's E4 D4 C4, but then… nothing!
Careful analysis is needed to solve the problem. However, this is simple logic. Remember that Alan is playing on "Bus 2", which is not connected to any MIDI device. If we hear Alan's production, it is because it is received by Beatrix on "Bus 2" and then forwarded to "Bus 1" (the Pianoteq synth). The problem is that the final part A2 B2 C3 is sent to Beatrix, but she has already stopped listening because her own data is finished!
You can imagine a band in which one musician plays an improvisation and then gives a signal to another musician to start their own improvisation, but the careless musician has already vacated the place believing that the programme was finished. The solution is to tell the musicians not to go away until they receive a STOP signal. Maybe a signal from a conductor (here using the Pocket Key 25 keyboard), maybe a signal from the musician who is in charge of ending the performance. So we'll tell Alan to send a STOP signal at the end of his performance, and Beatrix to wait for Alan's STOP signal. 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 messages Start, Continue, Stop have been used here to facilitate the reading of scores (or grammars), but these can be replaced by NoteOns with durations and velocities zero on different MIDI channels when working with a larger number of actors.
By the way, using MIDI messages Start, Continue and Stop can be problematic with physical or virtual MIDI devices. My Yamaha piano, for example, does not transmit these messages. So, when connected to an input, it will only send 3-byte messages such as NoteOn/NoteOffs. In the Windows environment, the Microsoft GS Wavetable Synth also does not transmit any message at all. The best way to exchange messages is via virtual MIDI ports created by "loopMIDI" (see below). In Linux, virtual ports such as 'VirMIDI 0-0' (see below) do not seem to transmit these Start, Continue and Stop messages.
For geeks:In the Bol processor, scripts are appended to the next following sound object. For example, _script(wait for Start) is appended to note E4 in Beatrix's score. But what about scripts at the end of a score? The secret is that BP3 creates an invisible MIDI event (ActiveSensing) at the end of each element to which it can append the final scripts.
Using control messages to interrupt a performance
This is the second way of using control messages. Let's try to stop a performance with a standard Stop MIDI message, play a few notes and then continue the performance with a standard Continue MIDI message.
We create a project "-da.tryStopContinue" as follows:
Running this project will interrupt a performance, for example "-da.Watch_What_Happens_by_Oscar_Peterson". For this to work, the "Respond to Stop/Continue" option must be checked in the Oscar Peterson data project.
Let us decide that the performance will be played on the Pianoteq synthesiser connected to "Bus 1" on a Mac.
The "-da.tryStopContinue" will send its data to a virtual port, for instance "Bus 2". To this effect, the "-da.Watch_What_Happens_by_Oscar_Peterson" project will have an input port listening to "Bus 2", accepting all messages and transmitting at least NoteOn/Noteoff.
Another solution is to set up another output port on the "-da.tryStopContinue" project, that sends all data to "Bus 1". The output to "Bus 2" will only send the Stop and Continue messages. The input port listening to "Bus 2" on the Oscar Peterson project will only accept Stop and Continue, and not transmit anything.
It is a good practice to use the filters for restriction of message management to the necessary tasks.
Now, play the Oscar Peterson performance, and at any point start "-da.tryStopContinue". The performance will pause and you will hear the external musical phrase. The performance will then resume. You can, of course, do this several times and insert any variety of musical fragments. For example:
Beginning of Oscar Peterson's "Watch What Happens" with two interruptions
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 agenda. These instructions are not case-sensitive.
Input scripts
When a note is specified, be sure to use the same note convention as in the project, e.g. C3 or do2 or sa3, etc.
Wait for note channel c
Wait for a NoteOn of the specified note on channel c (1…16)
Wait for Start
Wait for a Start MIDI message (250)
Wait for Continue
Wait for a Continue MIDI message (251)
Wait for Stop
Wait for a Stop MIDI message (252)
Wait forever
Wait until STOP or PANIC button is clicked
Velocity param Kx = note channel c
Set parameter Kx (0 < x < 128) to the velocity (range 0…127) of the specific note on channel c (1…16)
Control param Kx = #y channel c
Set parameter Kx (0 < x < 128) to the value (range 0…127) of MIDI controller #y (0 < y < 128) on channel c (1…16)
Output scripts
Hold for x milliseconds
Delay all subsequent events by the specified duration x (integer).
Send Start
Send Start MIDI message (250)
Send Continue
Send Continue MIDI message (251)
Send Stop
Send Stop MIDI message (252)
Scripts on top of a grammar
(To be continued)
Capture incoming events
The _capture() command allows incoming MIDI events to be recorded to a 'capture' text file. See the Capture MIDI input page for explanations.
Alternatives to IAC
Here are the equivalents of Apple's IAC (Inter-Application Communication) for each system:
Windows environment
On Windows, you can use software like loopMIDI or virtualMIDISynth to create virtual MIDI ports. These tools work similarly to the IAC Driver on macOS:
loopMIDI: Created by Tobias Erichsen, loopMIDI is a popular choice for creating virtual MIDI ports on Windows. It allows you to create and manage several virtual ports which can be used by applications to communicate with each other.
These tools integrate with software applications that support MIDI, providing a seamless way to connect various MIDI applications without needing external MIDI hardware.
Linux environment
On Linux, ALSA (Advanced Linux Sound Architecture) provides capabilities to create virtual MIDI devices through its sequencing API.
snd-virmidi: This ALSA MIDI driver provides virtual MIDI ports for sending and receiving MIDI between applications running on the same system. It's part of the standard ALSA module set and can be configured to provide multiple ports.
To set up virtual MIDI ports on Linux using ALSA, you typically need to load the snd-virmidi module. You can do this by running:
sudo modprobe snd-virmidi midi_devs=2
This command loads the snd-virmidi module and sets it up to provide two virtual MIDI devices (you can increase the number of devices by changing the midi_devs parameter). The virtual ports, namely 'VirMIDI 0-0' and 'VirMIDI 0-1' , can then be accessed by MIDI applications on the Linux system. Please note that they do not appear to transmit the Start, Stop and Continue messages.
This is done automatically by the "install_bp3.sh" shell script installing BP3 on Linux/Ubuntu (download here).
An earlier version of this page recommended w64devkit. This was a wrong choice, as its downloadable files are signalled with viruses or malicious code.
Look at the warning displayed at the top right of any page of the Bol Processor. In the Windows environment you can read:
Top right warning in Windows environment indicating that a 'gcc' installation is required.
The installation of MinGW will allow "gcc" to run on a Windows machine. This may not be necessary if it has already been installed by another application. In this case, there will be no such warning at the top right of Bol Processor pages:
Clicking on the "run the compiler" link will create the "bp.exe" console. After reloading the page you are ready to use BP3:
The PANIC button is used to get silence when you are running more than one instance of BP3.
If you get a warning that the file may contain malicious code, don't take the risk. Try another file!
Install MinGW-w64:
Open the MinGW file with 7-Zip, telling it to extract files and store them to a folder, by default "x86_64-13.2.0-release-win32-seh-ucrt-rt_v11-rev0" in your Downloads folder.
Save the path to this folder in a text file, for instance (if the user is named "berna"): C:\Users\berna\Downloads\x86_64-13.2.0-release-win32-seh-ucrt-rt_v11-rev0\mingw64
For geeks and expert Windows users: It is not good practice to keep executable files in the Downloads folder, as they may be deleted when optimising disk space. You should move them to a suitable location like other applications. I keep the Downloads location for the demo.
Set up the Environment Path:
Right-click on 'This PC' or 'Computer' on the desktop or in File Explorer, and select 'Properties'.
Click on 'Advanced system settings' and then 'Environment Variables'.
In the System Variables section, find and select the variable 'Path', then click on 'Edit'.
Click on 'New' and add the path to the directory 'bin' of your MinGW-w64 installation, such as "C:\Users\berna\Downloads\x86_64-13.2.0-release-win32-seh-ucrt-rt_v11-rev0\mingw64\bin" if you haven't changed the location.
Click 'OK' to close all dialogues.
Verify Installation:
The BP3 interface does this verification automatically. If ‘gcc’ responds you will be offered to (re)compile the console. The following instructions are for an additional check.
Open Command Prompt (cmd.exe) and type: cd C:\MinGW\bin gcc --version
The first command opens a Unix "shell". The second command should output the GCC version installed and include 'x86_64', indicating it's set up for 64-bit. Ignore the win32 segments you see in file and folder names. They are there to confuse you!
Additional Tips
Choosing a Shell: MinGW-w64 works with standard Windows command prompt and also with more Unix-like terminals like Git Bash or Cygwin if those are already installed.
Using Make: To use 'make' with MinGW-w64, make sure that package 'mingw32-make' is selected during installation. It might be named differently like 'mingw-w64-make' based on the version. You might need to rename 'mingw32-make.exe' to 'make.exe' in the bin directory to make it recognizable as 'make'.
By following these steps, you should be well-equipped to compile 64-bit applications — not only BP3 — using GCC on Windows via MinGW-w64. This setup is useful for developers who need a lightweight GCC environment without needing a full Linux setup or the bulk of Visual Studio.
Kippen, James & Bernard Bel (1989) https://hal.science/hal-00275429v1 Can a computer help resolve the problem of ethnographic description? Anthropological Quarterly, 62 (3): 131-144.
Bel, Bernard (1990) https://theses.hal.science/tel-00009692 Acquisition et représentation de connaissances en musique (Knowledge acquisition and representation in music) Thèse de doctorat en sciences. Université de droit, d'économie et des sciences - Aix-Marseille III.
Kippen, James & Bernard Bel (1992) https://hal.science/halshs-00004506v1 Modelling music with grammars: formal language representation in the Bol Processor. In A. Marsden & A. Pople (eds.) Computer Representations and Models in Music, London, Academic Press, 1992: 207-238.
Kippen, James & Bernard Bel (1992) https://hal.science/hal-00256386v1 Bol Processor Grammars. In Mira Balaban, Otto Laske et Kemal Ebcioglu (eds.) Understanding Music with AI, American Association for Artificial Intelligence Press, Menlo Park CA: 366-400.
Kippen, James & Bernard Bel (1992) https://bp3.tech/two-algorithms/ Symbolic and sonic representations of sound-object structures. In Mira Balaban, Otto Laske et Kemal Ebcioglu (eds.) Understanding Music with AI, American Association for Artificial Intelligence Press, Menlo Park CA: 64-110.
Kippen, James & Bernard Bel (1992) https://hal.science/hal-00256385v1 Modelling improvisatory and compositional processes. In Denise Penrose & Ray Lauzanna (eds.) Languages of Design, 1. Elsevier Science Publishers, Amsterdam: 11-26.
Bel, Bernard (1992) https://bp3.tech/time-setting-of-sound-objects/ Time-setting of sound-objects: a constraint-satisfaction approach. International Workshop on Sonic Representation and Transform, Trieste (Italy), 26-30 October.
Bel, Bernard (1998) https://hal.science/hal-00250274 Migrating Musical Concepts - an overview of the Bol Processor. Computer Music Journal, Vol. 22, 2: 56-64.
Bel, Bernard (2001) https://bp3.tech/rationalizing-musical-time/ Rationalizing musical time: syntactic and symbolic-numeric approaches. In Clarence Barlow, (ed.) The Ratio Book. Den Haag: Royal Conservatory - Institute of Sonology: 86-101.
QAVAID
Kippen, James & Bernard Bel (1989) https://hal.science/halshs-00004505 The identification and modelling of a percussion ‘language,’ and the Emergence of Musical Concepts in a machine-learning experimental set-up. Computers and the Humanities, 23 (3): 119-214.
Bel, Bernard (1990) https://hal.science/hal-00275789v2 Inférence de langages réguliers. Journées Françaises de l'Apprentissage, Lannion, France : 5-27.
Modelling music with grammars: formal language representation in the Bol Processor. In A. Marsden & A. Pople (eds.): Computer Representations and Models in Music, London, Academic Press, 1992, p. 207-238.
Abstract
Improvisation in North Indian tabla drumming is similar to speech insofar as it is bound to anunderlying system of rules determining correct sequences. The parallel is further reinforced by the fact that tabla music may be represented with an oral notation system used for its transmission and, occasionally, performance. Yet the rules are implicit and available only through the musicians’ ability to play correct sequences and recognise incorrect ones. A linguistic model of tabla improvisation and evaluation derived from pattern languages and formal grammars has been implemented in the Bol Processor, a software system used in interactive fieldwork with expert musicians. The paper demonstrates the ability of the model to handle complex structures by taking real examples from the repertoire. It also questions the relevance of attempting to model irregularities encountered in actual performance.
Pattern grammars in formal representations of musical structures. 11th International Joint Conference on Artificial Intelligence, Workshop on AI & Music, 20 August 1989, p.113-42
Abstract
This paper introduces several formal models of pattern representation in music. Polyvalent multimodal grammars describe partially overlapping sound events as found in polyphonic structures. Bol Processor grammars are characterisations of sequential events in terms of substring repetitions, homomorphisms, etc. Parsing techniques, stochastic production and recent developments of BP grammars are briefly described.
Time-setting of sound-objects: a constraint-satisfaction approach. Invited paper, Workshop on Sonic Representations and Transforms. INTERNATIONAL SCHOOL FOR ADVANCED STUDIES (ISAS), Trieste, 26-30 October 1992.
Abstract
This paper deals with the scheduling of “sound-objects”, hereby meaning predefined sequences of elementary tasks in a sound processor, with each task mapped to a time-point. Given a structure of sound-objects completely ordered in a phase diagram, an “instance” of the structure may be obtained by computing the dates at which each task should be executed. Time-setting the structure amounts to solving a system of constraints depending on (1) metric and topological properties of sound-objects, (2) contexts in which they are found, and (3) parameters related to the performance itself (“smooth” or “striated” time, speed, etc.). This may require relocating/truncating objects or delaying part of the sound-object structure. A constraint-satisfaction algorithm is introduced, the time complexity of which is O(n.k) in most cases, where n is the number of sequences and k the maximum length of a sequence. In the worst case it remains better than O(n2.k3). Other fields of applications are proposed, including multimedia performance and computer-aided video editing.
Below is the complete set of Preludes and Fugues by J.S. Bach known as The Well-Tempered Clavier, Books II and II, published around 1722 and 1742 respectively.
What was the composer's intention when he used the term "well tempered"?
The matching algorithm selected the tuning scheme(s) that best matched the definitions of 'consonant' and 'dissonant' melodic and harmonic intervals. Two sets of definitions were used: "standard" and " alternative". Obviously, under any hypothesis, some tuning schemes are more suitable than others for achieving the composer's presumed perception of 'consonance'. Therefore, the following sound productions of the Preludes and Fugues, with their "best" tuning schemes, should not be taken as a definitive answer to the question of temperament discussed by Bach's students and followers. They may, however, come closest to what the composer intended, within the limits of the ear's ability to discriminate between intervals.
Note that if several tuning schemes ranked first for matching a piece, only one of them was used for the demo. It is possible that another may sound better.
Settings of an audio unit for the post-processing
All the pieces were played and recorded on a Csound instrument, similar to a harpsichord, allowing a clear appreciation of the tonal intervals. This kind of "magnifying glass" view of the tonal intervals produced harsh sounding versions, available in the Standard (raw) and Alternate (raw) folders. These have been post-processed with a bit of reverb to produce softer attacks. The post-processed sound files are the ones accessed in the tables below. Readers familiar with sound editing are invited to download the raw files and suggest better post-processing options.
The last two columns of each table contain recordings of human interpretations of the same works by outstanding harpsichordists. These explore dimensions of musicality that the mechanical interpretation of the score with perfect tonal intervals could not reach. It remains that the challenge of accurate tonality was a priority for this corpus, as evidenced by the title "well-tempered" given by its composer.
Book I sound examples
These Bol Processor + Csound recordings may be reused under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) licence. Attribution includes links to the present page, to Csound and to the author/editor of its MusicXML score (listed on the Bach Well-tempered tonal analysis page).
Listen with headphones or a very good sound system!
As explained on the Bach Well-tempered tonal analysis page, the D'Alambert-Rousseau temperament was found to be equivalent to H.A. Kellner's BACH in terms of scale intervals.
Listen to the synthesis of Goldberg Variations with Sauveur's meantone temperament. Listen to the synthesis of Goldberg Variations with D'Alembert-Rousseau temperament. Listen to the Aria on a harpsichord tuned with Werckmeister III meantone temperament.
In the same period (1730), the French musician François Couperin composed Les Ombres Errantes, for which our tonal analysis suggests a Rameau en sib temperament:
François Couperin's “Les Ombres Errantes” interpreted by the Bol Processor + Csound with a “Rameau en sib” temperament Image Source: MusicXML score by Vinckenbosch in theMuseScore community
Conclusive remarks
The title of this corpus, The Well-Tempered Clavier, suggests that its composer intended to demonstrate the suitability of one or more temperaments for the performance of musical works in any tonality. As previously stated, this does not imply that they were all intended to conform to the same unique solution; however, it is tempting to hypothesize that the same instrument and tuning scheme were utilized for the entirety of the set. This has led to speculation by J.S. Bach's pupils, who were not instructed on how to proceed. Part of the reputation of great artists in those days was based on the withholding of information.
It would be illogical in the context of human musicians and physical instruments to play a prelude in one tuning and then retune the instrument solely for the purpose of playing the fugue. Consequently, these audio examples are not intended to emulate a genuine performance. They can, however, assist in evaluating the suitability of a preferred tuning scheme for each musical work.
A "deaf musicologist" employs a method of tonality assessment that involves measuring melodic and harmonic intervals in terms of frequency ratios. The results of this assessment depend on the values (weights) assigned to certain ratios in advance. Our findings demonstrate that equally meaningful sets of hypotheses can lead to completely different results, which only trained ears can distinguish. The combination of hypotheses may not elucidate the situation. An apparent preference for a tuning scheme may be the result of a numerical artefact rather than proof of its validity.
A meticulous listening to these recordings, with the exclusion of the somewhat inelegant rendering of fast trills in the lower octave, reveals a musical dimension that cannot be reduced to the concept of 'intervals'. Each piece can be likened to a precious stone, exhibiting an astonishing regularity in its structure. The listener is invited by the artist to explore all sides of the crystal and to appreciate its purity: a 'tonal landscape'. In this approach, the slightest imperfection, such as a few cents up or down, is amplified by the structure. In short, the most important feature may be less the choice of a structure than its consistency in rendering each musical phrase.
It is uncertain whether J.S. Bach had a specific, unique musical temperament in mind when he composed The Well-Tempered Clavier. This is because the highest rating in terms of intervals may not be the most appropriate. This question remains open to art historians and musicologists. However, from the sound examples, it is evident that playing this repertoire on improperly tuned instruments — in terms of consonance — is tantamount to exposing plastic imitations of diamonds.
Reference(s)
Asselin, P.-Y. Musique et tempérament. Paris, 1985, republished in 2000: Jobert. Soon available in English.
Musicians interested in continuing this research and related development can use the Bol Processor BP3 to process musical works and implement further tuning procedures. Follow the instructions on the Bol Processor ‘BP3’ and its PHP interface page to install BP3 and learn its basic operation. Download and install Csound from its distribution page.
Harpsichord jacks in a completed harpsichord Source: Material Matters
The following is a "computational" tonal analysis of musical works by J.S. Bach known as The Well-tempered Clavier, books II and II, published around 1722 and 1742 respectively, and the Goldberg Variations (1741).
The aim of this exercise was to match each musical work to a set of tuning schemes described and implemented on the Bol Processor. These include all the temperaments documented by Pierre-Yves Asselin ([1985], 2000) and "natural" scales systematically constructed — see Creation of just intonation scales.
It has been suggested that the best match for a scale is the tuning scheme that is appropriate for the interpretation of a musical work. This assumption is based on the hypotheses that (1) musicians and composers of the Baroque period aimed to achieve optimal 'consonance', and that (2) this notion implied a preference for certain intervals which we note as integer ratios. These claims are discussed on this page. Accurately tuned sound examples are suggested for auditive evaluation of the results.
The interest of this tonal analysis goes beyond the understanding of music theory and practice. Its epistemological dimension is the trustworthiness of today's fashionable mathematical "predictive models". We show that, given a set of hypotheses, the solution to an optimisation problem — finding the best tuning scheme for all musical works in a repertoire — is not unique, as it depends on initial conditions. Furthermore, the same initial conditions can produce a cloud of seemingly identical solutions, even though each of them points to completely different procedures for its realisation in the "real world" — here, the tuning of a harpsichord.
The take-home message is that scientists should not be impressed by the accuracy and apparent consistency of machine-generated solutions. They must critically examine the initial conditions and the calculation process itself.
Ultimately, the only acceptable way to (in)validate a compositional model is to listen to the audio rendering of the results.
“Standard” analysis
The Well-Tempered Clavier consists of two books, each containing 24 preludes and 24 fugues in all the usual key signatures. In total, this analysis covered 96 musical works (presumably) written by the same composer under (presumably) similar conditions.
Our first analysis is based on the following settings of intervals estimated to be consonant or dissonant:
Settings for a "standard" analysis
The analysis of ascending and descending melodic intervals looks for common frequency ratios close to 3/2 (Pythagorean fifths) and 5/4 (harmonic major thirds), which are widely regarded as 'consonant'. It also includes the ratios 6/5 (harmonic minor thirds) and 9/8 (Pythagorean major seconds), which can be considered optimal. Other ratios are often considered 'dissonant': 40/27 (wolf fifth), 320/243 (wolf fourth) and 81/64 (Pythagorean major third). These dissonant intervals are 1 comma (ratio 81/80) higher or lower than their "consonant" neighbours — see the Just intonation: a general framework page.
Consonant intervals are given positive weights, for example '1' for a harmonic major third and '2' for a Pythagorean fifth. Dissonant intervals are given negative weights, for example '-2' for wolfish intervals and '-1' for Pythagorean major thirds. These weights can be modified; indeed, the modification will in turn change the ratings of the tuning schemes.
Each melodic interval found in the musical work will be sized according to the same interval in the scale being tested for compatibility. For example, when trying to match the D'Alambert-Rousseau tuning scheme (see image), a note sequence 'C' - 'Eb' will be sized 290 cents, which is close to 294 cents or the ratio 32/27 (Pythagorean minor third). When this ratio appears in the settings, the scale value is increased by the weight of the ratio multiplied by the (symbolic) duration of the interval — see Tonal Analysis of Musical Works for details of this procedure.
The same method is applied to harmonic intervals, which are given the same weights as melodic intervals, except for the 9/8 ratio, which is ignored.
The scores for ascending and descending melodic intervals are then added to the score for harmonic intervals, with weights of 1, 1 and 2 respectively. This weighting may be modified if "consonance" is expected to be greater for melodic than for harmonic intervals, or if ascending and descending melodic intervals are not considered equally important.
Each scale is given a mark if it is found to be the best match for a piece of music. Counting these marks over the entire repertoire gives the best tuning scheme(s) for that repertoire.
Results are stored in tables that can be downloaded in both HTML and CSV formats. The initial settings are recalled at the bottom of the "All Results" HTML page.
Each cell in the "all results" table indicates the rank of a given tuning scheme (scale) that matches a given musical work. For example, in the fugues of book I, Corette's temperament (column corrette) was ranked 6th for the 5th fugue, and the best match for this piece was the Sauveur's temperament (column sauveur).
The line labelled Ranked first (times) shows the number of times each tuning scheme ranked first in the classification of this corpus. The line labelled Average score shows the average global (melodic + harmonic) score computed for this tuning scheme, as explained on our Tonal analysis page.
Abstract tables show the list of first ranked tuning schemes for each musical work.
The full set of scale images is available on this page.
Discussion of the standard analysis
The scale of Sauveur's temperament
Of of these 96 musical works, 56 chose 'sauveur' as their favourite tuning scheme, plus 9 as their second favourite. This temperament strikingly dominates the classification because of its ability to produce almost perfect Pythagorean fifths (ratio 3/2), harmonic major thirds (ratio 5/4) and harmonic minor thirds (ratio 6/5).
Note that it also contains a wolf fourth 'Eb' - 'G#' close to 477 cents (or ratio 320/243) which is perceived as a dissonant interval. It is assumed that these two notes are never (or rarely) found in melodic or harmonic intervals in this repertoire. This illustrates the fact that there is no one-size-fits-all solution to the problem of tuning an instrument for this type of music. In a kind of "reverse engineering", we can say that the composer explored melodic and harmonic pleasing effects in order to build this repertoire: playing on the instrument before notating it on sheets of music sheets.
As suggested in our tutorial, there is no evidence that J.S. Bach was aware of the theoretical work of the French physician Joseph Sauveur, but the theoretical framework of this temperament — a single sequence of fifths diminished by 1/5 comma (see image and read Asselin, 2000 p. 80) — suggests that any composer could work it out independently. This process has been recorded on the Bol Processor's Scale page as follows:
Created meantone downward notes “do,fa,sib,mib” fraction 3/2 adjusted -1/5 comma Created meantone upward notes “do,sol,re,la,mi,si,fa#,do#,sol#” fraction 3/2 adjusted -1/5 comma
Interestingly, "natural scales" with names corresponding to the key — for example, Abmin (i.e. G#min) for Fugue 18 in G♯ minor, Book II (BWV 887) — were often at the top of the popular tuning schemes, but in most cases were overtaken by several temperaments. For more details on these scales, see our page on the Creation of just-intonation scales.
In all cases, the equal temperament (see image) was among the lowest, due to its use of major and minor thirds close to Pythagorean. This contradicts the popular belief that Bach's series of Preludes and Fugues was intended to equate 'well-tempered' with 'equal-tempered'…
This first result also suggests that temperaments often provide a better tonal structure for achieving maximum consonance than the so-called just intonation scales.
Temperaments are based on empirical tuning procedures guided by perceived intervals (see Asselin, 2000) whereas "just intonation" is the result of speculation about numerical ratios — a deductive process. This brings us back to a discussion of the ancient Indian approach to tonality, see the page on The two-vina experiment.
“Alternate” analysis
At this stage, it is tempting to conclude that J.S. Bach's The Well-Tempered Clavier was intended to be played on instruments tuned to Sauveur's temperament. However, the result of any analysis must always be examined for bias in its hypotheses. In the present case, we must revise the choice of certain frequency ratios as criteria for assessing the 'consonance' of melodic and harmonic intervals.
The minor third — either harmonic (6/5) or Pythagorean (32/27) — is in question because the Pythagorean minor third appears in some temperaments. For example, the Cmaj natural scale (see image) uses 32/27 for its interval 'C' - 'Eb'. Therefore, it makes sense to ignore all minor thirds when evaluating harmonic intervals and to accept both ratios 6/5 and 32/27 as equal positive weights in melodic intervals. This option is illustrated by sound examples, read on. A useful variant would be different ratios in ascending and descending harmonic intervals.
The same observation applies to major thirds: although 5/4 (harmonic) certainly sounds better than 81/64 (Pythagorean) in harmonic intervals, there is no strong reason to prefer the former in melodic intervals — again with a possible distinction between ascending and descending movements.
Let us start the whole analysis again with these changed settings:
The results contradict the conclusion of the 'standard' analysis: Sauveur's temperament may not be such a good choice, given the alternative choice of ratios for consonant/dissonant melodic and harmonic intervals.
According to these settings, the best tuning schemes might be the D'Alambert-Rousseau temperament (see picture and read Asselin, 2000 p. 119) and H.A. Kellner's BACH temperament (see picture and read Asselin, 2000 p. 101). Both were designed after J.S. Bach's death, but similar or identical tuning procedures could have been devised by the composer.
A comparison of the images and cent positions (identical within ± 7 cents) explains why these two temperaments produced identical matches, despite their completely different tuning procedures. Look at the procedures (traced by the algorithm) and listen to short note sequences produced with these scales:
D'Alembert-Rousseau temperament Created meantone upward notes “do,sol,re,la,mi” fraction 3/2 adjusted -1/4 comma Created meantone downward notes “do,fa,sib,mib,sol#” fraction 3/2 adjusted 1/12 comma Equalized intervals over series “sol#,do#,fa#,si,mi” approx fraction 2/3 adjusted 2.2 cents to ratio = 0.668
Sequence of notes according to D'Alembert-Rousseau temperament
Sequence of notes according to Kellner's BACH temperament
As a reminder, the same sequence of notes with an equal-tempered scale:
Sequence of notes according to equal temperament
D'Alembert-Rousseau tuning scheme (Asselin, 2000 p. 119)
These tuning procedures are not exactly the same as those described by Asselin (2000, p. 120 and 102), but they produce the same tonal positions.
In these temperaments, intervals such as 'C' - 'Eb' are rendered as Pythagorean minor thirds (32/27), and many Pythagorean major thirds (ratio 81/64) are encountered. This justifies their choice, given the new conditions of analysis.
Again, these temperaments dominate the classification, taking first place 65 times and second place 15 times, while the equal temperament, despite its mastery of Pythagorean major thirds, took first place only 21 times. Compared to Sauveur's temperament in the standard analysis (56 first positions and 9 second positions), these temperaments look 'better', but this comparison is irrelevant as the two analyses focused on different ratios.
The 33 Preludes and Fugues that do not conform to these temperaments often prefer a just intonation scale in the same key; for example, Prelude 8 in E♭ minor of Book I (BWV 853) chooses the Ebmin scale, and Prelude 9 in E major of Book I (BWV 854) chooses the Emaj scale. However, this matching is less common in the "dissident" fugues.
More advanced analysis is required. Note that changing the weighting of intervals or the weighting in the summation of melodic and harmonic scores can radically change the classification.
In this discussion, we have only examined tuning schemes at the top of the classification. Other schemes may be preferable when looking at melodic or harmonic scores separately — see our tutorial Tonal analysis.
Sound examples
The automatic tonal analysis of a large repertoire, compared with the whole set of tuning schemes implemented in the Bol processor, did not solve the problem of finding "the best tuning scheme" for this repertoire, since it depends on the initial conditions: frequency ratios estimated as "consonant" or "dissonant", plus the composer's presumed focus on optimal consonance. Nevertheless, two analyses selected 2 (or 3) tuning schemes as dominant in the classification. Further analysis would be required to refine this result, if it is significant.
All sound examples are compared with human interpretations on (not so well-tempered?) physical instruments on the page The Well-tempered clavier.
These sound examples are useful to hear the difference between tuning schemes selected on the basis of the "standard" and "alternative" settings. For example, Fugue 8 of book I may sound more melodious with a Dmin tuning (see illustration) than with a Marpurg tuning (see illustration). The difference may lie in the choice of the most convenient ratios for minor thirds.
Is this method reliable?
As the results shown in the 4 tables for each book (see above) suggest, some preludes and fugues ranked several tuning schemes as their favourite: number '1' is coloured red in the 'all results' tables. However, we only recorded one of the winners. What does this mean?
Take for example Prelude 12 of book I. In the "alternate" settings, five scales are ranked first: Emin, Cmaj, BACH, d_alembert_rousseau, bethisy. We have already shown that BACH and d_alembert_rousseau are almost identical despite the differences in their tuning procedures. Emin and Cmaj are exactly the same. This leaves us with the following choice:
Three scales ranking 1st for Prelude 12 of book 1 as per "alternate" settings
Tonal positions differ by a only few cents, which may not be noticeable in melodic and harmonic intervals. Below are recordings using these three scales:
Prelude 12 of book I, Emin tuning schemePrelude 12 of book I, Bethisy temperamentPrelude 12 of book I, Kellner's BACH temperament
This example suggests that if the widths of acceptable melodic and harmonic intervals have been set small enough to provide a well-focused solution set, differences in the first-ranked scales may be inaudible.
Listen to minor thirds
Judging the sizes of the common minor thirds by ear may make it easier to decide which is more "consonant". Lucky users of the Bol Processor BP3 only need to create the following data file:
-to.tryTunings
// Harmonic minor third _scale(2_cycles_of_fifths,0) DO3 RE#3 DO3 RE#3 DO3 RE#3 {4,DO3,RE#3}
//Pythagorean minor third _scale(2_cycles_of_fifths,0) DO3 MIb=RE#-c3 DO3 MIb=RE#-c3 DO3 MIb=RE#-c3 {4,DO3,MIb=RE#-c3}
These items produce sequences of 'C' - 'D#' melodic and harmonic intervals using harmonic (6/5) and Pythagorean (32/27) minor thirds:
Harmonic minor thirds in sequence then superposedPythagorean minor thirds in sequence then superposedAlternance of harmonic then Pythagorean minor thirds
Listening to these examples suggests that both 6/5 and 32/27 are suitable ratios for minor thirds as "consonant" melodic intervals, while 6/5 sounds "softer" than 32/27 as a harmonic interval.
The names of the notes (inspired by the book, ibid.) sound bizarre but they make the positions explicit. For example, "Mib=RE#-c" indicates a position that is usually called mi bémol (E flat), which is identical to ré dièse (D sharp) minus one comma.
This scale — and the even more complicated "3_cycles_of_fifths" — is not practical for writing music… It is used to visualise (and hear) tonal positions produced by different tuning schemes that conform to the just intonation paradigm.
Listen to tempered fifths
Readers unfamiliar with tuning procedures may need to appreciate the tiny differences in intervals produced by temperaments created using the methods introduced on the Microtonality page and described in detail in Asselin (2000).
Let us listen to Pythagorean fifths in three forms: pure (frequency ratio 3/2 = 702 cents), equal-tempered (700 cents), diminished by 1/5 comma (697.3 cents) and diminished by 1/4 comma (696.2 cents).
Pure fifth (702 cents)Equal-tempered fifth (700 cents)Fifth diminished by 1/5 comma (697.3 cents)Fifth diminished by 1/4 comma (696.2 cents)Sequence of fifths: pure, then equal-tempered, then diminished by 1/5 comma, then diminished by 1/4 comma
The same exercise was attempted with J.S. Bach's Goldberg Variations (1741). The aria and its thirty variations were performed in a single sequence, apparently with the same instrument/tuning. For this reason, we checked a unique MusicXML score containing all the variations.
With the "standard" hypothesis of consonance, the result is as follows:
(As expected) Sauveur's meantone temperament won the game, followed by Kellner's BACH. The equal-tempered scale came 28th in this classification… (Note that the calculation of this table took 3 1/2 hours on an old MacBook Pro…).
Listen to the synthesis of the Goldberg Variations with Sauveur's meantone temperament:
The "alternative" model of consonance gives the following classification:
Favourite tuning schemes, according to this model, would be D'Alembert-Rousseau (see picture) and Kellner's BACH (see picture) meantone temperaments, both of which have equal value because their tonal intervals are almost identical.
Listen to the synthesis of the Goldberg Variations with the D'Alembert-Rousseau temperament:
These preferred tunings are the same as those best suited to the set of preludes and fugues in The Well-Tempered Clavier.
These sound examples can be compared to human performance, for example the Aria on a harpsichord tuned to the Werckmeister III meantone temperament — listen to this recording. In fact, the musicians show a more flexible timing than the Bol Processor, which sticks to the parameters of the MusicXML score. Nevertheless, a comparison focusing on tonal intervals remains possible.
The fact that Werckmeister III (see image) ranked low in the automatic tonal analysis does not indicate a wrong choice. This tuning scheme may perform better against a particular model of "consonance".
Let us use calculations to work out its main difference from D'Alembert-Rousseau and Kellner's BACH. We can limit the analysis to bars #1 to #32 (the Aria), which exposes most of the melodic/harmonic intervals; this Aria functions similarly to the opening section (ālāp) in North Indian classical music… We notice that neither D - F# (397 cents) nor G - B (398 cents) in Werckmeister III are exact harmonic major thirds (390 cents), intervals with a high frequency as shown in the table of interval frequencies:
Interval frequencies in the Aria of Goldberg Variations
Below is a comparison of the Werckmeister III and D'Alembert-Rousseau scales in terms of matching melodic intervals (in the "alternate" model of consonance) over the first 32 bars of the Goldberg Variations:
Matching two scales with the melodic intervals of the Aria in Goldberg Variations: Werckmeister III (left) and D'Alembert-Rousseau (right)
The width of the yellow lines is proportional to the occurrence/duration of melodic intervals in this part of the corpus. The picture confirms the absence of an exact harmonic major third D - F# in the Werckmeister III scale, and the same mismatch of the major third G - B. Another mismatch is on the minor third E - G, here aiming at a ratio of 6/5 (315 cents) or 32/27 (294 cents).
Sources of MusicXML scores
Links point to MusicXML scores used in this analysis. These links must be cited in the attribution part of Creative Commons licences. Updated versions are welcome.
Our thanks to the editors of these scores in the MuseScore community!