As a way to use random numbers without seed,
use_random_seed Time.new.usec
or
use_random_seed Random.new_seed
but what is the best recommended method?
As a way to use random numbers without seed,
use_random_seed Time.new.usec
or
use_random_seed Random.new_seed
but what is the best recommended method?
Hi @H_Tachibana did you also try?
use_random_seed Time.now.to_i
live_loop :boom do
play rrand(30, 110), amp: 0.4
sleep 0.25
end
Thanks.
I did not know about Time.now.to_i.
Time.now.to_i is a 10-digit integer.
Random.new_seed is a 38-digit integer. (Seedless random number in Ruby)
Time.new.usec is a 5-digit integer.
Would you all say that 38 digits is the best?
If by ābestā you mean most random, then Random.new_seed
is the best option here.
I believe the way that random numbers work in Sonic Pi is that it has a predetermined list of ārandomā numbers, and the seed just chooses the starting point in that list. This is to ensure reproducibility, so that running the same code with the same seed will generate the same sounds even if it uses randomness.
One effect of this is that if you use a similar seed (e.g. increment it by 1), you will get the same sequence of numbers, just offset a bit (in this case by 1), like this:
define :random_list do |seed|
use_random_seed seed
list = []
10.times { list.push(rand_i(100)) }
list
end
puts random_list(123)
puts random_list(123)
puts random_list(124)
# {run: 45, time: 0.0}
# āā [77, 8, 53, 70, 0, 19, 99, 24, 89, 46]
# āā [77, 8, 53, 70, 0, 19, 99, 24, 89, 46]
# āā [8, 53, 70, 0, 19, 99, 24, 89, 46, 9]
If you use Time.now.to_i
, it only changes once a second, so if not much time has passed since the last run, you will get a similar sequence.
Similarly for Time.new.usec
, this is the microseconds part of the time, which repeats every second, so you are likely to get a similar sequence when you rerun the code if it happens to be a similar fractional part of a second as the last time.
In contrast, Random.new_seed
returns a very large number that changes completely every time you call it, so you will start in a completely different part of the random sequence each time.
Thanks @emlyn for this interesting explanation! Do you mean that for Random.new_seed
, each call to it, it will generate different numbers with no reproducibility possible? And how do you use it, like this f.i?:
Random.new_seed
live_loop :seed do
play rrand(40, 90)
sleep 0.5
end
SP program is
use_random_seed Random.new_seed
live_loop :seed do
play rrand(40, 90)
sleep 0.5
end
But this programme keeps producing the same sound, doesnāt it?
Oh, thatās very weird, Iām not sure whatās happening there, but it seems when the random seed is too big things break.
You can get around this by restricting the random seed to a lower range:
use_random_seed Random.new_seed % 1e9
Hi @beryann, itās almost like that, you just have to pass the new seed into Sonic Piās use_random_seed
, but as @H_Tachibana found out it still doesnāt quite work because the numbers it generates are too big and Sonic Pi canāt handle them, so something like this should do the trick:
use_random_seed Random.new_seed % 1e9
live_loop :seed do
play rrand(40, 90)
sleep 0.5
end
ok Emelyn, thanks! @emlyn But then, are the sequences of notes predictable or not if I transmit my code to someone? Is there reproducibility?
If you use Random.new_seed
it will give you a new sequence each time.
If you want it to be random-sounding but reproducible, you can just not call use_random_seed
at all, or give it a fixed number. E.g. you could do something like:
use_random_seed 123456
live_loop :seed do
play rrand(40, 90)
sleep 0.5
end
And change the random seed until you get a ārandomā sequence that you like. Then if you send the code to someone else they will get the same sequence.
Thanks a lot Emlyn @emlyn so, random is a question of choice in Sonic Pi, if I can say so!
Supplementary question: Doing this sounds logical but is it redundant compared to āuse_random_seed 123456ā ?
use_random_seed rrand(1, 123456)
live_loop :seed do
play rrand(40, 90)
sleep 0.5
end
Hi
your code produces one random seed upon execution
myrand = rrand(1, 123456)
use_random_seed myrand
live_loop :seed do
play rrand(40, 90)
sleep 0.5
puts myrand
end
This helped me understand use_random_seed
Random.new_seed is entirely random every time, anything else is pseudo-random, i.e. random repeatedly. Built in to Sonic Pi for reproducability.
Thatās right, the above (even if it initially looks more random) is redundant. When rrand
is called at the start of the run, it will always generate the same number, so you might as well just type a ārandomā number yourself, no need to call rrand
.
Iāve been needing this.
You are are right Emelyn! @emlyn I forgot that my rrand generates the same numberā¦These concepts are subtle and we have to pay attention to each of these terms!