// Quintet: 5 for 4 // // - a quintet for four performers and five slork-stations // // by Robert Hamilton // ---------------------------------------- // COMMAND LINE ARGUMENT PROCESSING 0 => int SPEAKERSET; 900. => float SOUNDINGRADIUS; if(me.args() == 0) { <<< "Please enter a Speakerset number from 0-4: " >>>; me.exit(); } else { for( 0 => int i; i < me.args(); i++) { if(i==0) { if(Std.atoi(me.arg(i)) > 4) { <<< "Please enter a Speakerset number from 0-4: " >>>; me.exit(); } else { Std.atoi(me.arg(i)) => SPEAKERSET; <<< "Speakerset: ", SPEAKERSET >>>; } } else if(i==1) { Std.atoi(me.arg(i)) => SOUNDINGRADIUS; <<< "SoundingRadius: ", SOUNDINGRADIUS >>>; } } } // DEBUG FUNCTIONS 0 => int dbug; fun void debug(string loc, string msg) { if(dbug==1) <<>>; } fun void debug(string loc, int msg) { if(dbug==1) <<>>; } fun void debug(string loc, float msg) { if(dbug==1) <<>>; } // DECLARE CONSTANTS/VARS int UID; 4. => float SPEAKEROFFSET; [[0.,0.],[0.,900.],[900.,0.],[0.,-900.],[-900.,0.]] @=> float speakersets[][]; 24.0 => float z_static; 8 => int SPEAKERCOUNT; 32 => int CLIENTCOUNT; 1000 => int PROJECTILECOUNT; 2 => int LISTENERCOUNT; "plasma" => string PLASMA; "bfg" => string BFG; .5 => float ampPad; 30. => float ampScalar; 50. => float minFreq; 0 => int totalProjectiles; Impulse imp; LPF lowpass; JCRev rev => dac.chan(0); rev => dac.chan(1); rev => dac.chan(2); rev => dac.chan(3); rev => dac.chan(4); rev => dac.chan(5); .1 => rev.gain; .01 => rev.mix; // declare "global" vars int gClients; int gProjectiles; // create our OSC receiver OscRecv recv; 6662 => recv.port; recv.listen(); recv.event( "/projectile, s i i f f f i i i" ) @=> OscEvent oeProjectile; recv.event( "/player, s i f f f" ) @=> OscEvent oeClient; string type; int owner; int id; float X; float Y; float Z; int target; int bounce; int explode; int projectiles[PROJECTILECOUNT]; //ballEvent @ bprojectiles[PROJECTILECOUNT]; int temp; 0=>int inc; 100=> int filterUBOUND; ResonZ filters[filterUBOUND]; // Impulses will be used through ResonZ filters, selected from a rotating array 0 => int filtercount; 0 => int filternumber; int inuseFilters[filterUBOUND]; // calculate distance from ball or client's X,Y,Z (default for now) coords to current SPEAKERSET fun float speakersetDistance(float ballX, float ballY, float ballZ) { speakersets[SPEAKERSET][0] => float speakerX; speakersets[SPEAKERSET][1] => float speakerY; // basic Euclidean 3-dimensional distance calculation return Math.sqrt(Math.pow((speakerX - ballX), 2) + Math.pow((speakerY - ballY), 2) + Math.pow((z_static - ballZ), 2)); } // Simple loop to check for and sound Projectile Bounces while ( true ) { oeProjectile => now; while ( oeProjectile.nextMsg() != 0 ) { // get data from OSC Projectile event oeProjectile.getString() => type; oeProjectile.getInt() => owner; oeProjectile.getInt() => id; oeProjectile.getFloat() => X; oeProjectile.getFloat() => Y; oeProjectile.getFloat() => Z; oeProjectile.getInt() => target; oeProjectile.getInt() => bounce; oeProjectile.getInt() => explode; if(id-75>totalProjectiles) { id-75 => totalProjectiles; <<< "Projectile Count: ", totalProjectiles >>>; } // skip rest of current iteration if not a bounce flag if(bounce!= 1) continue; // Calculate distance from ball to speaker speakersetDistance(X, Y, Z) => float currentSpeakerDistance; // skipt rest of current iteration if bounce is outside the current SOUNDINGRADIUS for this SPEAKERSET if(currentSpeakerDistance>=SOUNDINGRADIUS) continue; float freq; ((SOUNDINGRADIUS - currentSpeakerDistance)/SOUNDINGRADIUS)*ampScalar => float amp; if(SPEAKERSET == 0) { currentSpeakerDistance + minFreq => freq; } else { (SOUNDINGRADIUS - currentSpeakerDistance) + minFreq => freq; } filtercount%filterUBOUND => filternumber; // get next available filter number filters[filternumber] @=> ResonZ thisRes; // create new ResonZ filtercount++; // increment filtercount freq => thisRes.freq; Z+30. => thisRes.Q; 100.* Z/600.+ 10.=> thisRes.gain; 4000. + owner*200. => lowpass.freq; 200. => lowpass.Q; imp => thisRes => lowpass => rev; amp => imp.next; // 10::ms => now; 1::samp => now; imp =< thisRes; } }