(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.
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
: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
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_loopis executing in a different thread to the main thread which is initiating the:syncand the ordering drops the firstcuebecause it is not after it in the total ordering of events.