Set/get not in all thread?

Hi,
i am playing around with the use of set/get.
I tried this code:

live_loop :met do; sleep 1; end
live_loop :met4 do; sleep 4; end
live_loop :met8 do; sleep 8; end
live_loop :met16 do; sleep 16; end

live_loop :chordSwitcher, sync: :met do
  chords = [
    [:C4, :major, 4],
    [:G4, :major, 4],
    [:A4, :minor, 2],
    [:G4, :major, 2],
    [:F4, :major, 4],
    [:C4, :major, 2],
    [:G4, :major, 6],
  ].ring
  
  c = chords[tick]
  
  print("set chord #{c}")
  set :ch, c
  set :chl, c[2]
  set :chc, (chord c[0], c[1])
  set :chs, (scale c[0], c[1] == :major ? :harmonic_major : :harmonic_minor)
  
  print("set chord #{c} end")
  sleep c[2]
end

live_loop :bg ,sync: :chordSwitcher do
  tick
  print("play chord #{get(:chc)}")
  play_chord get(:chc), sustain: get(:chl)
  sleep get(:chl)
end

live_loop :mel ,sync: :chordSwitcher do
  tick
  print("play mel #{get(:chs)}")
  use_random_seed 11 + look%8
  play (get(:chs).choose)
  sleep [0.5,1,1,2].choose
end

But unfortunately the melody sometime keeps an old scale instead of switching to the new one.

{run: 40, time: 21.2, thread: :live_loop_chordSwitcher}
 ├─ "set chord [:G4, :major, 4]"
 └─ "set chord [:G4, :major, 4] end"
 
{run: 40, time: 21.2, thread: :live_loop_mel}
 ├─ "play mel (ring <SonicPi::Scale :C :harmonic_major [60, 62, 64, 65, 67, 68, 71, 72])"
 └─ synth :beep, {note: 64.0, release: 0.4}
 
{run: 40, time: 21.2, thread: :live_loop_bg}
 ├─ "play chord (ring <SonicPi::Chord :G :major [67, 71, 74])"
 └─ synth :beep, {note: [67.0, 71.0, 74.0], sustain: 1.6, release: 0.4}

Am i using set/get wrong?
Thanks!

I’m not sure what’s going on there, it feels like a bug but I don’t understand things well enough to be sure.
However, I think you can work around it by syncing on :ch so that you are sure of getting the new value (and then you don’t need the sleep since the sync will wait anyway. I also changed it so that it only does set :ch so that there is only one thing to sync on, and it uses some helper functions to extract the other values (chc, chs, chl) from that:

live_loop :met do; sleep 1; end

live_loop :chordSwitcher, sync: :met do
  chords = [
    [:C4, :major, 4],
    [:G4, :major, 4],
    [:A4, :minor, 2],
    [:G4, :major, 2],
    [:F4, :major, 4],
    [:C4, :major, 2],
    [:G4, :major, 6],
  ].ring
  
  c = chords[tick]
  
  print("set chord #{c}")
  set :ch, c
  sleep c[2]
end

define :chl do |c|
  c[2]
end

define :chc do |c|
  (chord c[0], c[1])
end

define :chs do |c|
  (scale c[0], c[1] == :major ? :harmonic_major : :harmonic_minor)
end

live_loop :bg do
  c = sync :ch
  print("play chord #{chc(c)}")
  play_chord chc(c), sustain: chl(c)
end

live_loop :mel, sync: :chordSwitcher do
  c = get :ch
  tick
  print("play mel #{chs(c)}")
  use_random_seed 11 + look%8
  play (chs(c).choose)
  sleep [0.5,1,1,2].choose
end

That should fix the :bg loop, but unfortunately you can’t easily do that with the :mel loop because the sleeps don’t line up with the durations between sets; but maybe you can find a way to rework that too.

2 Likes

Thanks. i will give it a try. If you want to watch :smiley: : Twitch

1 Like

hi @synchron

About your video on twich, i like your pat method :slight_smile:

Thanks, but it is not from me. I copied it from dj_dave and now I try to figure out a good way to use it. I changed some details like “look” instead of “tick” and just added a .gsub(" “,”") to be able to format the string with spaces.
If you want to hear and/or help, I try to spend my lunch breaks every Tuesday to Friday, coding and learning with sonic pi :slight_smile:

why not for your lunch breaks, but the world is quite vast :slight_smile: What is your UTC ? I’m in France.

ps : i guess this discourse server is not in France as it is right now 10:00 not 11:00 :slight_smile:

I am in Germany (Hannover), so should be the same timezone.
Time will be: 1200 - 1230 Berlin-time

ok ok

By the way, i prefer to use ring on the amp parameter or use spread that return true or false. Knit can be used to but note that you have to use true or false values.

define :pat do | p |
  
  return p.ring.look
end


hh = (ring 1, 0.5,2,0.5) * 3 + (ring 1, 2, 1, 2)
bd = (spread 5,7)
sn = (knit false,4, true,1, false,3)

live_loop :drums do
  tick
  sample :drum_cymbal_closed, amp: hh.tick('hh')
  sample :drum_bass_hard if pat bd
  sample :drum_snare_hard if pat sn
  sleep 0.25
end

Cheers and maybe one day on a lunch break

1 Like

I will try out your example code.
For my “knit” i registered after the stream, that it is possible in ruby to just “multiply” Strings.
so i just could use "x---" * 3 + "--xx"
But i am still on my long journey to find a good way to organize my beats :slight_smile:

1 Like

Back to the main problem of this tread.
I opend an issue on github: Set/get not synced in all threads · Issue #3208 · sonic-pi-net/sonic-pi · GitHub

Can someone try to reproduce this on a newer Version of SonicPi than my 3.2.2 and maybe on other systems than my Linux machine?

If you can, please leave a comment in the github issue or here.
Thanks!