/* Interactive audio exploration of Perlin noise emoc / hackpact, september 2009 / http://emoc.org/hackpact/ Perlin noise code from Hugo Elias http://freespace.virgin.net/hugo.elias/models/m_perlin.htm ---------------------- mouse X changes increment mouse Y changes persistence keys : 'd' changes samples length down (between 2 and ...) 'f' changes samples length up 'g' switches modulo mode on/off 'h' changes modulo length down (between 10 and ...) 'j' changes modulo length up */ 0 => int deviceNum; Hid hi; HidMsg msg; if( !hi.openMouse( deviceNum ) ) me.exit(); 0 => int deviceNum2; Hid hi2; HidMsg msg2; if( !hi2.openKeyboard( deviceNum2 ) ) me.exit(); Step s => dac; .7 => s.gain; float z; .1 => float increment; .1 => float persistence; 4 => int octaves; 2::samp => dur T; 500 => int zmodulo; 0 => int moduloMode; spork ~ sound(); spork ~ keyboard(); spork ~ mouse(); while(1) { 1::day => now; } // ************************************************** fun void sound() { while (T => now) { perlinNoise(z, persistence, octaves) => s.next; increment +=> z; if (moduloMode == 1) z%zmodulo => z; } } // ************************************************** fun void mouse() { while(true) { hi => now; while( hi.recv( msg ) ) { if( msg.isMouseMotion() ) { if( msg.deltaX ) { increment + msg.deltaX$float/200 => increment; if (increment < .005) .005 => increment; if (increment > 10) 10 => increment; <<<"increment", increment>>>; } else if ( msg.deltaY ) { persistence + msg.deltaY$float/500 => persistence; if (persistence < .0005) .0005 => persistence; if (persistence > 1) 1 => persistence; <<<"persistence : ", persistence>>>; } } else if( msg.isButtonDown() ) { if (msg.which == 0) { .1 => float persistence; .1 +=> increment; } } } } } // ************************************************** fun void keyboard() { while( true ) { // wait on event hi2 => now; // get one or more messages while( hi2.recv( msg2 ) ) { // check for action type if( msg2.isButtonDown() ) { // <<< "down:", msg2.which >>>; if (msg2.which == 32) modifyDur(-1); // 'd' key if (msg2.which == 33) modifyDur(1); // 'f' key if (msg2.which == 34) switchModuloMode(); // 'g' key if (msg2.which == 35) modifyModulo(-10); // 'h' key if (msg2.which == 36) modifyModulo(10); // 'j' key } else { // <<< "up:", msg2.which >>>; } } } } // ************************************************** fun void switchModuloMode() { if (moduloMode == 0) 1 => moduloMode; else 0 => moduloMode; <<<"moduloMode ", moduloMode>>>; } fun void modifyModulo(int m) { if (m < 0 && zmodulo > 10) 10 -=> zmodulo; if (m > 0) 10 +=> zmodulo; <<<"zmodulo ", zmodulo>>>; } fun void modifyDur(int m) { if (m < 0 && T > 2::samp) 1::samp -=> T; if (m > 0) 1::samp +=> T; <<<"dur T", T>>>; } fun float noise2(int x) { (x << 13) ^ x => x; return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0); } fun float smoothedNoise(float x) { return noise2(x$int)/2 + noise2(x$int-1)/4 + noise2(x$int+1)/4; } fun float linearInterpolate(float a, float b, float x) { return a * (1 - x) + b * x; } fun float cosineInterpolate(float a, float b, float x) { x * 3.1415927 => float ft; (1 - Math.cos(ft)) * .5 => float f; return a * (1 - f) + b * f; } fun float interpolatedNoise(float x) { x$int => int intx; x - intx => float fx; smoothedNoise(intx) => float v1; smoothedNoise(intx + 1) => float v2; //return linearInterpolate(v1, v2, fx); return cosineInterpolate(v1, v2, fx); } fun float perlinNoise(float x, float persistence, int octaves) { 0 => float total; persistence => float p; octaves - 1 => float n; for (0 => int i; i <= n; i++) { Math.pow(2, i) => float frequency; Math.pow(p, i) => float amplitude; interpolatedNoise(x * frequency) * amplitude +=> total; } return total; }