Last active
October 31, 2016 14:28
-
-
Save vanderaalle/e67c88cad278a032ab3de13640ff018c to your computer and use it in GitHub Desktop.
SuperCollider Wavefield class interface at Detmold IOSONO system, including plotting, OSC dispatching and data login
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
# http://nodebox.net | |
f = open(u"/yourLog.log") | |
arr = eval(f.read()) ; | |
translate(10, 10) | |
step = 400 | |
size(step+20, step+20) | |
nofill() | |
stroke(0) | |
rect(0, 0, step, step) | |
fill(0) | |
j = 0 | |
for el in arr: | |
i = 0 | |
for data in el[:-1]: | |
fill(1.0-1.0/len(arr[j])*i) | |
start = [(data[1][0]+1)*0.5, (data[1][1]+1)*0.5] | |
end = [(el[i+1][1][0]+1)*0.5, (el[i+1][1][1]+1)*0.5] | |
line(start[0]*step, start[1]*step, end[0]*step, end[1]*step) | |
oval(start[0]*step-2, start[1]*step-2, 4, 4) | |
i = i+1 | |
end = [(el[-1][1][0]+1)*0.5, (el[-1][1][1]+1)*0.5] | |
oval(end[0]*step-2, end[1]*step-2, 4, 4) | |
j = j+1 | |
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
// a class to encapsulate Wavefield source | |
// a source is just a proxy to define position | |
// conversion to/from polar/cartesian | |
// if it has a synth associated, it can scale vol | |
// it notifies, e.g. to an OSC module | |
// and to a plotter module | |
/* | |
// my computer | |
// studio | |
192.168.0.56 | |
255.255.255.0 | |
// konzerthaus | |
192.168.1.1 | |
255.255.255.0 | |
//sending to | |
192.168.1.1, 4243 | |
*/ | |
WFSrc { | |
var <>id ; | |
var synth, <>bus, vol ; | |
var xy ; // an array, both normalized -1, 1 | |
*new { |id, x = 0, y = 0| | |
^super.new.initWFSrc(id, x, y) | |
} | |
initWFSrc { |anId,anX, anY| | |
id = anId; | |
this.xy_(anX,anY); | |
Server.local.waitForBoot{ | |
SynthDef(\wfsrc, {|in, out, amp = 1| | |
Out.ar(out, In.ar(in)*amp) | |
}).add ; | |
bus = Bus.audio(Server.local, 1) ; | |
Server.local.sync ; | |
synth = Synth(\wfsrc, [\in, bus, \out, id]) | |
} | |
} | |
xy_ {|newX,newY| xy = [newX, newY]; | |
this.changed(\xy, [id, xy]) | |
} | |
xy {^xy} | |
// synth interface | |
synth {^synth} | |
synth_{|aSynth| synth = aSynth; | |
//we get vol to store it | |
synth.get(\amp, {|v| vol = v.ampdb}) | |
} | |
route {|out| synth.set(\out, out) } | |
vol_ {|aVol| vol = aVol ; // in dB | |
synth.set(\amp, vol.dbamp) | |
} | |
vol {^vol} | |
pause {synth.run(false)} | |
play {synth.run} | |
mute { | |
synth.get(\amp, {|v| | |
vol = v.ampdb; | |
synth.set(\amp, 0) }) ; | |
} | |
unmute { synth.set(\amp, vol.dbamp) } | |
} | |
/* | |
SynthDef(\sine, {|out, amp = 1, freq = 440| | |
Out.ar(out, | |
SinOsc.ar(freq, mul: amp)) | |
}).add ; | |
~arr = Array.fill(10, {|i| | |
WFSrc(i)}).collect{|i|i.xy_(rrand(-1.0,1), rrand(-1.0,1))} | |
~synths = Array.fill(10, {|i|Synth(\sine, [\out, ~arr[i].bus])}) | |
s.scope | |
~arr.do{|i| i.mute} | |
~arr.do{|i| i.unmute} | |
~arr.do{|i| i.vol_(-6)} | |
~arr.do{|i| i.free} | |
*/ | |
WFSrcPlotter { | |
var <>wFSrcs ; | |
var <>or, <>dim, <>ptD ; | |
var <>window ; | |
*new { |aWFSrcArr| | |
^super.new.initWFSrcPlotter(aWFSrcArr) | |
} | |
initWFSrcPlotter { |wfsrcArr| | |
dim = 300 ; | |
ptD = 10 ; | |
or = Point(dim, dim) ; | |
wFSrcs = wfsrcArr ; | |
wFSrcs.do{|i| i.addDependant(this)} ; | |
this.createWindow ; | |
} | |
createWindow { | |
var col = 1.0/wFSrcs.size ; | |
window = Window("WFSrc Plotter", Rect(100, 100, dim*2, dim*2)).background_(Color.grey(0.2)) | |
.drawFunc_{ | |
wFSrcs.do{|i, id| | |
Pen.fillColor_(Color.hsv(col*id, 0.8, 1)) ; | |
Pen.fillOval( | |
Rect( | |
i.xy[0]*dim-(ptD*0.5)+or.x, | |
i.xy[1].neg*dim-(ptD*0.5)+or.y, ptD, ptD))} | |
} | |
.front ; | |
} | |
update { arg theChanged, theChanger, more; | |
//[theChanged, theChanger, more].postln ; | |
window.refresh | |
} | |
} | |
/* | |
a = WFSrc(0) ; b = WFSrc(1) ; | |
a.xy_(0.10, 0.20) | |
b.xy_(0.50,0.10) | |
c = WFSrcPlotter([a,b]) | |
c.wFSrcs | |
a.xy_(0,-1) | |
r = {inf.do{|i| | |
a.xy_(a.xy[0].postln+(i*0.01)%1, a.xy[1].postln+(i*0.01)%1) ; | |
0.5.wait | |
} | |
}.fork(AppClock) | |
r.stop | |
~arr = Array.fill(50, {|i| WFSrc(i)}).collect{|i|i.xy_(rrand(-1.0,1), rrand(-1.0,1))} ; | |
c = WFSrcPlotter(~arr) ; | |
r = {inf.do{ | |
var x, y; | |
~arr.do{|i| | |
x = (i.xy[0]+rrand(-0.01, 0.01)) ; | |
y = (i.xy[1]+rrand(-0.01, 0.01)) ; | |
case { x > 1 }{ | |
x = 1-x.frac; | |
} | |
{ x < -1}{ | |
x = x.frac.neg; | |
} ; | |
case { y > 1 }{ | |
y = 1-y.frac; | |
} | |
{ y < -1}{ | |
y = y.frac.neg; | |
} ; | |
i.xy_(x, y); | |
}; | |
0.05.wait | |
} | |
}.fork(AppClock) | |
r.stop | |
*/ | |
// does not need update from external sources | |
// dirty approach | |
WFSrcLifePlotter { | |
var <>or, <>dim, <>ptD ; | |
var <>window ; | |
var <>state ; | |
var <>grid ; | |
*new { |grid, state| | |
^super.new.initWFSrcPlotter(grid, state) | |
} | |
initWFSrcPlotter { |aGrid, aState| | |
dim = 300 ; | |
ptD = 10 ; | |
or = Point(dim, dim) ; | |
state = aState.flat ; // life matrix | |
grid = aGrid ; | |
this.createWindow ; | |
} | |
createWindow { | |
var col = 1.0/state.size ; | |
window = Window("Life Plotter", Rect(100, 100, dim*2, dim*2)).background_(Color.grey(0.2)) | |
.drawFunc_{ | |
grid.do{|i, id| | |
// BUGGY | |
if(state[id] == 1) { | |
Pen.fillColor_(Color.hsv(col*id, 0.8, 1)) ; | |
Pen.fillOval( | |
Rect( | |
i[0]*dim-(ptD*0.5)+or.x, | |
i[1].neg*dim-(ptD*0.5)+or.y, ptD, ptD))} | |
} | |
} | |
.front ; | |
} | |
refresh { window.refresh } | |
} | |
WFSrcDispatcher { | |
// this: | |
// 1. map to virtual dimension | |
// 2. converts to radians | |
// 3. dispatches to IP | |
var <>wFSrcs ; | |
var <>address ; | |
var <>meterFactor, <>ratioXY ; | |
*new { |aWFSrcArr, ip = "192.168.1.1", port = 4243, meterFactor = 1, ratioXY = 1| | |
^super.new.initWFSrcDispatcher(aWFSrcArr, ip, port, meterFactor, ratioXY) | |
} | |
initWFSrcDispatcher { |wfsrcArr, ip, port, | |
aMeterFactor, aRatioXY| | |
wFSrcs = wfsrcArr ; | |
wFSrcs.do{|i| i.addDependant(this)} ; | |
address = NetAddr(ip, port) ; | |
meterFactor = aMeterFactor ; | |
ratioXY = aRatioXY.reciprocal ; | |
NetAddr.broadcastFlag = true ; | |
address = NetAddr(ip, port) ; | |
} | |
update { arg theChanged, theChanger, more; | |
var point ; | |
//we have to select the src | |
// we have to convert in polar | |
//[theChanged, theChanger, more].postln ; | |
point = Point(more[1][0], | |
more[1][1]*ratioXY).asPolar ; | |
address.sendMsg("/iosono/renderer/version1/src", | |
more[0],// src | |
0, // type | |
point.theta, // azimuth: 1.57 | |
0.0, // elevation | |
point.rho*meterFactor, // radius: 5 | |
1.0, // vol | |
0.0, // LFE | |
0.0, // delay | |
0, //scaling | |
0, // screen | |
0.0, // spread | |
0 //srcTrait | |
) | |
} | |
} | |
/* | |
a = WFSrc(0) ; b = WFSrc(1) ; | |
a.xy_(0.10, 0.20) | |
b.xy_(0.50,0.10) | |
c = WFSrcPlotter([a,b]) | |
c.wFSrcs | |
d = WFSrcDispatcher([a,b], "192.168.0.255", 4243) | |
a.xy_(0,-1) | |
b.xy_(1,-1) | |
b.xy | |
*/ | |
WFSrcLogger { | |
// Following the model of the previous | |
// dependant classes creates a log ASCII | |
// file that can be easily parsed | |
// (Nodebox, SC etc) | |
// data represents for each WFSrc | |
// its time-stamped positions | |
var <>wFSrcs ; | |
var <>path, <>dict, <>file ; | |
var <>time ; | |
*new { |aWFSrcArr, path| | |
^super.new.initWFSrcLogger(aWFSrcArr, path) | |
} | |
initWFSrcLogger { |wfsrcArr, aPath| | |
wFSrcs = wfsrcArr ; | |
wFSrcs.do{|i| i.addDependant(this)} ; | |
path = aPath ; | |
file = File(path, "w") ; | |
time = thisThread.seconds ; | |
dict = () ; | |
wFSrcs.do{|i,j| | |
dict[j] = [] ; | |
}; | |
} | |
update { arg theChanged, theChanger, more; | |
var point ; | |
dict[more[0]] = dict[more[0]] | |
.add([thisThread.seconds-time, more[1]]) ; | |
} | |
close { | |
// write in an easy parsifiable ASCII format | |
file.write("[") ; | |
dict.do{|i| | |
file.write(i.asCompileString); | |
file.write(",") ; | |
}; | |
file.write("]") ; | |
file.close ; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment