Change random seed live?

Hey, everyone. I just discovered this today and have been obsessing over it for the last five hours straight. This tool is amazing.

How do I change a random seed live?

In a performance setting, can I avoid stopping and relaunching the script to set a new seed? I tried doing it inside a live loop, and it’s not changing. Specifically, I am trying to set it to a new random seed when a certain midi key on my launchpad is pressed. Here is my almost certainly horrible code below. It is working great and doing exactly what I want apart from allowing me to set a new seed and re-choose my notes based on that seed when I press the midi key again.

Update: I discovered this works fine if I get rid of the outer loop, and have since re-read the tutorial and caught the part I missed about loops being black holes for code.

I really want this thing to play these four bars until I press a different pad, which will give me four new random bars in scale. Is that not possible without stopping the music?

Thanks!
Jack

live_loop :midi_piano do
  use_real_time
  
  
  note, velocity = sync "/midi:launchpad_pro_mk3_lppromk3_midi:0:1/note_on"
  if (note<37)
    use_random_seed 26
    c4thing1=scale(:c4,:major).choose
    c4thing2=scale(:c4,:major).choose
    c4thing3=scale(:c4,:major).choose
    c4thing4=scale(:c4,:major).choose
    loop do
      
      
      4.times do
        
        use_synth :prophet
        play c4thing1,sustain: 0.2
        sleep 0.2
      end
      4.times do
        
        use_synth :prophet
        play c4thing2,sustain: 0.2
        sleep 0.2
      end
      4.times do
        
        use_synth :prophet
        play c4thing3,sustain: 0.2
        sleep 0.2
      end
      4.times do
        
        use_synth :prophet
        play c4thing4,sustain: 0.2
        sleep 0.2
      end
    end
  end
end

Look at that. I can’t even format a post yet. Sorry.

Update: I discovered this works fine if I get rid of the outer loop, and have since re-read the tutorial and caught the part I missed about loops being black holes for code.

I really want this thing to play these four bars until I press a different pad, which will give me four new random bars in scale. Is that not possible without stopping the music?

You need to get rid of the loop do and its corresponding end, otherwise it will continue looping forever and never get back to the part outside.
Then if you change the sync to a get, it will get the last value without waiting for you to press the key again.
However there is then a problem with the first time around the loop, because the note and velocity have not been set yet. You can test for this and either set a default value, or do a sync there.
I think something like this should do it:


live_loop :midi_piano do
  use_real_time
  
  note, velocity = get “/midi:launchpad_pro_mk3_lppromk3_midi:0:1/note_on”
  if note == nil
    note = 60
    # or you could do the sync here if you want to wait for a key:
    # note, velocity = sync “/midi:launchpad_pro_mk3_lppromk3_midi:0:1/note_on”
  end
  if (note<37) then
    use_random_seed 26
    c4thing1=scale(:c4,:major).choose
    c4thing2=scale(:c4,:major).choose
    c4thing3=scale(:c4,:major).choose
    c4thing4=scale(:c4,:major).choose
    
    4.times do
      
      use_synth :prophet
      play c4thing1,sustain: 0.2
      sleep 0.2
    end
    4.times do
      
      use_synth :prophet
      play c4thing2,sustain: 0.2
      sleep 0.2
    end
    4.times do
      
      use_synth :prophet
      play c4thing3,sustain: 0.2
      sleep 0.2
    end
    4.times do
      
      use_synth :prophet
      play c4thing4,sustain: 0.2
      sleep 0.2
    end
  end
end

Note: to format the code, make sure the three backticks are around the whole code block, it looks like you accidentally put only part of the code inside.

Hey, Emlyn! Thank you SO much for the reply. This is doing exactly what I want with regard to changing the seed, but isn’t taking any input from my launchpad anymore. Your sync suggestion was formatted as grey and pink in my editor, whereas my original working one was formatted green for some reason, I grabbed my old working line and pasted it into yours, it switched to green, but still does not pick up any presses from the launchpad. Do you have an idea what may be causing that?

Also, do you think there is a way to, with a button/key/pad press, change the random seed number to a random number? I tried the following, which did not work:

use_random_seed rrand_i(0, 100)

Thanks again. I really appreciate your time and help.

For the random random seed, I just tried this, and it looks like it’s inching me toward a solution. I just need to assign it to a keypress somehow:

r = rrand_i(0, 2000)
use_random_seed r

It looks like somehow the quote marks (") got changed to curly “smart” quotes (/) - that is why they were formatted differently. With the normal straight quotes I think it should work. Do you see the cues from the launchpad in the cues window?

For using a “random” random seed, the problem with using one of the Sonic Pi random numbers is that because they are deterministic, it will always do the same thing each time you play it. If instead you want it to be different each time, you could use the current time as a seed:

use_random_seed Time.now.to_i

Note though that this comes from Ruby and is not strictly supported by Sonic Pi, so although it works now, it’s possible that in a later version it will stop working.

The quotes fix worked! Thank you very much.

For the random random seed, the time solution is super clever, but it causes the seed to change live and without my control as the time changes. I’m looking to change the seed with a press from the launchpad.

Can the time-based solution be set outside the loop so it is waiting for me rather than triggering with every loop?

I just did

r = Time.now.to_i

Before starting the live loop, and that is working well. The seed now changes if I run again, which is cool.

If there is a more elegant way to change it with a pad, I’d love to do that, but this will for sure work well enough.

I think you can do it by using a separate live_loop to listen for the pad, and update the seed from there:

live_loop :pad do
  use_real_time
  note, velocity = get "/midi:launchpad_pro_mk3_lppromk3_midi:0:1/note_on"
  if (note<37) then
    set :myseed, Time.now.to_i
  end
end

Then at the start of the :midi_piano loop you can remove the current sync/get and set the seed with:

use_random_seed get[:myseed]

That way the seed will stay constant until you press the pad, and each time you press it, it will be updated with a new value. Is that what you want?

I think that will absolutely do the trick. This and your other solutions were insanely helpful. Thanks for taking the time to take a swing at this. You saved me a lot of digging.

2 Likes