// the patch SndBuf buf[5]; Envelope e[5]; JCRev R; for ( 1=> int i; i< 6; i++) { me.sourceDir() + "sounds/sound" + i + ".wav" => buf[i-1].read; 1 => buf[i-1].loop; buf[i-1] => e[i-1] => R => dac; } // number of the device to open (see: chuck --probe) 0 => int device; // get command line if( me.args() ) me.arg(0) => Std.atoi => device; Hid hi; HidMsg msg; // try if( !hi.openMouse( device ) ) me.exit(); <<< "mouse '" + hi.name() + "' ready...", "" >>>; 1.0 => float pitch; fun void grain(SndBuf buf, Envelope e) { int samples; buf.samples() => samples; Std.rand2(0, samples-1) => int position; Std.rand2(0, samples-1) => int randompos; <<< samples >>>; 1.0 => float pitch; 100 => int duration; // can be changed to acheive a more varying // asynchronous envelope for each grain duration //duration*Std.rand2f(1,5)::ms => e.duration; 1.0 => float randpitch; while( true ) { while(hi.recv(msg)) { if( msg.isMouseMotion() ) { (msg.scaledCursorX * 10000) $ int => position; if (msg.scaledCursorY < 0.5) { msg.scaledCursorY * 2.0 => pitch; } else { 1 + (msg.scaledCursorY-0.5)/(0.5) * 4 => pitch; } (msg.cursorX+msg.cursorY) => duration; //1000 => duration; <<< msg.scaledCursorX, msg.scaledCursorY >>>; } } Std.rand2f(pitch-randpitch,pitch+randpitch) => buf.rate; //pitch => buf.rate; //position => buf.pos; Std.rand2(position-randompos,position+randompos) % buf.samples() => buf.pos; 0.4 => buf.gain; e.keyOn(); duration::ms => now; //e.keyOff(); //duration*0.5::ms => now; } } fun void adjustGain() { while(hi.recv(msg)) { if( msg.isMouseMotion() ) { msg.scaledCursorX => float x; msg.scaledCursorY => float y; Math.fabs((x-1)*(y-1)) => buf[1].gain; Math.fabs((x)*(y-1)) => buf[2].gain; Math.fabs((x-1)*(y)) => buf[3].gain; Math.fabs((x)*(y)) => buf[4].gain; //1000 => duration; <<< msg.scaledCursorX, msg.scaledCursorY >>>; } } } 0.3 => R.mix; for (1 => int i; i < 5; i++) { spork ~ grain(buf[i], e[i]); 2::second => now; } spork ~ adjustGain(); // time loop while( true ) { 1::ms => now; }