//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