I’ve tried a couple of experiments with sonicpi, but I’ve had a recurring problem.
Say I create a live loop called bar, and then I write other live loops that sync :bar. The synchronization will work but with one problem. Even if the sleep calls in the other live loops add up to the same as the sleep call in bar, sometimes it seems the other loops take a fraction of a second longer, miss the sync and have to wait for the next one. So at random times the other live loops will go silent for a bar.
For example:
live_loop :a do
use_synth :prophet
sync :bar
play :F3
sleep 1
end
live_loop :bar do
sample :bd_haus
sleep 0.5
sample :sn_dolf
sleep 0.5
end
The note should play every bar (1 time step) but actually it plays only once every two bars because it misses the timing every other bar. Removing the sleep from :a solves this but means that the last note in a bar has to be constantly written as a special case in loops, etc.
I’m familiar with this as a thread synchronization issue in most programming languages but it seems particularly harsh in live coding music. Is there any way to prevent or work around this?
You’re in luck, there are some detailed discussions about this issue -
One of the best ways I think of avoiding the undesired delay is to use the sync: opt of live_loop. Ie:
live_loop :bar, sync: :a do
...
That way, your loop will sync before it’s about to start, and from then on, just plays without syncing further. There is a small gotcha though: it will only sync on cues after they have happened - so while the two loops would be in time, it would effectively wait for one iteration of loop :a before starting loop :bar.
(There are various comments in the second thread mentioned above about minimising this ‘side-effect’ - and also a very helpful diagram about halfway down that I think explains the two approaches to syncing threads well).
Feel free to have a read through those threads and ask us any further questions you might still have.