commit 81fb74dc004e223c47a50f1fddbacc8746c5f750 Author: Nova deViator Date: Wed Sep 9 14:03:24 2015 +0200 init commit diff --git a/pde/IF3Si/IF3Si.pde b/pde/IF3Si/IF3Si.pde new file mode 100644 index 0000000..270b300 --- /dev/null +++ b/pde/IF3Si/IF3Si.pde @@ -0,0 +1,237 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + Interface Fractures III - SILICON + (c) nova@deviator.si + + IF3Si.pde + + */ + +// undecorate window (remove window borders etc) - - - - - - - - - - - - - - - +public void init() { frame.removeNotify(); frame.setUndecorated(true); + frame.addNotify(); super.init(); } + +// load libs +import oscP5.*; // Open Sound Control +import netP5.*; + + +// declarations - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// declare OSC object +OscP5 oscP5; + + +// IMAGE POOL, a 2D array +PImage[][] imgPool; + +// texture (tiles) +float texX = 0; +float texY = 0; + +// generate an array of random numbers +int[] rands = new int[500]; +IntList randz; // arrayList + +// for draw cube +int cubesnum = 20; +PGraphics[] cubes = new PGraphics[cubesnum]; +PShader blur; +PGraphics bpass1, bpass2; + +// spheres +int ptsW, ptsH; + +int numPointsW; +int numPointsH_2pi; +int numPointsH; + +float[] coorX; +float[] coorY; +float[] coorZ; +float[] multXZ; + +PGraphics sphere; + + + +void setup() { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + float sizefactor = 1; // define the size of the screen, 1 = 1080p + size( int( 1920 * sizefactor ), + int( 1080 * sizefactor ), + P3D ); // renderer + + // framerate + frameRate(60); + smooth(32); // 32?? + noCursor(); + background(10); + + println("\n\n~~~ Hello. Starting Interface Fractures III - SILICON." + + " - - - - - - - - - - - - - - - - - - - - - -\n"); + + // start oscP5, listening for incoming messages at port 12000 + println("~~~ starting oscP5 ..."); + oscP5 = new OscP5(this,12000); + oscP5.plug(this,"ctlin","/ctlin"); // to be converted for PD OSC input + + // get all textures into an image pool + println("\n\n~~~ loading textures into image pool ...\n"); + imgPool = getImages("/images/"); + + // create an array of random value between -50 and 50 + for (int i=0; i < 500; i++) { rands[i] = i-250; } + shuffle(rands); + + + // drawCube ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` + // an array of PGraphics + for (int i = 0; i < cubesnum; i++) { + cubes[i] = createGraphics(width, height, P3D); + } + blur = loadShader("blur.glsl"); + bpass1 = createGraphics(width, height, P3D); + bpass1.smooth(); + bpass2 = createGraphics(width, height, P3D); + bpass2.smooth(); + + + randz = new IntList(width); + for (int i=0; i < width; i++) { + randz.set(i, i); + } + randz.shuffle(); + //println(randz); + + // spheres + ptsW=30; + ptsH=30; + initializeSphere(ptsW, ptsH); // number of vertices around the width and height + sphere = createGraphics(width, height, P3D); + +} + +void draw() { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // clean screen ````````````````````````````````````````````````````| + /* + blendMode(BLEND); + screenClean(color(50)); + + // SPHERES ----------------------------------------------------------- + //offscreen render spheres + + sphere.beginDraw(); + sphere.blendMode(BLEND); + sphere.rect(0, 0, width, height); + sphere.blendMode(DARKEST); + sphere.noStroke(); + sphere.pushMatrix(); + sphere.translate(width/2+(width/8), height/2, 580); + sphere.rotateX(radians(float(frameCount) * 0.1)); + sphere.rotateY(radians(float(frameCount) * 0.23)); + sphere.rotateZ(radians(float(frameCount) * 0.2)); + textureSphere(sphere, 400, 400, 400, imgPool[3][1]); + sphere.popMatrix(); + + sphere.pushMatrix(); + sphere.translate(width/2+(width/8), height/2, 580); + sphere.rotateX(radians(float(frameCount) * 0.2)); + sphere.rotateY(radians(float(frameCount) * 0.13)); + sphere.rotateZ(radians(float(frameCount) * 0.01)); + textureSphere(sphere, 390, 390, 390, imgPool[3][1]); + sphere.popMatrix(); + + sphere.endDraw(); + + + // tint(0); + // image(sphere, 0, 0); + + textureWrap(REPEAT); + //textureMode(NORMAL); + + pushMatrix(); + //tint(255); + translate(width/2, height/2); // center coordinate system + translate(((frameCount*1) % width) - width/2,0); + //stroke(0,50); + //strokeWeight(1); + noStroke(); + + float quadW = 500; + float quadH = height; + + float v1x = 0; // sin(radians(frameCount))*250+400; + + pushMatrix() ; + //rotate(PI/PI); + + beginShape(QUADS); + texture(sphere); + vertex(-quadW/2, -quadH/2, 0, 0); + vertex( quadW/2, -quadH/2, quadW, 0); + vertex( quadW/2, quadH/2, quadW, quadH); + vertex(-quadW/2, quadH/2, 0, quadH); + endShape(); + popMatrix(); + popMatrix(); + + */ + + // -------------------------------------------------------------------------- + // SCENENGINES + + + + + // draw tiles `````````````````````````````````````````````````````| + tiles(boolean(1), // render on/off + color(0, 0, 0, 80), // background color (HSBA) + color(80, 70, 20, 100), // tile color + 20, // tile hue distance + 0, // blendMode + 6, // number of tiles on X axis + 1, // number of tiles on Y axis + 2, // texture bank number + 0, // texture number/id + 10, // texture speed X + 1, // texture speed Y + 64 // overlap. 127 = 300% + ); + + + + // draw cubes `````````````````````````````````````````````````````| + drawCube(boolean(0), cubes, + 100, height/2, -100, + 400, 300, 300, + radians(frameCount), radians(frameCount*0.7), PI/2, + 0); + + + + // test pattern```````````````````````````````````````````````````| + testPattern(boolean(0), // on/off + 2, 0, // img bank & ID + 255, // image alpha + 10, // number of horizontal 'lanes' + 10, // density + 4, // stroke width + 255, // stroke alpha + 2 // speed + ); + + + // debug `````````````````````````````````````````````````````````| + // draw test picture + testPicture(boolean(0)); + + // frames per second + displayFps(true); + // document + autoSnap(false); +} // -------------------------------------------------------------------------- + + + diff --git a/pde/IF3Si/blur.glsl b/pde/IF3Si/blur.glsl new file mode 100644 index 0000000..1b15094 --- /dev/null +++ b/pde/IF3Si/blur.glsl @@ -0,0 +1,59 @@ +// Adapted from: +// http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html + +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +#define PROCESSING_TEXTURE_SHADER + +uniform sampler2D texture; + +// The inverse of the texture dimensions along X and Y +uniform vec2 texOffset; + +varying vec4 vertColor; +varying vec4 vertTexCoord; + +uniform int blurSize; +uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass +uniform float sigma; // The sigma value for the gaussian function: higher value means more blur + // A good value for 9x9 is around 3 to 5 + // A good value for 7x7 is around 2.5 to 4 + // A good value for 5x5 is around 2 to 3.5 + // ... play around with this based on what you need :) + +const float pi = 3.14159265; + +void main() { + float numBlurPixelsPerSide = float(blurSize / 2); + + vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0); + + // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889) + vec3 incrementalGaussian; + incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma); + incrementalGaussian.y = exp(-0.5 / (sigma * sigma)); + incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y; + + vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0); + float coefficientSum = 0.0; + + // Take the central sample first... + avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x; + coefficientSum += incrementalGaussian.x; + incrementalGaussian.xy *= incrementalGaussian.yz; + + // Go through the remaining 8 vertical samples (4 on each side of the center) + for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { + avgValue += texture2D(texture, vertTexCoord.st - i * texOffset * + blurMultiplyVec) * incrementalGaussian.x; + avgValue += texture2D(texture, vertTexCoord.st + i * texOffset * + blurMultiplyVec) * incrementalGaussian.x; + coefficientSum += 2.0 * incrementalGaussian.x; + incrementalGaussian.xy *= incrementalGaussian.yz; + } + + gl_FragColor = avgValue / coefficientSum; +} \ No newline at end of file diff --git a/pde/IF3Si/functions.pde b/pde/IF3Si/functions.pde new file mode 100644 index 0000000..154fbc5 --- /dev/null +++ b/pde/IF3Si/functions.pde @@ -0,0 +1,456 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + Interface Fractures III - SILICON + (c) nova@deviator.si + + functions.pde + + */ + +// loads all images into an array - - - - - - - - - - - - - - - - - - - - - - - - - +PImage[][] getImages(String folder) { + + PImage[][] imgPool; // declare 2D array imgPool + + File dir = new File(dataPath(sketchPath + folder)); // first folder + String[] dirlist = dir.list(); // an array of folders (strings) + dirlist = sort(dirlist); // + imgPool = new PImage[dirlist.length][10]; // create 2d array imgPool + + + for (int i = 0; i < dirlist.length; i++) { + String fulldir = dataPath(sketchPath + folder + dirlist[i]) + "/"; + File dir2 = new File(fulldir); + String[] filelist = dir2.list(); // an array of image names + filelist = sort(filelist); + + if (filelist.length != 0) { + + for (int j = 0; j < filelist.length; j++) { + println("imgPool[" + i + "][" + j + "]: " + fulldir + filelist[j]); + imgPool[i][j] = loadImage(fulldir + filelist[j]); + } + + } else { + println("No files in this folder: " + fulldir); + } + } + + return imgPool; + +} + + + +// function to shuffle an array of integers - - - - - - - - - - - - - - - - - - - - - +void shuffle(int[] a) +{ + int temp, pick; + + for(int i=0; i- more TO BE EXPANDED / REFINED!!! */ + +void testPattern( boolean render, + int imgBank, int imgID, + int imgAlpha, + int ylines, + int density, + int lwidth, + int lalpha, + int speed + ) +{ + if (render) { + + tint(imgAlpha); + image(imgPool[imgBank][imgID], 0, 0); + + blendMode(BLEND); + + int yheight = height/ylines; + + for (int y=0; y < ylines; y++) { + int yloc = int((y+1)*height/(ylines+1)); + for (int x=0; x < width; x++) { + + int index = x + (y * (width/ylines)); + index = index % width; + if (randz.get(index) < density * 0.01 * randz.get((index + x + y) % randz.size())) { + + int fx = (x + frameCount); // move! + fx = fx * speed * 1 * randz.get((abs(index - x + y) % randz.size())) / randz.size(); // speed! + fx %= width; // wrap at the right edge + + color imgC = imgPool[imgBank][imgID].get(fx, yloc); + stroke(imgC, lalpha); + strokeWeight(1 + map(brightness(imgC), 0, 255, 0, lwidth)); + + line(fx, yheight * y + (yheight/30), fx, yheight * (y+1) - (yheight/30)); + } + } + } + } +} + + + + + + + +// SPHERES - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// A 3D textured sphere with simple rotation control. +// thanks to https://processing.org/examples/texturesphere.html +// Texture Sphere written by Gillian Ramsay to better display the poles. +// Previous version by Mike 'Flux' Chang (and cleaned up by Aaron Koblin). +// Original based on code by Toxi. +// modified to accomodate offscreen PGraphics + +void initializeSphere(int numPtsW, int numPtsH_2pi) { + + // The number of points around the width and height + numPointsW=numPtsW+1; + numPointsH_2pi=numPtsH_2pi; // How many actual pts around the sphere (not just from top to bottom) + numPointsH=ceil((float)numPointsH_2pi/2)+1; // How many pts from top to bottom (abs(....) b/c of the possibility of an odd numPointsH_2pi) + + coorX=new float[numPointsW]; // All the x-coor in a horizontal circle radius 1 + coorY=new float[numPointsH]; // All the y-coor in a vertical circle radius 1 + coorZ=new float[numPointsW]; // All the z-coor in a horizontal circle radius 1 + multXZ=new float[numPointsH]; // The radius of each horizontal circle (that you will multiply with coorX and coorZ) + + for (int i=0; i>> Hello. Starting Interface Fractures III - SILICON <<< + .______________________ _________.__ + | \\_ _____/\\_____ \\ \/ _____\/|__| + | || __) _(__ < \\_____ \\ | | + | || \\ / \\/ \\| | + |___|\\___ / /______ /_______ /|__| + \\/ \\/ \\/ + +"); + +Server.default.waitForBoot { + + // where are we? + var dir = PathName(thisProcess.nowExecutingPath).pathOnly; + + // this might go to separate file at some point... ---------------------| + // will load samples for granular synthesis + // var dir = PathName(thisProcess.nowExecutingPath).pathOnly; // + var granSmp = PathName(dir +/+ "../smp/granul/").files; + var granBfr = List(); + + postln("\n~~~ Loading samples for granular synthesis ..." ); + granSmp.do({ |item, i| + postln(" " + i + "" + item.folderName +/+ item.fileName); + granBfr.add(Buffer.readChannel(s, item.fullPath, channels:[0])); // [0] forces mono! + }); + postln(""); + // ---------------------------------------------------------------------| + + // what are the files? + ~files = List[ + "sdefs.scd", // SynthDef definitions + "snd_lines.scd", // converting Si spectra lines to sound + "gui_core.scd", // basic general GUI setup + "gui_chaos.scd", // chaos tab + "gui_granul.scd", // + "gui_main.scd" + ]; + + // for each file in list, load/execute it + ~files.do({|item, i| this.executeFile(dir +/+ item) }); + +} +) + + +//s.meter; +//s.plotTree; +EnvirGui + + + diff --git a/scd/gui_chaos.scd b/scd/gui_chaos.scd new file mode 100644 index 0000000..6848114 --- /dev/null +++ b/scd/gui_chaos.scd @@ -0,0 +1,835 @@ +/* + part of: Interface Fractures III - Silicon + + (c) Luka Prinčič / Nova deViator + nova@deviator.si + + gui_chaos.scd - takes care of all GUI elements under + the chaos tab... + +********************************************************** */ + + +~tab_views[~tab_names.at("chaos")].layout = HLayout(); +~tab_views[~tab_names.at("chaos")].layout.margins = 0; +~tab_views[~tab_names.at("chaos")].layout.add(nil); + + +// create a view for StandardMap synth --------------------------------------------------------- +~standardMapView = View.new(~tab_views[~tab_names.at("chaos")]); +~standardMapView.background = Color.gray(0.5); +~standardMapView.layout = VLayout( // vert. layout: + + Button() + .states_([ + ["Standard"], + ["Standard", Color.gray(0.2), Color.grey(0.8)] ]) + .mouseDownAction_({ | state | + switch(state.value, + 0, {~standard2D = Synth(\StandardMap, [\amp, 0]);}, + 1, {~standard2D.free;} + ); + }) + .minHeight_(40).minWidth_(70), + + HLayout( + + VLayout( // parameters + StaticText().string_("frq"), + RangeSlider(nil,Rect(0,0,20,270)) + .minWidth_(70) .minHeight_(270) + .lo_(0) .hi_(0.11) + .action_({ | slider | + var minfreq, maxfreq; + minfreq = slider.lo.value.linexp(0, 1, 10, 15000); + maxfreq = slider.hi.value.linexp(0, 1, 10, 15000); + ~standard2D.set(\minfreq, minfreq.value); + ~standard2D.set(\maxfreq, maxfreq.value); + }), + + StaticText().string_("k"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 2.8); + ~standard2D.set(\k, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("x0"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 4.9789799812499 * 2); + ~standard2D.set(\x0, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("y0"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 5.7473416156381 * 2); + if(~standard2D.isPlaying, { + ~standard2D.set(\x0, val); } + ); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + nil + ), + + VLayout( // gains and filters section + + StaticText().string_("OUT"), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("N"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~standard2D.set(\ampN, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("L"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~standard2D.set(\ampL, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("C"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~standard2D.set(\ampC, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("f"), + Knob() .value_(1) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({arg freq; + freq = freq.value.linexp(0, 1, 40, 20000); + ~standard2D.set(\bpffreq, freq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().align_(\left).string_("q"), + Knob() .value_(0) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ arg rq; + rq = abs(rq.value - 1); + rq = rq.value.linexp(0, 1, 0.1, 100); + ~standard2D.set(\bpfrq, rq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("A"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~standard2D.set(\amp, amp); + }), + nil + ) + ), + nil; +); + + + +// ------------------------------------------------------------------------------------------------- + + +// create a view for GbmanMap synth --------------------------------------------------------- +~gbmanMapView = View.new(~tab_views[~tab_names.at("chaos")]); + +~gbmanMapView.background = Color.gray(0.5); +~gbmanMapView.layout = VLayout( // vert. layout: + + Button() + .states_([ + ["Gbman"], + ["Gbman", Color.gray(0.2), Color.grey(0.8)] ]) + .mouseDownAction_({ | state | + switch(state.value, + 0, {~gbman2D = Synth(\GbmanMap, [\amp, 0]);}, + 1, {~gbman2D.free;} + ); + }) + .minHeight_(40).minWidth_(70), + + HLayout( + + VLayout( // parameters + StaticText().string_("frq"), + RangeSlider(nil,Rect(0,0,20,270)) + .minWidth_(70) .minHeight_(270) + .lo_(0) .hi_(0.11) + .action_({ | slider | + var minfreq, maxfreq; + minfreq = slider.lo.value.linexp(0, 1, 10, 15000); + maxfreq = slider.hi.value.linexp(0, 1, 10, 15000); + ~gbman2D.set(\minfreq, minfreq.value); + ~gbman2D.set(\maxfreq, maxfreq.value); + }), + + + StaticText().string_("x0"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 1.2 * 2); + ~gbman2D.set(\x0, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("y0"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 2.1 * 2); + ~gbman2D.set(\y0, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + nil + ), + + VLayout( // gains and filters section + + StaticText().string_("OUT"), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("N"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~gbman2D.set(\ampN, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("L"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~gbman2D.set(\ampL, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("C"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~gbman2D.set(\ampC, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("f"), + Knob() .value_(1) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({arg freq; + freq = freq.value.linexp(0, 1, 40, 20000); + ~gbman2D.set(\bpffreq, freq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().align_(\left).string_("q"), + Knob() .value_(0) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ arg rq; + rq = abs(rq.value - 1); + rq = rq.value.linexp(0, 1, 0.1, 100); + ~gbman2D.set(\bpfrq, rq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("A"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~gbman2D.set(\amp, amp); + }), + nil + ) + ), + nil; +); +// ------------------------------------------------------------------------------------------------- + + + + +// create a view for HenonMap synth --------------------------------------------------------- +~henonMapView = View.new(~tab_views[~tab_names.at("chaos")]); + +~henonMapView.background = Color.gray(0.5); +~henonMapView.layout = VLayout( // vert. layout: + + Button() + .states_([ + ["Henon"], + ["Henon", Color.gray(0.2), Color.grey(0.8)] ]) + .mouseDownAction_({ | state | + switch(state.value, + 0, {~henon2D = Synth(\HenonMap, [\amp, 0]);}, + 1, {~henon2D.free;} + ); + }) + .minHeight_(40).minWidth_(70), + + HLayout( + + VLayout( // parameters + StaticText().string_("frq"), + RangeSlider(nil,Rect(0,0,20,270)) + .minWidth_(70) .minHeight_(270) + .lo_(0) .hi_(0.11) + .action_({ | slider | + var minfreq, maxfreq; + minfreq = slider.lo.value.linexp(0, 1, 10, 15000); + maxfreq = slider.hi.value.linexp(0, 1, 10, 15000); + ~henon2D.set(\minfreq, minfreq.value); + ~henon2D.set(\maxfreq, maxfreq.value); + }), + + + StaticText().string_("a"), + Knob() .centered_(true) .value_(0.9) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.explin(0.01, 1, 0, 1.42); + ~henon2D.set(\a, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + nil + ), + + VLayout( // gains and filters section - - - - + + StaticText().string_("OUT"), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("N"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~henon2D.set(\ampN, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("L"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~henon2D.set(\ampL, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("C"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~henon2D.set(\ampC, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("f"), + Knob() .value_(1) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({arg freq; + freq = freq.value.linexp(0, 1, 40, 20000); + ~henon2D.set(\bpffreq, freq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().align_(\left).string_("q"), + Knob() .value_(0) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ arg rq; + rq = abs(rq.value - 1); + rq = rq.value.linexp(0, 1, 0.1, 100); + ~henon2D.set(\bpfrq, rq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("A"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~henon2D.set(\amp, amp); + }), + nil + ) + ), + nil; +); +// ------------------------------------------------------------------------------------------------- + + +// create a view for LatoocarfianMap synth --------------------------------------------------------- +~latoocarfianMapView = View.new(~tab_views[~tab_names.at("chaos")]); +~latoocarfianMapView.background = Color.gray(0.5); +~latoocarfianMapView.layout = VLayout( // vert. layout: + + Button() + .states_([ + ["Latoocarfian"], + ["Latoocarfian", Color.gray(0.2), Color.grey(0.8)] ]) + .mouseDownAction_({ | state | + switch(state.value, + 0, {~latoocarfian2D = Synth(\LatoocarfianMap, [\amp, 0]);}, + 1, {~latoocarfian2D.free;} + ); + }) + .minHeight_(40).minWidth_(70), + + + HLayout( + + VLayout( // parameters + StaticText().string_("frq"), + RangeSlider(nil,Rect(0,0,20,180)) + .minWidth_(70) .minHeight_(180) + .lo_(0) .hi_(0.11) + .action_({ | slider | + var minfreq, maxfreq; + minfreq = slider.lo.value.linexp(0, 1, 10, 15000); + maxfreq = slider.hi.value.linexp(0, 1, 10, 15000); + ~latoocarfian2D.set(\minfreq, minfreq.value); + ~latoocarfian2D.set(\maxfreq, maxfreq.value); + }), + + StaticText().string_("a"), + Knob().centered_(true) .value_(0.5).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg a; + a = a.value.linlin(0, 1, 0, 2); + ~latoocarfian2D.set(\a, a); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("b"), + Knob().centered_(true) .value_(0.5) .mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg b; + b = b.value.linlin(0, 1, 0, 6); + ~latoocarfian2D.set(\b, b); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("c"), + Knob().centered_(true) .value_(0.5) .mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg c; + c = c.value; + ~latoocarfian2D.set(\c, c); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("d"), + Knob().centered_(true) .value_(0.5) .mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg d; + d = d.value; + ~latoocarfian2D.set(\d, d); + }), + + + nil + + ), + + + VLayout( // gains and filters section + + StaticText().string_("OUT"), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("N"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~latoocarfian2D.set(\ampN, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("L"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~latoocarfian2D.set(\ampL, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("C"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~latoocarfian2D.set(\ampC, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("f"), + Knob() .value_(1) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({arg freq; + freq = freq.value.linexp(0, 1, 40, 20000); + ~latoocarfian2D.set(\bpffreq, freq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().align_(\left).string_("q"), + Knob() .value_(0) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ arg rq; + rq = abs(rq.value - 1); + rq = rq.value.linexp(0, 1, 0.1, 100); + ~latoocarfian2D.set(\bpfrq, rq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("A"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~latoocarfian2D.set(\amp, amp); + }), + nil + ) + ), + nil; +); + + +// create a view for LorenzMap synth --------------------------------------------------------- +~lorenzMapView = View.new(~tab_views[~tab_names.at("chaos")]); +~lorenzMapView.background = Color.gray(0.5); +~lorenzMapView.layout = VLayout( // vert. layout: + + Button() + .states_([ + ["Lorenz"], + ["Lorenz", Color.gray(0.2), Color.grey(0.8)] ]) + .mouseDownAction_({ | state | + switch(state.value, + 0, {~lorenz2D = Synth(\LorenzMap, [\amp, 0]);}, + 1, {~lorenz2D.free;} + ); + }) + .minHeight_(40).minWidth_(70), + + HLayout( + + VLayout( // parameters + StaticText().string_("frq"), + RangeSlider(nil,Rect(0,0,20,270)) + .minWidth_(70) .minHeight_(270) + .lo_(0) .hi_(0.11) + .action_({ | slider | + var minfreq, maxfreq; + minfreq = slider.lo.value.linexp(0, 1, 10, 15000); + maxfreq = slider.hi.value.linexp(0, 1, 10, 15000); + ~lorenz2D.set(\minfreq, minfreq.value); + ~lorenz2D.set(\maxfreq, maxfreq.value); + }), + + + + + StaticText().string_("x0"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 0.090879182417163 * 2); + ~lorenz2D.set(\x0, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("y0"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 2.97077458055 * 2); + ~lorenz2D.set(\y0, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("z0"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 24.282041054363 * 2); + ~lorenz2D.set(\z0, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + nil + ), + + + VLayout( + + nil, + + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("s"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 10 * 2); + ~lorenz2D.set(\s, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("r"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 28 * 2); + ~lorenz2D.set(\r, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("b"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 2.666666667 * 2); + ~lorenz2D.set(\b, val); + }), + + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("h"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 0.02 * 2); + ~lorenz2D.set(\h, val); + }), + + nil + + ), + + + VLayout( // gains and filters section + + StaticText().string_("OUT"), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("N"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~lorenz2D.set(\ampN, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("L"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~lorenz2D.set(\ampL, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("C"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~lorenz2D.set(\ampC, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("f"), + Knob() .value_(1) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({arg freq; + freq = freq.value.linexp(0, 1, 40, 20000); + ~lorenz2D.set(\bpffreq, freq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().align_(\left).string_("q"), + Knob() .value_(0) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ arg rq; + rq = abs(rq.value - 1); + rq = rq.value.linexp(0, 1, 0.1, 100); + ~lorenz2D.set(\bpfrq, rq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("A"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~lorenz2D.set(\amp, amp); + }), + nil + ) + ), + nil; +); + + + + + + + + + + + + +// create a view for FhnMap synth --------------------------------------------------------- +~fhnMapView = View.new(~tab_views[~tab_names.at("chaos")]); +~fhnMapView.background = Color.gray(0.5); +~fhnMapView.layout = VLayout( // vert. layout: + + Button() + .states_([ + ["Fhn"], + ["Fhn", Color.gray(0.2), Color.grey(0.8)] ]) + .mouseDownAction_({ | state | + switch(state.value, + 0, {~fhn2D = Synth(\FhnMap, [\amp, 0]);}, + 1, {~fhn2D.free;} + ); + }) + .minHeight_(40).minWidth_(70), + + + + HLayout( + + VLayout( // parameters + StaticText().string_("frq"), + RangeSlider(nil,Rect(0,0,20,270)) + .minWidth_(70) .minHeight_(270) + .lo_(0) .hi_(0.11) + .action_({ | slider | + var minfreq, maxfreq; + minfreq = slider.lo.value.linexp(0, 1, 10, 15000); + maxfreq = slider.hi.value.linexp(0, 1, 10, 15000); + ~fhn2D.set(\minfreq, minfreq.value); + ~fhn2D.set(\maxfreq, maxfreq.value); + }), + + /* urate: 0.1, wrate: 0.1, + b0: 0.6, b1: 0.8, + i: 0, u0: 0, w0: 0, */ + StaticText().string_("urate"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 0.1 * 2); + ~fhn2D.set(\urate, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("wrate"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 0.1 * 2); + ~fhn2D.set(\wrate, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + nil + ), + + + VLayout( + + nil, + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("b0"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 0.6 * 2); + ~fhn2D.set(\b0, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("b1"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, 0, 0.8 * 2); + ~fhn2D.set(\b1, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("i"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, -1, 1); + ~fhn2D.set(\i, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("u0"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, -1, 1); + ~fhn2D.set(\u0, val); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("w0"), + Knob() .centered_(true) .value_(0.5) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ | val | + val = val.value.linlin(0, 1, -1, 1); + ~fhn2D.set(\w0, val); + }), + nil + + ), + + + VLayout( // gains and filters section + + StaticText().string_("OUT"), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("N"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~fhn2D.set(\ampN, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("L"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~fhn2D.set(\ampL, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("C"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~fhn2D.set(\ampC, amp); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("f"), + Knob() .value_(1) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({arg freq; + freq = freq.value.linexp(0, 1, 40, 20000); + ~fhn2D.set(\bpffreq, freq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().align_(\left).string_("q"), + Knob() .value_(0) .mode_(\horiz) .step_(0.003) .minHeight_(60).minWidth_(60) + .action_({ arg rq; + rq = abs(rq.value - 1); + rq = rq.value.linexp(0, 1, 0.1, 100); + ~fhn2D.set(\bpfrq, rq); + }), + + StaticText().maxHeight_(1).background_(Color.gray(0.1,0.2)), + StaticText().string_("A"), + Knob().value_(0).mode_(\horiz).step_(0.003).minHeight_(60).minWidth_(60) + .action_({ arg amp; + amp = amp.value.linexp(0, 1, 0.01, 1) - 0.01; + ~fhn2D.set(\amp, amp); + }), + nil + ) + ), + nil; +); + + + +// ------------------------------------------------------------------------------------------------- + +~tab_views[~tab_names.at("chaos")].layout.add(nil); + +// ------------------------------------------------------------------------------------------------- diff --git a/scd/gui_core.scd b/scd/gui_core.scd new file mode 100644 index 0000000..dff7008 --- /dev/null +++ b/scd/gui_core.scd @@ -0,0 +1,146 @@ +/* + part of: Interface Fractures III - Silicon + + (c) Luka Prinčič / Nova deViator + nova@deviator.si + + gui_core.scd - takes care of core GUI things: layouts, + tabs, window, sizes... + +********************************************************** */ + + + +// general color palette +QtGUI.palette = QPalette.dark; + +~screenWidth = 1348; +~screenHeight = 753; + +~pagerbuttonwidth = 90; +~pagerbuttonheight = 55; +~pagerbuttonpadding = 3; + +~pagerwidth = ~pagerbuttonpadding + ~pagerbuttonwidth * ~tabs.size - ~pagerbuttonpadding; +~pagerheight = ~pagerbuttonheight; + + +// make a window +w = Window.new( name: "Interface Fractures III", + bounds: Rect(0, 2, ~screenWidth, ~screenHeight), + //bounds: w.availableBounds, + resizable: true, + border: false, + server: s, + scroll: true +).front; +w.fullScreen; +postln("~~~ Created window ..." + w.bounds); +w.background_(Color.gray(0.2)); + + +~pager = View.new(w, Rect(0,0,100,100)) +.minHeight_(~pagerheight) +.minWidth_(~pagerwidth) +.background_(Color.gray(0.4,0.0)); + +~content = View.new(w, w.view.bounds) +.minWidth_(w.view.bounds.width - 2) +.minHeight_(w.view.bounds.height - ~pagerheight - 20) +.background_(Color.gray(0.3,0.2)); + +w.layout = VLayout( [~pager, align:\top], + [~content, align:\center], nil ); +w.layout.margins = 2; + +~pager.layout = HLayout();//margins=1; +~pager.layout.margins = 1; + +// CREATE TABS --------------------------------------------------------------- +~tabs = List["chaos", "granul", "players", "processing", "main"]; +~tab_btns = List(); +~tab_views = List(); +~tab_names = Dictionary.new; +//~tab_btns_view = View.new(); + +// go through all of tabs and make buttons and views +~tabs.do( + { |item, i| + + ~tab_names.put(item, i); + + // views / containers / pages - - - - - + ~tab_views.add( + View.new(~content,Rect(0, 0, 1344, 700)) + .background_(Color.gray(0.4,0.4)) + //.layout(HLayout) + .visible_(0); + + ); + + // buttons / tabs - - - - - + ~tab_btns.add( + //Button(~pager, Rect((~pagerbuttonpadding + ~pagerbuttonwidth * i), 0, ~pagerbuttonwidth, ~pagerbuttonheight)) + Button(~pager, Rect((~pagerbuttonpadding + ~pagerbuttonwidth * i), 0, ~pagerbuttonwidth, ~pagerbuttonheight)) + .states_([[item], + [item, Color.white, Color.gray(0.6)]]) + .action_({arg btn; + switch(btn.value, + 0, { postln("~~~ Hide:" + item); + ~tab_views[i].visible = 0; }, + 1, { ~tab_btns.do( + { |b_item,b_i| + if (b_i != i, { + ~tab_btns[b_i].enabled_(1); + ~tab_btns[b_i].valueAction = 0; + }) + }); + ~tab_btns[i].enabled_(0); + postln("~~~ Show:" + item + "\n"); + ~tab_views[i].visible = 1; + + }) + }) + .minHeight_(~pagerbuttonheight).minWidth_(~pagerbuttonwidth); + ); + } +); + + + + + + +// CLOSING //////////////////////////////////////////////////////////////////////// + +w.view.keyDownAction_({ |view, char, modifiers, unicode, keycode, key| + if (unicode == 27) { + postln("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"); + postln("~~~ Cought an ESC key. Closing window, freeing synths..."); + postln("~~~ Wait, let me see the window bounds:" + w.bounds + "!\n"); + + w.close; + postln("\n\n<<< So long and thanks for all the fish! >>>" + + "\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - "); + } +}); + + + +// free all UGens on server (stop sound, etc) +w.onClose_({ + postln("<<< Platform IDE:" + Platform.ideName); + s.freeAll; + + // when running 'standalone' from shell: + if (Platform.ideName == "none") { + postln("<<< ... sclang is killed. Stockhausen forgives you!"); + 0.exit; + } { + postln("<<< ... stopping Main."); + thisProcess.stop; + }; + postln("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"); +}); + + diff --git a/scd/gui_granul.scd b/scd/gui_granul.scd new file mode 100644 index 0000000..325b18f --- /dev/null +++ b/scd/gui_granul.scd @@ -0,0 +1,588 @@ +/* + part of: Interface Fractures III - Silicon + + (c) Luka Prinčič / Nova deViator + nova@deviator.si + + gui_granul.scd - takes care of all GUI elements under + the 'granul' tab... + +********************************************************** */ + + +~tab_views[~tab_names.at("granul")].layout = HLayout( + + VLayout( // left half starts here + + + //~tab_views[~tab_names.at("granul")].layout.add(nil); + + //~granSynth1 = View.new(~tab_views[~tab_names.at("granul")]); + //~granSynth1.background = Color.gray(0.5); + //~granSynth1.layout = HLayout( // vert. layout: + + // Synth starts here -------------------------------------------------------------------- + HLayout( + + VLayout( + + StaticText().string_("GRANULATOR"), + Button() + .states_([ + ["OFF", Color.gray(0.2), Color.gray(0.8)], + ["ON", Color.gray(0.8), Color.grey(0.2)] ]) + .mouseDownAction_({ + arg state; + state.value.postln; + if (state.value == 0) { + ~granSynth = Synth(\Granny, [\bufnum, b]); + } { + ~granSynth.free; + } + }) + .minHeight_(70) + .minWidth_(70), + nil + ), + + VLayout( + PopUpMenu().items_(["buffer1","file2","file3"]).font_(Font("Sans",20)), + StaticText().string_("Filter vs. Position"), + Slider2D() + .x_(0.05) + .y_(0.05) + .action_({ arg slider; + ~granSynth.set(\pos, slider.x); + ~granSynth.set(\lpfFreq, slider.y.value.linexp(0,1,30,20000,nil))}), + StaticText().string_("Position variation"), + Slider(nil,Rect(0,0,50,10)) + .minHeight_(20) + .thumbSize_(50) + .action_({ arg posvar; + posvar = posvar.value; + ~granSynth.set(\posvar, posvar.value); + }) + ), + + VLayout( + + StaticText().string_("Frequency of grains"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(50).thumbSize_(50) + .action_({ arg freq; + freq = ((freq.value * 200) + 1).asInt; + ~granSynth.set(\freq, freq.value); freq.value.postln; + ~nbf.value_(freq)}), + VLayout(nil, + ~nbf = NumberBox(nil,Rect(0,0,1,1)) + .font_(Font("Sans",20)) + .maxWidth_(50) + .minHeight_(30); + ) + ), + HLayout( + StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg fvar; + fvar = fvar.value * 2; + ~granSynth.set(\fvar, fvar.value); + }) + ), + nil, + StaticText().string_("Duration of grains"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(50).thumbSize_(50) + .action_({ arg dur; + dur = dur.value; + ~granSynth.set(\dur, dur.value); + ~nbd.value_((dur.value * 100).asInt); }), + VLayout(nil, + ~nbd = NumberBox(nil,Rect(0,0,1,1)) + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ), + HLayout(StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg durvar; + durvar = durvar.value * 2; + ~granSynth.set(\durvar, durvar.value); + }) + ), + nil, + StaticText().string_("Pitch"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(20).thumbSize_(50) + .action_({ arg pitch; + pitch = pitch.value * 2; + ~granSynth.set(\pitch, pitch.value); + ~nbp.value_(pitch.value); }), + VLayout(nil, + ~nbp = NumberBox() + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ), + HLayout(StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg pitchvar; + pitchvar = pitchvar.value; + ~granSynth.set(\pitchvar, pitchvar.value); + }) + ), + nil, + StaticText().string_("Width (Stereo)"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(20).thumbSize_(50) + .action_({ arg width; + width = width.value; + ~granSynth.set(\width, width.value); + ~nbw.value_(width.value); + }), + VLayout(nil, + ~nbw = NumberBox() + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ) + ), + VLayout( + StaticText().string_("Gain") + .align_(\center), + Slider(nil, Rect(0,0,1,2)) + .minWidth_(50) + .thumbSize_(50) + .action_({ arg gain; + ~granSynth.set(\gain, gain.value.linexp(0,1,0.01,10,nil)-0.01 * 0.05)}) + .valueAction_(0) + ; + ) + ), // synth ends here + + + + HLayout( // bottom left synth starts here -------------------------------------------------------------------- + + + VLayout( + + StaticText().string_("GRANULATOR"), + Button() + .states_([ + ["OFF", Color.gray(0.2), Color.gray(0.8)], + ["ON", Color.gray(0.8), Color.grey(0.2)] ]) + .mouseDownAction_({ + arg state; + state.value.postln; + if (state.value == 0) { + ~granSynth = Synth(\Granny, [\bufnum, b]); + } { + ~granSynth.free; + } + }) + .minHeight_(70) + .minWidth_(70), + nil + ), + + VLayout( + PopUpMenu().items_(["buffer1","file2","file3"]).font_(Font("Sans",20)), + StaticText().string_("Filter vs. Position"), + Slider2D() + .x_(0.05) + .y_(0.05) + .action_({ arg slider; + ~granSynth.set(\pos, slider.x); + ~granSynth.set(\lpfFreq, slider.y.value.linexp(0,1,30,20000,nil))}), + StaticText().string_("Position variation"), + Slider(nil,Rect(0,0,50,10)) + .minHeight_(20) + .thumbSize_(50) + .action_({ arg posvar; + posvar = posvar.value; + ~granSynth.set(\posvar, posvar.value); + }) + ), + + VLayout( + + StaticText().string_("Frequency of grains"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(50).thumbSize_(50) + .action_({ arg freq; + freq = ((freq.value * 200) + 1).asInt; + ~granSynth.set(\freq, freq.value); freq.value.postln; + ~nbf.value_(freq)}), + VLayout(nil, + ~nbf = NumberBox(nil,Rect(0,0,1,1)) + .font_(Font("Sans",20)) + .maxWidth_(50) + .minHeight_(30); + ) + ), + HLayout( + StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg fvar; + fvar = fvar.value * 2; + ~granSynth.set(\fvar, fvar.value); + }) + ), + nil, + StaticText().string_("Duration of grains"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(50).thumbSize_(50) + .action_({ arg dur; + dur = dur.value; + ~granSynth.set(\dur, dur.value); + ~nbd.value_((dur.value * 100).asInt); }), + VLayout(nil, + ~nbd = NumberBox(nil,Rect(0,0,1,1)) + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ), + HLayout(StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg durvar; + durvar = durvar.value * 2; + ~granSynth.set(\durvar, durvar.value); + }) + ), + nil, + StaticText().string_("Pitch"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(20).thumbSize_(50) + .action_({ arg pitch; + pitch = pitch.value * 2; + ~granSynth.set(\pitch, pitch.value); + ~nbp.value_(pitch.value); }), + VLayout(nil, + ~nbp = NumberBox() + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ), + HLayout(StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg pitchvar; + pitchvar = pitchvar.value; + ~granSynth.set(\pitchvar, pitchvar.value); + }) + ), + nil, + StaticText().string_("Width (Stereo)"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(20).thumbSize_(50) + .action_({ arg width; + width = width.value; + ~granSynth.set(\width, width.value); + ~nbw.value_(width.value); + }), + VLayout(nil, + ~nbw = NumberBox() + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ) + ), + VLayout( + StaticText().string_("Gain") + .align_(\center), + Slider(nil, Rect(0,0,1,2)) + .minWidth_(50) + .thumbSize_(50) + .action_({ arg gain; + ~granSynth.set(\gain, gain.value.linexp(0,1,0.01,10,nil)-0.01 * 0.05)}) + .valueAction_(0) + ; + ) + ); // bottom left synth ends here + ), // left half ends here + + VLayout( // right half starts here + + + // left top synth starts here -------------------------------------------------------------------- + HLayout( + + VLayout( + + StaticText().string_("GRANULATOR"), + Button() + .states_([ + ["OFF", Color.gray(0.2), Color.gray(0.8)], + ["ON", Color.gray(0.8), Color.grey(0.2)] ]) + .mouseDownAction_({ + arg state; + state.value.postln; + if (state.value == 0) { + ~granSynth = Synth(\Granny, [\bufnum, b]); + } { + ~granSynth.free; + } + }) + .minHeight_(70) + .minWidth_(70), + nil + ), + + VLayout( + PopUpMenu().items_(["buffer1","file2","file3"]).font_(Font("Sans",20)), + StaticText().string_("Filter vs. Position"), + Slider2D() + .x_(0.05) + .y_(0.05) + .action_({ arg slider; + ~granSynth.set(\pos, slider.x); + ~granSynth.set(\lpfFreq, slider.y.value.linexp(0,1,30,20000,nil))}), + StaticText().string_("Position variation"), + Slider(nil,Rect(0,0,50,10)) + .minHeight_(20) + .thumbSize_(50) + .action_({ arg posvar; + posvar = posvar.value; + ~granSynth.set(\posvar, posvar.value); + }) + ), + + VLayout( + + StaticText().string_("Frequency of grains"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(50).thumbSize_(50) + .action_({ arg freq; + freq = ((freq.value * 200) + 1).asInt; + ~granSynth.set(\freq, freq.value); freq.value.postln; + ~nbf.value_(freq)}), + VLayout(nil, + ~nbf = NumberBox(nil,Rect(0,0,1,1)) + .font_(Font("Sans",20)) + .maxWidth_(50) + .minHeight_(30); + ) + ), + HLayout( + StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg fvar; + fvar = fvar.value * 2; + ~granSynth.set(\fvar, fvar.value); + }) + ), + nil, + StaticText().string_("Duration of grains"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(50).thumbSize_(50) + .action_({ arg dur; + dur = dur.value; + ~granSynth.set(\dur, dur.value); + ~nbd.value_((dur.value * 100).asInt); }), + VLayout(nil, + ~nbd = NumberBox(nil,Rect(0,0,1,1)) + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ), + HLayout(StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg durvar; + durvar = durvar.value * 2; + ~granSynth.set(\durvar, durvar.value); + }) + ), + nil, + StaticText().string_("Pitch"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(20).thumbSize_(50) + .action_({ arg pitch; + pitch = pitch.value * 2; + ~granSynth.set(\pitch, pitch.value); + ~nbp.value_(pitch.value); }), + VLayout(nil, + ~nbp = NumberBox() + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ), + HLayout(StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg pitchvar; + pitchvar = pitchvar.value; + ~granSynth.set(\pitchvar, pitchvar.value); + }) + ), + nil, + StaticText().string_("Width (Stereo)"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(20).thumbSize_(50) + .action_({ arg width; + width = width.value; + ~granSynth.set(\width, width.value); + ~nbw.value_(width.value); + }), + VLayout(nil, + ~nbw = NumberBox() + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ) + ), + VLayout( + StaticText().string_("Gain") + .align_(\center), + Slider(nil, Rect(0,0,1,2)) + .minWidth_(50) + .thumbSize_(50) + .action_({ arg gain; + ~granSynth.set(\gain, gain.value.linexp(0,1,0.01,10,nil)-0.01 * 0.05)}) + .valueAction_(0) + ; + ) + ), // synth ends here + + + + HLayout( // bottom right synth starts here -------------------------------------------------------------------- + + + VLayout( + + StaticText().string_("GRANULATOR"), + Button() + .states_([ + ["OFF", Color.gray(0.2), Color.gray(0.8)], + ["ON", Color.gray(0.8), Color.grey(0.2)] ]) + .mouseDownAction_({ + arg state; + state.value.postln; + if (state.value == 0) { + ~granSynth = Synth(\Granny, [\bufnum, b]); + } { + ~granSynth.free; + } + }) + .minHeight_(70) + .minWidth_(70), + nil + ), + + VLayout( + PopUpMenu().items_(["buffer1","file2","file3"]).font_(Font("Sans",20)), + StaticText().string_("Filter vs. Position"), + Slider2D() + .x_(0.05) + .y_(0.05) + .action_({ arg slider; + ~granSynth.set(\pos, slider.x); + ~granSynth.set(\lpfFreq, slider.y.value.linexp(0,1,30,20000,nil))}), + StaticText().string_("Position variation"), + Slider(nil,Rect(0,0,50,10)) + .minHeight_(20) + .thumbSize_(50) + .action_({ arg posvar; + posvar = posvar.value; + ~granSynth.set(\posvar, posvar.value); + }) + ), + + VLayout( + + StaticText().string_("Frequency of grains"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(50).thumbSize_(50) + .action_({ arg freq; + freq = ((freq.value * 200) + 1).asInt; + ~granSynth.set(\freq, freq.value); freq.value.postln; + ~nbf.value_(freq)}), + VLayout(nil, + ~nbf = NumberBox(nil,Rect(0,0,1,1)) + .font_(Font("Sans",20)) + .maxWidth_(50) + .minHeight_(30); + ) + ), + HLayout( + StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg fvar; + fvar = fvar.value * 2; + ~granSynth.set(\fvar, fvar.value); + }) + ), + nil, + StaticText().string_("Duration of grains"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(50).thumbSize_(50) + .action_({ arg dur; + dur = dur.value; + ~granSynth.set(\dur, dur.value); + ~nbd.value_((dur.value * 100).asInt); }), + VLayout(nil, + ~nbd = NumberBox(nil,Rect(0,0,1,1)) + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ), + HLayout(StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg durvar; + durvar = durvar.value * 2; + ~granSynth.set(\durvar, durvar.value); + }) + ), + nil, + StaticText().string_("Pitch"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(20).thumbSize_(50) + .action_({ arg pitch; + pitch = pitch.value * 2; + ~granSynth.set(\pitch, pitch.value); + ~nbp.value_(pitch.value); }), + VLayout(nil, + ~nbp = NumberBox() + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ), + HLayout(StaticText().string_("variation"), + Slider(nil,Rect(0,0,2,1)).thumbSize_(50) + .action_({ arg pitchvar; + pitchvar = pitchvar.value; + ~granSynth.set(\pitchvar, pitchvar.value); + }) + ), + nil, + StaticText().string_("Width (Stereo)"), + HLayout( + Slider(nil,Rect(0,0,2,1)).minHeight_(20).thumbSize_(50) + .action_({ arg width; + width = width.value; + ~granSynth.set(\width, width.value); + ~nbw.value_(width.value); + }), + VLayout(nil, + ~nbw = NumberBox() + .font_(Font("Sans", 20)) + .maxWidth_(50) + .minHeight_(30);) + ) + ), + VLayout( + StaticText().string_("Gain") + .align_(\center), + Slider(nil, Rect(0,0,1,2)) + .minWidth_(50) + .thumbSize_(50) + .action_({ arg gain; + ~granSynth.set(\gain, gain.value.linexp(0,1,0.01,10,nil)-0.01 * 0.05)}) + .valueAction_(0) + ; + ) + ); // bottom right synth ends here + ); // right half ends here + +); + + +~tab_views[~tab_names.at("granul")].layout.margins = 2; diff --git a/scd/gui_main.scd b/scd/gui_main.scd new file mode 100644 index 0000000..745a4d5 --- /dev/null +++ b/scd/gui_main.scd @@ -0,0 +1,45 @@ +/* + part of: Interface Fractures III - Silicon + + (c) Luka Prinčič / Nova deViator + nova@deviator.si + + gui_main.scd - responsible for GUI elements under + the 'main' tab ... + +********************************************************** */ + + +~tab_views[~tab_names.at("main")].layout = HLayout( + + nil, + + VLayout( + + nil, + Button() + .states_([ + ["Clock"], + ["Clock", Color.gray(0.2), Color.grey(0.8)] ]) + .mouseDownAction_({ | state | + switch(state.value, + 0, { + postln("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - "); + postln("~~~ starting clock!"); + TempoClock.default.sched(0, ~mainTimeline); + ~mainTimeline.reset; + }, + 1, { + postln("\n~~~ stopping clock!"); + ~mainTimeline.stop; + //~mainTimeline.reset; + postln("~~~ some synths might still be running"); + } + ); + }) + .minHeight_(70).minWidth_(70), + + + nil), + nil); + diff --git a/scd/sdefs.scd b/scd/sdefs.scd new file mode 100644 index 0000000..48d8f64 --- /dev/null +++ b/scd/sdefs.scd @@ -0,0 +1,265 @@ +/* + part of: Interface Fractures III - Silicon + + (c) Luka Prinčič / Nova deViator + nova@deviator.si + + sdefs.scd - should contain most of SynthDefs ... + +********************************************************** */ + + + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// NOISE + +SynthDef(\StandardMap, { + arg out=0, minfreq=10, maxfreq=22, + k=1.4, x0=4.9789799812499, y0=5.7473416156381, + ampN=0, ampL=0, ampC=0, + amp=0, bpffreq=20000, bpfrq = 100 ; + var signal ; + + postln("~~~ Loading StandardMap to server..."); + + // poor man's stereo expander + minfreq = [minfreq, minfreq +1 ]; + maxfreq = [maxfreq, maxfreq -1 ]; + + /* Standard2DN.ar(minfreq: 11025, maxfreq: 22050, + k: 1.4, x0: 4.9789799812499, y0: 5.7473416156381, mul: 1, add: 0) */ + signal = Standard2DN.ar( minfreq, maxfreq, k, x0, y0, ampN ) + + Standard2DL.ar( minfreq, maxfreq, k, x0, y0, ampL ) + + Standard2DC.ar( minfreq, maxfreq, k, x0, y0, ampC ); + + // band pass filter // ----- BPF.ar(in: 0, freq: 440, rq: 1, mul: 1, add: 0) + signal = BPF.ar(in: signal, freq: bpffreq.min(bpffreq / bpfrq), rq: bpfrq); + + signal = signal * amp; + signal = signal.clip2(0.99); + Out.ar(out, signal) + +}).add; + + + + + +//Gbman2DN Gbman2DL Gbman2DC GbmanTrig +//(minfreq: 11025, maxfreq: 22050, x0: 1.2, y0: 2.1, mul: 1, add: 0) + + +SynthDef(\GbmanMap, { + arg out=0, minfreq=10, maxfreq=22, + x0=1.2, y0=2.1, + ampN=0, ampL=0, ampC=0, + amp=0, bpffreq=20000, bpfrq = 100 ; + var signal ; + + postln("~~~ Loading GbmanMap to server..."); + + // poor man's stereo expander + minfreq = [minfreq, minfreq +1 ]; + maxfreq = [maxfreq, maxfreq -1 ]; + + signal = Gbman2DN.ar( minfreq, maxfreq, x0, y0, ampN ) + + Gbman2DL.ar( minfreq, maxfreq, x0, y0, ampL ) + + Gbman2DC.ar( minfreq, maxfreq, x0, y0, ampC ); + + // band pass filter // ----- BPF.ar(in: 0, freq: 440, rq: 1, mul: 1, add: 0) + signal = BPF.ar(in: signal, freq: bpffreq.min(bpffreq / bpfrq), rq: bpfrq); + + signal = signal * amp; + signal = signal.clip2(0.99); + Out.ar(out, signal) + +}).add; + + +//Henon2DN +// a: 1.4, b: 0.3, +// x0: 0.30501993062401, y0: 0.20938865431933, + +SynthDef(\HenonMap, { + arg out=0, minfreq=10, maxfreq=22, + a = 1.4, b = 0.3, + x0 = 0.30501993062401, y0 = 0.20938865431933, + ampN=0, ampL=0, ampC=0, + amp=0, bpffreq=20000, bpfrq = 100 ; + var signal ; + + // poor man's stereo expander + minfreq = [minfreq, minfreq +1 ]; + maxfreq = [maxfreq, maxfreq -1 ]; + + signal = Henon2DN.ar( minfreq, maxfreq, a, b, x0, y0, ampN ) + + Henon2DL.ar( minfreq, maxfreq, a, b, x0, y0, ampL ) + + Henon2DC.ar( minfreq, maxfreq, a, b, x0, y0, ampC ); + + // band pass filter // ----- BPF.ar(in: 0, freq: 440, rq: 1, mul: 1, add: 0) + signal = BPF.ar(in: signal, freq: bpffreq.min(bpffreq / bpfrq), rq: bpfrq); + + signal = signal * amp; + signal = signal.clip2(0.99); + Out.ar(out, signal); + + postln("~~~ Loading HenonMap to server..."); + +}).add; + + +SynthDef(\LatoocarfianMap, { + + /* a: 1, b: 3, c: 0.5, d: 0.5, + x0: 0.34082301375036, y0: -0.38270086971332, */ + + arg out=0, minfreq=10, maxfreq=22, + a = 1, b = 3, c = 0.5, d = 0.5, + x0 = 0.34082301375036, y0 = -0.38270086971332, + ampN=0, ampL=0, ampC=0, + amp=0, bpffreq=20000, bpfrq = 100 ; + var signal ; + + // poor man's stereo expander + minfreq = [minfreq, minfreq +1 ]; + maxfreq = [maxfreq, maxfreq -1 ]; + + /* Latoocarfian2DN.ar(minfreq: 11025, maxfreq: 22050, + k: 1.4, x0: 4.9789799812499, y0: 5.7473416156381, mul: 1, add: 0) */ + signal = Latoocarfian2DN.ar( minfreq, maxfreq, a, b, c, d, x0, y0, ampN ) + + Latoocarfian2DL.ar( minfreq, maxfreq, a, b, c, d, x0, y0, ampL ) + + Latoocarfian2DC.ar( minfreq, maxfreq, a, b, c, d, x0, y0, ampC ); + + // band pass filter // ----- BPF.ar(in: 0, freq: 440, rq: 1, mul: 1, add: 0) + signal = BPF.ar(in: signal, freq: bpffreq.min(bpffreq / bpfrq), rq: bpfrq); + + signal = signal * amp; + signal = signal.clip2(0.99); + Out.ar(out, signal); + + postln("~~~ Loading LatoocarfianMap to server..."); + +}).add; + + + + +/* + s: 10, r: 28, b: 2.6666667, h: 0.02, + x0: 0.090879182417163, y0: 2.97077458055, z0: 24.282041054363, */ + +SynthDef(\LorenzMap, { + + /* a: 1, b: 3, c: 0.5, d: 0.5, + x0: 0.34082301375036, y0: -0.38270086971332, */ + + arg out=0, minfreq=10, maxfreq=22, + s = 10, r = 28, b = 2.6666667, h = 0.02, + x0 = 0.090879182417163, y0 = 2.97077458055, z0 = 24.282041054363, + ampN=0, ampL=0, ampC=0, + amp=0, bpffreq=20000, bpfrq = 100 ; + var signal ; + + // poor man's stereo expander + minfreq = [minfreq, minfreq +1 ]; + maxfreq = [maxfreq, maxfreq -1 ]; + + signal = Lorenz2DN.ar( minfreq, maxfreq, s, r, b, h, x0, y0, z0, ampN ) + + Lorenz2DL.ar( minfreq, maxfreq, s, r, b, h, x0, y0, z0, ampL ) + + Lorenz2DC.ar( minfreq, maxfreq, s, r, b, h, x0, y0, z0, ampC ); + + // band pass filter // ----- BPF.ar(in: 0, freq: 440, rq: 1, mul: 1, add: 0) + signal = BPF.ar(in: signal, freq: bpffreq.min(bpffreq / bpfrq), rq: bpfrq); + + signal = signal * amp; + signal = signal.clip2(0.99); + Out.ar(out, signal); + + postln("~~~ Loading LorenzMap to server..."); + + + +}).add; + + +/* urate: 0.1, wrate: 0.1, + b0: 0.6, b1: 0.8, + i: 0, u0: 0, w0: 0, */ + + +SynthDef(\FhnMap, { + + + arg out=0, minfreq=10, maxfreq=22, + urate = 0.1, wrate = 0.1, + b0 = 0.6, b1 = 0.8, + i = 0, u0 = 0, w0 = 0, + ampN=0, ampL=0, ampC=0, + amp=0, bpffreq=20000, bpfrq = 100 ; + var signal ; + + // poor man's stereo expander + minfreq = [minfreq, minfreq +1 ]; + maxfreq = [maxfreq, maxfreq -1 ]; + + signal = Fhn2DN.ar( minfreq, maxfreq, urate, wrate, b0, b1, i, u0, w0, ampN ) + + Fhn2DL.ar( minfreq, maxfreq, urate, wrate, b0, b1, i, u0, w0, ampL ) + + Fhn2DC.ar( minfreq, maxfreq, urate, wrate, b0, b1, i, u0, w0, ampC ); + + // band pass filter // ----- BPF.ar(in: 0, freq: 440, rq: 1, mul: 1, add: 0) + signal = BPF.ar(in: signal, freq: bpffreq.min(bpffreq / bpfrq), rq: bpfrq); + + signal = signal * amp; + signal = signal.clip2(0.99); + Out.ar(out, signal); + + + postln("~~~ Loading FhnMap to server..."); + + +}).add; + + + + +// GRANULATORS + + +SynthDef(\Granny, { + + arg bufnum, + freq = 10, fvar = 1, + dur = 0.1, durvar = 0, + pos = 0, posvar = 0, + pitch = 1, pitchvar = 0, + width = 0.2, + gain = 0.5, + lpfFreq = 400 + ; + var signal; + + signal = GrainBuf.ar( + numChannels: 2, // we want stereo! + trigger: Impulse.kr(freq + (freq * (fvar * LFNoise2.kr(freq)))), // a UGen? + dur: dur + (durvar * LFNoise2.kr(freq)), // in seconds + sndbuf: bufnum, + rate: pitch + (pitchvar * LFNoise2.kr(5)), // pitch !! WHAT IS THE SPEED OF VARIATIONS? setable?? + pos: pos + (posvar * LFNoise2.kr(freq)), // position 0-1 + interp: 2, // interpolation for pitchshifting + pan: LFNoise1.kr(10).range(width.neg, width), // if numChannels=2, similar to Pan2, -1 left, +1 right + // envbunum: -1, // the buffer number cont. grain envelope + maxGrains: 512, + mul: gain, + add: 0 + ); + + signal = LPF.ar( + in: signal, + freq: lpfFreq); + + Out.ar(0, signal); + + postln("~~~ adding SynthDef: Granny ..."); + +}).add; + diff --git a/scd/snd_lines.scd b/scd/snd_lines.scd new file mode 100644 index 0000000..6cb3730 --- /dev/null +++ b/scd/snd_lines.scd @@ -0,0 +1,402 @@ +/* + part of: Interface Fractures III - Silicon + + (c) Luka Prinčič / Nova deViator + nova@deviator.si + + snd_lines.scd - deals with converting spectral lines + of silicon into sound in time... + +********************************************************** */ + +var dir = PathName(thisProcess.nowExecutingPath).pathOnly; +var siLines = FileReader.read(path: dir +/+ "../dev/silicon_lines.txt", skipBlanks:true, skipEmptyLines:true); + + + +( ///////////////////////////////////////////////////////////////////////////////////////////// + + +// split function: +// 1) List-generation +// 2) draw the spectrum/score +// add 3) synth uses generated List + +~siLinesData = List[]; + +~printLines = { + + var dir = PathName(thisProcess.nowExecutingPath).pathOnly; + var siLines = FileReader.read(path: dir +/+ "../dev/silicon_lines.txt", skipBlanks:true, skipEmptyLines:true); + var intensity, minutes, seconds, freq1, freq2, midi1, midi2, red, green, blue; + var colors = [ // these are taken from http://astro.u-strasbg.fr/~koppen/discharge/discharge.html + [ 3800.0, 0, 0, 0], + [ 4000.0, 150, 0, 150], + [ 4400.0, 120, 0, 255], // violet + [ 4500.0, 0, 0, 255], // blue + [ 4800.0, 0, 255, 255], // cyan + [ 5200.0, 0, 255, 0], // green + [ 5800.0, 255, 255, 0], // yellow + [ 6500.0, 255, 0, 0], // red + [ 7000.0, 80, 0, 0], + [ 7300.0, 0, 0, 0] ]; + + // + var threshold = 0; + var linewidth = 3; + var spectrumheight = 750; + var colorpenlen = 40; + var siLinesData = List.newClear(0); + + + + var w = Window("TempSpectre", Rect(600, 5, width:560, height:spectrumheight)); + w.view.background_(Color.black); + w.drawFunc = { + + siLinesData = List.newClear(0); + + spectrumheight = w.bounds.height; + Pen.smoothing_(false); + Pen.translate(0,0); + + Pen.fillColor = Color.white; + Pen.fillRect(Rect(colorpenlen * 3, 0, w.bounds.width - (colorpenlen * 3), spectrumheight)); + + // function that prints a table of data from lines and draws a window with lines + ~processItem = { |item, i, reverse=false, layer=0, tscale=1, toffset=0| + + // if(i == 0, { post("\n--- processing spectrum ...\n")}); // nice output + + if((item[1].asInt > threshold) && (item[0].asInt < 6741) && (item[0].asInt > 3950), { + var peny, penx; + var alpha = item[1].asFloat.linlin(0, 1000, 10, 255); + var color; + var time, time_end = 60*37+5; + + + // wavelength + //post(item[0]); + //post("nm"); + + // intensity + intensity = item[1].asInt; + //post(item[1].asString.padLeft(5, " ")); + //post(" "); + + // time + if(reverse == false, + // then + { time = (item[0].asFloat.linlin(3950, 6741, 0, time_end)); }, + // else: + { time = (item[0].asFloat.linlin(3950, 6741, time_end, 0)); } ); + time = time * tscale ; + time = time + (toffset * time_end); + + minutes = (time / 60).round(1); + seconds = (time % 60).round(1); + /* + post(time.round(0.001) + ""); + if ( minutes < 10, {post("0")}); + post(minutes); + post(":"); + + if(seconds < 10, {post("0")}); + post(seconds); + post(" "); + */ + + + //freq1 + freq1 = item[0].asFloat.linexp(3900, 7200, 16000, 40 ).asInt; + freq1 = freq1.asString.padLeft(5, " "); + // post(freq1); post("hz"); post(" "); + + // freq2 + freq2 = item[0].asFloat.linexp(3900, 7200, 40, 16000 ).asInt; + freq2 = freq2.asString.padLeft(5, " "); + // post(freq2); post("Hz"); post(" "); + + // midi + midi1 = item[0].asFloat.linlin(3900, 7200, 0, 12 ).round(0.01); + // post(midi1.asString.padRight(5, " ")); + // post(" "); + + midi2 = item[0].asFloat.linlin(3900, 7200, 12, 0 ).round(0.01); + // post(midi2.asString.padRight(6, " ")); + + colors.do({ |colordb, i| + var thisboundary = colors[i][0]; + if (i+1 < colors.size, { + var nextboundary = colors[i+1][0]; + if ((item[0].asFloat > thisboundary) && (item[0].asFloat < nextboundary), { + + var range = nextboundary - thisboundary; + var koef = (item[0].asFloat-thisboundary / range).round(0.0001); + var red = colors[i][1] + ( ( (colors[i+1][1] - colors[i][1]) / (colors[i+1][0] - colors[i][0]) ) + * (item[0].asFloat - colors[i][0]) ); + var green = colors[i][2] + ( ( (colors[i+1][2] - colors[i][2]) / (colors[i+1][0] - colors[i][0]) ) + * (item[0].asFloat - colors[i][0]) ); + var blue = colors[i][3] + ( ( (colors[i+1][3] - colors[i][3]) / (colors[i+1][0] - colors[i][0]) ) + * (item[0].asFloat - colors[i][0]) ); + var color = Color.new255(red.round(1),green.round(1),blue.round(1), alpha); + var colorHSV = color.asHSV; + peny = time.linlin(0, time_end, 0, spectrumheight); + penx = 2 - layer * colorpenlen; + + Pen.fillColor = color; + Pen.fillRect(Rect(penx, peny, colorpenlen, alpha.linlin(0,255,1,linewidth))); + Pen.fillColor = Color.black.alpha_(alpha.linlin(0,255,0,1)); + Pen.fillRect(Rect( colorpenlen*3, peny, + w.bounds.width - (colorpenlen * 3) * intensity.linlin(0,1000,0,1), + alpha.linlin(0,255,1,linewidth))); + Pen.stroke; // draw the path + + /* + post("R"); + post( red.round(1)); + post(" G"); + post(green.round(1)); + post(" B"); + post( blue.round(1)); + + post(" H"); + post((colorHSV[0]*360).round(1)); + post(" S"); + post((colorHSV[1]*100).round(1)); + post(" V"); + post((colorHSV[2]*100).round(1)); + post(" A"); + post((colorHSV[3]*100).round(1)); + post(""); + */ + + // add line data as a List to the siLinesData List + ~siLinesData.add(List[ + time, + layer, + item[0], + intensity, + freq1, freq2, + midi1, midi2, + // R, G, B, + red.round(1), green.round(1), blue.round(1), + // H, S, V, Alpha + (colorHSV[0] * 360).round(1), // hue + (colorHSV[1] * 100).round(1), // saturation + (colorHSV[2] * 100).round(1), // value + (colorHSV[3] * 100).round(1), // ALPHA + item[0] + ]); + + + }); + + + }); + + }); + //post("\n"); + + }); + + }; // end of function + + + + siLines.do({ |item, i| ~processItem.value(item, i, layer:0); }); + + siLines.do({ | item, i| ~processItem.value(item, i, layer:1, reverse:true, + tscale:0.618); }); + + siLines.do({ | item, i| ~processItem.value(item, i, layer:1, reverse:true, + tscale: 0.618.squared, toffset:0.618); }); + + siLines.do({ | item, i| ~processItem.value(item, i, layer:2, reverse:false, + tscale: 0.618.cubed, toffset:(0.618.squared-0.618.cubed)+0.618); }); + + }; // end of drawFunc + + w.refresh; + w.front; + + + siLinesData; + +}; + +// execute it +~siLinesData = ~printLines.value; + + + +// table of all data, sorted +~siLinesData = ~siLinesData.sortBy(0); +~siLinesData.do({ |item, i| + post(i + ""); + item.do({ |value, i| + post(value); + post(" "); + + }); + post("\n"); +}); + + + +) + + + + + +// move to sdefs.scd at one point? -------------------------------------------- +SynthDef(\siliconSynth, { |freq = 440, amp = 0.2, attack = 1, release = 1| + + var sig, env, frequency, amply; + + frequency = [freq * 1.005, freq]; + amply = amp * 0.3; + + env = EnvGen.kr(Env.perc(attack, release, 1, [10, -10]), doneAction: 2); // ENVELOPE + + sig // ----------------------------------------------------------------------------------------- + = SinOsc.ar( freq: frequency, mul: amply * 0.9) + + SinOsc.ar( freq: frequency * 0.5 * LFNoise1.kr(0.1).linlin(-1, 1, 0.998, 1.002), mul: amply) + + SinOsc.ar( freq: frequency * 0.25 * LFNoise1.kr(0.1).linlin(-1, 1, 0.998, 1.002), mul: amply) + + + Saw.ar( freq: frequency * LFNoise1.kr(0.1).linlin(-1, 1, 0.998, 1.002), mul: amply * 0.5) + + Saw.ar( freq: frequency * 0.5 * LFNoise1.kr(0.1).linlin(-1, 1, 0.998, 1.002), mul: amply * 0.5) + + Saw.ar( freq: frequency * 0.25 * LFNoise1.kr(0.1).linlin(-1, 1, 0.998, 1.002), mul: amply * 0.5) + + + Pulse.ar( freq: frequency * LFNoise1.kr(0.1).linlin(-1, 1, 0.998, 1.002), mul: amply * 0.5) + + Pulse.ar( freq: frequency * 0.5 * LFNoise1.kr(0.1).linlin(-1, 1, 0.998, 1.002), mul: amply * 0.5) + + Pulse.ar( freq: frequency * 0.24 * LFNoise1.kr(0.1).linlin(-1, 1, 0.998, 1.002), mul: amply * 0.5) + + + BPF.ar(BrownNoise.ar(), freq: frequency * LFNoise1.kr(0.01).linlin(-1, 1, 0.8, 1.2), rq: 0.1) + + BPF.ar(WhiteNoise.ar(), freq: frequency * 0.5 * LFNoise1.kr(0.01).linlin(-1, 1, 0.8, 1.2), rq: 0.1) + + + BPF.ar(Crackle.ar(SinOsc.kr(0.1).linlin(-1, 1, 0.8, 2)), frequency * LFNoise1.kr(0.01).linlin(-1, 1, 0.8, 1.2), rq:0.1, mul:2) + + BPF.ar(Crackle.ar(SinOsc.kr(0.1).linlin(-1, 1, 0.8, 2)), frequency * 0.5 * LFNoise1.kr(0.01).linlin(-1, 1, 0.8, 1.2), rq:0.1, mul:2) + + ; // ------------------------------------------------------------------------------------------- + + sig = sig * env; // envlope the final sound + Out.ar(0, sig); // output + postln("\n~~~ adding SynthDef: siliconSynth ..."); +}).add; +// ----------------------------------------------------------------------------- + + +postln("~~~ loading mainTimeline routine"); + +~mainTimeline = Routine({ + + var delta, playhead, frequency, amp, step=0, + nextdelta, nextplayhead, nextfrequency, nextamp, + frequency_alt, nextfrequency_alt; + + while { + + step < siLines.size; + + } { + // exposition + frequency = siLines[step][0].asFloat.linexp(3900, 7200, 16000, 40); + frequency_alt = siLines[step][0].asFloat.linexp(3900, 7200, 40, 16000); + nextfrequency = siLines[step+1][0].asFloat.linexp(3900, 7200, 16000, 40); + nextfrequency_alt = siLines[step+1][0].asFloat.linexp(3900, 7200, 40, 16000); + nextplayhead = siLines[step+1][0].asFloat.linlin(3905.52, 7193.9, 0, (60*37+5)); + playhead = siLines[step][0].asFloat.linlin(3905.52, 7193.9, 0, (60*37+5)); + delta = nextplayhead - playhead; + amp = siLines[step][1].asInt * 0.001; + nextamp = siLines[step+1][1].asInt * 0.001; + nextdelta = siLines[step+2][0].asFloat.linlin(3905.52, 7193.9, 0, (60*37+5)) - nextplayhead; + + //action::documentation + post("\n~" + step + "| "); + post((playhead/60).round(1)); + post(":"); + post((playhead%60).round(1)); + post(" | "); + post(siLines[step][0]); + post( "nm | " ); + post(frequency.round(1)); + post("Hz | "); + post(frequency_alt.round(1)); + post("Hz | "); + post(amp.ampdb.round(1)); + post("dB \\ "); + post(delta.round(1)); + postln("s"); + + post(" "); + post(delta.round(1)); + post("s / "); + post(nextfrequency.round(1)); + post("Hz | "); + post(nextfrequency_alt.round(1)); + post("Hz | "); + post(nextamp.ampdb.round(1)); + post("dB \\ "); + post(nextdelta.round(1)); + postln("s"); + + Synth(\siliconSynth, [ + freq: nextfrequency, + amp: nextamp, + attack: delta, + release: nextdelta + ]); + + Synth(\siliconSynth, [ + freq: nextfrequency_alt, + amp: nextamp, + attack: delta, + release: nextdelta + ]); + + // epilogue + step = step + 1; + delta.yield; + + } + +}); + + +TempoClock.default.tempo = 1; // beats/sec /BPS + + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DEBUG +//~siLines = FileReader.read(path:"../dev/silicon_lines.txt", skipBlanks:true, skipEmptyLines:true); +//~siLines[124][0].postln; +//siLines.size.postln; +//r.next; +//r.stop; + + // if (siLines[step-1].notNil, { + // playhead = siLines[step-1][0].asFloat.linlin(3900, 7200, 0, (60*37+5)); // at the end these are seconds! + // }, { playhead = 0 }); + // nextdelta = siLines[step][0].asFloat.linlin(3900, 7200, 0, (60*37+5)) - playhead; + // delta = playhead - prevplayhead; + // prevplayhead = playhead; + +/* + post("t:" + item[0].asFloat.linlin(3900, 7200, 0, 12 ).asStringPrec(5) + Char.tab ); // tone + post("t:" + item[0].asFloat.linlin(3900, 7200, 12, 0 ).asStringPrec(5) ); // tone reverse + + //{SinOsc.ar((item[0].asFloat.linlin(3900, 7200, 0, 12)+60).midicps, mul:item[1].asInt * 0.000005)}.play; + /*{LFPar.ar(( + item[0].asFloat.linlin(3900, 7200, 0, 12) + + ( ( (i+1) % 1) * 12) + 60).midicps, + mul:(item[1].asInt.linlin(0, 1000, 0.0, 0.5) + item[1].asInt.linexp(0, 1000, 0.01, 0.5)) * [i%2,abs(i%2-1)] * 0.05)}.play; + */ + //{SinOsc.ar(item[0].asFloat.linexp(3900, 7200, 20000, 40 ).asInt, mul:item[1].asInt * 0.000005)}.play; + {SinOsc.ar(item[0].asFloat.linexp(3900, 7200, 20000, 40).asInt, mul:item[1].asInt * 0.00005)}.play; +*/ + + +