//audiovisual programming / mapping and visualization
//organized by lullcec, barcelona 18-20 may 2012
//----------------------------
//session #01.0
//introduction to sound synthesis with the scope and plot windows
//--simple sounds
s.boot
{SinOsc.ar(440)}.play
{Saw.ar}.play
{LFTri.ar}.play
{SinOsc.ar(1600)}.play
{Saw.ar(700)}.play
{SinOsc.ar(Saw.ar(0.1)*800)}.play
{SinOsc.ar([400, 404])}.play
{Mix(SinOsc.ar([400, 404]))*0.3}.play
{SinOsc.ar([400, 500, 600, 700, 800])}.play
s.options.dump //show your current settings in post
s.meter //level meters for inputs and outputs
{SinOsc.ar(SinOsc.ar(1)*400, 0, 0.5)}.play
{SinOsc.ar(LFSaw.ar(1)*400+400, 0, 0.5)}.play
//--plotter
{SinOsc.ar}.plot(minval: -1, maxval: 1)
{SinOsc.ar}.plot(duration: 1, minval: -1, maxval: 1)
{SinOsc.ar(12000)}.plot(duration: 0.5, minval:-10, maxval:10)
{SinOsc.ar([400, 404])}.plot(duration: 1, minval: -1, maxval: 1)
//watch out not to plot too long... save often - might crash
//try keyboard shortcuts: +/-, s, m, g, G
//see Plotter helpfile
a= {SinOsc.ar([101, 2020, 303, 4040])}.plot(minval: -1, maxval: 1)
a.setProperties(\backgroundColor, Color.black)
a.refresh
a.setProperties(\plotColor, Color.white)
a.refresh
a.resolution= 30 //downsample
a.refresh
{Mix(SinOsc.ar([101, 2020, 303, 4040]))}.plot
//try different oscillators
//also plotting collections
//show print to pdf / screencapture
//mac osx: press cmd+shift+4 and the <space>, click in the window you want to grab
//windows: click window and press Alt+Print Screen (psc) to take a screenshot under win xp
// open Accessories/Paint and Paste
//linux: ?
//--scope
s.boot
s.scope
//if no window appear on osx (sc3.5):
GUI.qt
s.scope
//or boot internal server and click 'default' in gui window
{SinOsc.ar([400, 404])}.play
//try keyboard shortcuts: +/-, */_, s, S, m,
//see Server helpfile
s.scope(bufsize:8192)
s.scope(bufsize:1024)
s.scope(bufsize:4096)
{SinOsc.ar([30, 40, 50, 60, 70, 80]*0.01)}.play
a= s.scope
a.setProperties(6, 0, 8192, 1) //channels, index, size, rate
a.scopeView.background= Color.white
a.scopeView.waveColors= Color.red.dup(6)
a.scopeView.waveColors= {Color.rand}.dup(6)
a.scopeView.waveColors= [Color.red, Color.blue, Color.yellow, Color(0.2, 0.3, 0.5)]
a.xZoom= 0.5
a.yZoom= 0.1
a.style= 0
a.style= 1
a.style= 2
//phase osc.scope mode
{SinOsc.ar([3, 3.1])}.play
//----------------------------
//session #01.1
//more on sound synthesis and how to generate 'good looking waveforms'
s.boot
GUI.qt
{SinOsc.ar([1, 1.05])}.scope
a= s.scope
a.style= 2
a.setProperties(2, 0, 2048, 1)
//--simple sound experiments
{SinOsc.ar([SinOsc.ar(1)+1, SinOsc.ar(1.05)+1])}.scope
{SinOsc.ar([SinOsc.ar(1)+1, SinOsc.ar(1.05)+500])}.scope
{SinOsc.ar([SinOsc.ar(1)+500, SinOsc.ar(1.05)+500])}.scope
{SinOsc.ar([1, 1.05], SinOsc.ar(100)*2pi)}.scope
{SinOsc.ar([1, 1.05], SinOsc.ar(2000)*2pi)}.scope
{SinOsc.ar([1, 1500], SinOsc.ar(10)*2pi)}.scope
{SinOsc.ar([1, 2], SinOsc.ar([10, 11])*2pi)}.scope
{SinOsc.ar([1, 2], SinOsc.ar([100, 101])*2pi)}.scope
{SinOsc.ar([1, 2], SinOsc.ar(10)*2pi, SinOsc.ar(0.1))}.scope
{SinOsc.ar([1, 2], SinOsc.ar(10)*2pi, SinOsc.ar([0.2, 0.3]))}.scope
{SinOsc.ar([1, 1.05])*SinOsc.ar(100)}.scope
{SinOsc.ar([1, 1.05])+SinOsc.ar(1000)}.scope //note +
//adding mouse x and y control to test parameters
{SinOsc.ar([1, MouseX.kr(0, 10)])*SinOsc.ar(1000)}.scope
{SinOsc.ar([MouseY.kr(0, 10), MouseX.kr(0, 10)])+SinOsc.ar(1000)}.scope
{SinOsc.ar([400+MouseX.kr(0, 10).poll, 500])}.scope
{LFTri.ar([400, 500])}.scope
{LFTri.ar([400, 500.1])}.scope
{[LFTri.ar(400), SinOsc.ar(500.1)]}.scope
{[LFTri.ar(MouseX.kr(100, 500)), SinOsc.ar(MouseY.kr(100, 500))]}.scope
{[Saw.ar(MouseX.kr(100, 500)), SinOsc.ar(MouseY.kr(100, 500))]}.scope
{[Saw.ar(MouseX.kr(10, 500)), Saw.ar(MouseY.kr(10, 500))]}.scope
//see Tour of UGens helpfile for inspiration
//save good looking sounds for later
//--freqscope
s.boot
GUI.qt
FreqScope.server= s;
a= FreqScope.new
{Saw.ar(MouseX.kr(10, 1000, 1))}.play
//----------------------------
//session #01.2
//theory of 2d graphics, drawing and plotting waveforms, example applications and visualizers
//discuss number of pixels, screen resolution, window size
//60hz, screen size, samplerate
44100/1024
{SinOsc.ar(100, 0.5)}.plot
768/2.pow(16)
{Impulse.ar(1000)}.plot
//interpolation, plotting averages vs peaks, log/exp/lin
//framerate vs samplerate, chunks of samples, nyquist
//how to map sound volume to brightness, colour, etc
//--examples
//cymatics - "the study of visible sound and vibration"
/*
http://en.wikipedia.org/wiki/Cymatics
http://www.youtube.com/watch?v=sY6z2hLgYuY
http://www.youtube.com/watch?v=3csi-2Hrzhg
http://www.youtube.com/watch?v=3zoTKXXNQIU
http://www.youtube.com/watch?v=uQWBA8q8JEs
http://www.youtube.com/watch?v=NIoFJibzww8
*/
//using oscilloscopes
/*
http://robinfox.net/projects/oscilloscope/
http://www.youtube.com/watch?v=GFBHVDMUgXM
*/
//spectrograms
/*
aphex twin http://www.youtube.com/watch?v=M9xMuPWAZW8
metasynth http://www.uisoftware.com/MetaSynth/index.php
xenakis upic http://www.youtube.com/watch?v=yztoaNakKok
*/
//--my examples
//* ström - 5.1 surround sound (by m. petersson) directly mapped to 6 lines
// made with opengl in max/jitter
// playing with buffersize, scale, rotate, translate, feedback
//* redShift - slowly scrolling spectrogram
// made with sc pen class - see example session #02
// playing with gain, presets: rotation, speed, style (lines, points)
//* redUniform - less direct mapping of graphical object to sound
// made with sc pen class - see examples session #03
// mapping positions, velocities, collisions, sizes, number of objects
//----------------------------
//session #01.3
//using the pen and userview classes with the simple built-in shapes
//see Pen and UserView helpfiles
(
var win= Window("test", Rect(10, 20, 640, 480), false);
win.front;
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
)
(
var width= 640;
var height= 480;
var win= Window("fillRect test", Rect(100, 100, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
usr.drawFunc= {
Pen.fillColor= Color.yellow;
Pen.fillRect(Rect(10, 60, 20, 20));
};
win.front;
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
)
(
var width= 640;
var height= 480;
var win= Window("strokeRect test", Rect(100, 100, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
usr.drawFunc= {
Pen.width= 5;
Pen.strokeColor= Color.rand;
Pen.strokeRect(Rect(10, 60, width-20, height-120));
Pen.strokeColor= Color.rand;
Pen.strokeRect(Rect(20, 70, width-40, height-140));
Pen.strokeColor= Color.rand;
Pen.strokeRect(Rect(30, 80, width-60, height-160));
};
win.front;
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
)
(
var width= 640;
var height= 480;
var win= Window("line test", Rect(100, 100, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
usr.background= Color.black;
usr.drawFunc= {
Pen.strokeColor= Color.white;
Pen.width= 2;
Pen.line(Point(width*0.5, height*0.5), Point(100, 100));
Pen.line(Point(100, 100), Point(width*0.5, 10));
Pen.stroke;
};
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
win.front;
)
(
var width= 640;
var height= 480;
var win= Window("lineTo moveTo test", Rect(100, 100, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
usr.background= Color.black;
usr.drawFunc= {
Pen.strokeColor= Color.white;
Pen.width= 1;
Pen.moveTo(Point(width*0.5, height*0.5));
500.do{
Pen.lineTo(Point(width.rand, height.rand));
};
Pen.stroke;
};
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
win.front;
)
(
var width= 640;
var height= 480;
var win= Window("addRect test", Rect(100, 100, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
usr.background= Color.black;
usr.drawFunc= {
Pen.smoothing= false;
Pen.strokeColor= Color.white;
50.do{|i|
Pen.addRect(Rect.aboutPoint(Point(i/50*width, height*0.5), 10.rand, 10.rand));
};
Pen.stroke;
};
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
win.front;
)
(
var width= 640;
var height= 480;
var win= Window("addRect test2", Rect(100, 100, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
usr.background= Color.black;
usr.drawFunc= {
Pen.smoothing= false;
Pen.strokeColor= Color.white;
50.do{|i|
Pen.addRect(Rect.aboutPoint(Point(i/50*width, height*0.5), i+1, i+1));
};
Pen.stroke;
};
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
win.front;
)
(
var width= 640;
var height= 480;
var win= Window("addOval test", Rect(100, 100, width, height), false);
var usr= UserView(win, Rect(0, 0, width, height));
usr.background= Color.black;
usr.drawFunc= {
Pen.width= 10;
Pen.fillColor= Color.white;
Pen.strokeColor= Color.red;
20.do{|i|
Pen.addOval(Rect.aboutPoint(Point(i/20*width, height*0.5), 100.rand, 100.rand));
};
Pen.draw(4); //draw modes
};
CmdPeriod.doOnce({if(win.isClosed.not, {win.close})});
win.front;
)
//see Pen helpfile for more primitives: arcs, curves, wedges etc
//again see UserView helpfile
(
var width= 800;
var height= 600;
var win= Window("scratch", Rect(80, 100, width, height), false, false); //here change 80 to 1680 after connecting external monitor
var usr= UserView(win, Rect(0, 0, width, height));
usr.background= Color.red;
win.front;
CmdPeriod.doOnce({win.close});
usr.drawFunc= {
500.do{|i|
Pen.fillColor= Color.green(i/499, 0.1);
Pen.fillRect(Rect(i/500*width, (i/500).rand2.linlin(-1, 1, 0, height), 50.rand, 60.rand));
};
};
)
//presenting stuff on separate screen - desktop background
//* set desktop background to black png file
//* in sc set window border and resizable flags to false
//* set bounds to start at xpos 1680