LiveOSC (Sonic Pi -> Ableton Live)

Hi Isaac,

I don’t work with Ableton but I really appreciate this thorough documentation you have shared here!

The context of why I am generally interested in interfacing Sonic Pi with external gear/software: I meanwhile have a Fates, which is a Raspberry-based music platform originally developed by Monome and its community. Currently I am trying to marry Sonic Pi live coding with the different applications which Fates provides. So one of the main goals here is to clock Fates with Sonic Pi, which proves to be kind of tricky (although it seems to be simple).

Nice article. This was my previous post about using Ableton with SP

@nlb - I’m running the full version of Live 10, but I think it should work with the Lite version. LiveOSC also has two different forks on Github for 9.6 or later and also for prior. TouchOSC is a Max 4 Live device so you need the full version to access that (as Max iisn’t included in the lite version).

If it does work in the Lite versions I’m sure people would like to know. If you try it, please share your findings!

@Martin. Thanks! And that Fates looks like fun - now I want one! I need to dig deeper into that. It should be noted I suppose that yeah, the syncing is something I’m not even totally sure about yet with Ableton. As I’m just for now looking at recording and manipulating, the above works - trying to perform it all might be another story. As I’m still learning SP in the first place I haven’t gotten that deep yet. But algorithmic control of Ableton Live via SP code is definitely intriguing to me. Max is just not the way I envision code - at least for most of what I want to do. I’m not a super coder either but am familiar with many languages. Obviously using something more standardized is very powerful.

1 Like

Well bad news…

Tested with Adobe Live 9 Lite:

it seems not to work.

Am i correct with the set up in Ableton ?

the osc messages are well received (checked with another program)

EDIT : python must be installed ? Start of headhache :slight_smile: under windows 10

Interesting. Yeah, the Live setup looks accurate. I failed to mention the need for Python (forgetting the LiveOSC is python based). Python 2.7 is default on Macs and I had actually upgraded to 3.8 when installing PyLive, so I had that dependency already. I’ll edit my notes above though. Sorry if I steered you down one of those hurdle paths.

And yeah, worse, testing inside (other than trial and error) is tough without Max 4 Live and some of the tools in their connection kit (which mentioned in my caveat, don’t register with LiveOSC). TouchOSC is great for mapping any commands from SP to various things as @robin.newman showed, but I was most interested in the way I could have easy command control for recording at this point. You can’t for instance map TouchOSC to the transport record button. For algorithmic ‘knob twiddling’ and everything else it would be great. Another ideal would be if you do get it working with the Lite - but it is possible the developers realized that it was opening up the door to getting around a full purchase and stopped OSC support on it. I’ll try and do some research into that.

One thing @nlb - Here are my MIDI/Link settings:

  • I don’t believe the Link features (not in your Lite version) matter - that’s for Midi.

It is interesting though that under “input” it shows the greyed out “touchAble”. I’ll have to look into this, but again might be a default only included in the full Live Suite.

Hi
I’m trying to try LiveOSC with Ableton Live but it’s not working, something i am doing wrong

LiveOSC1

@Lunatico - for starters, it looks like you have the error OSC line incorrect:

osc "osc "/remix/set_peer", "", 4559

EDIT: I realize that this was in my code above. My fault for not typing code in the forum properly! And seems it’s been too long and I can’t edit.

should be

osc "/remix/set_peer", "", 4560

The first issue is the two osc calls with one in quotes. The second is that this command is telling Ableton to send OSC messages back to Sonic Pi on 4560, which can’t be easily adjusted. I think by default LiveOSC uses 9001, which means Sonic Pi won’t hear the messages. Sonic Pi sending can be whatever port you prefer (matching the port set wherever you are sending obviously), but the incoming is fixed for now.

Also, make sure you also have the send and receive OSC turned on in the Sonic Pi settings.

ADDITION: It’s been a while since I’ve done this all, but make sure @Lunatico that you do all of the setup mentioned above, including install python if you don’t have it already. On Mac OS (which I was using for this) python 2.7 should be installed. I updated to python 3 though.

