Demo of experimental Ableton Link with Sonic Pi

Thanks for making this demo – I got the basics to work with Bitwig from your explanation. It got out of sync if I messed too much with the tempo, but generally worked ok.

Can Sonic Pi monitor individual beats and also know when measure downbeats occur? That would help keep things in sync.

(When linking two Bitwigs, it will not only match the beat but also the downbeat so the measures start together. It’s very robust – you can go nuts with tempo changes and start and stop all over the place, and in almost not time it will get back together.)

I’m very excited to see this feature being developed in Sonic Pi! Thanks for this very helpful demo!

Hi @psh_vt,

welcome to our community!

Great that you got the latest beta working and neat that you managed to sync up to Bigwig with it.

I’m intrigued as to how it got out of sync when you messed with the tempo. As far as I’m aware this shouldn’t happen as Link is dictating the clock. I do know that if you’re using long samples and synths, then if you change the tempo whilst they are playing, they won’t change - only newly triggered synths and samples will honour the new tempo (if you’re stretching things with beat_stretch). I’d love to know more about this and what you’re observing - perhaps a video would be a useful way of sharing this?

With respect to downbeats - this isn’t something that Sonic Pi supports natively as there’s no global BPM or metronome. I do plan to add something like this specifically for Link prior to the release of v4 so you will be able to sync on a downbeat. However, I just moved house and have covid so development is definitely on hold for the short term :slight_smile:

@psh_vt

sorry for the late response

  1. use this code:
sched_time = 0.5
use_bpm :link

$latency = 25.0 + sched_time*1000.0

def beat_fix(quantum=4)
  diff = @tau_api.link_current_time_and_beat(false)[1] % quantum
  x = ((quantum-diff) + 0 - rt($latency/1000.0)) % quantum
  epsilon = 0.02
  sleepytime = (x < epsilon or x > (quantum-epsilon)) ? 0 : x
  sleep sleepytime
end

Now put in beat_fix 4 (for example, assuming you are in 4/4 time) right before defining your loops, or even inside loops where needed. They will then sync to the downbeat (more precisely, to a beat whose number is divisible by 4).

Hope this is clear.

  1. To change the tempo, use set_link_bpm! 120 or set_link_bpm! current_bpm+20 or whatever. If other instruments/DAWs are on the link, you can of course do it from there.

Fantastic, shemp! Many thanks.

I tried it with Bitwig and it works. But when I change the tempo in Bitwig, Sonic Pi gets out of sync (the tempo changes but the beats aren’t lined up). I have to stop and then restart the Sonic Pi code and then the beats will be back in sync.

I’m curious about @tau.api.link… Is there documentation somewhere? Are there more commands like this that could be useful?

Thanks very much for your help!

If you can post a small snippet of your code that gets out of sync when you change the tempo, we can try to figure it out.

As for the @tau_api stuff, we found it in app/server/ruby/lib/sonicpi/tau_api.rb. Maybe @samaaron knows if there is any better documentation? Just looking at the file, though, there are many useful-looking Ableton Link-related methods like link_get_beat_at_time and link_get_time_at_beat

According to this Ableton Link code,

So if we can convert between beat and time values and get/set the tempo then we are well on our way to using Ableton Link.

Here’s the code:

sched_time = 0.5
use_bpm :link

$latency = 0 + sched_time*1000.00

def beat_fix(quantum=4)
diff = @tau_api.link_current_time_and_beat(false)[1] % quantum
x = ((quantum-diff) + 0 - rt($latency/1000.0)) % quantum
epsilon = 0.02
sleepytime = (x < epsilon or x > (quantum-epsilon)) ? 0 : x
sleep sleepytime
end

beat_fix()

live_loop :measure do
puts @tau_api.link_current_time_and_beat(false)[1] % 4
sample :perc_snap
sleep 1
end

#-----

I’m starting a Live Sync master, then when I start Sonic Pi the pattern plays in time. If I change the tempo on the master, the tempo changes but beats aren’t aligned. If I stop/start Sonic Pi, the beats line up. I tried it with Bitwig and an iPad app as the Link master, and it worked the same.

Thanks! I’ll check out that site when I have a chance.

OK, I think I am able to reproduce the same effect. It could be a side-effect of sleep 1 being supposed to sleep for 1 beat, but then you change the tempo so it does not make up the difference and ends up in the middle of a beat. Try to fix it by adding a beat_fix inside your loop:

live_loop :measure do
  beat_fix 1
  puts @tau_api.link_current_time_and_beat(false)[1] % 4
  sample :perc_snap
  sleep 1
end

Hi there,

just here to say that the Ableton Link functionality isn’t yet complete and there’s still work to be done to integrate phase syncing - as you’ve observed. I’ve been busy moving house and recovering from COVID this past month, but starting to get back into things again. Getting this stuff right takes quite a bit of deep thought.

One thing to point out is that whilst it’s totally possible to play around with @tau_api it’s definitely not supported functionality and might change/disappear without warning :slight_smile:

Hopefully I’ll have something a bit more complete in the next BETA in a few weeks.

2 Likes

Hi everyone. I’m curious if there are any updates on this thread? :thinking:

Hi @srothst1 - Ableton Link support has been part of Sonic Pi since version 4 was released just over a year ago :slight_smile: - Release Link · sonic-pi-net/sonic-pi · GitHub