# Poly round robin - any new developments?



## Mr. Anxiety (Jun 23, 2009)

Hello All,

Has there been any recent scripting that handles polyphonic round robin?
i.e. playing chords (for example - marcato string chords).

The last I saw was Andrew's Intelligent Round Robin Script 1.1.

Curious

Mr. Anxiety


----------



## sevaels (Jan 27, 2010)

I'd also really love to see this. Has anyone made any progress?


----------



## sevaels (Jan 27, 2010)

Sorry for the double post :oops:


----------



## Mr. Anxiety (Jan 27, 2010)

I wonder how Kirk Hunter is achieving this with his new String Library. 

From what I've heard, it's working pretty good.

Mr. A.


----------



## Mark Belbin (Jan 27, 2010)

Hi Guys,

The trouble with this is that it involves group management (obviously). Since a developer's approach can run the gamut from building instruments in Kontakt (uggh...) to using Keymap or converting from Giga or EXS, etc, group layout can vary wildly from instrument to instrument. So it would be hard to script something that could read any instrument's layout and manage rr's accordingly. Failing that, I've written an example script that presupposes the following (but it's editable, of course):

1) The instrument uses three velocity layers, with specific min and max values, the same for every note.

2) The instrument uses eight round robins.

3) All groups must have their group start options set to "always", allowing the script to manage them instead of Kontakt's internal group management.

4) This is a good example of why group management can be so instrument specific, and is very important: 

-In this example, each velocity layer of each round robin is expected to be in its own group; it is possible in Kontakt to have all velocities in a single group, with only the rr's seperated. If you use this script on an instrument with velocities not seperated, simply delete the last two code blocks in the note callback, and remove the outer if statement from the remaining one. Having the capability to deal with velocities being separated as groups is important where the instrument is designed that way (instruments converted from giga using Kontakt will seperate both rr's and velocities). 

-Each velocity's rr groups must be contingent in the group editor's display; that is, (for example) if the lowest velocity's first rr is group 0, then the lowest velocity's second rr must be group 1, the third must be group 2, etc, until we run into the second-lowest velocity's first rr, continuing in the same pattern. Other layouts will require more in depth editing of the script to manage.

So this script, if loaded on an instrument that meets these criteria (or edited to fit variations thereof), will independently track the current location in the round robin chain for each velocity layer of each note. Play a middle C at a velocity of 64, and the affected velocity layer of that note will sit there forever and remember which round robin to use next, whether you play the same note again at a different velocity, or play different notes before returning to that zone. Instruments with a few RR's and adequate velocities will sound equally natural on chords, arpeggios, etc, as they would on simple one-note repetitions.

Anyone with basic KSP chops should be able to edit as needed with the help of the comments.

Oh, and even though I've used this approach extensively on a few instruments, I haven't tested this exact example.... :oops: 

Enjoy!

Belbin

Edit/p.s. I'm not sure what the indentation tags are all about, but it seems the tidiest option for pasting code with comments...you could do a find and replace, for those tags if they're troublesome (replace with "{}"). 

Edit 2/p.p.s Pasting to Nil's K Script Editor will remove the tags and substitute....indentation!


----------



## Mark Belbin (Jan 27, 2010)

*on init*