Hi
Hypostatic a lot of thanks for your answer & help
I’ve tried but it doesn’t work.
No problem, I’ll wait for the configuration of the fantastic Reaper :wink:

Hey @Lunatico - see if this works for you: Sonic Pi OSC with REAPER

The hardest part might be routing all of the audio which is different on each system but I tried to explain the best I could.

Hello !

AbletonOSC sends response on the 11001 port. Sonic pi use 4560. How can i change this port to set to 11001 ?
Cheers

Probably easier to change it at the Control Ableton_Live 11 end. Looking at the software there is a file constants.py which sets the OSC_LISTEN_PORT and the OSC_SEND_PORT change the send port from 11001 to 4560 Before you install it. I think that should work, unless Ableton itself requires port 11001. I only have an earlier version of Ableton so cant test.

EDIT you can alter the code similarly in the sonic pi daemon.rb file Look for the line that says
"osc-cues" => 4560, This is around line 1363 and alter it to say "osc-cues" => 11001
Then resave. (you may want to save a copy of tehe original first). YOu can do this in an existing build, as it will not afrfect or need any files to be recompiled.
I tried it on a mac build looking inside the package Contents/Resources/App/Server/Ruby/bin folder to find the file. This will also work in LInuc builds. Haven’t tried Windows, but should be possible there tool.

1 Like

Thanks @robin.newman ! Your help is always appreciated :slight_smile:
it works a priori. I mean spi receives some osc messages from ableton live so good point.

in this folder, edit constants.py and restart Ableton Live
image

Now in SPI. I can set easily but get data is harder.

use_osc "localhost", 11000

# sending osc

osc "/live/song/set/tempo", 60
sleep 1
osc "/live/song/set/tempo", 110
sleep 1

# getting




##| (1653)(AbletonOSC)$ ./run-console.py
##| AbletonOSC command console
##| Usage: /live/osc/command [params]
##| >>> /live/song/set/tempo 123.0
##| >>> /live/song/get/tempo
##| (123.0,)
##| >>> /live/song/get/track_names
##| ('1-MIDI', '2-MIDI', '3-Audio', '4-Audio')

foo = osc "/live/song/get/tempo"

print foo

image

I guess i have to use a live_loop but i have to check my past notes :slight_smile:

Yup, you need a live loop. Something like this I would imagine, looking at your info above

live_loop :getTempo do
  t = sync "/osc*/live/song/get/tempo"
  puts "tempo is: #{t[0]}"
end

live_loop :getTrackNames do
  tn = sync "/osc*/live/song/get/track_names"
  tn.length.times do |x|
    puts "track_name #{(x+1)} is #{tn[x}" #index goes from 0 so track_name 1 is when x=0
end

thank you @robin.newman but no success with this code ( a little typo)…

live_loop :getTempo do
  t = sync "/osc*/live/song/get/tempo"
  puts "tempo is: #{t[0]}"
end

live_loop :getTrackNames do
  tn = sync "/osc*/live/song/get/track_names"
  tn.length.times do |x|
    puts "track_name #{(x+1)} is #{tn[x]}" #index goes from 0 so track_name 1 is when x=0
  end
end

i will look at the reasons why tomorrow :slight_smile:

Good morning,

Okay so with AbletonOSC to get some data, you have first to send the osc message then AbletonOSC will send you the answer

use_osc "localhost", 11000

# sending osc

osc "/live/song/set/tempo", 60
sleep 1
osc "/live/song/set/tempo", 110
sleep 1

# getting




##| (1653)(AbletonOSC)$ ./run-console.py
##| AbletonOSC command console
##| Usage: /live/osc/command [params]
##| >>> /live/song/set/tempo 123.0
##| >>> /live/song/get/tempo
##| (123.0,)
##| >>> /live/song/get/track_names
##| ('1-MIDI', '2-MIDI', '3-Audio', '4-Audio')

live_loop :getTempo do
  osc "/live/song/get/tempo"
  t = sync "/osc*/live/song/get/tempo"
  puts "tempo is: #{t[0]}"
