Skip to content

Instantly share code, notes, and snippets.

@AlexandreRangel
Last active April 8, 2019 10:40
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save AlexandreRangel/e82072203fcf4b89f12003b1f1a957fa to your computer and use it in GitHub Desktop.
Save AlexandreRangel/e82072203fcf4b89f12003b1f1a957fa to your computer and use it in GitHub Desktop.
Controling Sonic Pi from Processing OSC
# reading OSC from Processing, Alexandre Enkerli
# full screen, fulltime mouse, Alexandre Rangel
# 24-Nov-2016
# Sonic Pi 2.11
use_bpm 120
set_sched_ahead_time! 0 # Setting that one to a negative value makes Sonic Pi complain, it sounds like.
live_loop :osc do # The loop is inside the fx as this is where the action will be.
osc=sync "/osc" # The OSC message which Processing sends, based on mouse coordinates.
mousex=osc[:args][0] # Assigning the first argument to resonance.
mousey=osc[:args][1] # Assigning the second argument to centre.
use_synth :piano
myscale = scale_names[(73 * mousey).to_int] # mouse y sets scale
mynote = 24 + (48 * mousex) # mouse x sets scale root note
play scale(mynote,myscale,num_ontaves: 5).tick
sleep 0.25
end
// sending OSC from Processing to Sonic Pi, Alexandre Enkerli
// full screen, fulltime mouse, Alexandre Rangel
// 24-Nov-2016
// Processing 3.2.3
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import oscP5.*;
import netP5.*;
Point mouse;
OscP5 oscP5;
NetAddress myBroadcastLocation;
float mousex, mousey;
void setup() {
background(0,255,0);
frameRate(60);
size (160,140);
mouse = MouseInfo.getPointerInfo().getLocation();
oscP5 = new OscP5(this,12000);
myBroadcastLocation = new NetAddress("127.0.0.1",4559);
}
void draw() {
mouse = MouseInfo.getPointerInfo().getLocation();
mousex = float(mouse.x) / float(displayWidth); // normalizes mouse to 0.0-1.0
mousey = float(mouse.y) / float(displayHeight); // normalizes mouse to 0.0-1.0
OscMessage myOscMessage = new OscMessage("/osc"); // Preparing the OSC message to be sent to the right address, the one Sonic Pi expects.
myOscMessage.add(mousex); // Adding those floats to the OSC message…
myOscMessage.add(mousey);
//println(mouse.x, mouse.y); // To check on those values…
//println(mousex, mousey); // To check on those values…
oscP5.send(myOscMessage, myBroadcastLocation); // Broadcast
}
@Enkerli
Copy link

Enkerli commented Nov 24, 2016

Great job! Thanks a lot for posting this!

As said on Twitter, the original Sonic Pi script was from @rbnpi (also on Gist/GitHub). His experiments are so useful, to me.

Glad you improved my little attempt. Your scripts make more sense than mine and don’t sound like they have performance issues.

Was working more with the continuous slider/knob idea, which made more sense with a fx control. More specifically, controlling Sonic Pi every frame doesn’t really work with one note per control (unless the frames are really slow). But with continuous control, there can be a noticeable lag between the control and the change in sound. So your approach makes more sense, in context. Sam Aaron tells us that an update should alleviate performance problems. In the meantime, your work is clearly going in the right direction.

Quite liking the use of different scales as what mouseY controls. Might tweak that to be about scale-like or arpeggio-like patterns, with more similarities from one to the next.

Oh, as for the fullscreen part. Thanks for the note about displayWidth and displayHeight. Knew about sketch width and height, of course, but had an issue with making the results be floats, at first (forgot to convert them). Tried with another strategy which was using the numbers themselves. For something which needs to be a MIDI note number, it was just easy to divide 400 by four. Of course, it’s as easy to map the 0 to 1 range to MIDI note numbers.

Using the display instead of the sketch really does make a lot of sense. Might still try with a sketch showing something to orient the user. Like labelled axes or, in fact, some zones. “In this area, the notes played will always be in a pentatonic scale” kind of thing.

Of course, much of this can be done in Processing itself. Or Processing could control SuperCollider directly. But Sonic Pi does make it more fun. And easier to understand. With a Raspberry Pi, it could lead to really neat things with physical controls.

Might also switch to TouchOSC, if there’s a way to get Sonic Pi to accept data from another device.

So, thanks a lot for the significant improvements!

By the by, on line 18, you mean num_octaves, right?

play scale(mynote,myscale,num_octaves: 5).tick

Cheers!

@mikkoelo
Copy link

mikkoelo commented Feb 5, 2018

Hi! I think on latest Sonic Pi 3, you have to add one /osc -path to the messages in Sonic Pi to make it work. It also didn't work on my computer with the :args- commands so I left them out.

So the first three lines in Sonic Pi should maybe be:

osc=sync "/osc/osc" #One more "/osc" added!
mousex=osc[0]
mousey=osc[1]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment