// Define first passage "He suddenly saw how fertile was the ground into which he had fallen, and with this realization, the terrible purpose filled him, creeping through the empty place within, threatening to choke him with grief. He had seen two main branchings along the way ahead…He had seen a warrior religion there, a fire spreading across the universe with the Atreides green and black banner waving at the head of fanatic legions drunk on spice liquor. " => string passage_one; // Define second passage "The Messiah's imperial missionaries carried their religious war across space in a Jihad whose major impetus endured only twelve standard years, but in that time, religious colonialism brought all but a fraction of the human universe under one rule. He did this because capture of Arrakis, that planet known more often as Dune, gave him a monopoly over the ultimate coin of the realm -- the geriatric spice, melange, the poison that gave life. " => string passage_two; // line string line[0]; // instantiate word2vec model Word2Vec model; // pre-trained model to load "glove-wiki-gigaword-50-tsne-2.txt" => string filepath; <<< "loading model:", filepath >>>; <<< "(this could take a few seconds)...", "" >>>; model.load( filepath ); // define tokenizer StringTokenizer tok; // make a ConsoleInput ConsoleInput in; string prompt; // create vectors for first passage tok.set(passage_one); 0 => int i; float passage_one_sentence_vector[74][model.dim()]; while( tok.more() ) { // put into array line << tok.next().lower(); float vector[model.dim()]; model.getVector( line[line.size()-1], vector ); vector @=> passage_one_sentence_vector[i]; i++; } // create vectors for second passage tok.set(passage_two); 0 => i; float passage_two_sentence_vector[74][model.dim()]; while( tok.more() ) { // put into array line << tok.next().lower(); float vector[model.dim()]; model.getVector( line[line.size()-1], vector ); vector @=> passage_two_sentence_vector[i]; i++; } // define print_vector function for debugging fun void print_vector(float a[]){ "[" => string str; <<< a.cap() >>>; for (0 => int i; i < a.cap(); i++) { str + a[i] + ", " => str; } str + "]" => str; <<< str >>>; } // function that adds two vectors together fun float[] add_vectors(float a[], float b[]){ float new_vec[model.dim()]; for (0 => int i; i < a.cap(); i++) { a[i] + b[i] => new_vec[i]; } return new_vec; } // function that multiplies a vector by a scalar fun float[] multiply_vector_by_scalar(float a[], float c){ float new_vec[model.dim()]; for (0 => int i; i < a.cap(); i++) { a[i] * c => new_vec[i]; } return new_vec; } // function that linearly interpolates between two vectors fun float[] interpolate_vectors(float a[], float b[], float j) { multiply_vector_by_scalar(a, 1 - j) @=> float c[]; multiply_vector_by_scalar(b, j) @=> float d[]; add_vectors(c, d) @=> float e[]; return e; } // ------------ audio: shepard tone generator --------- // starting pitches (in MIDI note numbers, octaves apart) [ 12.0, 24, 36, 48, 60, 72, 84, 96, 108 ] @=> float pitches[]; // number of tones pitches.size() => int N; // bank of tones SawOsc tones[N]; // overall gain Gain gain => Envelope envelope => NRev reverb => dac; 1.0/N => gain.gain; .05 => reverb.mix; // connect to dac for( int i; i < N; i++ ) { tones[i] => gain; } // set envelope envelope.duration(1::second); // increment per unit time (use negative for descending) -.001 => float INC; fun void execute_interpolation(int num_steps) { envelope.keyOn(); for (0 => int j; j < num_steps; j++) { j $ float / (num_steps $ float - 1.0) => float factor; float interpolated_passage_vector[74][model.dim()]; for (0 => int i; i < interpolated_passage_vector.cap(); i++) { passage_one_sentence_vector[i] @=> float a[]; passage_two_sentence_vector[i] @=> float b[]; interpolate_vectors(a, b, factor) @=> interpolated_passage_vector[i]; } "" => string str; for (0 => int i; i < interpolated_passage_vector.cap(); i++) { string words[1]; interpolated_passage_vector[i] @=> float vector[]; model.getSimilar(vector, words.size(), words); str + words[0] + " " => str; } <<< str, "" >>>; 10::second => now; } envelope.keyOff(); } spork ~ shepard(); while(true){ "How many interpolations in total? => " => prompt; in.prompt( prompt ) => now; while (in.more() ) { Std.atoi(in.getLine()) => int entry; execute_interpolation(entry); } } // shepard tone generator fun void shepard() { //-------------------------------------------------------------------- // continuous shepard-risset tone generator // adapted from https://chuck.stanford.edu/doc/examples/deep/shepard.ck //-------------------------------------------------------------------- // mean for normal intensity curve 66 => float MU; // standard deviation for normal intensity curve 42 => float SIGMA; // normalize to 1.0 at x==MU 1 / Math.gauss(MU, MU, SIGMA) => float SCALE; // unit time (change interval) 5::ms => dur T; // infinite time loop while( true ) { for( int i; i < N; i++ ) { // set frequency from pitch pitches[i] => Std.mtof => tones[i].freq; // compute loundess for each tone Math.gauss( pitches[i], MU, SIGMA ) * SCALE => float intensity; // map intensity to amplitude intensity*96 => Math.dbtorms => tones[i].gain; // increment pitch INC +=> pitches[i]; // wrap (for positive INC) if( pitches[i] > 120 ) 108 -=> pitches[i]; // wrap (for negative INC) else if( pitches[i] < 12 ) 108 +=> pitches[i]; } // advance time T => now; } }