import ddf.minim.*; import ddf.minim.analysis.*; Minim minim; AudioPlayer ap; BeatDetect bd; BeatListener bl; float[] fNums = new float[13]; int minVal = 0; int maxVal = 1000; int particleMin = 180; int particleMax = 220; color[] clr = { #333333,#494949,#5F5F5F,#707070,#7D7D7D,#888888,#949494,#A2A2A2,#B1B1B1,#C3C3C3,#D6D6D6,#EBEBEB,#FFFFFF }; HSphere baseSphere; HDrawablePool pool; void setup() { size(700,700,P3D); H.init(this).background(#202020).use3D(true); smooth(); /* check here # 1 - you'll need an .mp3 edit line 33 with your MP3 */ minim = new Minim(this); ap = minim.loadFile("seeya.mp3", 2048); ap.play(); bd = new BeatDetect(ap.bufferSize(), ap.sampleRate()); bd.setSensitivity(0); bl = new BeatListener(bd, ap); H.add( baseSphere = new HSphere() ) .size(190) .strokeWeight(0) .noStroke() .fill(#666666) .anchorAt(H.CENTER) .loc(width/2, height/2) ; pool = new HDrawablePool(100); pool.autoAddToStage() .add(new HSphere()) .onCreate( new HCallback() { public void run(Object obj) { HSphere d = (HSphere) obj; int ranSize = 10 + ( (int)random(3)*7 ); d .size(ranSize) .strokeWeight(0) .noStroke() .fill(#FF3300) .anchorAt(H.CENTER) ; /* check here # 2 - pool will always keep track of drawables but not other behaviors associated with a drawable so here we have an HOrbiter3D - I want to use audio reaction to change .radius() to the music this way the drawable "d" HSphere will bounce up and down to the music */ HOrbiter3D orb = new HOrbiter3D(width/2, height/2, 0) .target(d) .zSpeed(random(-1.5, 1.5)) .ySpeed(random(-0.5, 0.5)) .radius(195) .zAngle( (int)random(360) ) .yAngle( (int)random(360) ) ; /* check here # 3 - we can make a link to an attached behavior with HBundle this will pass "f" which frequence range d is assoicated with and "o" the HOrbiter3D behavior */ d.extras( new HBundle().num("f", (int)random(fNums.length)).obj("o", orb) ); } } ) .requestAll() ; } void draw() { sphereDetail(20); pointLight(100, 0, 0, width/2, height, 200); // red pointLight(51, 153, 153, width/2, -50, 150); // teal pointLight(204, 204, 204, width/2, (height/2) - 50, 500); // white H.drawStage(); for (int i = 0; i < fNums.length; ++i) { if ( bd.isOnset( (i+1)*2 ) ) { fNums[i] = maxVal; } fNums[i] = constrain(fNums[i] * 0.9, particleMin, particleMax); /* check here # 4 - so this for loop cycles through pool... and then we can lookup HBundle HBundle obj1 = d.extras(); so "d" can look up extras() to find the bridge between "d" and the object associated behavior HOrbiter3D o = (HOrbiter3D) obj1.obj("o"); hooray we're now talking to "d"'s' related HOrbiter3D behavior I can then dynamically change the radius for each "d" o.radius( fNums[ whichFreq ] ); this mean that "d" changes it's orbit behavior based on the fluctuating radius which is changing based on the audio */ for(HDrawable d : pool) { HBundle obj1 = d.extras(); HOrbiter3D o = (HOrbiter3D) obj1.obj("o"); int whichFreq = (int)obj1.num("f"); d.fill( clr[ whichFreq ] ); o.radius( fNums[ whichFreq ] ); } } } void stop() { ap.close(); minim.stop(); super.stop(); } class BeatListener implements AudioListener { private BeatDetect bd; private AudioPlayer source; BeatListener(BeatDetect bd, AudioPlayer source) { this.source = source; this.source.addListener(this); this.bd = bd; } void samples(float[] samps) { bd.detect(source.mix); } void samples(float[] sampsL, float[] sampsR) { bd.detect(source.mix); } }