Sonic-pi: live_loop syncing issue?

Created on 18 Sep 2017  路  9Comments  路  Source: sonic-pi-net/sonic-pi

(Hopefully I haven't somehow completely missed this being reported already, and also hopefully I'm not just noticing expected behaviour!) - I have noticed that the following simple code example behaves differently between several versions of Sonic Pi:

live_loop :a do
  sleep 4
end

live_loop :b, sync: :a do
  sample :bd_808
  sleep 1
end

On v2.10 on my Mac, you can hear the bass drum sample start straight away.
On v3.0.1, both on my Mac and on Windows, (which are at different commits, but both say 3.0.1) the bass drum is not heard until after the delay of the first live loop's sleep.

Most helpful comment

This behaviour prior to v3 was non-deterministic (although it largely did the same thing). This is because the original implementation was a race condition with respect to cue/sync ordering.

In v3 I made this deterministic which also meant deciding on a repeatable set of semantics. This in turn means that each cue is totally ordered across all runs and all syncs are also ordered. In v3 syncs will only catch cues after them. Which means that for threads syncing and queueing on the same logical time, their thread ID will determine whether they are before or after.

In this case the live_loop is executing in a different thread to the main thread which is initiating the :sync and the ordering drops the first cue because it is not after it in the total ordering of events.

All 9 comments

I've been looking at this, and it does seem to be an issue. if you use auto_sync: it works

live_loop :a do
  sleep 4
end

live_loop :b, auto_sync: :a do 
  sample :bd_808
  sleep 1
end

Actually I think this is just fortuitous and is NOT syncing at all. the auto_sync will be ignored as an unkown parameter and the loop just starts anyway,

I can confirm this behaviour for SP 3.0 on Linux (Mint 18.1). And I also wonder, if this is an expectable behaviour:

live_loop :bar do
   sample :elec_blip2, amp: 0.5
   sleep 4
end
live_loop :test1, sync: :bar do
   play :c4
   sleep 1
end
live_loop :test2 do
   sync :bar
   4.times do
     play :g4
     sleep 1
   end
end
  • live_loop :test1 starts to sync when :bar has run once. (I might be wrong but I remember it to start imediatelly in SP 2.x)
  • live_loop :test2 also starts after :bar has run once. As far as I understood it should sync every time :bar runs. Every second :bar-run it stops. (Which is somehow logical given the behaviour of :test1.)

@samaaron I don't suppose this has anything to do with it but I also found some unused functions in event_history.rb

I don't know for sure but I wonder whether it's at least something to do with the event history class, (perhaps the wait_for_threads function...)

This behaviour prior to v3 was non-deterministic (although it largely did the same thing). This is because the original implementation was a race condition with respect to cue/sync ordering.

In v3 I made this deterministic which also meant deciding on a repeatable set of semantics. This in turn means that each cue is totally ordered across all runs and all syncs are also ordered. In v3 syncs will only catch cues after them. Which means that for threads syncing and queueing on the same logical time, their thread ID will determine whether they are before or after.

In this case the live_loop is executing in a different thread to the main thread which is initiating the :sync and the ordering drops the first cue because it is not after it in the total ordering of events.

Ok. Thanks for clearing that up.

Cheers @samaaron. I'll close this as expected behaviour.

Sorry but I still don't get it, now is harder to sync loops, for example I would expect that the snippet from @ethancrawford behaves as he describes (The sample of bd_808 should sound right away, not after 4 beats), yet I can't figure out how to modify this snippet in a way that behaves in v3 as it does in v2.

@divisiondeariza this has been discussed at length on the Sonic Pi community forum. The new behaviour was a requirement of keeping thread synchronisation deterministic.
Here are some links worth reading to see the background and methods surrounding synchronisation of threads:
https://in-thread.sonic-pi.net/t/using-sync-with-live-loops/172/
https://in-thread.sonic-pi.net/t/live-loops-sync-questions/1172
https://github.com/mbutz/sonic-pi-resources/blob/master/synchronisation-of-live-loops.rb

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AlexandreRangel picture AlexandreRangel  路  7Comments

MegumiSoft picture MegumiSoft  路  7Comments

reiner-dolp picture reiner-dolp  路  6Comments

josephwilk picture josephwilk  路  3Comments

ostephagus picture ostephagus  路  4Comments