Author Topic: Voice allocation / keyboard management  (Read 6858 times)

Đorđe Golubović

  • Team member
  • *
  • Posts: 19
    • View Profile
Voice allocation / keyboard management
« on: February 04, 2016, 12:02:19 AM »
I am trying to modify voice allocation in preenfm2, and I'm currently studying the code.
I want to make it more playable by keyboard - for instance, in current implementation, when monophonic mode is chosen, when I press and hold 3 keys in some order, and then I lift first and last, second one isn't triggered.
What I want to do is add stack which will hold all pressed keys in order they are pressed, and as a player depresses some key, it is removed from stack and replaced by the one before it.
Few top keys on stack (depending on the polyphony) will activate voices, and as they are released, the ones before them will jump into freed voice, and trigger a note. (I don't know if I explained it well)

I have a basic logic figured out, and implemented a very simple test console application (it will surely need some work to be adapted to preenfm2).

Now I want to understand as much as possible logic around current implementation, so I could do it with as smoothly as possible.

For now, I have few questions about some specific details:
I understand (maybe incorrectly) that first for loop in preenNoteOn iterates through all voices reserved for this timbre to check if they are free to use. I think I understand remaining logic, as well, but I don't quite understand what "index" of a voice is used for. I suppose it has something to do with the order of voice allocation, but it may not be the case...

Anyway, thank you Xavier for making this very great synth, and above all for making it open source, so people can see how things are done in real world. I am really inspired to make my own, if I find enough free time, and after I get my hands dirty enough with preen.

edit:
Attached first working changes - patch file and two firmware variants (optimized and non-optimized).
In monophonic mode it works perfectly, as far as I have tested it. In polyphony it doesn't work as I intended it to, so I will investigate it further.
I am uploading it here as it is for anyone that want's to check it out, but I will continue working on this, depending on my free time.

Anyway, changes are miniscule as note_stack is already there and used by arpeggiator (I've added separate instance for manual performance), and I've added one method to it that I needed, and few small changes in other places...

another edit (mar 15, 2016):
New upload. I've experimented with polyphony and note stack, and when implemented correctly, it feels strange - imagine 4x polyphony, you hold 3 note chord with one hand, and than press another 3 note chord with another hand, than release second chord. When released, first chord gets triggered, and most of the time it doesn't sound like something you would have wanted to play on keys.
So I've decided to leave keyboard behavior in polyphony as it is originally implemented by Xavier, it's probably the best way to do it in poly. In this latest patch, stacked legato is active only when glide parameter is greater than 0.

I could (and will, as I find some more time) clean this patch a bit, as I think nextGlidingNote might be redundant after this change... And probably few other things.

Attached are both prepared firmware (including compressor/distortion/fuzz effect) and patch with newest changes. Old versions are removed, as this new version is like totally better than the older one.
« Last Edit: March 15, 2016, 02:49:51 AM by jarilo »

Xavier

  • Administrator
  • Hero Member
  • *
  • Posts: 2256
    • View Profile
Re: Voice allocation / keyboard management
« Reply #1 on: February 04, 2016, 01:23:50 PM »
Hi Jarilo,

Yes indexVoice is to keep track of the voices order allocation.
When we have to stop a playing voice, we stop the older one.

Just had a look at the code to refresh my memory ;)
The logic in the first loop :
. is the note we ask is already paying => use same voice
. If a voice is not playing => use voice (I don't remember why we don't stop looping here :/ )
. If a voice is still playing but has been release => use it unless we find a not playing voice or an older note that is also realeased later in the loop

If we didn't find any available voice. We must chose one :Second loop....
. chose the older one but excludes voices that are about to start (isNewNotePending()).

That's the idea....

Xavier
« Last Edit: February 04, 2016, 01:28:42 PM by Xavier »

Xavier

  • Administrator
  • Hero Member
  • *
  • Posts: 2256
    • View Profile
Re: Voice allocation / keyboard management
« Reply #2 on: February 04, 2016, 01:27:44 PM »
"I don't remember why we don't stop looping here".....

Actually we continue looping to check whether we have a voice playing the requested note ;) First point of the first loop...
« Last Edit: February 04, 2016, 03:10:21 PM by Xavier »

