// FFTbars.ck // copyright 2007 Les Hall // This software released under the GNU General Protective License // Makes an FFT built of cylinders for POV-Ray animation // control variables 12 => int frames_per_second; // FPS 60 => int animation_duration; // in seconds frames_per_second * animation_duration => int num_ffts; // number of FFT's to sample 32768/16 => int num_samples; // number of FFT samples num_samples / 2 => int num_freq; // number of FFT frequencies 0.001 => float noise_threshold; // below this is noise 32768/16/16 => int k; // divisor of spectrum to visualize // the FFT patch dac => FFT fft => blackhole; num_samples => fft.size; Windowing.hamming(num_samples) => fft.window; // declare variables float fsamples[num_freq]; // one frequency sample set float history[num_ffts][num_freq]; // complete history of ffts int f1; // freqency counter int t; // time counter // time loop for (0 => t; t < num_ffts; t++) { // take the FFT fft.upchuck(); // save samples for (0 => f1; f1 < num_freq; f1++) { fft.fval(f1) => history[t][f1]; } // advance time 1::second / frames_per_second => now; } // print out the POV-Ray code // output header text // these are the include files <<<"#include \"colors.inc\"", " ">>>; <<<"#include \"textures.inc\"", " ">>>; <<<"#include \"finish.inc\"", " ">>>; // these are the settings <<<"global_settings", "{">>>; <<<" assumed_gamma", "1">>>; <<<" max_trace_level 256", " ">>>; <<<"}", " ">>>; // this is the camera <<<"camera { location <0, 0, -10> look_at <0, 0, 0> rotate <0, -360*clock, 0>", "}">>>; // this is the light source // add the light sources <<<"light_source {", " ">>>; <<<" <-5, 5, -5>, rgb <1, 1, 1>", " ">>>; <<<"}", " ">>>; <<<"light_source {", " ">>>; <<<" <-5, 5, 5>, rgb <1, 1, 1>", " ">>>; <<<"}", " ">>>; // save magnitude of fft history array to POV-Ray <<<"#declare fft_hist = array[", num_ffts, "][", num_freq/k, "]{">>>; for (0 => t; t < num_ffts; t++) { <<<"{", " ">>>; for (0 => f1; f1 < num_freq/k; f1++) { if ((history[t][f1] $ polar).mag < noise_threshold) { <<>>; } else { <<<(history[t][f1] $ polar).mag, ",">>>; } } <<<"},", " ">>>; } <<<"}", " ">>>; // draw FFT for (0 => f1; f1 < num_freq/k; f1++) { f1/(num_freq - 1.0) * k => float fn; <<<"object {", " ">>>; <<<" cylinder {<", -5+10*fn, ", -3, 0>">>>; <<<" <", -5+10*fn, ", -3+70*fft_hist[clock *", num_ffts-1, "][", f1, "], 0 >,", 4.0/(num_freq/k), "}">>>; <<<" interior {", " ">>>; <<<" ior 1.5", " ">>>; <<<" }", " ">>>; <<<" pigment { rgb<", 1-fn, ",", fn, ", 0> }", " ">>>; <<<"}", " ">>>; }