Random round robin with Kontakt scripting

Acoustic instruments, and also some synthesizers and drum machines, produce a different sound each time a note is played. To capture this with sampling, something called "round robin sampling" is used. It means using multiple samples of the same note. When that note is played repeatedly, the sampler cycles through the samples in round robin order. The result can be much more realistic than using a single sample.

Round robin order usually works fine, but not always. It is sometimes possible to hear that the same sequence of samples are repeated over and over. For example, playing drum samples usually means playing the same note repeatedly in a way that makes it easier to hear.

Random order

Kontakt has a group start option called "Cycle random". It will play a random sample. The problem is that the same sample can be played twice (or more) in a row.

It is easy to make a Kontakt script that plays a random sample and also avoids playing the same sample twice. This is kind of nice, but it can still result in only two samples playing over and over.

Combining round robin and random order

To make it harder to hear that the same samples are used over and over, I came up with this:

Create a random order of all samples, play through all of them, then create a new random order of all samples. And make sure that a single sample is never played twice in a row.

I am probably not the first person to think of this, but it works pretty well and I found no examples of it anywhere. So here it is. I hope you will find it useful:

 

Download example
For Kontakt 4.0 or later (1.5MB)

Kontakt script

This script (included in the example download) can be used with any number of round robin samples with minimal changes.

on init
  declare %list[7]
  declare $at := num_elements(%list)
  { %list is the order the groups will play, $at is the current position in the list. } 
  { for any number of round robin groups other than 7, change the %list size. }

  
  declare $x
  declare $last

  declare @debug { remove this and the debug section below after testing }
end on

on note
  disallow_group($ALL_GROUPS)
  
  inc($at)
  
  { if all groups in the list have been played, fill the list with all groups in random }
  { order, and make sure the last played group is not the first in the new list }
  if($at >= num_elements(%list))
  
    { remember last played group }
    $last := %list[num_elements(%list) - 1]
    
    { fill list with all groups in random order }
    %list[0] := 0
    $at := 1
    while($at # num_elements(%list))
      $x := random(0, $at)
      %list[$at] := %list[$x]
      %list[$x] := $at
      inc($at)
    end while
    $at := 0
    
    { if the last played group is first in the new list, swap first and last in the list }
    if(%list[0] = $last)
      %list[0] := %list[num_elements(%list) - 1]
      %list[num_elements(%list) - 1] := $last
    end if
    
    { debug: show list }
    $x := 0
    @debug := "list:"
    while($x # num_elements(%list))
      @debug := @debug & " " & %list[$x]
      inc($x)
    end while
    message(@debug)
    { debug end }
  
  end if
  
  { enable a group from the list }
  allow_group(%list[$at])
end on
NNN OOO RRR MMM AAA LLL
NNN OOO RRR MMM AAA LLL
NNN OOO RRR MMM AAA LLL
SSS OOO UUU NNN DDD SSS
SSS OOO UUU NNN DDD SSS
SSS OOO UUU NNN DDD SSS

© 2011-2018 Normal Sounds
E-mail adress is "hello" before the @-sign