Nibble: "Processing für Geeks" von Nikolaus Gradwohl, gehalten am Abend der Eroeffnungsveranstaltung am 10. April 2010

Code des gezeigten Processing Audio Visualizers

Datei: particle.pde: <geshi lang="python">

public class Particle {
 float x, y, z;
 float vx, vy, vz;
 boolean alive;
 PImage tex;
 color ti;
 
 public Particle( float x, float y, float z,  float vx, float vy, float vz, PImage tex, color ti ) {
   this.tex = tex;  
   this.x = x;
   this.y = y;
   this.z = z;
   this.vx = vx;
   this.vy = vy;
   this.vz = vz;
   this.ti = ti;
   alive = true;
 }
 
 public Particle( float x, float y, float z,  float vx, float vy, float vz, PImage tex ) {
   this( x, y, z, vx, vy, vz, tex, color( 255, 255, 255 ));
 }
 
 public void update() {
   x += vx * 0.1f;
   y += vy * 0.1f;
   z += vz * 0.1f;
   
   vy += 0.1;
   
   if (y > 600) {
     alive = false;
   }
 }
 
 public void draw( float alph ) {
   pushMatrix();
   translate( x, y, z );
   rotateY( alph );
   textureMode(NORMALIZED);
   tint(ti);
   beginShape();
   texture( tex );
   vertex( -20, -20, 0, 0, 0 );
   vertex( -20, 20, 0, 0, 1 );
   vertex( 20, 20, 0, 1, 1 );
   vertex( 20, -20, 0, 1, 0 );
   endShape(CLOSE);
   popMatrix();
 }
 
 public boolean isAlive() {
   return alive;
 }
}

</geshi>

Datei: particledemo.pde: <geshi lang="python">

/**
 a 3d particle audio vizualizer by
 <a href="http://www.local-guru.net/blog">Guru</a>
 press any key to emit a new burst of particles
*/

import processing.opengl.*;
import javax.media.opengl.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
//Particle[] p;
ArrayList p = new ArrayList();
Particle[] burst;
PImage tex;
boolean present = false;
Minim minim;
AudioInput in;
FFT fft;

void setup() {
 for ( int i = 0; i < args.length; i ++ ) {
   if ("--present".equals(args[i])) {
     present = true;
     break;
   }
 }
 if (present) {
   size(screen.width,screen.height, OPENGL);
 } else {
   size(600,600, OPENGL);
 }

 tex = makeTexture( 10 );
 burst = new Particle[100];
 
 minim = new Minim(this);
 in = minim.getLineIn( Minim.MONO, 512 );
 fft = new FFT( in.bufferSize(), in.sampleRate());
}

float alph = 0;

void draw() {
 background(0);
 
 alph += 0.01f;
 PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;
 GL gl = pgl.gl;
 pgl.beginGL();
 
 gl.glDepthMask(false);  
 gl.glDisable(GL.GL_DEPTH_TEST); 
 gl.glEnable(GL.GL_BLEND); 
 gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE); 
  
 pushMatrix();
 translate( width, 0, -300 );
 scale( min( width, height) /150 );

 rotateY( alph );
 
 fft.forward( in.mix );
 
 for( int i = 0; i < fft.specSize(); i++) {
    float val = fft.getBand(i)*(i+1)/75;
    if( val > 2  && random(1000) > 800 + p.size()  ) {
      colorMode(HSB,fft.specSize(),100,100);
      p.add( new Particle( 0, 300, 0 , random( -5, 5 ), random( -20, -5), random( -5, 5 ), tex, color( i, 40,100)));
    }
 }
 
 ArrayList dead = new ArrayList();
 for( Iterator i = p.iterator(); i.hasNext(); ) {
   Particle par = (Particle)i.next();
   par.update();
   par.draw( - alph );
   if (!par.isAlive()) {
     dead.add( par );
   }
 }
 
 for( Iterator i = dead.iterator(); i.hasNext(); ) {
   p.remove( i.next());
 }

 for( int i = 0; i < burst.length; i ++ ) {
   if ( burst[i] != null && burst[i].isAlive()) {
      burst[i].update();
      burst[i].draw( -alph );
   }
 }
 
 pgl.endGL();
 popMatrix();
}


PGraphics makeTexture( int r ) {
 PGraphics res = createGraphics( r * 6, r * 6, P2D);
 res.beginDraw();
 res.loadPixels();
   for ( int x = 0; x < res.width; x++) {   
     for( int y = 0; y < res.height; y++ ) {
       float d = min( 512, 50*  sq( r / sqrt( sq( x - 3 * r) + sq( y - 3 * r))));
       res.pixels[y * res.width + x] = color( min(255,d), min(255, d*0.8), d* 0.5 );
     }
   }
 res.updatePixels();
 res.endDraw();
 
 return res;  
}

</geshi>