end

live_loop :getBeat do
  
  t = sync "/osc*/live/song/beat"
  puts "beat number: #{t[0]}"
end

live_loop :getTrackNames do
  
  path = "/live/song/get/track_names"
  osc path
  tn = sync "/osc*"+path
  tn.length.times do |x|
    puts "track_name #{(x+1)} is #{tn[x]}" #index goes from 0 so track_name 1 is when x=0
  end
end

image

Maybe kill the live_loop when i get the info but don’t know how to. @robin.newman an idea ?

First use of AbletonOSC so i guess my journey just begins :slight_smile:
So next episode soon

Have a good day

That looks good.
One or two comments.
First, you can already get tempo data and set tempo with the built in support for Ableton Link in Sonic Pi.

secondly, do you need to stop the live_loops? They wont consume many resources, but can be used for subsequent calls when they will update the data whenever it changes. Downside, you do have to prsss stop to completely finish the program.

You can however change them to stop once they have acquired their data. I usually do this by creating functions as below. This means you can use them wherever they are needed on your program, and that the liveloop will automatically restart if needed more than once. The results are updated to the time liene using set commands, from where you can subsequently retrive the data.

Here is the whole program, with the input OSC data from Live simulated at the end of the program.

#turn off some logging
use_debug false
use_osc_logging false

#define functions to set up live_loops to receive OSC data
define :getTempo do
  live_loop :getTempoLoop do
    t = sync "/osc*/live/song/get/tempo"
    ##| puts "tempo is: #{t[0]}"
    set :tempo,t[0]
    stop 
  end
end

define :getTrackNames do
  live_loop :getTrackNamesLoop do
    tn = sync "/osc*/live/song/get/track_names"
    ##| tn.length.times do |x|
    ##|   puts "track_name #{x+1} is #{tn[x]}"
    ##| end
    set :trackNames, tn
    stop #the live_loop
  end
end

define :listTrackNames do
  tn=get :trackNames
  tn.length.times do |x|
    puts "track_name #{x+1} is #{tn[x]}"
  end
end


#initiate the flive_loops
getTempo
getTrackNames


#simulate OSC data coming from Live
use_osc "localhost",4560
osc "/live/song/get/tempo",60
osc "/live/song/get/track_names","1-Selector Kit Wars",
  "2-Grand Piano Single Sample",
  "3,Basic Electric Drum Bass",
  "4-Drum Rack",
  "5-voix femenines",
  "6-Awakening Pad"

#check that data received and stored in time state
puts "Retrieved tempo is",get(:tempo)
puts "Retrieved track names list is",get(:trackNames)
puts "Track names are:"
listTrackNames

EDIT
produces this output:

=> Starting run 40

=> Redefining fn :getTempo

=> Redefining fn :getTrackNames

=> Redefining fn :listTrackNames

=> Redefining fn :live_loop_getTempoLoop

=> Redefining fn :live_loop_getTrackNamesLoop

{run: 40, time: 0.0}
 ├─ "Retrieved tempo is" 60
 ├─ "Retrieved track names list is" ["1-Selector Kit Wars", "2-Grand Piano Single Sample", "3,Basic Electric Drum Bass", "4-Drum Rack", "5-voix femenines", "6-Awakening Pad"]
 ├─ "Track names are:"
 ├─ "track_name 1 is 1-Selector Kit Wars"
 ├─ "track_name 2 is 2-Grand Piano Single Sample"
 ├─ "track_name 3 is 3,Basic Electric Drum Bass"
 ├─ "track_name 4 is 4-Drum Rack"
 ├─ "track_name 5 is 5-voix femenines"
 └─ "track_name 6 is 6-Awakening Pad"
 
=> Stopping thread :live_loop_getTrackNamesLoop

=> Stopping thread :live_loop_getTempoLoop

=> Completed run 40

=> All runs completed

=> Pausing SuperCollider Audio Server
1 Like

very elegant ! as usual !
thank you again and again