ConsoleInput in; // tokenizer StringTokenizer tok; // line string line[0]; // our default model Word2Vec model; // loading any default here "glove-wiki-gigaword-50-tsne-2.txt" => string filepath; model.load( filepath ); TriOsc osc[144]; ADSR env => JCRev rev => dac; [64,71,67,62,76,86,72,79,88,86,90,95] @=> int notes[]; for(0 => int i; i < osc.cap(); i++){ osc[i] => env; 0.8/144.0 => osc[i].gain; } fun int execute( string line[] ) { // check line[0] => string command; // index 1 => int index; if( command == "load" || command == "load" ) { if( line.size() < 2 ) { <<< "usage: load [model]", "" >>>; } else { //<<< "loading model (this could take a few seconds)...", "" >>>; // load if( !model.load( me.dir() + filepath ) ) { <<< "cannot load model file...", "" >>>; return 1; } // print info //print( model ); } } else if( command == "eval" || command == "e" ) { if( line.size() < 2 ) { <<< "usage: eval [word expression]", "" >>>; <<< " for example: eval rome - italy + china", "" >>>; <<< " (note: don't forget white spaces around + and -)", "" >>>; } else { // expression string line[1] => string expr; // concatenate for( 2 => int i; i < line.size(); i++ ) { expr + " " + line[i] => expr; } // eval W2V.eval( model, expr, 10 ) @=> string words[]; // print search results for (0 => int i; i < words.size(); i++) { <<< " ", words[i], "" >>>; } } } else if( command == "go" || command == "g" ) { if( line.size() < 5 ) { <<< "usage: go [word/start] [word/end] [second] [steps] [k results]", "" >>>; } else { //<<< "going from", line[1], "to", line[2], "over", line[3], "seconds in", line[4], "steps" >>>; float coord1[model.dim()], coord2[model.dim()]; model.getVector(line[1], coord1); model.getVector(line[2], coord2); 1 => int k; if( line.size() > 5 ) Std.atoi(line[5]) => k; go( line[1], line[2], Std.atof(line[3])::second, Std.atoi(line[4]), k ); } } return 0; // 0 is good } fun void sonify( float params[], float vstart[], float vend[], float T ) { if( params.size() < 2 ) { <<< "not enough params!", "" >>>; return; } 0.1 => rev.mix; for(0 => int i; i < osc.cap(); i++){ Std.mtof(notes[Std.abs(Math.floor(Math.remap(params[0], vstart[0], vend[0], 0, notes.cap()-1 ))$int)]) => float f; f+Math.random2f(-30,30) => osc[i].freq; } (T/16)::second => env.attackTime => env.releaseTime; env.keyOn(); (T/16)::second => now; env.keyOff(); (T/16)::second => now; } fun void go( string start, string end, dur T, int steps, int k ) { float vstart[model.dim()], vend[model.dim()]; model.getVector(start, vstart); model.getVector(end, vend); // get bounds for mapping float mins[0], maxs[0]; model.minMax( mins, maxs ); W2V.dup( vend ) @=> float vdiff[]; W2V.dup( vstart ) @=> float v[]; W2V.minus( vdiff, vstart ); 1.0 / steps => float inc; // time step T * inc => dur Tstep; // scale 0 => float factor; string results[1000]; float coord[model.dim()]; for( int i; i < steps; i++ ) { // scale difference vector W2V.scale( v, vdiff, factor ); inc +=> factor; // add W2V.add( v, vstart ); // search model.getSimilar( v, k, results); results[Math.random2(0,k-1)] => string word; model.getVector( word, coord ); chout <= word <= " "; chout.flush(); sonify( coord, vstart, vend, (((5000::ms/T) * inc)+0.075)); // advance time (((5000::ms/T) * inc)+0.09)::second => now; } } // word2vec helper class W2V { fun static void copy( float to[], float from[] ) { to.size(from.size()); // add into element for( int i; i < to.size(); i++ ) from[i] => to[i]; } fun static float[] dup( float from[] ) { float to[from.size()]; // add into element for( int i; i < to.size(); i++ ) from[i] => to[i]; // return return to; } // result stored in x fun static void add( float x[], float y[] ) { // smaller of the two x.size() < y.size() ? x.size() : y.size() => int size; // add into element for( int i; i < size; i++ ) y[i] +=> x[i]; } // result stored in x fun static void minus( float x[], float y[] ) { // smaller of the two x.size() < y.size() ? x.size() : y.size() => int size; // add into element for( int i; i < size; i++ ) y[i] -=> x[i]; } fun static void scale( float x[], float scalar ) { // scale for( int i; i < x.size(); i++ ) scalar *=> x[i]; } fun static void scale( float result[], float x[], float scalar ) { // scale for( int i; i < x.size(); i++ ) scalar * x[i] => result[i]; } fun static string[] eval( Word2Vec @ w, string expr, int k ) { // init int pos; 1.0 => float multiplier; string word; float wordVector[w.dim()]; float exprVector[w.dim()]; // compute while( true ) { expr.find(" ") => pos; if( pos == -1 ) { w.getVector(expr, wordVector); for( 0 => int i; i < w.dim(); i++ ) { wordVector[i] * multiplier +=> exprVector[i]; } break; } else { expr.substring(0, pos) => word; w.getVector(word, wordVector); for( 0 => int i; i < w.dim(); i++ ) { wordVector[i] * multiplier +=> exprVector[i]; } expr.substring(pos + 1) => expr; if( expr.charAt(0) == '+' ) { 1.0 => multiplier; expr.substring(2) => expr; } else { -1.0 => multiplier; expr.substring(2) => expr; } } } string results[k]; w.getSimilar( exprVector, k, results ); return results; } } [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,233,377] @=> int fibonacci[]; for(0 => int i; i < fibonacci.cap(); i++){ execute(["go","me","we",Std.itoa(fibonacci[i]),Std.itoa(fibonacci[i]),Std.itoa(fibonacci[i])]); chout <= IO.newline(); chout.flush(); chout <= IO.newline(); chout.flush(); chout <= IO.newline(); chout.flush(); }