// Poem lovehate test // Second Poem Etude 1 // A poem that transitions from love to hate, or hate to love // instantiate Word2Vec model; // pre-trained model to load me.dir() + "glove-wiki-gigaword-50-tsne-2.txt" => string filepath; // load pre-trained model (see URLs above for download) if( !model.load( filepath ) ) { <<< "cannot load model:", filepath >>>; me.exit(); } //copying Word2Vec helper functions from word2vec-basic.ck 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; } } } // return string results[k]; w.getSimilar( exprVector, k, results ); return results; } // logical analogy: A to B is as C is to [what this function returns] fun static string[] analogy( Word2Vec @ w, string A, string B, string C, int k ) { // the vector sum B + " - " + A + " + " + C => string v; return eval( w, v, k ); } } //<<< "vector associated with 'love' is:", "" >>>; float love[model.dim()]; model.getVector("love", love); //for( int i; i < love.size(); i++ ) { chout <= love[i] <= " "; } //chout <= IO.newline(); //<<< "vector associated with 'hatred' is:", "" >>>; float hate[model.dim()]; model.getVector("hatred", hate); //for( int i; i < hate.size(); i++ ) { chout <= hate[i] <= " "; } //chout <= IO.newline(); //<<< "vector associated with 'indifference' is:", "" >>>; float indifference[model.dim()]; model.getVector("indifference", indifference); //for( int i; i < indifference.size(); i++ ) { chout <= indifference[i] <= " "; } //chout <= IO.newline(); //creating directional vector pointing from love towards hate float LHdiff[model.dim()]; hate[0] - love[0] => LHdiff[0]; hate[1] - love[1] => LHdiff[1]; //<<< "vector difference 'hate' - 'love':", "" >>>; //for( int i; i < LHdiff.size(); i++ ) { chout <= LHdiff[i] <= " "; } //chout <= IO.newline(); //creating directional vector pointing from hate towards indifference float HIdiff[model.dim()]; indifference[0] - hate[0] => HIdiff[0]; indifference[1] - hate[1] => HIdiff[1]; //<<< "vector difference 'indifference' - 'hate':", "" >>>; //for( int i; i < HIdiff.size(); i++ ) { chout <= HIdiff[i] <= " "; } //chout <= IO.newline(); SndBuf buffy => NRev r => dac; me.dir() + "train15.wav" => buffy.read; 0.5 => float gain; 0.0 => float reverb; 0 => int position; gain => buffy.gain; reverb => r.mix; position => buffy.pos; fun string vec2word(float lyricvec[]) { // number of nearest words to retrieve for each word // higher this number the higher the variance per word 1 => int K_NEAREST; // search results string words[K_NEAREST]; // get similar words model.getSimilar( lyricvec, words.size(), words ); // choose one at random words[Math.random2(0,words.size()-1)] => string lyric; //output new word return lyric; } 190::ms => dur T_WORD; // wait function taken from poem-i-feel fun void wait() { wait( T_WORD ); } // wait fun void wait( dur T ) { // let time pass, let sound...sound T => now; } //say function taken from poem-i-feel.ck // say a word with space after fun void say( string word ) { say( word, " " ); } // say a word fun void say( string word, string append ) { // print it chout <= word <= append; chout.flush(); } //assigning lyric numbers to make looping easier (hard-coded message) //"love" => string lyric1; //"makes" => string lyric2; //"the" => string lyric3; //"world" => string lyric4; //"go" => string lyric5; //"around" => string lyric6; float L1vec[model.dim()]; float L2vec[model.dim()]; float L3vec[model.dim()]; float L4vec[model.dim()]; float L5vec[model.dim()]; float L6vec[model.dim()]; model.getVector("love", L1vec); model.getVector("makes", L2vec); model.getVector("the", L3vec); model.getVector("world", L4vec); model.getVector("go", L5vec); model.getVector("around", L6vec); chout <= IO.newline(); chout.flush(); chout <= IO.newline(); chout.flush(); <<<"They say love makes the world go around.", " ">>>; wait(10*T_WORD); <<<"This begs the questions, what about hate?", " ">>>; chout <= IO.newline(); chout.flush(); wait(10*T_WORD); say("love"); wait(); say("makes"); wait(); say("the"); wait(); say("world"); wait(); say("go"); wait(); say("around"); wait(); wait(10*T_WORD); chout <= IO.newline(); chout.flush(); //selecting number of steps between love and hate 5 => int steps; 0.2 => float dec; 0.01 => float g; 0.025 => float rev; // for loop printing lines from love towards hate for( 0 => int foo; foo < 5 ; foo++ ) { dec*LHdiff[0] +=> L1vec[0]; dec*LHdiff[1] +=> L1vec[1]; vec2word(L1vec) => string lyric1; say(lyric1); wait(); g +=> gain => buffy.gain; rev +=> reverb => r.mix; dec*LHdiff[0] +=> L2vec[0]; dec*LHdiff[1] +=> L2vec[1]; vec2word(L2vec) => string lyric2; say(lyric2); wait(); g +=> gain => buffy.gain; rev +=> reverb => r.mix; dec*LHdiff[0] +=> L3vec[0]; dec*LHdiff[1] +=> L3vec[1]; vec2word(L3vec) => string lyric3; say(lyric3); wait(); g +=> gain => buffy.gain; rev +=> reverb => r.mix; dec*LHdiff[0] +=> L4vec[0]; dec*LHdiff[1] +=> L4vec[1]; vec2word(L4vec) => string lyric4; say(lyric4); wait(); g +=> gain => buffy.gain; rev +=> reverb => r.mix; dec*LHdiff[0] +=> L5vec[0]; dec*LHdiff[1] +=> L5vec[1]; vec2word(L5vec) => string lyric5; say(lyric5); wait(); g +=> gain => buffy.gain; rev +=> reverb => r.mix; dec*LHdiff[0] +=> L6vec[0]; dec*LHdiff[1] +=> L6vec[1]; vec2word(L6vec) => string lyric6; say(lyric6); wait(); g +=> gain => buffy.gain; rev +=> reverb => r.mix; chout <= IO.newline(); chout.flush(); wait( 5 * T_WORD); g +=> gain => buffy.gain; rev +=> reverb => r.mix; } chout <= IO.newline(); chout.flush(); wait( 5 * T_WORD); <<<"But is hatred truly the opposite of love, or is it the absence of all emotion: indifference.", " ">>>; wait(10*T_WORD); <<<"Does indifference power anything?", " ">>>; chout <= IO.newline(); chout.flush(); wait(10*T_WORD); // for loop printing lines from love towards hate for( 0 => int foo; foo < steps ; foo++ ) { dec*HIdiff[0] +=> L1vec[0]; dec*HIdiff[1] +=> L1vec[1]; vec2word(L1vec) => string lyric1; say(lyric1); wait(); 2*g -=> gain => buffy.gain; rev -=> reverb => r.mix; dec*HIdiff[0] +=> L2vec[0]; dec*HIdiff[1] +=> L2vec[1]; vec2word(L2vec) => string lyric2; say(lyric2); wait(); 2*g -=> gain => buffy.gain; rev -=> reverb => r.mix; dec*HIdiff[0] +=> L3vec[0]; dec*HIdiff[1] +=> L3vec[1]; vec2word(L3vec) => string lyric3; say(lyric3); wait(); 2*g -=> gain => buffy.gain; rev -=> reverb => r.mix; dec*HIdiff[0] +=> L4vec[0]; dec*HIdiff[1] +=> L4vec[1]; vec2word(L4vec) => string lyric4; say(lyric4); wait(); 2*g -=> gain => buffy.gain; rev -=> reverb => r.mix; dec*HIdiff[0] +=> L5vec[0]; dec*HIdiff[1] +=> L5vec[1]; vec2word(L5vec) => string lyric5; say(lyric5); wait(); 2*g -=> gain => buffy.gain; rev -=> reverb => r.mix; dec*HIdiff[0] +=> L6vec[0]; dec*HIdiff[1] +=> L6vec[1]; vec2word(L6vec) => string lyric6; say(lyric6); wait(); 2*g -=> gain => buffy.gain; rev -=> reverb => r.mix; chout <= IO.newline(); chout.flush(); wait(5 * T_WORD); } chout <= IO.newline(); chout.flush();