I spent easter getting TouchOSC to work with sonic pi and I thought I’d share my work. Hopefully this will help someone avoid a few of the problems I ran into.
The first thing you need to do is go to settings -> Input/Output and allow Sonic Pi to receive external OSC messages. Then you need to grab the TouchOSC App from the App Store / Play Store. In TouchOSC you will need to set up the connection between it and your computer by entering the IP Address of the machine. You will also want to set the Outgoing Port field to 4559, since that’s the port Sonic Pi expects to get OSC messages from. Once you’ve done this, open Sonic Pi and TouchOSC, pick a layout on your app, and give one of the sliders a wiggle. If the connection works, you’ll see a ton of messages in the Cues section.
Once you got this part working, you’ll probably want to make a less expansive layout at first. These are made with the TouchOSC Editor. My layout looks like this: 5 sliders for amplitude, 5 toggle buttons for on-off effects, and 6 sliders for messing with effects and parameters. You can download the layout file here and give it a try. OSC Layouts is a very personal thing, and I encourage you spend a bit of time making your own. It’s your instrument, after all!
Getting the code working
Accessing the OSC elements is quite simple. You refer to it as a web address like “/osc/1/Slider1”, and TouchOSC gives you a floating point number back. Usually one between 0 and 1. The question is how to save the data you get. This is where I ran into most of my trouble.
The general approach is to use
get to store your OSC data in Time States and use those as a kind of global variable. With set, you can either
sync the OSC data.
sync makes the code wait until something changes, whereas
get continuously poll the device for data. Using get will give you the most up-to-date data, but it takes up a ton of resources, and even on the biggest machines Sonic Pi will start cracking and popping within 10 minutes or so.
So what I did was to save a script for setting up the process of gathering data, and loading that in another buffer. This script has a loop for each layout item, which waits for changes in the layout items. I also ran into another problem, which is that since i wanted to fade my loops in and out, i needed them to run constantly. This also made Sonic Pi cry. So i also made a framework for having my five loops (one for each amplitude slider), and having them sleep when the amp is 0. This helped a ton, and now I can do fancy stuff with fading in and out and changing code snippets on the fly.
This first one is where I set up my communication with TouchOSC. It’s not very complicated, just awfully repetitive. It works perfectly with the layout I linked above. The second code piece is my “Boilerplate” where I put the actual music loops. I’m going to experiment with the idle time and see how responsive i can make it, while making sure it runs flawlessly.
use_osc "localhost",4559 #remote_ip="192.168.43.1" #hotspot remote_ip="192.168.1.3" #at home live_loop :bar1 do sig1 = sync "/osc/AmpFader/1" set :amp1,sig1 end live_loop :bar2 do sig2 = sync "/osc/AmpFader/2" set :amp2,sig2 end live_loop :bar3 do sig3 = sync "/osc/AmpFader/3" set :amp3,sig3 end live_loop :bar4 do sig4 = sync "/osc/AmpFader/4" set :amp4,sig4 end live_loop :bar5 do sig5 = sync "/osc/AmpFader/5" set :amp5,sig5 end live_loop :dial1 do sig6 = sync "/osc/FxRotary1" set :fx1,sig6 end live_loop :dial2 do sig7 = sync "/osc/FxRotary2" set :fx2,sig7 end live_loop :dial3 do sig8 = sync "/osc/FxRotary3" set :fx3,sig8 end live_loop :dial4 do sig9 = sync "/osc/FxRotary4" set :fx4,sig9 end live_loop :dial5 do sig10 = sync "/osc/FxRotary5" set :fx5,sig10 end live_loop :dial6 do sig11 = sync "/osc/FxRotary6" set :fx6,sig11 end live_loop :Toggle1 do sig12 = sync "/osc/FxToggle/1/1" set :toggle1,sig12 end live_loop :Toggle2 do sig13 = sync "/osc/FxToggle/1/2" set :toggle2,sig13 end live_loop :Toggle3 do sig14 = sync "/osc/FxToggle/1/3" set :toggle3,sig14 end live_loop :Toggle4 do sig15 = sync "/osc/FxToggle/1/4" set :toggle4,sig15 end live_loop :toggle5 do sig16 = sync "/osc/FxToggle/1/5" set :toggle5,sig16 end
live_loop :loop1 do if (get(:amp1) > 0) then else sleep 1 end end live_loop :loop2 do if (get(:amp2) > 0) then else sleep 1 end end live_loop :loop3 do if(get(:amp3) > 0) then else sleep 1 end end live_loop :loop4 if (get(:amp4) > 0) then else sleep 1 end end live_loop :loop5 if (get(:amp5) > 0) then else sleep 1 end end
So there you have it. A basic setup for you to get started working with TouchOSC. Just having the amp sliders is priceless for fine-tuning your mix, fading seamlessly from one to another, and because Sonic Pi’s synthesizers have very different opinions on what amp: 1 means.