Last active
August 3, 2021 14:09
-
-
Save aike/26236e96523d99a11ba855969c37976e to your computer and use it in GitHub Desktop.
Mersenne Twister (MT19937) random number generation library in KONTAKT KSP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{========================================== | |
Mersenne Twister example | |
random sequencer multi script | |
==========================================} | |
on init | |
set_ui_height_px(200) | |
make_perfview | |
set_script_title("MT Sequencer") | |
declare const $wait := 150000 | |
declare %scale[8] := (0, 2, 4, 5, 7, 9, 11, 12) | |
declare ui_table %notes[16](4,6,8) | |
set_control_par(get_ui_id(%notes), $CONTROL_PAR_WIDTH, 400) | |
set_control_par(get_ui_id(%notes), $CONTROL_PAR_HEIGHT, 150) | |
move_control_px(%notes, 180, 20) | |
declare ui_value_edit $Seed(0, 07fffffffh, 1) | |
$Seed := 0 | |
set_control_par(get_ui_id($Seed), $CONTROL_PAR_WIDTH, 90) | |
move_control_px($Seed, 70, 20) | |
declare ui_switch $Play | |
set_control_par(get_ui_id($Play), $CONTROL_PAR_WIDTH, 90) | |
move_control_px($Play, 70, 60) | |
declare $n | |
declare $beat | |
declare $playing | |
{========================================== | |
Mersenne Twister (MT19937) | |
random number generation library in KSP | |
usage: | |
call mt_init | |
initialize with $mt_seed | |
call mt_genrand | |
get a random number into $mt_rand | |
the range is 31bit (0-07fffffffh) | |
license: | |
MIT License | |
original version in C | |
http://www.math.sci.hiroshima-u.ac.jp/m-mat/MT/MT2002/CODES/mt19937ar.c | |
==========================================} | |
{ MT access variables } | |
declare $mt_seed | |
$mt_seed := 0 | |
declare $mt_rand | |
{ MT xor helper variables } | |
declare $mt_xor_arg1 | |
declare $mt_xor_arg2 | |
declare $mt_xor_tmp_or | |
declare $mt_xor_tmp_nand | |
declare $mt_xor_result | |
{ MT Period parameters } | |
declare const $mt_N := 624 | |
declare const $mt_M := 397 | |
declare const $mt_MATRIX_A := 09908b0dfh | |
declare const $mt_UPPER_MASK := 080000000h | |
declare const $mt_LOWER_MASK := 07fffffffh | |
declare %mt_x[$mt_N] | |
declare $mt_i | |
declare $mt_y | |
declare $mt_z | |
{ MT initialize array with $mt_seed } | |
%mt_x[0] := $mt_seed .and. 0ffffffffh | |
$mt_i := 1 | |
while ($mt_i < $mt_N) | |
$mt_xor_arg1 := %mt_x[$mt_i - 1] | |
$mt_xor_arg2 := sh_right(%mt_x[$mt_i - 1] .and. $mt_LOWER_MASK, 30) | |
if (%mt_x[$mt_i - 1] < 0) | |
$mt_xor_arg2 := $mt_xor_arg2 .or. 2 | |
end if | |
$mt_xor_tmp_or := $mt_xor_arg1 .or. $mt_xor_arg2 | |
$mt_xor_tmp_nand := .not. ($mt_xor_arg1 .and. $mt_xor_arg2) | |
$mt_xor_result := $mt_xor_tmp_or .and. $mt_xor_tmp_nand | |
%mt_x[$mt_i] := (1812433253 * $mt_xor_result) + $mt_i | |
%mt_x[$mt_i] := %mt_x[$mt_i] .and. 0ffffffffh | |
inc($mt_i) | |
end while | |
$mt_i := 0 | |
message("") | |
end on | |
{ MT helper function calculate $mt_xor_arg1 XOR $mt_xor_arg2 } | |
function mt_xor | |
$mt_xor_tmp_or := $mt_xor_arg1 .or. $mt_xor_arg2 | |
$mt_xor_tmp_nand := .not. ($mt_xor_arg1 .and. $mt_xor_arg2) | |
$mt_xor_result := $mt_xor_tmp_or .and. $mt_xor_tmp_nand | |
end function | |
{ MT initialize array with $mt_seed } | |
function mt_init | |
%mt_x[0] := $mt_seed .and. 0ffffffffh | |
$mt_i := 1 | |
while ($mt_i < $mt_N) | |
$mt_xor_arg1 := %mt_x[$mt_i - 1] | |
$mt_xor_arg2 := sh_right(%mt_x[$mt_i - 1] .and. $mt_LOWER_MASK, 30) | |
if (%mt_x[$mt_i - 1] < 0) | |
$mt_xor_arg2 := $mt_xor_arg2 .or. 2 | |
end if | |
call mt_xor | |
%mt_x[$mt_i] := (1812433253 * $mt_xor_result) + $mt_i | |
%mt_x[$mt_i] := %mt_x[$mt_i] .and. 0ffffffffh | |
inc($mt_i) | |
end while | |
$mt_i := 0 | |
end function | |
{ MT generates a random number } | |
function mt_genrand | |
$mt_z := %mt_x[$mt_i] .and. $mt_UPPER_MASK | |
$mt_z := $mt_z .or. (%mt_x[($mt_i + 1) mod $mt_N] .and. $mt_LOWER_MASK) | |
$mt_xor_arg1 := %mt_x[($mt_i + $mt_M) mod $mt_N] | |
$mt_xor_arg2 := sh_right($mt_z .and. $mt_LOWER_MASK, 1) | |
if ($mt_z < 0) | |
$mt_xor_arg2 := $mt_xor_arg2 .or. 040000000h | |
end if | |
call mt_xor | |
$mt_xor_arg1 := $mt_xor_result | |
if (($mt_z .and. 1) = 0) | |
$mt_xor_arg2 := 0 | |
else | |
$mt_xor_arg2 := $mt_MATRIX_A | |
end if | |
call mt_xor | |
%mt_x[$mt_i] := $mt_xor_result | |
$mt_y := %mt_x[$mt_i] | |
{ Tempering } | |
$mt_xor_arg1 := $mt_y | |
$mt_xor_arg2 := sh_right($mt_y .and. $mt_LOWER_MASK, 11) | |
if ($mt_y < 0) | |
$mt_xor_arg2 := $mt_xor_arg2 .or. 100000h | |
end if | |
call mt_xor | |
$mt_y := $mt_xor_result | |
$mt_xor_arg1 := $mt_y | |
$mt_xor_arg2 := sh_left($mt_y, 7) .and. 09d2c5680h | |
call mt_xor | |
$mt_y := $mt_xor_result | |
$mt_xor_arg1 := $mt_y | |
$mt_xor_arg2 := sh_left($mt_y, 15) .and. 0efc60000h | |
call mt_xor | |
$mt_y := $mt_xor_result | |
$mt_xor_arg1 := $mt_y | |
$mt_xor_arg2 := sh_right($mt_y .and. $mt_LOWER_MASK, 18) | |
if ($mt_y < 0) | |
$mt_xor_arg2 := $mt_xor_arg2 .or. 2000h | |
end if | |
call mt_xor | |
$mt_y := $mt_xor_result | |
{ get 31bit unsigned int } | |
$mt_rand := sh_right($mt_y .and. $mt_LOWER_MASK, 1) | |
if ($mt_y < 0) | |
$mt_rand := $mt_rand .or. 040000000h | |
end if | |
$mt_i := ($mt_i + 1) mod $mt_n | |
end function | |
{========================================== | |
Mersenne Twister End | |
==========================================} | |
on ui_control($Seed) | |
{ initialize MT with $mt_seed } | |
$mt_seed := $Seed | |
call mt_init | |
set_midi(0,$MIDI_COMMAND_NOTE_ON, $n, 0) { note off } | |
$n := 0 | |
while ($n < 16) | |
{ get a MT random number into $mt_rand } | |
call mt_genrand | |
%notes[$n] := $mt_rand mod 8 | |
inc($n) | |
end while | |
end on | |
on ui_control($Play) | |
if ($Play = 1) | |
$playing := 1 | |
$beat := 0 | |
while ($playing = 1) | |
$n := 60 + %scale[%notes[$beat]] | |
set_midi(0,$MIDI_COMMAND_NOTE_ON,$n,100) { note on } | |
wait($wait) | |
set_midi(0,$MIDI_COMMAND_NOTE_ON,$n, 0) { note off } | |
wait(100) | |
$beat := ($beat + 1) mod 16 | |
end while | |
else | |
$playing := 0 | |
end if | |
end on |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment