I tried to build my own [poly]-like object.
The simplest polyphonic synthesizer is build of several monophonic synth instances (each of them plays one voice at the time). So if we have got raw MIDI data, we should split it in order to send proper data to each of the synths. I showed it in following diagram:
We'll focus only on data splitter and how should it work. Idea for build simple splitter is making a set of single modules that will be connected into a chain. Each of these modules deals with data that it get, holds one note at the time, sends it to synth instance. As it goes about data processing, such a module can store received note and throw it to next module in the chain. Following diagram shows, how should it work:
As I mentioned, the splitter module should process the notes that it gets. In general we assume that it should:
Store received note, if it doesn't play any note at the moment.
Update information about currently playing note (eg. mute the note or change its velocity), if such a data comes to it.
Send received note further, if it plays some note at the moment.
I'll apply idea mentioned above, with one more thing - even if we use received note off (note with velocity equals to 0) to update current note, we have to throw it to the next instance. Then we'll be sure that in case of sending note off from our external MIDI device, all unison voices will be muted. So let's look at patch implementing that idea.
Note 1: That patch sends and receives lists of two floats - first one is MIDI note number, second one is its velocity. In further part of that text I'll call this data type note list.
Note 2: If order of connecting outlets from an object matters, that one, which need to be connected as the first one is marked using (1).
If received note's number is equal to the note that we hold in current module, we just use it here. Contrary we need to check some other parameters of it. In order to split the data by cases I used [list prepend] that put 0 or 1 on the beginning of the list. Which one? It depends about equality of note number stored in current module and the received one. I also use route object - it sends the list without the first element to the output that is determined by the first element of received list - combining these two objects gives us very simple demultiplex.
It contains objects used to store current note number and velocity. In case of updating current note it's automatically sent to the synth (by the outlet) and also to the comparing objects in current patch. Loadbang is used in order to let these comparsions work properly during first use.
If received and held notes' numbers aren't equal, we should check, if current module is in use. So we just check if held note's velocity is equal to 0. If it's, then we apply a received note, else we throw it to the next module in a chain.
We should also consider one more feature, that I mentioned. So we check, if applied note's velocity is equal to 0. If it's, we just throw it further.
Connecting these modules is very simple.
To the first module we should send note list from external source (MIDI keyboard, controller, random number generator, etc.), then we connect each module's first outlet to first inlet of the next one. Second outlet of each module is connected to monophonic synthesizer. Of course we should process note list properly in order to make them play.
The simplest way of connecting them may look like this (I named single module plpmod):
As you noticed, such an approach to polyphony gives you lots of freedom about constructing your synth's maximum polyphony and simply sends overflown notes staight to /dev/null, as we wanted, I think.
Template of the website is ready, so I can start publishing my content right here. Okay, so...
Hey! I'm gz and this is my blog-like website. Here you'll find my works linked with sound, music and programming.
At the moment of writing that it's empty here but it'll change in a days. See you soon!