Hello Folks.
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.
Basic Setup
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.
Making Layouts
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 set
and get
to store your OSC data in Time States and use those as a kind of global variable. With set, you can either get
or 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.
Setup
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[0]
end
live_loop :bar2 do
sig2 = sync "/osc/AmpFader/2"
set :amp2,sig2[0]
end
live_loop :bar3 do
sig3 = sync "/osc/AmpFader/3"
set :amp3,sig3[0]
end
live_loop :bar4 do
sig4 = sync "/osc/AmpFader/4"
set :amp4,sig4[0]
end
live_loop :bar5 do
sig5 = sync "/osc/AmpFader/5"
set :amp5,sig5[0]
end
live_loop :dial1 do
sig6 = sync "/osc/FxRotary1"
set :fx1,sig6[0]
end
live_loop :dial2 do
sig7 = sync "/osc/FxRotary2"
set :fx2,sig7[0]
end
live_loop :dial3 do
sig8 = sync "/osc/FxRotary3"
set :fx3,sig8[0]
end
live_loop :dial4 do
sig9 = sync "/osc/FxRotary4"
set :fx4,sig9[0]
end
live_loop :dial5 do
sig10 = sync "/osc/FxRotary5"
set :fx5,sig10[0]
end
live_loop :dial6 do
sig11 = sync "/osc/FxRotary6"
set :fx6,sig11[0]
end
live_loop :Toggle1 do
sig12 = sync "/osc/FxToggle/1/1"
set :toggle1,sig12[0]
end
live_loop :Toggle2 do
sig13 = sync "/osc/FxToggle/1/2"
set :toggle2,sig13[0]
end
live_loop :Toggle3 do
sig14 = sync "/osc/FxToggle/1/3"
set :toggle3,sig14[0]
end
live_loop :Toggle4 do
sig15 = sync "/osc/FxToggle/1/4"
set :toggle4,sig15[0]
end
live_loop :toggle5 do
sig16 = sync "/osc/FxToggle/1/5"
set :toggle5,sig16[0]
end
Boilerplate
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.