External engine and polyphony

Hi, I think I’m in need of a clarification on how the external engine handles polyphony (classic MIDI not MPE).

I have this setup:

my first pulse is set on midi out channel 1. The second one midi out channel 2. I’ve set things so that the first pulse plays a long sustained note (say a bar), while the second pulse plays 4 shorter notes. So the interval of pulse 1 is set to 32, the interval of pulse 2 set to 8. The hold time for pulse 1 is set to 1,85 seconds (considering the track runs at 122 bpm and clock division is set to 8, it stops just before the next pulse), the hold time for pulse 2 is set to 26ms. Btw am I correct in thinking that “hold time” simply is the time before a note off message is sent ?

So, you’d suppose that a mere polyphony of two is enough for this. There is never more than two notes playing at the same time. And the monitoring on my multitimbral external synth confirms that it never plays more than two notes at a time (on differents channels).

But with a polyphony of 2, as soon as the second note of the second pulse is played, the sustained note on pulse 1 is cut (receives a note off), though, of course, the former pulse of the second pulse line is exginguished if I may say (has already received its note off).

Curiously, if I set the polyphony to 3, it allows the sustained note of the first pulse to be played just a quarter longer. Same thing if set to 4 ; it is as if it was couting / adding the total number of pulse played, regardless of the notes off sent, and when it has reached its limit it sends a note off and reset its count– doesn’t make a lot of sense but that’s how I’ll describe it.

So in order to play my “one sustained note on a channel and a sequences of four short (not overlaping) notes on another channel”, I have to set polyphony to 5.

Not sure if it is a bug, or just something I don’t understand !

1 Like

In all sound engines (except quad engine) the voice stealing behavior is: when a new voice/note is triggered and that would cause it to exceed the polyphony value, the oldest active voice (regardless of what pulse it was triggered by) is stopped to free up a voice for a new note.

For example: polyphony is 2 so only two voices are used. Pulse 1 triggers at the beginning once and pulse 2 triggers at each clock.

polyphony = 2
clock | | | | | | 
      1=
      2===
        2===
          2===
            2===

If we increase polyphony the voices can last longer:

polyphony = 3
clock | | | | | | 
      1===
      2=====
        2=====
          2=====
            2=====

So what you are seeing is the intended behavior.

Yes

But isn’t my situation a bit different ? Since the enveloppe (hold time) for the notes on pulse 2 are short, the note off message is sent before the start of the next one, so there in never more than two voices. In your example, the notes duration on pulse two is longer than the time before the next note, hence the overlap and voice stealing, no ?

Your example is how I expect the pp to behave with every other engine, where there is one envelope (or rather set of envelopes) for every note triggered by the engine, whatever the pulse. But the external has the peculiarity that it has four envelopes to define hold time per pulse.

So should’nt my case look more like :

polyphony = 2
clock | | | | | | 
      1==========
      2= 2= 2= 2=

The notes on the second pulse never overlap, so how come it steals the voice of the first pulse ? There is never more than two notes playing at a time.

My expectation is based on the assumption that sending a note off message frees the voice – but is that right ? Actually what happens in my situtation could be described as : the note off sending doesn’t free the voice. So it continues adding up, and eventually steals.
There really is something I don’t get here :sweat_smile:

What I wrote earlier is not quite correct, sorry. I checked in the code and what actually happens is:

quad engine: uses the same voice each time a note is triggered. This means that pulses generally don’t stop notes triggered by other pulses, although it still can happen with low polyphony values.

all other sound engines: cycles sequentially through the voices regardless of whether voices are active or not. When all envelopes are the same length that means the ‘oldest voice’ being used for new notes.

1 Like

Ah thanks, that makes much more sense to me now. It’s a kind of round robin between voices, within the set polyphony limit, regardless, as you said, of the satus of the current voice. So as opposed to what I assumed, a note off doesn’t make the voice immediatlly available for reuse, the round robin continues. Hence the behaviour that puzzled me at first.

It seems just fine with most of the engine where there in one shared note length for all pulses, but then may I ask why not use for the external engine the same method of voice allocation you choosed for the quad ? – considering they share the same specificity of having per pulse note lengths.

Quad engine has the limitation that each pulse/part can only play monophonic because each quad engine part uses up to 2 voices: left and right (if unison=2). So 4 quad parts x 2 voices per part = 8 voices.

Well, the quad engine method makes sense in some situations but not in others. When you want to playing polyphonic stuff the quad engine method would actually be bad.

I must admit this is not something I really thought about until this thread. I do think now that it makes sense to make voice stealing behavior configurable (at least for the external sound engine) from track settings, so I will write it down so I can look at it later!

Yes that was just an idea, and I don’t have a full understanding of the polyphony implementation of the quad engine. But yes maybe the polyphony implementation of the external engine could be refined somehow, I don’t know. Thanks for the clarification on this topic !

1 Like