// chuck2POVRay1.ck // copyright 2007 Les Hall // This software released under the GNU General Protective License // experiments in visualization of music using chuck to produce POV-Ray code // control variables 10 => float k; // time multiple to wait between samples. get all samples: k=1 10 => int ns; // number of samples to take 4 => int n; // base resolution, must be a binary integer n * n * n * n => int num_samples; // number of samples in each FFT num_samples / 2 => int num_freq; // number of frequencies in each FFT output // the patch(es) adc => Gain g => LPF lpf => FFT fft => blackhole; // set controlling parameters // set gains 1.0 => g.gain; // set lpf 10000 => lpf.freq; // set fft num_samples => fft.size; Windowing.hamming(num_samples) => fft.window; // declare variables int t; float time; float dtime; float total_time; complex samples[num_freq]; int peak; float max_peak; float base[3]; float cap[3]; float radius; // output header text // this is the camera <<<"camera { location <0, 0, 3> look_at <0, 0,", 0, "> }">>>; // this is the light source <<<"light_source { <5, 5, 5>, rgb <1, 1,", 1, "> }">>>; // this is the sky sphere <<<"sky_sphere { pigment { rgb<1, 1,", 1, "> } }">>>; // time loop num_samples::samp => now; 0 => t; 1.0 / (ns $float) => dtime; while (t < ns) { // take fft fft.upchuck().cvals() @=> samples; // find the peak value in the fft 0 => peak; 0.0 => max_peak; for (0 => int i1; i1 < num_freq; i1++) { if ((samples[i1] $ polar).mag > max_peak) { i1 => peak; (samples[i1] $ polar).mag => max_peak; } } // normalize the fft so that largest sample is 1.000 and all others are proportional for (0 => int i1; i1 < num_freq; i1++) { samples[i1] / max_peak => samples[i1]; } // loop thru the fft and encode the frequencies as a chain of cylinders 0.0 => base[0]; 0.0 => base[1]; 0.0 => base[2]; 0.1 => radius; (t $ float) / (ns $float) => time; <<<"// ", t, "of", ns>>>; for (0 => int i1; i1 < num_freq; i1++) { base[0] + samples[i1].re => cap[0]; base[1] + samples[i1].im => cap[1]; base[2] + 0.0 => cap[2]; <<< "cylinder { <", base[0], ",", base[1], ",", base[2], ">, ">>>; <<< " <", cap[0], ",", cap[1], ",", cap[2], ">,", radius >>>; <<< "pigment { rgb <1, 1, 1> transmit 1 - ((clock >", time, ") & (clock <", time + dtime, ")) } }">>>; cap[0] => base[0]; cap[1] => base[1]; cap[2] => base[2]; } // advance time t++; k * num_samples::samp => now; } (num_samples::samp * ns * k) / (1::second) => total_time; <<< "// total time in seconds =", total_time >>>;