Đorđe Golubović

  • Team member
  • *
  • Posts: 19
    • View Profile
Re: Voice allocation / keyboard management
« Reply #3 on: February 04, 2016, 07:57:36 PM »
Hi Xavier,
thanks for clearing everything up, I think I now understand it fully, and I see most of the hard work is already done here.
It only leaves me with adding note stack, and automatic note triggering logic on noteOff (if voice is freed in process). And, of course, having in mind voice index.

I will put updates here as I progress (and when I am stuck :D )

Thanks very much,
Djordje

Đorđe Golubović

  • Team member
  • *
  • Posts: 19
    • View Profile
Re: Voice allocation / keyboard management
« Reply #4 on: February 22, 2016, 11:17:18 PM »
Hi,
I've finally managed to find some spare time and work a bit on this.

I've attached patch file and compiled firmware so anyone could test it out. Long story short - it works for monophonic mode (glide or no glide), but acts weird in polyphony. It's probably not a big problem in polyphonic mode, as playing style is quite different from monophonic, but I will continue working on this for the sake of completeness :)

Cheers,
Djordje

Đorđe Golubović

  • Team member
  • *
  • Posts: 19
    • View Profile
Re: Voice allocation / keyboard management
« Reply #5 on: March 15, 2016, 03:02:04 AM »
Hi,

here's the new update.

Last edit in first post explains what this update is all about. I could maybe organize this a little better, to avoid flooding this thread with redundant info...

All the best,
Djordje

Đorđe Golubović

  • Team member
  • *
  • Posts: 19
    • View Profile
Re: Voice allocation / keyboard management
« Reply #6 on: March 19, 2016, 11:41:24 PM »
Hi,

I have more questions for you, Xavier :)

I am still looking into this "voiceIndex" logic - I think I understand it completely, just want to be sure of these few things:
- I don't see voiceIndex being initialized to any particular value anywhere in code, I suppose it mostly doesn't matter, or is it implicitly initialized to 0?
- As I understand, once in a while voiceIndex reaches maximum 32bit value, and wraps around (very rarely, obviously, once in 4 billion noteon events :) ). Does this mean that during this wrapping, some of the allocated voices will be incorrectly tagged as older, even though they aren't?
For instance we have voiceIndex values MAX-1, MAX, 0 and 1 - logic is such that smallest value is regarded as oldest, but in this example this is not the case. Did I understand this correctly?

Sorry for bugging you with all these questions, but I really enjoy all of this. :) As a side note, I started prototyping my own hobby synth on linux pc, and as one of first things I want to solve voice allocation.

Cheers,
Djordje

Xavier

  • Administrator
  • Hero Member
  • *
  • Posts: 2256
    • View Profile
Re: Voice allocation / keyboard management
« Reply #7 on: March 22, 2016, 12:05:04 PM »
Hi,

Yes it would be better to initialise member variables. Even if the compiler clear them to 0.

Answer to your second question. Yes there is a problem every 4000000000 notes.
If you play 10 notes per seconds without stopping, that will take 12 years so that a younger notes is cut instead of a older one.
That's acceptable  ;)

Best,

Xavie
« Last Edit: March 22, 2016, 12:53:04 PM by Xavier »

Đorđe Golubović

  • Team member
  • *
  • Posts: 19
    • View Profile
Re: Voice allocation / keyboard management
« Reply #8 on: March 22, 2016, 04:46:04 PM »
And more than a month if we fed it only noteon messages as fast as serial midi allows, if I've calculated it right.
Yes, acceptable to say the least! :)

And it's easy on cpu operations, compared to what monstrosity of a logic I had in mind!

I just wanted to be completely sure I understood this.
Thanks for the reply!

All the best,
Djordje
« Last Edit: March 22, 2016, 04:53:12 PM by jarilo »