Created
December 24, 2017 10:02
-
-
Save rbnpi/ba302fb6c4fa1036cc2b31a456b30649 to your computer and use it in GitHub Desktop.
A visualisation of a four part round of Frere Jaques played by Sonic Pi 3 and a processing sketch, linked by OSC messages. They should both be run on the same computer. A video of the project is at https://youtu.be/w89G0dN2BM0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Processing sketch to display Frere Jacques | |
//4 part round played in Sonic Pi 3 | |
//control via OSC messages sent from Sonic Pi | |
//written by Robin Newman december 23rd 2017 | |
import oscP5.*; | |
import netP5.*; | |
OscP5 oscP5; | |
NetAddress myRemotelocation; | |
//declare variables | |
int[] circle_colora = new int[3]; | |
int[] circle_colorb = new int[3]; | |
int[] circle_colorc = new int[3]; | |
int[] circle_colord = new int[3]; | |
float rada,radb,radc,radd; | |
int na,nb,nc,nd; | |
int chana,chanb,chanc,chand; | |
void setup() { | |
size(400,400); | |
frameRate(30); | |
oscP5 = new OscP5(this,8000); //set up osc connection, localhost port 8000 | |
} | |
void draw() { | |
smooth(); | |
background(0); | |
//set fill colour and draw ellipse for each part (channel) | |
fill(circle_colora[0],circle_colora[1],circle_colora[2]); | |
ellipse(200+chana*9,388-na,20*rada*2,20*rada*2); | |
fill(circle_colorb[0],circle_colorb[1],circle_colorb[2]); | |
ellipse(200+chanb*9,388-nb,20*radb*2,20*radb*2); | |
fill(circle_colorc[0],circle_colorc[1],circle_colorc[2]); | |
ellipse(200+chanc*9,388-nc,20*radc*2,20*radc*2); | |
fill(circle_colord[0],circle_colord[1],circle_colord[2]); | |
ellipse(200+chand*9,388-nd,20*radd*2,20*radd*2); | |
} | |
void mousePressed(){ | |
} | |
void oscEvent(OscMessage theOscMessage){ | |
if (theOscMessage.checkAddrPattern("/na")==true) //deal with osc "/na" | |
{ | |
na = theOscMessage.get(0).intValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/colora")==true) //deal with osc "/colora" | |
{ | |
circle_colora[0]= theOscMessage.get(0).intValue(); | |
circle_colora[1]= theOscMessage.get(1).intValue(); | |
circle_colora[2]= theOscMessage.get(2).intValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/rada")==true) //deal with osc "/rada" | |
{ | |
rada= theOscMessage.get(0).floatValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/chana")==true) //deal with osc "/chana" | |
{ | |
chana= theOscMessage.get(0).intValue(); | |
} | |
//repeat osc parsing for channesl b,c and d | |
if (theOscMessage.checkAddrPattern("/nb")==true) | |
{ | |
nb = theOscMessage.get(0).intValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/colorb")==true) | |
{ | |
circle_colorb[0]= theOscMessage.get(0).intValue(); | |
circle_colorb[1]= theOscMessage.get(1).intValue(); | |
circle_colorb[2]= theOscMessage.get(2).intValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/radb")==true) | |
{ | |
radb= theOscMessage.get(0).floatValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/chanb")==true) | |
{ | |
chanb= theOscMessage.get(0).intValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/nc")==true) | |
{ | |
nc = theOscMessage.get(0).intValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/colorc")==true) | |
{ | |
circle_colorc[0]= theOscMessage.get(0).intValue(); | |
circle_colorc[1]= theOscMessage.get(1).intValue(); | |
circle_colorc[2]= theOscMessage.get(2).intValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/radc")==true) | |
{ | |
radc= theOscMessage.get(0).floatValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/chanc")==true) | |
{ | |
chanc= theOscMessage.get(0).intValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/nd")==true) | |
{ | |
nd = theOscMessage.get(0).intValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/colord")==true) | |
{ | |
circle_colord[0]= theOscMessage.get(0).intValue(); | |
circle_colord[1]= theOscMessage.get(1).intValue(); | |
circle_colord[2]= theOscMessage.get(2).intValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/radd")==true) | |
{ | |
radd= theOscMessage.get(0).floatValue(); | |
} | |
if (theOscMessage.checkAddrPattern("/chand")==true) | |
{ | |
chand= theOscMessage.get(0).intValue(); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Frere jaques with visualization in Processing | |
#written by Robin Newman, December 23rd 2017 | |
#info from Sonic Pi transmitted in OSC messages to drive the processing sketch | |
#A 4 part round is played, and each part is represented by a separate column | |
#the colour of each part varies with pitch as does the vertical postion of each note | |
#The radius of each "note" depends on its duration. | |
nmax=2 #number of iterations of Frère Jaques played | |
use_osc_logging true | |
#note and duration data for Frère Jaques | |
nf=[:c4,:d4,:e4,:c4]*2+[:e4,:f4,:g4]*2+[:g4,:a4,:g4,:f4,:e4,:c4]*2+[:c4,:g3,:c4]*2 | |
df=[1,1,1,1,1,1,1,1,1,1,2,1,1,2,0.5,0.5,0.5,0.5,1,1,0.5,0.5,0.5,0.5,1,1,1,1,2,1,1,2] | |
use_bpm 180 | |
with_fx :reverb,room: 0.8,mix: 0.6 do #add reverb for interest | |
use_osc "localhost",8000 #link to processing sketch on same machine. Can be on external machine too | |
live_loop :notes do #first part | |
use_synth :pulse #differnt synth for each part | |
use_bpm 180 | |
nv = nf.ring.tick #select each note in turn | |
rel=df.ring.look #select corresponding duration | |
play nv,release: rel,amp: 0.2 #play note with release set by duration | |
osc "/chana",-18 #send channel position | |
osc "/na",(note(nv)-48)*16 #send scaled note info to set vertical pos | |
osc "/rada",rel.to_f #send rel value to set radius | |
osc "/colora",128,(note(nv)-48)*16,0 #send colour info related to pitch | |
sleep df.ring.look #sleep for durtation of note | |
stop if look >= (df.length*nmax-1) | |
end | |
#subesequent parts identical apart from synth, channel, color setting | |
live_loop :notes2,delay: 8 do #secnd part delayed 8 beats | |
use_synth :tri | |
use_bpm 180 | |
nv = nf.ring.tick | |
rel=df.ring.look | |
play nv,release: rel,amp: 0.2 | |
osc "/chanb",-6 | |
osc "/nb",(note(nv)-48)*16 | |
osc "/radb",rel.to_f | |
osc "/colorb",0,128,(note(nv)-48)*16 | |
sleep df.ring.look | |
stop if look >= (df.length*nmax-1) | |
end | |
live_loop :notes3,delay: 16 do #third part delayed 16 beats | |
use_synth :prophet | |
use_bpm 180 | |
nv = nf.ring.tick | |
rel=df.ring.look | |
play nv,release: rel,amp: 0.2 | |
osc "/chanc",6 | |
osc "/nc",(note(nv)-48)*16 | |
osc "/radc",rel.to_f | |
osc "/colorc",(note(nv)-48)*16,0,128 | |
sleep df.ring.look | |
stop if look >= (df.length*nmax-1) | |
end | |
live_loop :notes4,delay: 24 do #fourth part delayed 24 beats | |
use_synth :saw | |
use_bpm 180 | |
nv = nf.ring.tick | |
rel=df.ring.look | |
play nv,release: rel,amp: 0.2 | |
osc "/chand",18 | |
osc "/nd",(note(nv)-48)*16 | |
osc "/radd",rel.to_f | |
osc "/colord",(note(nv)-48)*16,128,0 | |
sleep df.ring.look | |
stop if look >= (df.length*nmax-1) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment