// instantiate Word2Vec model; // pre-trained model to load me.dir() + "glove-wiki-gigaword-50.txt" => string filepath; // load pre-trained model (see URLs above for download) if( !model.load( filepath ) ) { <<< "cannot load model:", filepath >>>; me.exit(); } // starter art description words with positive connotations ["fine", "joy", "exciting", "inspiring", "artful", "playful", "amazing", "optimistic", "sublime", "meta", "inquisitive", "powerful", "empowering", "biting", "game-changing", "transformative", "kino", "peak"] @=> string positives[]; ["god-tier" , "peak fiction", "making Ge happy", "a gift from god", "fucking beautiful", "based af", "S U B L I M E", "good shit my guy", "real hot girl shit", "sublime af", "sublime af fr on god no cap"] @=> string super_positives[]; // starter art description words with negative connotations ["sad", "boring", "meh", "worried", "tired", "unoriginal", "marginalizing", "unintelligible", "powerless", "derivative", "unfinished", "cringey", "dreadful", "horrible", "trash", "disgusting", "gross", "unlikeable", "garbage", "convoluted", "tone-deaf"] @=> string negatives[]; ["an insult to life itself", "a steaming pile of shit", "worse than a toxic relationship", "like stubbing your toe", "tone-deaf af", "scary (in a bad way)", "fake af", "giving us nothing", "small (in terms of impact)", "making me think of my shitty ex", "making Ge sad"] @=> string super_negatives[]; // starter "i feel" emotion words with other connotations ["numb", "nothing", "weird", "meh", "disjointed", "scattered", "complicated", "sus" ] @=> string others[]; ["complicated but not in a bad way but and more in a way I can't describe", "ineffable", "making me hungry", "not particularly memorable in a bad way", "making me think about the immortality of the crab", "distracting me from my work", "making me turn off my brain"] @=> string super_others[]; // conditions 5=> int LINES_PER_STANZA; 3 => int NUM_SECTIONS; // here each section is a fixed stanzas format // number of nearest words to retrieve for each word // higher this number the higher the variance per word 10 => int K_NEAREST; // timing 400::ms => dur T_WORD; // duration per word false => int shouldScaleTimeToWordLength; // longer words take longer? T_WORD => dur T_LINE_PAUSE; // a little pause after each line T_WORD * 2 => dur T_STANZA_PAUSE; // pause after each stanza // sound ModalBar crystal => Gain left => dac.left; crystal => Gain right => dac.right; 1 => crystal.preset; // feedback delay for echos left => DelayL DL => left; .5 => DL.gain; T_WORD*1.5 => DL.max => DL.delay; right => DelayL DR => right; .3 => DR.gain; T_WORD*2 => DR.max => DR.delay; // current word string feeling; string super_feeling; // word vector float vec[model.dim()]; // search results string words[K_NEAREST]; // line break chout <= IO.newline(); chout.flush(); // loop over stanzas for( int s; s < NUM_SECTIONS; s++ ) { // grab a word out of the "good" bag positives[Math.random2(0,positives.size()-1)] => feeling; // print a stanza stanza( feeling, LINES_PER_STANZA, 50, 66, "positive" ); // grab a word out of the "bad" bag negatives[Math.random2(0,negatives.size()-1)] => feeling; // print a stanza stanza( feeling, LINES_PER_STANZA, 50, 65, "negative" ); // grab a word out of the "other" bag others[Math.random2(0,others.size()-1)] => feeling; // print a stanza stanza( feeling, LINES_PER_STANZA, 38, Math.random2(35,38)*2, "other" ); endStanza(); chout <= IO.newline() <= IO.newline(); chout.flush(); // pause at end of line T_STANZA_PAUSE => now; } // print at the end chout <= "\"Is this art?\"" <= IO.newline(); chout <= "-- A stream of unconsciousness poem that rates itself!" <= IO.newline(); chout.flush(); // print a stanza from a starter feeling word fun void stanza( string feeling, int numLines, int pitch1, int pitch2, string mode ) { // loop over lines in a stanza for( int n; n < numLines; n++ ) { Math.randomf() => float super_prob; // a line say("this"); play(pitch1); wait(); say("particular"); wait(); say("piece"); wait(); play(pitch1); wait(); say("of"); wait(); say("art"); play(pitch1); wait(); say("is"); wait(); if (super_prob > 0.33) { say(feeling); play(pitch2); wait(); } else { if (mode == "positive") { super_positives[Math.random2(0,super_positives.size()-1)] => super_feeling; } else if (mode == "negative") { super_negatives[Math.random2(0,super_negatives.size()-1)] => super_feeling; } else { super_others[Math.random2(0,super_others.size()-1)] => super_feeling; } say(super_feeling); play(pitch2); wait(); } endl(); wait(); // get similar words model.getSimilar( feeling, words.size(), words ); // choose one at random words[Math.random2(0,words.size()-1)] => feeling; } // next line! chout <= IO.newline(); chout.flush(); // pause at end of line T_LINE_PAUSE => now; } fun void endStanza() { // stanza break; no new sound for now say("maybe"); wait(); say("i"); wait(); say("should"); wait(); say("try"); wait(); say("to"); wait(); say("think"); wait(); say("about"); wait(); say("myself"); wait(); say("a"); wait(); say("bit"); wait(); say("more..."); wait(); } // 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(); } // sonify fun void play( int pitch ) { play( pitch, Math.random2f(.8,1) ); } // sonify fun void play( int pitch, float velocity ) { // convert pitch to frequency and set it pitch => Std.mtof => crystal.freq; // note on velocity => crystal.noteOn; } // wait fun void wait() { wait( T_WORD ); } // wait fun void wait( dur T ) { // let time pass, let sound...sound T => now; } // new line with timing fun void endl() { endl( T_WORD ); } // new line with timing fun void endl( dur T ) { // new line chout <= IO.newline(); chout.flush(); // let time pass T => now; }