Kontakt Scripting · KSP
Playing a Random Set of Samples in Kontakt
June 2014
For a project I am working on I am using Native Instruments Kontakt's scripting language (KSP) to trigger random samples from a range within the sampler.
This was all working well but when the sample size was getting too small the script was getting locked in a while loop trying to find notes that it had not used before — which was very inefficient and would eventually cause Kontakt to hang.
The Solution: Shuffle an Array
The solution I came up with was to use an array to store all the note indices, which gets shuffled randomly whenever the playhead reaches the end of the list. This way we cycle through every sample exactly once before repeating — no infinite loops, no repeated samples until the full set has played.
The Script
on init
message("Loaded...")
declare $temp := 0
declare $random_temp := 0
declare $counter := 0
declare $lower_limit := 0
declare $upper_limit := 10
declare $play_head := 0
declare %array_one[10]
{ Populate array with sequential indices }
while($counter < num_elements(%array_one))
%array_one[$counter] := $counter
inc($counter)
end while
{ Initial shuffle }
$counter := 0
while($counter < num_elements(%array_one))
$random_temp := random(0, num_elements(%array_one) - 1)
$temp := %array_one[$counter]
%array_one[$counter] := %array_one[$random_temp]
%array_one[$random_temp] := $temp
inc($counter)
end while
end on
function shuffleArray
$counter := 0
while($counter < num_elements(%array_one))
$random_temp := random(0, num_elements(%array_one) - 1)
$temp := %array_one[$counter]
%array_one[$counter] := %array_one[$random_temp]
%array_one[$random_temp] := $temp
inc($counter)
end while
end function
on note
if ($play_head < 10)
message("Playing....")
play_note(%array_one[$play_head], 100, 0, -0)
inc($play_head)
else
message("Shuffle....")
call shuffleArray
$play_head := 0
play_note(%array_one[$play_head], 100, 0, -0)
inc($play_head)
end if
end onHow it Works
On initialisation, the array is filled with sequential indices (0 through 9) and then immediately shuffled using a Fisher-Yates style swap. On each note trigger, the script plays the sample at the current playhead position and advances. Once the playhead reaches the array limit, the array is reshuffled and the playhead resets — guaranteeing a new random order each cycle.
This approach is far more efficient than searching for an unused note. It also guarantees every sample is heard before any repeats, which gives a much more natural and musical result.