1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
title::Random Seed
summary:: Random generator seed
categories::Core>Kernel, Random
related:: Guides/Randomness, Classes/RandSeed, Classes/Pseed, Classes/Thread
section:: Introduction
Every link::Classes/Thread:: in sclang has a (pseudo-) random number generator that is responsible for all randomization within this thread. Each random number generator has its own seed (starting point) from which the series of values is generated. This seed can be set and after that, the randgen (being strictly deterministic) produces exactly the same numbers again.
In order to save disk space, you can reproduce any sequence of randomized data just by one Integer number that you can write down in your notebook.
method:: randSeed
code::
// every thread, also a Routine, has a random generator seed:
(
r = Routine({
loop({#[1,2,3,4,5].choose.yield })
});
r.randSeed = 1923;
)
// using the routine to fill an array
Array.fill(7, r);
// setting the random generator seed back to our initial seed
r.randSeed = 1923;
// causes this array to be identical
Array.fill(7, r);
::
subsection::Inheriting Seeds
When a routine is created, it inherits its random number generator from the parent thread (link::Classes/Thread#.thisThread#thisThread::). If no particular randSeed is set (the normal case), then the same random number generator object provides numbers to both the parent and the child (one stream of random numbers, distributed between both).
The parent thread is whichever Routine is in force at the moment of creating a new Routine. If no Routine is evaluating at that moment, then the parent is the sclang process main link::Classes/Thread::. By default, all Routines inherit the random number generator from the main thread.
To set the main random seed for the entire application, then, evaluate code::thisThread.randSeed = yourSeed:: outside of the context of any Routine, as in the example below.
code::
thisThread.randSeed = 1923;
// create a function that returns a Routine
r = { Routine({
loop({#[1,2,3,4,5].choose.yield })
}) };
Array.fill(7, r.value);
// reset the seed
thisThread.randSeed = 1923;
Array.fill(7, r.value);
::
When you set code::randSeed:: on a Routine, the Routine switches to its own random number generator, independent of any other. Subsequently, Routines created within this Routine will inherit its unique random number generator.
code::
(
thisThread.randSeed = 1000;
TempoClock.sched(0, { 1000.rand.debug("main RNG"); 1 });
fork {
2.1.wait;
thisThread.randSeed = 1000;
loop { 1000.rand.debug("routine RNG"); 1.wait }
};
)
main RNG: 592 // sequence is 592, 876, 614, 236...
main RNG: 876
main RNG: 614
routine RNG: 592 // sequence is 592, 876...
main RNG: 236
routine RNG: 876
::
Note that this inheritance takes place only at the moment of creating a new Routine. Calling code::next:: or code::play:: on the child Routine does not override that Routine's random number generator.
subsection:: Audio example
code::
// use the seed to completely reproduce a sound:
(
SynthDef(\help_randomSeed, { arg out=0, freq=440;
Out.ar(out,
Line.kr(1, 0, 0.3, doneAction: Done.freeSelf) *
Resonz.ar(
Dust2.ar([10, 10], 270) + WhiteNoise.ar(4),
freq, 0.01)
)
}).send(s);
SynthDef(\help_setRandomSeed, { arg seed=1956, tbus=0.0;
RandSeed.kr(tbus, seed);
}).send(s);
)
// run a patch
(
x = Synth(\help_setRandomSeed);
r = Routine({
loop({
Synth(\help_randomSeed, [\freq, rrand(440, 700)]);
0.25.wait;
})
}).play;
)
// make a reset task
(
d = 1250;// seed
t = Task({
loop({
x.set(\seed, d, \tbus, 1.0); r.randSeed = d;
0.1.wait;
x.set(\tbus, 0.0);
1.9.wait;
})
});
)
// sound starts to loop
t.start;
d = 1251; // different loop
d = 1925;
// sound is just like random again, not interested in anything.
t.stop;
::
|