I have been having a play at syncing 4 sonic pi computers together, using OSC messages to perform the sync. I find that the OSC signals enable syncing quite easily, but there can be a problem is the Sonic Pi computers are different especially if they have different audio setups (as was the case here) and they can they have quite different audio latencies. However, it is possible to sync them to the machine with the worst audio latency by employing some time warp in the other computers with smaller latency. The good thing is that latency is a fixed value and so can be compensated for.
The four computers I used were:
1 a Mac Book Pro which acted as the “conductor” and sent out the sync signals.
2 an RPI 3 with a Pisound audio card
3 an old iMac repurposed as a LInux Machine running Ubuntu 17.04
4 an RPi 3 in a Pi-topCEED with a PiPulse audio card (HiFi Berry guts)
The code in the MacBookPro was this
set :bpm,20
set :f,0
live_loop :speed do
b=get(:bpm)
if b<220 and get(:f)==0
b+=10
else
set :f,1
end
if get(:f)==1 and b>20
b-=10
else
set :f,0
end
use_bpm b
set :bpm,b
sleep 0.5
end
live_loop :sendsync do
bpm=get(:bpm)
use_real_time
use_bpm bpm
osc_send "192.168.1.190",4559,"/sync",bpm
osc_send "192.168.1.234",4559,"/sync2",bpm
osc_send "192.168.1.238",4559,"/sync3",bpm
sleep 0.25
end
The code in the 1st RPi was this
live_loop :n2 do
use_real_time
b = sync "/osc/sync2"
#set time_warp to delay note to match greatest latency. use rt so time not affected by bpm
time_warp rt(0.18) do
use_bpm b[0)
play scale(:e3,:minor_pentatonic).tick,release: 0.25
end
end
The code for the Ubuntu Sonic PI was this
live_loop :n1 do
use_real_time
b = sync "/osc/sync"
#set time_warp to delay note to match greatest latency. use rt so time not affected by bpm
time_warp rt(0.18) do
use_bpm b[0)
play scale(:e4,:minor_pentatonic).tick,release: 0.25
end
end
The code for the pi-topCEED (with the greatest latency) was this
live_loop :n3 do
use_real_time
b = sync "/osc/sync3"
use_bpm b[0)
play scale(:e5,:minor_pentatonic).tick,release: 0.25
end
Start the three slave machines running, then start the MBP "conductor"
You should adjust the time_warp settings so all notes play together. To set up start with the live_loop
:speed commented out in the MBP code and you can adjust the notes so they sound together.
You can then uncomment the MPB code and re-run the “conductor” machine and the tempo of thenotes
will be speeded up and slowed down.
You should be able to extend the technique for a larger number of machines. I am investigating whether it is possible to send a “broadcast” OSC message which would only need one sync, but I’m not sure if this is possible yet.
A video of the program in action is shown here: