Grids: an object oriented approach

posted by on 2016.04.07, under Processing
07:

I have been working recently on a small audio-visual installation based essentially on grid manipulations, inspired by the art of the amazing Casey Reas.
Grids are some of the first interesting repetitive structures one learns to build. For instance, a one parameter function which displays a regular grid of rectangles maximising the surface of the screen used might look like this

void grid(int n){
float stepx = width/n;
float stepy = height/n;

for (int x = 0; x < width; x+=stepx){
   for (int y = 0; y < height; y+=stepy){
    rectMode(CENTER);
    noStroke();
    fill(255);
    rect(x + stepx/2.0, y + stepy/2.0, 20, 20);
    }
  }
}

It will produce a grid of equally spaced white rectangles (so, better set the background to black before in your code). This is all fun and cosy for a couple of milliseconds, but if you are like me, you will look immediately for possibilities of explorations, and honestly the bit of code above doesn’t offer much. Let’s be precise: it *can* offer a lot of ways of tweaking, but they become cumbersome very very quickly. Also, I like to write codes which are conceptually structural and modular, and which allow to separate more clearly the “data holding” part from its representation. I find that this helps a lot the sense of surprise I get from playing with my newly created tool/toy. For instance, all that white is boring: how about we assign a different color to each rectangle? Not randomly though, which would be very cheap. Let’s use an image as a palette, and have each rectangle carry the color of the image pixel at the center of the rectangle. This can be attained by introducing the following line

fill(img.pixels[x + y * width]);

where img is the PImage variable holding your image (which I assume you have resized to the screen width and height, unless you have a fetish for ArrayOutOfBound messages :) ). Nice. But I guess you still can’t see my point, of course. Okay, let’s do the same but with a video. Now the image is changing at each frame, so the function grid() must be called in the animation loop, i.e. inside draw(). Here you can see my point: by proceding in this way, you are doing a certain amount of redundant computations. Indeed, the only thing that you would like to modify in this case is how each node of the grid is represented, and *not* the grid structure itself. So, it helps then to think of a grid as a data holder for the positions of its nodes, which, once we require some extra properties, are directly determined by a single integer n, the number of nodes per row and column. What we draw on the screen is then a representation of this bunch of information. Anytime you have something that behaves like a collection of data, object oriented programming (OOP) is not far from sight. Building objects (or rather classes) is kind of an art: extracting the relevant properties we want in our objects so that further manipulation becomes reactive and enjoyable is not an easy task. This to say that the are some basic rules in object oriented programming, but for artistic reason we can (and should) ignore many standard design patterns, and look at each case separately. Since I like thinking in terms of objects when programming, I feel the following warning is due: do *not* overuse OOP! There are fantastic pieces of algorithmic/generative art which do not use objects at all. The point is that you might run the risk to decompose the problem in its atomic parts, which has a certain intellectual appeal, no doubt, but then get lost when it comes to exploration and tweaking. So, case by case, see what works best, and, most importantly, what puts you in that spot where you can still get surprised. This said, let’s move on.
So, we can model a grid with the following Grid class

class Grid {
  int n;
  float[] posx;
  float[] posy;
  float offsetx;
  float offsety;
  Shape[] shapes = {};
 
  Grid(int _n){
    n = _n;
    int stepx = width/n;
    int stepy = height/n;
    offsetx = stepx/2.0;
    offsety = stepy/2.0;
    posx = new float[n];
    posy = new float[n];
   
    for (int i = 0; i < n; i++){
      posx[i] = i * stepx;
      posy[i] = i * stepy;
    }

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
        shapes = (Shape[]) append(shapes,new Shape(posx[i], posy[j]));
        }
      }

    }
   
    Grid(int _n, float _offsetx, float _offsety){
    n = _n;
    int stepx = width/n;
    int stepy = height/n;
    offsetx = _offsetx;
    offsety = _offsety;
    posx = new float[n];
    posy = new float[n];
   
    for (int i = 0; i < n; i++){
      posx[i] = i * stepx;
      posy[i] = i * stepy;
    }

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
        shapes = (Shape[]) append(shapes,new Shape(posx[i], posy[j]));
        }
      }

    }
   
    Grid(int _n, float len, float _offsetx, float _offsety){
    n = _n;
    int stepx = int(len/n);
    int stepy = int(len/n);
    offsetx = _offsetx;
    offsety = stepy;
    posx = new float[n];
    posy = new float[n];
   
    for (int i = 0; i < n; i++){
      posx[i] = i * stepx;
      posy[i] = i * stepy;
    }

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
        shapes = (Shape[]) append(shapes,new Shape(posx[i], posy[j]));
        }
      }

    }  
   
    void display(){
      pushMatrix();
      translate(offsetx, offsety);

      for (int i = 0; i < shapes.length; i++){
        shapes[i].display(20);
      }

      popMatrix();
    }
   
    void display(PImage _img){
      _img.loadPixels();
      pushMatrix();
      translate(offsetx, offsety);

      for (int i = 0; i < shapes.length; i++){
        shapes[i].setColor(_img.pixels[int(shapes[i].x) + int(shapes[i].y) * _img.width]);
        shapes[i].display(20);
      }

      popMatrix();
    }
   
  }

So, you can see that I have heavily used that you can overload constructors and methods, so to give some default behaviours when we don’t want to bother passing a lot of parameters. An instance of Grid will also carry an array of Shape objects: this is the “representational” informations of our grid. Here’s how the Shape class looks like:

class Shape {
  float x, y;
  color c;
 
  Shape(float _x, float _y){
    x = _x;
    y = _y;
    c = color(255, 255, 255);
  }
 
  Shape(float _x, float _y, color _c){
    x = _x;
    y = _y;
    c = _c;
  }
 
  void display(float w){
    rectMode(CENTER);
    noStroke();
    fill(c, 255);
    rect(x, y, w , w);
    rectMode(CORNER);
  }
 
  void setColor(color _c){
    c = _c;
  }
 
}

If you don’t specify any color, the rectangle will be white.
So, now the previous function grid() is subsumed in the following lines of code

Grid grid = new Grid(20);
grid.display(img);

Apart from the elegance of it, that as I mentioned before should not be the only criterion of judgement, the code now is amenable to vast explorations. For instance, by modifying the display() method of the Shape class we can completely change the appearance of our grid, even so much that it doesn’t look like a grid anymore! Moreover, we don’t have all those redundant computations to be made.
One thing that comes to mind when you have a class is that you can produce many objects from that class with slightly different properties. In this case I have decided to use this expedient in order to explore “fractalization”, which is another (made up?) word for “apply recursion carefully”. Add the following function to your code

void fractalize(int n){
  if (n > 1){
  grid = new Grid(n, x, y);
  grid.display();
  x+= grid.offsetx;
  y+= grid.offsety;
  fractalize(n - 1);
  }
}

To make the most of it, you might want to lower the alpha of the filling for the rectangles. Actually, as I mentioned before, we can start exploring the code and the questions it naturally suggests, like: “why restrict ourselves to rectangles?” Or “why even filling them?” “Can I add some stochastic noise here and there to make everything not so hearthless and rigid?” “What is the meaning of life?”
When you start raising these questions, a vast playground (or/and a deep existential pit) opens up.
Believe it or not, after very few adjustments to the Shape class here’s what I got

1

1

which I find having an interesting balance between structure and randomness. A nice surprise! :)

Noise, flows and generative art

posted by on 2016.03.26, under Processing
26:

What is and what isn’t generative art is a long standing debate, in which I do not want to enter here. Just to put things in context, though, I’ll share some words about it. For some people, a piece of art is generative if it is the product of some sort of system which, once set in motion, is left to itself, with no further interaction. These systems are also called autonomous. Though generative art is usually associated to algorithmic art, i.e. art generated by some computer algorithm, autonomous systems can be found in biology, chemistry, mechanics, etc. Personally, I find the constraint on the autonomy of the system a bit too tight. While I do think that autonomous systems produce fascinating pieces of art, hence showing the beauty of complexity and emergency, I’m also very much interested in the dichotomy creator/tool, which in this case manifests itself as a shadow of the interaction between human and machine. I’m thinking about art which is computer assisted, more specifically which arises from the interaction of some sort of (algorithmic) system with the creator/spectator. This interaction poses interesting questions. We can indeed consider the total generative system as the combination autonomous system + spectator. This would be an autonomous system itself, if not for one little detail: the spectator is aware (whatever that means) that he’s a tool of a machine which is producing a piece of art. A more concrete example would be the following. Consider a live art installation in which the movements of spectators are used to control some given parameters of a system, which is then used to draw on a big screen, or produce sounds. There is going to be a huge conceptual difference if the spectators are aware of the tracking of their movements or not. In the second case, we are in the presence of something which looks like an autonomous system, while in the first case the spectators could use their awareness to drive the artistic outcome. The topic is incredibly fascinating and worth thinking about: these few words were only meant as a support to the fact that I would consider as generative art* the piece that you are going to see in the following.
Since discussions surrounding art are not notoriously controversial enough, I’ll move to noise and randomness (yeeeih!). Let’s start with saying: you can’t generate random numbers with a computer. Behind any random number produced with a programming language, there is an algorithm: in general it is a very complicated one and takes as parameter physical parameters of your machine (say, the speed of the CPU at the moment you request a random number), but it is still an algorithm. It is just so complex that we (as humans) can’t see any logical pattern behind it. I already feel the objection coming: “Well, what is randomness anyway? Is there anything truly random?”. I’m going to skip this objection quickly, pointing here instead. Enjoy! 😉
Processing offers two functions to treat randomness and noise: one is random(), and the other is noise(). Actually, noise() is a function that reproduces Perlin noise, a type of gradient noise which is extremely useful to reproduce organic textures.
Though Perlin noise is great, no doubt about that, and since randomness for a machine is just a function which looks unpredictable, why not make one’s own noise? After all, one of the point of generative art is that it allows to build tools which can be played with and explored. The function customNoise() in the code below does exactly that: it is a function from -1 to 1 which behaves in an erratic enough way to be a good substitute for noise(). You have now got your very own noise function, well done! The question is: what are we going to do with that? That’s where the second noun in the title of this post enters the stage. Every time you have a nice function in two variables, you can build out of it a vector field. “What’s that?”, you might say. You can think of it as an assignment of a little arrow to each point of the screen, with the angle (in this case) respect to the x-axis determined by our noise function. Once we have such a little arrow, we can use it to tell a particle which is at a given position on the screen where to go next. You can imagine the vector field as being associated to a fluid which at each point moves exactly with velocity given by the value of the vector field. If you then drop tiny particles in the fluid, they will start moving along curves, which are called the flow curves of the vector field. Moreover, they will start accumulate along specific flow curves: I leave you to investigate why it is that. 😉
So, the following Processing code brings home all these ideas, plus a last one, which has to do with the beginning of this post. You will notice that the function customNoise() has a mouseX inside, and there’s a mouseY controlling the variable depth. This means that the function interacts with the mouse movement, and hence the output of the code can be driven by the user. In particular, the piece you get stays comfortably in that gray area between generative and nongenerative art, one of those interesting arguments you can entertain your friends with at the next vernissage or pub quiz you go. 😉
Here’s the code:

float[] x;
float[] y;
color[] col;
float s = 0.001;
float depth = 0.5;
PImage img;

void setup() {
  size(1000, 1000);
  background(0);
  int n = 1000;
  x = new float[n];
  y = new float[n];
  col = new color[n];
  img = loadImage(pathtoimage/image);
  img.resize(width, height);
  img.loadPixels();
  for (int i = 0; i < x.length; i++) {
    x[i]= random(0, width);
    y[i]= random(0, height);
    int loc = int(x[i]) + int(y[i])*width;
    col[i] = img.pixels[loc];
  }
}

void draw() {
  noStroke();
  depth = map(mouseY, 0, height, 0.5, 1.5);
  //fill(255, 4); //Uncomment if you don't want to use an image;
  for (int i = 0; i < x.length; i++) {
    float alpha = customNoise(x[i] * s, y[i] * s)*2*PI;
    x[i]+= depth * cos(alpha); // + random(-0.4, 0.4);
    y[i]+= depth * sin(alpha); // + random(-0.4, 0.4);
    if (y[i] > height) {
      y[i] = 0;
      x[i] = random(0, width);
    }
    x[i]= x[i]%width;
    fill(c[i], 4); //Comment if you don't want to use an image;
    ellipse(x[i], y[i], 2, 2);
  }
}


float customNoise(float x, float y) {
  return pow(sin(0.9*x + noise(x, y)*map(mouseX, 0, width, 0, 5)*y), 3);
}

You will get something like this

noise2

noise1

Notice that the first piece is obtained by commenting/uncommenting some few lines.
Finally, there is one last question you might ask, and it is the following:”How did you come up with those peculiar numbers for the parameters in the code?”. Well, the answer is: by a certain amount of trial and error. As I mentioned more than once, making art with code allows for a great degree of exploration: tweaking a parameter here and changing a line there can give you very different and unexpected results. That what you get at the end is artistically appealing or not, well, nobody else can tell but you. These highly subjective decisions are what transforms a bunch of programming lines into something meaningful and beautiful. So, go on tweaking and looking for something you find interesting and worth sharing, then! :)

*If you are post-modernly thinking “Who cares if it’s called generative or not?”, you definitely have all my sympathy.

Digital poetry and text glitching

posted by on 2016.03.21, under Processing
21:

Digital poetry is that part of literature which is concerned with poetic forms of expression which are mainly computer aided. I am using the term in a strong sense here, i.e. I am thinking about generative poetry, hypertext poetry, and for this occasion in particular digital visual poetry. In general, the relation between the (graphical) sign used to represent a word and its actual meaning in a poetic text is a very interesting (and crucial) one. Indeed, the way words are represented can be an integral part of the aesthetic value of a piece of literary text, poetry in this case. Just think about the beautiful art of Chinese calligraphy, for example. It is then not surprising that poetry, as many forms of digital art, can be glitched* too. I have written about glitch art already, and we can use a couple of ideas and methodology from there. One way to glitch a piece of poetry would be to introduce orthographic anomalies/errors in the text to get for instance something like**

“SnOww i% my s!hoooe
AbanNdo;^^ed
Sparr#w^s nset”

At this stage we are working mainly with the signifier, but in a way which doesn’t take into account the actual spatial representation of the text itself. (Yes, the text is actually represented already, I’m being a bit sloppy here.)
More in the direction of digital visual poetry, we can work with properties of the visualized text: the position of the actual characters involved, for instance. The graphical atoms will be then the characters forming the words in the text, in this case, and we introduce perturbations to their positions in space, and some other visual artifacts. To achieve this, we can regard the various lines of text, which are of type String, as array of characters, and display them. We have then to take care of the length in pixels of each character with the function textWidth(), in order to be able to display the various lines of text.
Here’s how a simple Processing code inspired by these ideas would look like:

PFont font;
String[] text = {"Oh you can't help that,",  "said the Cat.", "We're all mad here.",  "I'm mad. You're mad." };
int size = 48;
int index = 0;

void setup(){
  size(800, 800);
  background(0);
  textAlign(CENTER);
  font = loadFont("TlwgTypewriter-48.vlw"); //You can create fonts with Tools/Create Font in Processing
  textFont(font, size);
  for (int i = 0; i < text.length; i++){
    float posx = 200;
    float posy =  200 + i * 50;
    for (int j = 0; j < text[i].length(); j++){
    textSize(size);
    text(text[i].charAt(j), posx, posy);
    posx = posx + textWidth(text[i].charAt(j)) +random(-10, 10);
    if (random(0.0, 1.0) < 0.3){
       size = size + int(random(-10, 10));
       glitch(posx, posy);
      }
    }
  }
}

void draw(){
}

void glitch(float x, float y){
  char c = char(int(random(130, 255)));
  text(c, x + random(-10, 10), y + random(-10, 10));
}

You would get something like this

1

I have been lazy, and introduced the array of strings directly in the code: an easy (but instructive) variation would be to load a piece of text from a .txt file, and parse it to obtain the individual lines.
Finally, we could work at a third layer of graphic “deepness”: we could consider the whole text as an image, and use the ideas in the previous post to glitch it. This is left to you as an interesting exercise.
Most importantly: never contradict the Cheshire Cat, mind you. 😉

*I avoid using the term “hacked”, since nowadays it is practically and culturally meaningless. Someone suggested “hijacked”, which I prefer.
** Thanks to Kerouac for the raw material to esperiment with.

On the poetics of artistic suicide

posted by on 2016.03.14, under Uncategorized
14:

I have not updated this blog in several months now: various reasons, some more personal than others, have taken a role in this. I felt though the strong need to write again here.
No, I won’t show any code this time. Simply because there is no algorithm for the kind of artistic pieces I want to point your attention to.
Rather, I want to talk about what I consider one of the greatest performance acts of recent years. Italian street artist Blu has recently erased all the murals he had created in his very own city of Bologna during the last twenty years. The manifesto and the words explaining the reasons behind this decision have been left to Wu Ming, a collective of writers active since the mid ’90s.
You can read everything here. (There is an english translation as well.)
In an impressive act of artistic suicide, at the same time creative and destructive, aesthetic and poetic, Blu has reminded us that art has still the power to challenge and raise questions concerning urbanism, commonalities, public spaces, recuperation, power.
By subtracting those walls to a since too long ongoing process of cultural and economic reappropriation by a repressive establishment, he has left big “grayboards” for all to take part in the everyday struggle for freedom. The brush is in our hands, and it’s leaking.
These phenomena of reappropriation are not particular to street art.
“Coding”, the topic of this blog, is nowadays a buzzword everyone wants to pronounce. A piece of cake shot with low depth of field and Instagram filter everyone wants to taste. The latest golden egg chicken, or whatever. With various blogs and online magazines feeding you the latest technological wonders and the new emergent trends in this or that artistic field, where has the sense of exploration gone? How can we bring it back, and make it challenging once again, freeing it from the multiple petty boxes the corporate machine wants us to frame it?
Can we bring digital art “in the streets”, or will it always be confined to our smart and self-reassuring conventions and gatherings?

After a few hours from its repainting, the following writings have appeared on one of the gray walls left

La felicità che mi era sempre stata negata.
Avevo il diritto di viverla quella felicità.
Non me l’avete concesso.
Allora peggio per me, peggio per voi, peggio per tutti.
Rimpianti si, ma in ogni caso nessun rimorso.”

For a little while, we had a glimpse of a Blu sky.

openFrameworks: a primer

posted by on 2014.09.02, under openFrameworks
02:

Since a couple of weeks I have been looking at openFrameworks, an amazing C++ toolkit, which is used to do amazing things. Until now, I have only showed code in Processing (basically Java), and SuperCollider: C++ is a beast in its own, though, and in future posts I will try to talk about pointers, memory allocation, the way classes are defined, etc. For now, I’ll just briefly explain the main idea around this simple project. Basically, the webcam is taking frames, converting them into textures, which are then mapped on meshes, which are then deformed, etc. to get very interesting shapes, colors, etc. You are not seeing any change in the frame grabbed simply because I am not in the video, and the camera is fixed :).
Here it is what you get

You can download the source code here. (You will need to put the texture .png file in a bin/data/texture folder).
In the following posts I will try to talk about more basic examples using the techniques in the project above.

The Molecular Music Box in SuperCollider

posted by on 2014.08.19, under Supercollider
19:

Via Reaktor tutorials I came across this video. I have already talked about generative systems that create rich patterns (see here, and here), and how simple rules can give rise to emergent complexity.
Watch the video to know what the simple rules are in this case (and to see why it is called “molecular” :) ), or look at the following SuperCollider code, which, I must say, took me a bit more than I thought

MIDIClient.init;

~mOut = MIDIOut.new(3);

(
var seed = 48;
var degrees, deg;
var length = Pseq([4, 3], inf).asStream;
var dur = length.next();
var bars = 25;
var quant = 16;
var notes = [];
var loop = [];
var pos = [];
var next = 0;

degrees = [];

//Building the MIDI values for the white keys

9.do({|i|
degrees = degrees++([0, 2, 4, 5, 7, 9, 11] + (12*i));
});

//Starting notes from the seed

deg = Pseq(degrees, inf, degrees.indexOf(seed)).asStream;


(bars * quant).do({|i|
  var note;

    if((i%quant == 0) && (notes != []),
    {
     loop = loop.add(notes);
     notes = [];
    });

    if((i%quant == next) && (pos.includes(next) == false),{
      notes = notes.add([deg.next(), dur/4]);
      pos = pos.add(next);
      next = (next + dur)%quant;
    });

    if ( (i%quant == next) && (pos.includes(next) == true),{
     dur = length.next();
     notes = notes.add([deg.next(), dur/4]);
     next = (next + dur)%quant;
    });

   });

  loop.do({|patt, i|
      patt.postln;
      patterns = patterns++([i * 4, Pbind(*[\type,\midi,\chan,0,
         \midiout,~mOut,
        [\midinote, \dur]: Pseq(patt, inf),
        \legato: 1,
            \amp: rrand(0.1,0.5)])]);
      });

  Ptpar(patterns, 1).trace.play;
)

Notice that you can very easily change any of the rules (duration length, scale used, etc.) with a few keyboard strokes: the power of a text based programming language! :)
I have sent the output of this to the Grand Piano instrument in Ableton Live 9.
Here is the result for 4C3

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.


and here is the one for 9C14½

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Objects manipulation in SuperCollider and Synths generation

posted by on 2014.08.18, under Supercollider
18:

In the last post, I wrote about some object oriented techniques in Processing which simplyfied our code, and gave the possibilty to reason more abstractly. Also SuperCollider is an object oriented programming language, and in this little example below I want to explore a situation where we can really take advantage of this: it somehow belongs to the category of “things one (or I?) can’t really do in Max/Msp, Reaktor, etc.”. :)
Here’s the simple situation: suppose we want to create 100 different percussive sounds with FM synthesis, with random waveforms as carrier, random harmonics for the modulating signal, etc., and play them randomly. We don’t want to change the sounds later, just play them. So, the first strategy we could adopt is the dirty and cheap no-brainer approach, which works along the following lines: well, what I will do is to create a SynthDef, i.e. an audio graph on the server, which is “big” enough to encompass the various possibilities of sounds, store the various randomly created combinations of waveforms, frequencies, etc. in an array, and poll these data when needed. The SynthDef would look like

 SynthDef(\perc, { arg out = 0, freq = 0, decay = 0.5, pan = 0, depth = 1, waveform = 0, harm = 0;
            var sig = Select.ar(waveform, [SinOsc.ar(freq + (SinOsc.ar(harm * freq) * depth)), Saw.ar(freq + (SinOsc.ar(harm * freq) * depth))]);
        var env = EnvGen.kr(Env.perc(0.01, decay), doneAction: 2);
            Out.ar(out, Pan2.ar(LPF.ar(sig * env * 0.1, 3000), pan));
    }).add;

Setting the parameter waveform will choose among the waveforms, freq will determine the frequency, etc. A big array (or dictionary, if you prefer) with randomly generated values, and I’m done!
Well, yeah, this approach will work, but it’s quite ugly, and, more importantly, inefficient: indeed, for each Synth created, a copy is kept of the two waveforms, only one of which is heard. So, for each percussion sound, we allocate twice what we need. Remember that there is a difference between not having a sound generator on the audio server, and having one which is muted, since in the second case, the sample rate computations are performed anyways.
Let’s think about this situation from a different angle, which makes more use of the language capabilities of SuperCollider. What we really need are different percussion sounds: they are different enough to be considered not as different instances of the same SynthDefs, but rather as instances of different SynthDefs. Instead of having SuperCollider creating different Synth instances, we can tell it to create different SynthDefs! Indeed, consider the following code (assuming a given choice for the range of the parameters)

100.do({|i|
    var name;  
    name = "perc"++i;
    SynthDef(name, { arg out = 0;
                        var freq = [24, 57, 68, 29, 87, 39, 70].choose.midicps;
                        var decay =  rrand(0.1, 0.5);
                        var pan = rrand(-1.0, 1.0);
            var sig = [SinOsc, Saw].choose.ar(freq + (SinOsc.ar([0, 1, 2, 3, 4].choose*freq*rrand(1, 30))))*0.1;
        var env = EnvGen.kr(Env.perc(0.01, decay), doneAction: 2);
            Out.ar(out, Pan2.ar(LPF.ar(sig*env, 3000), pan));
    }).add;
    })
});

First, we are defining names with which we can refer to the SynthDef: this is easily done, since a name for a Synth is a string (or a symbol), and we can obtain each of them by concatenating a string (in this case “perc”) with the counter index. Next, we define different SynthDefs: the beautiful thing that makes this work in a nice way is contained in the part

[SinOsc, Saw].choose.ar()

Remember: SuperCollider is object oriented, and in most cases, even if we don’t think about it, we are dealing with objects. Indeed, when we write something like SinOsc.ar(440), we are actually creating an object of type SinOsc, and sending to it the value 440 via the method .ar (which stands for “audio rate”), which provides the necessary computations to produce audio on scsynth, the audio server. Since SinOsc, Saw, etc are an “extension” of the class UGen (more or less), we can make a list (or Collection) with objects of this type, and use the powerful collection manipulation methods provided by SuperCollider (in this case the method .choose). Since both SinOsc and Saw react in the same way to the method .ar (this is an example of “polymorphism”), we can have it follow the method .choose, and pass everything in the round brackets. In this way the SynthDef itself will only have one copy of the choosen waveform per name.
This way of reasoning might look a bit abstract at the beginning, but it’s based on a simple concept: everything that require repetitive actions is best left to a programming language! Moreover, since SuperCollider is heavily object oriented, it gives really serious manipulations possibilities, as we have seen. We used already an incarnation of this concept when we built graphical interfaces.
Finally, the percussive sounds can be played via something like this

fork{
inf.do({
    i = rrand(0, 99);
    Synth("perc"++i);
    rrand(0.1, 0.4).wait;
})
}

Here’s the complete code

s.boot;

(

var reverb, delay;
reverb = Bus.audio(s, 2);
delay = Bus.audio(s, 2);


SynthDef(\reverb, {arg out = 0, in;
    var sig = In.ar(in, 2);
    sig = FreeVerb.ar(sig);
    Out.ar(out, sig);
}).add;

SynthDef(\delay, {arg out = 0, in;
    var sig = In.ar(in, 2) + LocalIn.ar(2);
    LocalOut.ar(DelayL.ar(sig, 0.5, 0.1)*0.8);
    Out.ar(out, sig);
}).add;

fork{
   
100.do({|i|
    var name;  
    name = "perc"++i;
    SynthDef(name, { arg out = 0;
                        var freq = [24, 57, 68, 29, 87, 39, 70].choose.midicps;
                        var decay =  rrand(0.1, 0.5);
                        var pan = rrand(-1.0, 1.0);
            var sig = [SinOsc, Saw].choose.ar(freq + (SinOsc.ar([0, 1, 2, 3, 4].choose*freq*rrand(1, 30))))*0.1;
        var env = EnvGen.kr(Env.perc(0.01, decay), doneAction: 2);
            Out.ar(out, Pan2.ar(LPF.ar(sig*env, 3000), pan));
    }).add;
    });
   

s.sync;

        Synth(\reverb, [\in: reverb]);
    Synth(\delay, [\in: delay]);
   
    inf.do({
    i = rrand(0, 99);
        Synth("perc"++i, [\out: [reverb, delay].choose]);
    rrand(0.1, 0.4).wait;
})
}
)

I have added some reverb and delay to taste.
Notice that this code illustrate only the tip of the iceberg concerning what you can achieve with an object oriented approach to structure your code.
No audio this time, since it is not that interesting. :)

Colliding particles and the power of abstraction

posted by on 2014.08.17, under Processing
17:

This code is a nice playground for some advanced aspects of Object Oriented Programming (OOP): it is simple enough to be interesting, and show the power and elegance of a more abstract approach to programming. What does the code do? It generates a number of bouncing particles which disappear when colliding with each other. Pretty simple. Now, in general, when you have to test a condition for an object against the totality of objects present, you may run soon in annoying cycles which can obscure the code itself, making it less readable, and which would be best avoided. To do this, I need to introduce one easy, but extremely important observation on how function in Processing (and Java, and many other languages) work: “Objects to a function are passed by reference“. Remember this, write it somewhere, do whatever but don’t forget it. “Oookay”, you say, “but, what does “passed by reference” even mean? What’s a “reference”?”. In OOP, objects are instantiated as initialized references, which means the following: suppose we have a class Ball (with empty constructor), and the following piece of code

Ball p;
p = new Ball();

In plain English, the code above says: create a label p which labels an object of type Ball, then create an object of type Ball, and attach to it the label p. In other words, p is *not* the object*, but it is just a label “referencing” the actual Ball object. Indeed, if we add the following piece of code

Ball q;
q = p;

we are asking to create a new label q, referencing to the same object p is referencing. Now, as soon as we modify the actual object which is referenced, these modifications will reflect on the behaviour of p and q. For instance, suppose that the class Ball has a field a, of type integer, which is initialized to 10. Then the following code

println(q.a);
p.a = 15;
println(q.a);

will return 10, and then 15. In other words, changing p has changed *also* q, and the reason is that we are really not changing p, but rather the object p references to. A bit confusing, right? Neverthless I bet you have seen this behaviour before, if you have ever used (and who hasn’t) arrays.
Indeed, this piece of code would give the same results;

int[] p = new int[10];
int[] q;
q = p;
q[0] = 10;
p[0] = 15;
println(q[0]);

Okay, we are ready to talk about “passing by reference”**. Suppose you have a function

void f(Ball b){
   do something;
}

and suppose we evaluate it on p, as in f(p). What happens is that b becomes a reference to the object referenced by p (as in b = p). So, if you modify b inside the scope of f, then you are really modifying the referenced object, and hence also p. Of course, the same is true for arrays, so be careful with what you do inside the scope of a function, when arrays are involved.
Supposing this is more or less, clear, the question remains: why caring about this for some stupid balls? Well, this simple observation allows to define something like this

class Ball{
int a;
Ball[] balls;

  Ball(int _a, Ball[] _balls){
   a  = 10;
   balls = _balls;
 }
}

Wait, what’s going on here? Am I defining a class Ball in which one of its fields is an array of objects of type… Ball?! Like, isn’t there gonna be a nasty recursion type of end of the universe OMG!!
Calm down, nothing’s bad gonna happen. And the reason lies in the simple observations above: objects variable (and arrays) are defined as reference, and they need to be initialized. In the case above, we are asking for a label balls which is a reference to an array of type Ball: at this point we are *not* calling the constructor Ball( ). When it will be called, though, the array balls will reference to the same array referenced by the label (or variable) _balls. Here we are using that objects are passed to functions by reference (the constructor, in this case). Nice, uh? :)
Notice that, on the other hand, this piece of code

class Ball{
int a;
Ball p;

  Ball(int _a){
   a  = 10;
   p = new Ball();
 }
}

will give a nasty recursion, since we are indeed calling the constructor inside itself.
Ok, still, what do we do with this?

Here’s the Processing code

int num = 50;
ArrayList<Particle> partls;

void setup(){
  size(600, 600);
  background(0);
  partls = new ArrayList<Particle>();

  for (int i = 0; i < num; i++){
    partls.add(new Particle(random(0, width), random(0, height), partls));
  }
}

void draw(){
  ArrayList<Particle> remove = new ArrayList<Particle>();
  background(0);
   
   for (Particle par: partls){
    par.update();
    par.display();
   }
 
   for (Particle par: partls){
    if (par.collide()) remove.add(par);
   }
   
   for (Particle par: remove){
    partls.remove(par);
   }
}

///Define the class Particle

class Particle{
  float x, y, vx, vy, r;
  ArrayList<Particle> others;
 
Particle(float _x, float _y, ArrayList<Particle> _others){
  x = _x;
  y = _y;
  vx = random(-5, 5);
  vy = random(-5, 5);
  others = _others;
  r = 20;
}  

void update(){
  if ( x <=0 || x >= width) vx = -vx;
  if ( y <=0 || y >= height) vy = -vy;
 
  x = (x + vx);
  y = (y + vy);
}

void display(){
  fill(255, 200);
  ellipse(x, y, r, r);
}

boolean collide(){
  boolean b = false;
   for (Particle p: others){
    if (dist(x, y, p.x, p.y) <= r & dist(x, y, p.x, p.y) > 0.0){
     b = true;
     }
   }
   return b;
 }
 
}

Let’s look at the Particle class. Among other fields, we have others, an ArrayList of type Particle, which refers to the ArrayList _others passed to the constructor. The variable others is used in the method collide, which tests the distance between the instantiated object and all the particles in the list others, and returns the value true if a collision happens (the condition dist(x, y, p.x, p.y) > 0.0 ensures no self-collision). Also, notice the “enhanced” for loop, which is pretty elegant.
Now, the magic appears in the main code, namely in

partls = new ArrayList();

for (int i = 0; i < num; i++){ partls.add(new Particle(random(0, width), random(0, height), partls)); } The first line initializes the variable partls as an (empty) ArrayList of type Particle. In the for loop, we add to partls some objects of type Particle by passing to the constructor the required fields: x, y, and others. Since objects are passed by reference to the constructor, this means that, at the end of the for loop, for each object instance of Particle the field others will reference to the same ArrayList referenced by partls, which, by construction, is an ArrayList in which each element is exactly the object Particle created in the for loop. The reference partls gets modified at each iteration of the cycle, and since we are passing it by reference, this modification will reflect also on the variable others. Pretty cool, uh? This is quite a convenient way to manage collisions. Indeed, in the draw() function we have first the usual (enhanced) for loop which updates, and displays the particles. Then we check for collisions: if the particle collides with any other particle, we add it to a remove list. We need to do this, instead of removing it on the spot, because otherwise only one of the two particles involved in a collision would get removed. Finally, we have another for loop, in order to dispose of the colliding particles. Everything is pretty elegant and compact, and most importantly, the code is more readable this way! :)
No video this time, since it’s pretty visually uninteresting.

*Not 100% true, but pretty close.
**There exists also the notion of “passing by value”.

Polygonal Camera

posted by on 2014.08.13, under Processing
13:

It has been a while since my last update, and in particular since my last Processing code! So, here’s something very simple. Basically, it’s a grid of points connected by lines, which form the edges of polygons. The points move almost periodically: each of them undergoes an oscillatory motion, to which I’ve added a bit of noise, to make things more interesting. The polygons, which during the motion change their shape as the vertices move, are colored. Here comes the nice part: the color of a single polygon is given by taking at its geometric center the color of the pixel of the image obtained by capturing a frame via the webcam. In this way, the colors are “smeared”, but you can still somehow discern the webcam input. Here’s the code.

import processing.video.*;

Capture cam;

int n = 30;
float t = 0;
Point[][] points = new Point[n][n];