_{round-robin control}_
*declare* %p_rr_track[128] _{tracks lowest velocity's per-note location in round-robin chain}_
*declare* %mf_rr_track[128] _{tracks middle velocity's per-note location in round-robin chain}_
*declare* %f_rr_track [128] _{tracks highest velocity's per-note location in round-robin chain}_

*declare* *const* $p_starts_at_group := 0 _{set this to the index of the first group that uses the lowest velocity}_
*declare* *const* $mf_starts_at_group := 8 _{set this to the index of the first group that uses the middle velocity}_
*declare* *const* $f_starts_at_group := 16 _{set this to the index of the first group that uses the highest velocity}_

*declare* *const* $p_hi_velocity := 43 _{set this value to the highest velocity value of the lowest velocity layer}_
*declare* *const* $p_lo_velocity := 0 _{set this value to the lowest velocity value of the lowest velocity layer}_

*declare* *const* $mf_hi_velocity := 85 _{set this value to the highest velocity value of the middle velocity layer}_
*declare* *const* $mf_lo_velocity := 44 _{set this value to the lowest velocity value of the middle velocity layer}_

*declare* *const* $f_hi_velocity := 127 _{set this value to the highest velocity value of the middle velocity layer}_
*declare* *const* $f_lo_velocity := 86 _{set this value to the lowest velocity value of the middle velocity layer}_

*declare* *const* $how_many_round_robins := 7 _{zero based, so set this to the number of rr's minus one; this setting presupposes 8 rr's}_


*declare* $allow_group _{the actual group that will be played}_
​*end on*

*on note*


disallow_group($ALL_GROUPS)

_{lowest velocity layer}_

​ *if* (in_range ($EVENT_VELOCITY, $p_lo_velocity, $p_hi_velocity)) 

​ *if* (in_range (%p_rr_track[$EVENT_NOTE], 0, $how_many_round_robins)) _{if we've not run out of rr's....}_

$allow_group := $p_starts_at_group + %p_rr_track[$EVENT_NOTE] _{use first group of this velocity layer plus current location in chain}_
inc (%p_rr_track[$EVENT_NOTE]) _{advance current location in chain for this note at lowest velocity layer}_​ *else* _{....but if we have run out of rr's}_

$allow_group := $p_starts_at_group _{use first group of this velocity layer}_
%p_rr_track[$EVENT_NOTE] := 1 _{set current location in chain for this note at lowest velocity layer to second group for this velocity layer}_​ *end if*

​ *end if* 

_{middle velocity layer}_


​ *if* (in_range ($EVENT_VELOCITY, $mf_lo_velocity, $mf_hi_velocity)) 

​ *if* (in_range (%mf_rr_track[$EVENT_NOTE], 0, $how_many_round_robins)) _{if we've not run out of rr's....}_

$allow_group := $mf_starts_at_group + %mf_rr_track[$EVENT_NOTE] _{use first group of this velocity layer plus current location in chain}_
inc (%mf_rr_track[$EVENT_NOTE]) _{advance current location in chain for this note at middle velocity layer}_​ *else* _{....but if we have run out of rr's}_

$allow_group := $mf_starts_at_group _{use first group of this velocity layer}_
%mf_rr_track[$EVENT_NOTE] := 1 _{set current location in chain for this note at middle velocity layer to second group for this velocity layer}_​ *end if*

​ *end if* 

_{highest velocity layer}_


​ *if* (in_range ($EVENT_VELOCITY, $f_lo_velocity, $f_hi_velocity)) 

​ *if* (in_range (%f_rr_track[$EVENT_NOTE], 0, $how_many_round_robins)) _{if we've not run out of rr's....}_

$allow_group := $f_starts_at_group + %f_rr_track[$EVENT_NOTE] _{use first group of this velocity layer plus current location in chain}_
inc (%f_rr_track[$EVENT_NOTE]) _{advance current location in chain for this note at highest velocity layer}_​ *else* _{....but if we have run out of rr's}_

$allow_group := $f_starts_at_group _{use first group of this velocity layer}_
%f_rr_track[$EVENT_NOTE] := 1 _{set current location in chain for this note at highest velocity layer to second group for this velocity layer}_​ *end if*

​ *end if* 
​allow_group ($allow_group) 

*end on*


----------



## kotori (Jan 27, 2010)

Btw. there are two options in my editor: Copy as BBCode, and Copy as BBCode with indent. Please choose the first one for posting on forums that do not support the indent tag.


----------



## Mark Belbin (Jan 27, 2010)

thanks Nils - I tried that, but it had a negative impact on the spacing of the comments. Then I realized that the editor removes the indentation tags when the code is pasted back in after I wrote my p.s. See new p.p.s.


----------



## sevaels (Jan 27, 2010)

Great response guys thanks!

What if you wanted all the groups in the instrument to shuffle randomly with poly-round robin so:

If you play a standard 3 note triad it choses group 1 lets say for all 3 notes played in a certain timeframe lets say. Then if you trigger the chord again all 3 notes play group 2 then group 5 etc etc etc..

Clear as mud?

~o)


----------



## Mr. Anxiety (Jan 27, 2010)

Wow Mark, this looks rather impressive. As you said, it has to be problematic with such a wide variety of instrument libraries, done every which way out in the marketplace.

But if we can find some consistency with a few, this could surely work, I believe. 

I will try to put this to use as soon as I can and report back. I hope others will do the same.

Thanks so much for your efforts Mark!

Mr. A.


----------

