// voice2music.ck // copyright 2007 Les Hall // converts mic input to something like the galaga bees talking // our patches adc => Gain g1 => LPF lpf => FFT fft =^ Centroid cent => blackhole; IFFT ifft => Gain g2 => dac; // set controlling parameters 4096 => int num_samples; // number of samples per fft, use binary multiple 2 => float overlap_factor; // overlaps the fft window, use number > 1 0.005 => float noise_threshold; // threshold of noise // set gains 1.0 => g1.gain; 1.0 => g2.gain; // set up low pass filter lpf.freq(20000); // set up fft and ifft num_samples => fft.size; num_samples => ifft.size; Windowing.hamming(num_samples) => fft.window; Windowing.hamming(num_samples) => ifft.window; // declare variables num_samples / 2 => int num_freq; complex spec_out[num_samples/2]; ((num_samples / overlap_factor) $ float) / (second / samp) => float frm; // determine frequency multiplier // create one note fun void note(float f, float a, float d) { // calculate the frequency index (f * frm) $ int => int fi; // clear out the spectrum for (0 => int i; i < num_freq; i++) #(0, 0) => spec_out[i]; // fill in the samples if (1 * fi <= num_freq) #(0.7, 0) * a => spec_out[1 * fi]; if (2 * fi <= num_freq) #(1.0, 0) * a => spec_out[2 * fi]; if (3 * fi <= num_freq) #(0.6, 0) * a => spec_out[3 * fi]; if (4 * fi <= num_freq) #(0.6, 0) * a => spec_out[4 * fi]; if (5 * fi <= num_freq) #(0.6, 0) * a => spec_out[5 * fi]; if (6 * fi <= num_freq) #(0.3, 0) * a => spec_out[6 * fi]; if (7 * fi <= num_freq) #(0.2, 0) * a => spec_out[7 * fi]; if (8 * fi <= num_freq) #(0.1, 0) * a => spec_out[8 * fi]; if (9 * fi <= num_freq) #(0.1, 0) * a => spec_out[9 * fi]; // loop through d durations of time for (0 => int i; i < d; i++) { // do ifft on the transformed spectrum ifft.transform(spec_out); // advance time ifft.size()::samp / overlap_factor => now; } } // control loop num_samples::samp => now; while( true ) { // get the centroid value cent.upchuck(); cent.fval(0) * (second / samp) / overlap_factor / 2 => float frequency; // calculate the total signal amplitude 0 => float sum; for (0 => int i; i < num_freq; i++) if (fft.fval(i) > noise_threshold) fft.fval(i) +=> sum; sum => float amplitude; // play the note note(frequency, amplitude, 1); //1::second => now; }