void setup(){
  size(320, 240);
  cam = new Capture(this, 320, 240, 30);
  cam.start();
  background(0);

  /* Setup the grid;
  for (int i = 0; i < n; i++)
  {
    for (int j = 0; j < n; j++)
    {
      points[i][j] = new Point(i*width/n, j*height/n);
    }
  }
}

void draw(){
   if(cam.available()) {
    cam.read();
  }  
 background(0);
  for (int i = 0; i < n; i++)
  {
    for (int j = 0; j < n; j++)
    {
      points[i][j].move();
      points[i][j].display();
    }
  }
  grid(points);
  t+= 0.1;
}

void grid(Point[][] gr){
  int c_x, c_y;
  for (int i = 0 ; i < n; i++){
    for (int j = 0; j < n; j++){
      if ( j < n -1 && i < n - 1){
        stroke(255, 100);
       /* Compute the geometric center;

        c_x = constrain(int((gr[i][j].pos.x + gr[i][j + 1].pos.x + gr[i + 1][j + 1].pos.x + gr[i + 1][j].pos.x)/4), 0, width);
        c_y = constrain(int((gr[i][j].pos.y + gr[i][j + 1].pos.y + gr[i + 1][j + 1].pos.y + gr[i + 1][j].pos.y)/4), 0, height);
       
          /* Create the polygon;
          fill(cam.pixels[constrain(c_x + width*c_y, 0, cam.pixels.length - 1)], 250);
          beginShape();
          vertex(gr[i][j].pos.x, gr[i][j].pos.y);
          vertex(gr[i][j + 1].pos.x, gr[i][j + 1].pos.y);
          vertex(gr[i + 1][j + 1].pos.x, gr[i + 1][j + 1].pos.y);
          vertex(gr[i + 1][j].pos.x, gr[i + 1][j].pos.y);
        endShape();
      }
    }
  }
}

/* Define the class Point

class Point{
  PVector pos;
  float angle;
  float depth;
  PVector dir;
  float phase;
  float vel;
 
Point(float _x, float _y){
  pos = new PVector(_x, _y);
  angle = random(0.0, 2*PI);
  depth = random(0.8, 2.4);
  dir = new PVector(cos(angle), sin(angle));
  vel = random(0.5, 1.5);
}

void display(){
  noStroke();
  fill(255, 255);
  ellipse(pos.x, pos.y, 4, 4);
}

void move(){
  /* Oscillatory motion with noise which depends on the "time" variable t;
  pos.x = pos.x + dir.x * cos(vel*t + noise(t*angle)*0.1) * depth;
  pos.y = pos.y + dir.y * cos(vel*t + noise(t*angle)*0.1) * depth;
}

}

Warning: Kids, don’t code the way I do! In this case I was particularly lazy: indeed, a more elegant way to do it would have been to create another class, say Grid, and hide there the polygon making, etc. The code would have been more readable and reusable, that way. But as I said, lazyness. :)

Here’s a little video of what you get

(If it doesn’t work, you can download or stream this )

Drones, drones, drones

posted by on 2014.07.05, under Supercollider
05:

Who doesn’t like ambient drones? Ok, I guess some people might not like them.
Here’s a little code in SuperCollider to generate a kind of feedbacky ambient atmosphere. It does look involved, but it isn’t. The main thing is using Wavetable synthesis : what the method .sine1Msg does is to fill the buffer b with a sinewave (of 512 sample “period”), and its harmonics, whose number and amplitudes are specified in the array parameter of the method. Then we can “play” the wavetable with Osc.ar, which is a wavetable oscillator. Moreover, for added noisyness and ambience, I have added a bitcrusher with randomly varying samplerate and bit depth, and also a sample player playing the buffer c, which is not too loud, and just contributes to textures. You could modify it easily to load multiple samples, and choose between them. The last part involves a nice trick I learned here : basically, you stack a certain number of short time delays, and use a feedback line to simulate a reverberation effect. In particular, if the feedback parameter is 1, you get an “infinite reverb”. Very cool. Be careful not to keep feeding input in this situation, otherwise you will get the usual feedback headache! 😀

s.boot;

(
b = Buffer.alloc(s,512,1,{|z|z.sine1Msg(1.0/[1,3,5,7,9,11,13,15,17])});
c = Buffer.read(s, "/pathtothesample");

fork{
    s.sync;
~sound = {
    var sig;
    var local;
    var f = [30,60,15]*Lag.kr(TChoose.kr(Impulse.kr(0.05),[0.75, 0.5, 1]), 8);
    sig = Mix(COsc.ar(b.bufnum,f + SinOsc.ar(f*25, 0, LFTri.kr(0.01).range(0, 10)), [0.1, 0.1001, 0.2], 0.2))*0.1;
sig = sig;
sig = LeakDC.ar(Ringz.ar(sig, TChoose.kr(Impulse.kr(0.1),[88, 97, 99, 100].midicps), LFTri.kr([0.05, 0.051]).range(0.2, 0.5)));
sig = sig + Decimator.ar(sig, 48000*LFNoise0.kr(1).range(0.25, 1), TChoose.kr(Impulse.kr(4), [8, 12, 16, 24]), 0.4);
    sig = LPF.ar(sig, 3000*LFTri.kr(0.01).range(0.1, 1));
    sig = sig + (Splay.ar(Array.fill(4, {PlayBuf.ar(2, c, rrand(-0.8, 0.8), loop: 2)*0.01}), 0.5));
    sig = CombC.ar(sig, 1.0, [0.1, 0.2], LFTri.kr(0.05).range(5, 9));
       
    local = sig + LocalIn.ar(2);
    15.do({
            local = AllpassN.ar(local, 0.06, Rand(0.001, 0.06), 3)
          });
    LocalOut.ar(local*0.4);
       
    Out.ar(0, Limiter.ar(LPF.ar(local, 4000), 0.8)*EnvGen.kr(Env([0, 1, 1, 0],[3, 100, 10])));
}.play;
}
)

s.quit;

You can listen to the result here

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

pagetop